Presented by Benjamin McMillan & David Hilley on February 28, 2007
Table of Contents
- 1. What is SSH?
- 2. Basic Usage
- 3. Using SCP
- 4. SSH Config File
- 5. SSH Keys
- 5.1. Passphrases
- 5.2. Generating a key
- 5.3. Distributing the key
- 5.4. Finer-grained Key Control
- 6. SSH Agent
- 7. SOCKS Proxy
- 8. Port Forwarding
- 8.1. Local: -L
- 8.2. Remote: -R
- 9. ControlMaster
- 10. SSH Escape Sequences
- 11. VPN Tunneling
NB: All of these tips are to be used on the command line
with OpenSSH. This article doesn’t cover graphical SSH implementations
like Putty, nor does it cover other command line implementations,
although some things might be the same. OpenSSH is the default ssh
client shipped with most popular Linux distributions.
1. What is SSH?
"Secure Shell or SSH is a set of standards and an associated network
protocol that allows establishing a secure channel between a local and
a remote computer. It uses public-key cryptography to authenticate the
remote computer and (optionally) to allow the remote computer to
authenticate the user. SSH provides confidentiality and integrity of
data exchanged between the two computers using encryption and message
authentication codes (MACs). SSH is typically used to log into a remote
machine and execute commands, but it also supports tunneling,
forwarding arbitrary TCP ports and X11 connections; it can transfer
files using the associated SFTP or SCP protocols. An SSH server, by
default, listens on the standard TCP port 22" (Wikipedia: SSH).
2. Basic Usage
To login to server with username user:
$> ssh user@server
You may also run a command on a remote server and immediately
return by suffixing the previous command with what you want to run:
$> ssh user@server command
An example:
$> ssh ben@curie ls
Desktop/
inSpace/
JAZZ/
LUG/
Misc/
Personal/
PHIL/
PHYS/
School/
TCOMM/
Work/
3. Using SCP
SCP allows you to copy files to and from computers over ssh. The
below command copies file from benmcmillan.com to the
current directory (.). You can also do it from one remote server
to another remote server, given they both know about each other
and stuff.
$> scp ben@benmcmillan.com:file .
Note: You must use the "-r" option to copy directories (r means
recursive).
4. SSH Config File
Typing your username for every host is a pain. And so is
specifying specific options (like for some hosts you want
compression, for some you want to forward agent, etc). You
don’t have to! In your .ssh directory, put a file named
"config."
Example .ssh/config:
Host feynman
Host hawking 192.168.1.1 router
Host *.cc.gatech.edu
Run man ssh_config to view documentation
about ssh config files.
5. SSH Keys
You know what’s also a pain? Typing in your password each time.
Furthermore, remembering the password for each server can be very
difficult. Solution? SSH keys (specifically user keys)!
An ssh key is much like a physical key, in that only you has
it, and the server(s) you want to "unlock" with it know about it.
In your .ssh directory you will generate a key (a pair, actually:
private and public), and assuming the servers allow key based
authentication, that’s all you need to login. However, first
you will have to distribute the public key to those servers
so they know about you. This article will not explain the
details of how it works.
Now when you login, instead of asking you for a password, it will
either ask you for your passphrase to unlock the key (same passphrase
for all servers using the same key) or will just let you in, if your
passphrase is blank. Continue reading to add even more convenience!
5.1. Passphrases
A passphrase is a password that unlocks the generated key. Think
of it as a master password. It may be blank, but we suggest only
making it blank if you have other security measures (one of those
is detailed below).
5.2. Generating a key
$> ssh-keygen -t rsa
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): (enter passphrase)
Enter same passphrase again: (enter passphrase)
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
2c:3f:a4:be:46:23:47:19:f7:dc:74:9b:69:24:4a:44 user@mydesktop
5.3. Distributing the key
$> cat .ssh/id_rsa.pub | ssh user@server "cat - >> .ssh/authorized_keys"
All that does is append your public key to the server’s list of
authorized keys (for just your account on that server).
5.4. Finer-grained Key Control
You can limit the power of keys torun certain commands, to only
connect from certain hosts, and disallow things like port forwarding, X
forwarding, etc.
Concrete example:
I use a restricted ssh key to run fetchmail. My mailhome
is baobab.cc.gatech.edu, and I’ve set up a special entry
in my .ssh/config for email checking:
Host email
Hostname baobab.cc.gatech.edu
User davidhi
IdentityFile ~/.ssh/mail_check
LogLevel QUIET
The mail_check key is a special password-less key. In my
authorized_keys file, I have the following prepended before the public key:
command="/usr/sbin/imapd",no-X11-forwarding,no-port-forwarding,
no-agent-forwarding,no-pty ssh-dss A...
This restricts connections made via the key to only running
imapd and disallows X11 forwarding, port forwarding, agent
forwarding and pty access. This means that the password-less
key is locked down (assuming imapd is not compromised) [0].
List of things:
- no-agent-forwarding
- no-port-forwarding
- no-pty
- no-X11-forwarding
- command="command"
- environment="NAME=value"
- from="pattern-list"
- permitopen="host:port"
- tunnel="n"
Notes:
- ‘command’ sets a command to run. Adding no-pty makes the command
8-bit clean for two way data transfer. In command, one can use
$SSH_ORIGINAL_COMMAND to refer to the command the user wants to
execute. Using the shell expression "${SSH_ORIGINAL_COMMAND:-}"
handles the case in which no command is specified gracefully
[1].
- ‘environment’ modifies the environment variables.
- ‘from’ restricts based on the remote host (see ssh patterns).
- ‘permitopen’ allows -L forwarding for specified host/port combinations only.
- ‘tunnel’ sets up VPN tunnels.
[0] Not sure of the original source of this since I’ve been using it since
at least 2003. This might be it, though:
[1] Hint from:
http://www.oreilly.com/catalog/sshtdg/chapter/ch11.html
6. SSH Agent
Even though typing in your key’s passphrase instead of a specific
password is a little better, it is still annoying. Wouldn’t you like
to just enter that passphrase once, and have it unlock your key for
that computer session? SSH Agent is a daemon (a background process)
that keeps track of your keys. It can manage multiple keys, and you
can at any time add an identity/key, remove one, or remove all. When
you use ssh to login to a server, and have a key that the server
knows about (has the associated public key), ssh will ask your agent
if it already has it stored.
6.1. Starting the agent
Sometimes your distribution’s X server will start up the agent
automatically. If it doesn’t, you can either start it automatically
each time, or better, you can add it yourself to an X startup
script. The details of which depends on your environment. For
Gnome, I would put this in /etc/X11/gdm/PreSession/Default.
$> eval `ssh-agent -s`
This will start up the agent, and set some environment variables
which ssh will later use to connect to this agent.
6.2. Adding an identity to the agent
Before things will start working, you must add your key(s)
to the agent. You can do this automatically when you login
to Gnome by adding it to your Gnome session (Startup Programs).
$> ssh-add
That’s it! By default it will add .ssh/id_rsa and .ssh/id_dsa,
which are the most popular key filenames. If you have a custom
key, just suffix the name of the key to that command. If your
passphrase is not blank, it will prompt you for the passphrase,
but this will be the only time you have to enter it (until
the agent stops or you manually remove the identity from the
agent). Confirm that the agent has the key by running:
$> ssh-add -l
7. SOCKS Proxy
Use -D to create a SOCKS proxy.
$> ssh -D 8080 helsinki.cc.gatech.edu
Now set your web browser to use localhost:8080 as a SOCKS5 proxy.
For Firefox, set network.proxy.socks_remote_dns = true and
DNS resolving will occur via the proxy, too.
8. Port Forwarding
8.1. Local: -L
Let’s say there is a network you have access to, but services on
that network can only be seen while you’re on the network. For example,
there is an internal website running on webhost. You can’t access
it from a web browser at home but would like to. This is what ssh
port forwarding is for!
$> ssh -L 80:webhost:80 webhost
This will bind the local port 80 (the first 80) to a tunnel, with the other end
pointing to port 80 (the 2nd 80) of the webhost. You may then access the website
by pointing your browser to http://localhost. However, in the case
of websites, apache won’t respond to localhost, but (for example)
intranet (due to vhosts). You would then need to either edit /etc/hosts and
append intranet to the "127.0.0.1 localhost" line or if you
manage internal DNS, create an A record.
Both hosts need not be the same. Sometimes you can’t directly login
to the server — like a mailserver. You can actually ssh into a server
you can login to via a shell instead, as long as that server has access
to (on the same network as) the server you’re forwarding to.
$> ssh -L 9999:mailserver:110 shellserver -N -f
After that, you can setup your mail app to use localhost:9999 instead.
Also, as illustrated in the last example, you may use -N -f:
- -N tells the client not to execute anything remotely
- -f tells ssh to background
8.2. Remote: -R
Thanks to SecurityFocus.com.
The classic example of using a Remote Forward goes something like
this. You’re at work, and the VPN access is going to be down for maintenance
for the weekend. However you really have some important work to do, but you’d
rather work from the comfort of your desk at home, rather than being stuck at
work all weekend. There’s no way for you to SSH to your work desktop because
it’s behind the firewall.
Before you leave for the evening, you SSH from your work desktop
back to your home network.
.ssh/config:
Host home-with-tunnel
Hostname benmcmillan.com
RemoteForward 2222:localhost:22
User ben
Then you just ssh to ‘home-with-tunnel’! When you get home, ssh into
localhost over port 2222 (using the -p option). Take note this also
illustrates the ability to setup forwards using your config file. Even
more convenience! Yay!
9. ControlMaster
Use ControlMaster auto to speed up remote filename tab completion,
sshfs, or other ssh operations to the same host.
.ssh/config:
Host *
ControlMaster auto
ControlPath ~/.ssh/.sock_%r@%h:%p
Usage:
$> ssh -Nf helsinki.cc.gatech.edu
$> ls ~/.ssh -la | grep sock
.sock_davidhi@helsinki.cc.gatech.edu:22
(Thanks to Robert Edmonds for showing me the usefulness of this
in speeding up things.)
10. SSH Escape Sequences
Escape sequences are only recognized after a newline and are
initiated with a tilde (~) unless you modify it with the -e
flag.
Hit
Supported escape sequences:
~. – terminate connection
~B – send a BREAK to the remote system
~C – open a command line
~R – Request rekey (SSH protocol 2 only)
~^Z – suspend ssh
~# – list forwarded connections
~& – background ssh (when waiting for connections to terminate)
~? – this message
~~ – send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)
~. and ~# are particularly useful.
11. VPN Tunneling
Did you know that ssh can do layer 2 and 3 VPN tunneling?
Check out ssh -w. Example from manpage:
$> ssh -f -w 0:1 192.168.1.15 true
$> ifconfig tun0 10.0.50.1 10.0.99.1 netmask 255.255.255.252