scp and ssh

When we need to login a remote machine via ssh, we will do something like

1
ssh <user>@<host> [-p<port>]

where <port> is required if the remote machine’s ssh listens on non-default port number 22, and then type <password> in the prompt.

And sometimes you may need to transfer files between remote machines and local machine, you will do

1
2
scp [-P<port>] [-r] <user>@<host>:<path-to-copy> <local-path-to-save>
scp [-P<port>] [-r] <local-path-to-copy> <user>@<host>:<path-to-save>

where -r flag is needed if you are going to copy a directory, and then type <password> in the prompt.

In order to not to type <password> every time you start a ssh connection, we can use ssh keys. First, generate the ssh key in a local path, like

1
ssh-keygen -t rsa -b 4096 -N <passphrase> -C <comment> -f <keyfile>

where -t flag is for key type, such as rsa, dsa, etc, and -b flag is for key bit length, such as 2048, 4096, etc, and -C flag is for <comment>, can be viewed as an identity of the keyfile, and -f is for <keyfile> whose default value is like id_rsa and generate a file in path ~/.ssh/id_rsa with a public key file in path ~/.ssh/id_rsa.pub. And in this case, we will omit <passphrase>.

If we generate the keyfile with no passphrase and with default path, and copy the content of ~/.ssh/<keyfile>.pub into the ~/.ssh/authorized_keys manually or via

1
2
3
# ??? if no specific configuration, following command only works
#     when <path-to-keyfile> is default value
ssh-copy-id <user>@<host> -p<port>

And now, we can access remote machine without typing <password>.

What if I want to use different sshkey with different remote machine?

What if <host> of remote machine is hard to remember (like ip addresses) or to type (to long to type)?

What if <post> of remote machine is hard to remember?

To make life easier, we can make some configurations of ssh.

Create a configuration file config in ~/.ssh, with something like

1
2
3
4
5
6
7
8
9
10
11
Host                <easy-to-remember-host-name>
    HostName        <host>
    IdentityFile    ~/.ssh/<keyfile>
    User            <user>
    Port            <port>
    *LocalForward    <local port>    <remote host>:<remote port>
    *RemoteForward   <remote port>   <local host>:<local port>
Host                <another easy-to-remember-host-name>
    HostName        <another host>
    IdentityFile    ~/.ssh/<another keyfile>
    User            <another user>

Then,

1
ssh <easy-to-remember-host-name>

is equivalent to

1
ssh <user>@<host> -p<port>

And,

1
ssh <another easy-to-remember-host-name>

is equivalent to

1
ssh <another user>@<another host>

Note that, you can also specify Local Forward and Remote Forward in the config file. And in order to avoid allocating a tty when forwarding, -nNT is useful.

Besides that we can assign other options to both scp and ssh via -o flag. When the first try to connect to a remote end takes place, the message asking for something like remembering new key will prompt. We can use -o "StrictHostKeyChecking no" to avoid prompting of the message.

In order to pull/push to Github via ssh behind a http proxy, you may use the connect program to manage the proxy http connection as:

1
2
3
Host                github.com
    User            git
    ProxyCommand    connect -H <proxy host>:<proxy port> ssh.github.com 443

Note that ssh.github.com and 443 is the real remote url and port as Github doesn’t allow http proxy to its github.com:22.

pscp and pssh

Sometimes you will need to transfer the same files with multiple remote ends or take the same actions on multiple remote ends, repeatedly doing the same work with different hosts is quite cumbersome. Use pscp and pssh will save much efforts.

1
pscp -h <hosts> -l <user> -O <ssh options> <local-path-to-copy> <remote-path-to-save>

The above line shows how to use pscp to transfer local file to multiple remote ends, where <hosts> points to the file containing a list of remote hosts, -l is an option to set login user whose default value is root, and -O flag corresponds to -o of command scp.

Similarly, usage of pssh is as follows:

1
pssh -h <hosts> -l <user> -O <ssh options> <command>

When you try to login in remote ends for the first time, by default you will be asked to confirm new host key and with pscp and pssh you have no chance to confirm it which will finally result in failure. At this point, -O flag is very useful, so that you can use -O "StrictHostKeyChecking no" to login remote ends successfully.

When using pssh you may also meet with following error code caused by wrong <command>:

exit code number meaning comment
1 catchall for general errors miscellaneous errors
2 misuse of shell builtins missing keyword or command or permission problems
126 command invoked cannot execute permission problem or command is not an executable
127 command not found command not found
128 invalid arugment to exit exit only takes integer arguments in the range 0 ~ 255
128 + n fatal error signal n  
130 script terminated by Ctrl + C Ctrl + C is fatal error signal 2
255* exit status out of range exit takes only integer arguments in the range 0 ~ 255

change user

If you want to execute some commands on remote end with some other user account other than the login account, then you will need to change user via su command as following:

1
ssh <user>@<host> -p <port> -o <ssh options> "su - <another user> -c \"<command>\""