The following are a number of SSH tips and tricks you will find useful if you use SSH in your daily life. Below each tip is an example of what it looks like to run these commands, captured with the script command.
Logging in is the most basic (and most common) of all tasks with SSH. The most basic form is ssh user@host, where user is your user on the remote host and host is the hostname of the remote machine. If your username on the local machine and remote machine are the same, then the user@ portion can be omitted.
mik@salo ~/articles/ssh % ssh uzimonkey@melug-central.org Password: Last login: Wed Oct 13 20:00:33 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout
If you only need to run a single command, spawning a shell on the remote system may not be necessary. Also, you can pipe the output of remote commands to the input of local commands or vice versa. The form for this command is ssh user@host command arg1 arg2 ... argn.
mik@salo ~/articles/ssh % ssh uzimonkey@melug-central.org uname -a Password: Linux changeling 2.4.21-xxx-default #1 Thu Aug 12 15:22:14 UTC 2004 i586 i586 i386 GNU/Linux mik@salo ~/articles/ssh % echo abcdefg | ssh uzimonkey@melug-central.org sed s/e/3/ Password: abcd3fg
Files may be copied from one machine to another via SSH. The basic form for this command is scp file user@host:/path. It's important to note that path may be either absolute (such as /home/user/some/file) or relative (such as some/file). Remote paths on scp are always relative to your home directory on the remote host. Knowing that, you can even use a blank path if you want to copy something to your home directory like this scp file user@host:. The : must remain in the remote path though, else scp will think user@host is the name of a file to copy on the local host. There is also another option for copying files interactively, sftp, which uses ssh in a very ftp-like manner.
mik@salo ~/articles/ssh % echo "SSH is useful" >testfile mik@salo ~/articles/ssh % scp testfile uzimonkey@melug-central.org: Password: testfile 100% 14 0.0KB/s 00:00 mik@salo ~/articles/ssh % ssh uzimonkey@melug-central.org cat testfile Password: SSH is useful
There is a tiny shortcut that I think is important to bring up. If you notice in the above examples, I have to type uzimonkey@ in front of the host each time. That's 10 or so keystrokes each time, and that can get pretty annoying. I did mention that if your local and remote usernames are the same, you can omit this, but my local username is mik, not uzimonkey. Thankfully, one of the many configuration options for OpenSSH allows you to define a default username for hosts. Your ssh config file is stored in ~/.ssh/config, adding the following two lines to it will allow me to omit the uzimonkey@.
mik@salo ~/articles/ssh % cat >>~/.ssh/config Host melug-central.org User uzimonkey (hit control-D here) mik@salo ~/articles/ssh % ssh melug-central.org Password: Last login: Wed Oct 13 20:03:03 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
Having to remember long hostnames is a pain. The SSH config file makes this easier by providing a HostName option. You can use this to make "address book" type entries in your config file. After I add these lines to ~/.ssh/config, not only will I not have to type my username, but I won't have to type the entire hostname either, I'll just have to type "ssh melug". This same method can be used for all types of things, such as easy access to ssh running on a non-standard port.
mik@salo ~/articles/ssh % cat >>~/.ssh/config Host melug HostName melug-central.org User uzimonkey (hit control-D here) mik@salo ~/articles/ssh % ssh melug Password: Last login: Wed Oct 13 20:03:03 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
SSH has multiple modes of authentication, password being the default. All of the examples above used password authentication. There are, however, other options.
SSH can use a public/private key exchange instead of the normal password authentication method. To really understand what's happening here, a proper explanation of PKI is needed, which is beyond the scope here. Just know that there are two "keys", represented as two files. A private key which you never give out to anyone (called id_dsa), and a public key which others can use to identify with you (called id_dsa.pub). I'll break this example into two sections. First, generating your keys.
mik@salo ~/articles/ssh % cd ~/.ssh mik@salo ~/.ssh % ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/mik/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mik/.ssh/id_dsa. Your public key has been saved in /home/mik/.ssh/id_dsa.pub. The key fingerprint is: cb:ba:88:20:71:e4:cc:94:25:a4:7d:b1:00:ea:fe:1e mik@salo mik@salo ~/.ssh % ls id_dsa* id_dsa id_dsa.pub
As you can see, it asked for a password. This is to "lock" the private key. However, since we're doing this to eliminate the need for any passwords, just hit enter at the password prompts.
Next we have to append the id_dsa.pub file to ~/.ssh/authorized_keys, we can do this by using scp to copy the file to the remote host. After we append the key to the authorized keys file, we should be able to log in without a password. Also, note that I made sure ~/.ssh existed and had the correct permissions (0700) before appending the key.
mik@salo ~/.ssh % scp id_dsa.pub melug-central.org: Password: id_dsa.pub 100% 598 0.6KB/s 00:00 mik@salo ~/.ssh % ssh melug-central.org Password: Last login: Wed Oct 13 20:50:18 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> ls -ld .ssh /bin/ls: .ssh: No such file or directory uzimonkey@changeling:~> mkdir .ssh uzimonkey@changeling:~> chmod 0700 .ssh uzimonkey@changeling:~> cat id_dsa.pub >> ~/.ssh/authorized_keys uzimonkey@changeling:~> exit logout Connection to melug-central.org closed. mik@salo ~/.ssh % ssh melug-central.org Last login: Wed Oct 13 21:25:48 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
As you can see, after I appended the key, I could log back in without it asking for a password. I should mention that this is not exactly the best way of doing things from a security standpoint. If someone captures the the private key from your system, they have full access to the account. It sure is convenient though. Another advantage to using public key authentication is the ability to use one password-protected private key on multiple sites without having to remember multiple passwords. You can store your actual passwords in an encrypted file and have only one password to remember.
Above, I explained the weaknesses of public key authentication. There is another way to authenticate jobs that need to run unattended or to make many ssh sessions less password-intensive. Firstly, create a password-protected key instructions and add the public key to your authorized_keys file on the remote host. Next, run the ssh-agent program with your shell (probably /bin/bash for you, /bin/zsh in my case) as an argument. ssh-agent holds all of your keys in memory and will authenticate for you. To add your keys, use the ssh-add command and give it your private key password. When you're finished and no longer need ssh, type exit to get out of the subshell that ssh-agent started and all of your keys will be forgotten. This is a long example, but I couldn't think of a way to make it much shorter without sacrificing anything.
mik@salo ~/articles/ssh % cd ~/.ssh mik@salo ~/.ssh % ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/mik/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mik/.ssh/id_dsa. Your public key has been saved in /home/mik/.ssh/id_dsa.pub. The key fingerprint is: bd:55:4e:b6:b7:fc:de:c0:b2:28:9e:ee:61:97:88:67 mik@salo mik@salo ~/.ssh % scp id_dsa.pub melug-central.org: Password: id_dsa.pub 100% 598 0.6KB/s 00:00 mik@salo ~/.ssh % ssh melug-central.org Password: Last login: Wed Oct 13 21:45:30 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> cat id_dsa.pub >> ~/.ssh/authorized_keys uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
Now when I ssh to melug-central.org, it will ask for my private key's password.
mik@salo ~/.ssh % ssh melug-central.org Enter passphrase for key '/home/mik/.ssh/id_dsa': Last login: Wed Oct 13 21:46:15 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
Next, start up ssh-agent with your again with your shell run ssh-add
mik@salo ~/.ssh % ssh-agent /bin/bash mik@salo ~/.ssh % ssh-add Enter passphrase for /home/mik/.ssh/id_dsa: Identity added: /home/mik/.ssh/id_dsa (/home/mik/.ssh/id_dsa)
Now I can ssh to melug-central.org multiple times and ssh-agent will authenticate for me. I won't need a password.
mik@salo ~/.ssh % ssh melug-central.org Last login: Wed Oct 13 21:47:12 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed. mik@salo ~/.ssh % ssh melug-central.org Last login: Wed Oct 13 21:48:32 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
Now, I can type exit to get out of the ssh-agent subshell and it will forget all my keys
mik@salo ~/.ssh % exit mik@salo ~/.ssh %
Imagine this situation. You're sitting outside surfing the web on an open 802.11 access point. The traffic is not encrypted (this is an open access point, no WEP), but you want to check your email via POP3. POP3 is not an encrypted protocol, your email password will be being broadcast to anyone willing to receive it. This won't do at all.
Luckily, SSH can tunnel traffic. What does this mean? The SSH client will forward traffic through the encrypted SSH stream to the SSH server. The SSH server will then connect to the remote host (in this case, your mail server). All traffic between you and the SSH server will be encrypted, the POP3 connection will be tunneled through the SSH connection, preventing the POP3 cleartext password from being transmitted to any baddies who might be listening.
The basic form for tunneling traffic is ssh -L local-port:remote-host:remote-port user@host. local-port is the port your SSH client will listen on for connections. remote-host and remote-port define where connections will be tunneled to. user@host should be familiar to you by now, the normal rules apply. So, I'll give an example. I want to check my mail on my Adelphia account from an untrusted network, so I tunnel through the MELUG server. I configure kmail (my mail client) to connect to localhost on port 40000 (an arbitrarily chosen high-numbered port, any unused port over 1024 will work) and everything will be encrypted over the untrusted network.
mik@salo ~/articles/ssh % ssh -L 40000:mail.adelphia.net:110 melug-central.org Password: Last login: Wed Oct 13 22:37:57 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~> echo Keep this traffic open while you\'re checking your mail Keep this traffic open while you're checking your mail uzimonkey@changeling:~> echo Type exit when you\'re finished Type exit when you're finished uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
There are more ways than one to tunnel traffic like in the last trick. A more useful trick is to use dynamic tunneling, which makes your SSH client become a SOCKS 5 proxy, tunneling all traffic through the SSH session. The upside of this? Any network client with SOCKS 5 proxy support can get the full effect of this with minimal effort. The downside? Network clients without SOCKS 5 support won't benefit from this. The basic form for this command is ssh -D local-port user@host where local-port is the port on the local machine you want to bind your SOCKS 5 server to.
mik@salo ~/articles/ssh % ssh -D 7000 melug-central.org Password: Last login: Wed Oct 13 23:24:21 2004 from xx-xx-xxx-xxx.agstme.adelphia.net Have a lot of fun... uzimonkey@changeling:~>
At this point, I can tunnel any traffic through port 7000 on the localhost. So why is this useful? For the same reasons as the last tip. I can configure my web browser to use this proxy server to tunnel its traffic through the SSH tunnel, preventing people on the untrusted networking from seeing what I'm up to. When you're finished using the tunnel, just type exit.
uzimonkey@changeling:~> exit logout Connection to melug-central.org closed.
These are only a few of the things I've found useful using OpenSSH. The OpenSSH team maintains a very good set of man pages, the FAQ is also a good source of information, as are the mailing list archives. The OpenSSH website is http://www.openssh.org/, and of course, if you can't find what you're looking for, there's always Google™!