Some Tips To Make SSH/SCP Usage More Convenient

Want to support HowtoForge? Become a subscriber!
 
Submitted by tony2 (Contact Author) (Forums) on Thu, 2008-05-29 13:02. :: Linux | Other

Some Tips To Make SSH/SCP Usage More Convenient

I guess many of us rely heavily on ssh/scp to access/maintain remote hosts. In this short article I would like to share some experiences I find useful for ssh/scp usage.

First let's have a look how things started:

  • In the beginning: ssh 192.168.0.1
  • Then we get another host, this time with a different user id: ssh root@192.168.0.2
  • Since we use those commands quite often and it's not fun to type the ip address over and over, let's simplify this a bit by putting those IP's to /etc/hosts and using hostnames instead of IP's: ssh host1, resp. ssh root@host2
  • Then we got another host to maintain, this time with a non-standard port for ssh: ssh -p 222 admin@host3
  • Hm it's getting a bit messy, let's simplify this: for each host let's have a simple script so we don't need to remember the user id and port to connect. Let's put the above commands to ssh-host1, ssh-host2 and ssh-host3. Great, now we can enjoy the auto-completion feature of shells to access those hosts, and forget all those parameters...
  • Then we need to scp something to these hosts: hm it's getting messy again, let's create another set of scripts for scp...
  • Then we get another host...
  • It's not hard to imagine how this would continue.

I use a simple trick to get out of this mess: I have a simple script named ssh-generic that looks as follows:

#!/bin/bash
port="22"
case "$0" in
*-host1)
    account="myid@192.168.0.1"
    ;;
*-host2)
    account="root@192.168.0.2"
    ;;
*-host3)
    account="admin@192.168.0.3"
    port="222"
    ;;
*)  
    echo "unsupported name: $0"
    exit 1
    ;;
esac

case "$0" in
*/ssh-*)
    echo running ssh -p $port $account "$@"
    ssh -p $port $account "$@"
    ;;
*/scp-to-*)
    echo running scp -P $port "$@" $account:
    scp -P $port "$@" $account:$scpdir
    ;;
*/scp-from-*)
    echo scp -P $port $account:$1 .
    scp -P $port $account:$1 .
    ;;
*) echo "unsupported name: $0" exit 1 ;; esac

Then I make ssh-host1, scp-to-host1 and scp-from-host1 as symlink to the above script (ie ssh-generic). Usage is trivial:

  • To ssh to host1: ssh-host1
  • To copy a file to host1: scp-to-host1 <filename>
  • To copy a file from host1: scp-from-host1 <filename>

Similar for host2 and host3. When we get another host, it's easy to edit ssh-generic, add the relevant entry and make needed symlinks. For example, let's add another host with ip 192.168.0.4, port for ssh 2222 and user id admin2. We want to access this host by simply saying ssh-host4. This turns out to be easy:

  • Edit ssh-generic and add the follwing lines to the right place (left as exercise for readers):
*-host4)
    account="admin2@192.168.0.4"
    port="2222"
    ;;
  • Make ssh-host4, scp-to-host4 and scp-from-host4 as symlink to ssh-generic

A bonus is that we can say in the command line eg ssh-host<Tab> to free ourselves from remembering the hostnames, connection details and hence from making mistakes. There are some cosmetic details that I left out from the script for clarity, like automatically setting the title of current xshell before running ssh/scp, or a dryrun option for the script.

I also have a companion script that can be used to ease uploading ssh keys. I named it "enable-ssh" (a bit poor chosen name, should be renamed to something better) and it looks as follows:

if test -z "$1"; then
        echo Usage: $0 '[-p <port>] <host>'
        exit 1
fi

if ! test -s $HOME/.ssh/id_rsa.pub; then
    ssh-keygen -t rsa
fi

cd
cat $HOME/.ssh/id_rsa.pub | \
    ssh "$@" "mkdir -p .ssh; touch .ssh/authorized_keys; cat >> .ssh/authorized_keys"

Usage:

  • To upload ssh key to a host with the standard port and the same user id: enable-ssh host1
  • To upload ssh key to a host with non-standard port and different user id:
    • First try to ssh to that host to find out the needed parameters (we don't want to remember anything that we have written down, don't we?): ssh-host4
    • The above comment will write the command used to connect to host4: running ssh -p 2222 admin2@192.168.0.4
    • Run in another terminal: enable-ssh -p 2222 admin2@192.168.0.4

That's it. I hope you find this useful.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Tenzer (registered user) on Thu, 2008-05-29 17:47.

I would say that a much better approach is to use the .ssh/config file in your home dir. (create it if it's missing). Then you have all the settings together in one place, and you don't need extra scripts or root privileges for instance to change the hosts file.An example of a host entry in the config file could be: Host server #Name of the host
Hostname 192.168.10.20 #IP address or DNS name
Port 2222 #Custom port number
User root #Username to use
In order to connect to the host, we just type "ssh server" and all the settings defined in the file will be used. It also works with scp.You don't have to be familiar with shell scripting in order to use this, and it is easier to copy the one file around between several clients where you would use it.The best part is that it also works with tab completion when you have typed "ssh " :)

Submitted by fubarza (registered user) on Thu, 2008-05-29 16:28.
Why not use .ssh/config?
Submitted by jadonohu (registered user) on Thu, 2008-05-29 15:08.

I think you can accomplish the same thing a bit more easily with a config file (~/.ssh/config per-user, or /etc/ssh/ssh_config for all users). You can also set tonnes of other options there. See man ssh_config.

I like the enable-ssh script, though.

Submitted by Tenzer (registered user) on Mon, 2008-06-02 07:49.
There is a built in version of that script in most distributions called "ssh-copy-id", it achieves the same thing.
Submitted by thomasiweb (registered user) on Thu, 2008-05-29 14:33.

Have you tried using the config file? I beleive it would be more simple. 

create a config file for you user, usually ~/.ssh/config

 

In it you can put the following

 

host=host1

user=root

 

host=host2

user=admin

port=23230

 

 You can also use wildcards

 

host=*domain.com

port=12345

 

Personnaly I have to connect to many servers as the user admin, so I have the following:

 

host *

user=admin 

 

another useful option is

ControlMaster auto

ControlPath /tmp/%h

this creates a control file in /tmp. This lets you open new sessions on the same host without reauthenticating yoruself. I put this in the host * block.

 

Since scp/rsync etc use ssh, these settings apply to them also. In addition these specify "defaults". For example even though I specify admin as the user for all hosts, if I run ssh root@host it will overwrite the setting and conenct as root.

Hope these help :) 

Submitted by dune73 (registered user) on Thu, 2008-05-29 13:47.

Most of the things discussed in this tutorial are better configured in the ssh_config. Most likely residing at $HOME/.ssh/config

See the man page ssh_config.

You can easily configure ports and users for certain hosts or domains  and all sort of other config options. 

 

Submitted by DonQuichote (registered user) on Thu, 2008-05-29 13:28.

You can put a lot of custom settings per host in the .ssh/config file as well:

Host host_name: the following settings are for this host.

User your_remote_user_name: use this user as default for the above host.

ForwardX11 yes: can be used to run X over SSH (I use this a lot).

Compression yes: If you run SSH over the internet, this may speed up things. Do not use compression over LANs.

CompressionLevel 9: if you need even more compression.

Cipher blowfish: should speed up the connection as well.

 

On some systems (Ubuntu, for instance), a known host is automatically used in autocompletion.

Submitted by tony2 (registered user) on Sun, 2008-06-01 18:05.
Hi all, thanks for your excellent comments. I used this method with other applications in the old days (rsh, telnet, ftp) and was not aware that with ssh, all of this can be done easier via .ssh/config. I wanted to share something and in turn I learned much more from your comments. I hope I will receive similar comments for my next articles :)