OpenSSH

From HerzbubeWiki

Jump to: navigation, search

Contents

Overview

This page provides information about configuring and using SSH (or rather, the quasi-standard OpenSSH implementation).


References

http://www.securityfocus.com/infocus/1810 
A very good introductory article about user identities.
http://www.securityfocus.com/infocus/1812 
A very good introductory article about using ssh-agent


Debian packages

The following Debian package needs to be installed:

ssh

This is a meta package which resolves to

openssh-server
openssh-client


Server configuration

Global configuration

So far, no manual configuration has been necessary.

For future reference:

  • the daemon's configuration is located in
/etc/ssh/sshd_config
  • the (unencrypted) private and public host keys are located in
/etc/ssh/ssh_host_dsa_key
/etc/ssh/ssh_host_dsa_key.pub
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub


Per user configuration

To allow login by public/private key instead of password-based, those public keys that are allowed to login must be listed in

~/.ssh/authorized_keys

To quote from man sshd: "The content of the file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others.". My personal file therefore looks like this:

patrick@pelargir:~$ l .ssh
total 12
drwxr-xr-x 2 patrick patrick 4096 Jun 11 21:04 .
drwxr-xr-x 8 patrick patrick 4096 Jul 13 20:00 ..
-rw------- 1 patrick patrick  725 Nov 12  2009 authorized_keys
patrick@pelargir:~$ cat .ssh/authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCuR259CxKjoSQd7cHy0IkXoUbmjqhTHkrSBX1NlZll0OluMVqZ/Pj6ntf4oqPL [...]

Note: See this HOWTO on the PGP page for a instructions on how to use GnuPG to generate an RSA key that is usable for SSH authentication.


Client configuration

Location of configuration files

The client's configuration is located in these files:

  • /etc/ssh_config : Default configuration for all users on the machine
  • ~/.ssh/config : User-specific configuration


Identity/Public key authentication

Instead of providing a password for authentication, it is also possible to identify using an RSA or DSA public/private keypair. Basically it works like this:

  • You generate a keypair
  • You copy the public key to the remote machine and add it to the file ~/.ssh/authorized_keys in the target user's home directory
  • You keep the private key on the local machine in the file ~/.ssh/id_rsa (if it's an RSA key) in your home directory
  • You initiate an SSH session
  • SSH asks you for the private key's passphrase
  • If the passphrase is correct, the login will be successful.
  • If you don't want to enter the passphrase for each new SSH session, you have to either use an unencrypted private key (BAD idea), or use ssh-agent (see appropriate section further down)
  • Note: When logging in, the private key is never transmitted from local to remote machine! Instead the two machines work out a challenge that can only be "solved" by the local machine when it has access to the decrypted private key. When the user supplies the correct passphrase, the local machine gains access to the decrypted private key, can "solve" the challenge and therefore prove to the remote machine that the local user is indeed who he claims to be. To see all the stuff that happens behind the scenes during a login, use the command line option -v.


To create an RSA public/private keypair (public key is stored in ~/.ssh/id_rsa.pub, private key is stored in ~/.ssh/id_rsa):

ssh-keygen -t rsa

To view the fingerprint of an RSA key (using the public part of the keypair):

ssh-keygen -lf id_rsa.pub


Multiple identities

  • If you want to allow multiple identities to login to a remote account, that account's authorized_keys file must contain a list of all those keys.
  • If you want to have multiple identities on your local machine, each identity's private key must be placed in its own file. You then have to select the appropriate identity file using the -i command line option, or the identity file must be specified on a per-host basis in SSH's configuration file ~/.ssh/config. For instance, to use a different identity for each different user on a remote system, place the following snippet in ~/.ssh/config:
Host pelargir pelargir.herzbube.ch
# %r expands to the remote user name
IdentityFile ~/.ssh/%r.id_rsa


Multiple identities (roles) with which to connect to the same remote account

A real-life example that I use to distinguish between the administrator and user roles when working with Gitosis (see the Git page on this wiki):

Host gitosis-admin
HostName pelargir
User gitosis
IdentityFile ~/.ssh/admin.id_rsa
IdentitiesOnly yes

Host gitosis-user
HostName pelargir
User gitosis
IdentityFile ~/.ssh/patrick.id_rsa
IdentitiesOnly yes

What does this mean?

  • We have defined two host aliases: One is called "gitosis-admin", the other "gitosis-user"
  • Whenever we refer to one of these aliases in the future, SSH will use the options below the alias to perform the connection to the server
  • If we want to perform administrative duties, we use the alias "gitosis-admin" which will cause SSH to use the "admin" identity
  • If we want to do normal developer work (which hopefully will be most of the time) we use the alias "gitosis-user", which will cause SSH to use the "patrick" identity
  • 'The IdentitiesOnly yes option is required to prevent ssh-agent from offering the wrong key file to SSH. Instead, ssh-agent is forced to only use the identity that is explicitly specified under the host alias. To understand the issue, let's have a look at the following scenario:
    • You have done some work under the normal user identity, which means that ssh-agent has now cached that identity's key
    • Now you want to perform admin work and try to clone the gitosis-admin.git repository - BOOM, cloning does not work and you get a mysterious message "Repository read access denied"
    • What happens here is this: Because ssh-agent has cached the normal user identity key, it offers that key to SSH every time a connection is about to be made. When SSH finds out that the key is allowed to login to the server's gitosis account, it happily accepts and uses the key. Once the connection has been established, SSH hands control over to the Gitosis software which finds out - too late - that the identity used does not have sufficient access rights to read the gitosis-admin.git repository
The problem here is conceptual: SSH only cares about authentication, not authorization - authorization is the domain of the application using SSH (Gitosis in this case). In other words: For SSH, every identity has the same "value": Either it is allowed to login (authenticate) to the remote side, or it is not. Gitosis, though, attaches an additional meaning to identities: Authorization, or access rights. The IdentitiesOnly option must therefore be used to ensure that the proper identity is used on every connection attempt, regardless of the state of the ssh-agent cache at connection time.


Using ssh-agent

If you make repeated connections to the same remote user/host, it quickly becomes tiring to enter the same passphrase for accessing the authenticating RSA key over and over again. One solution would be to store the private key unprotected, i.e. without a passphrase. For obvious reasons, this is not a very good solution.

An alternative is to use the Authentication Agent ssh-agent. ssh-agent will cache a private RSA key once it has been decrypted so that it can be used repeatedly for SSH connections. It works like this:

  • Start ssh-agent, e.g. when you log in.
    • This can be done automatically by adding the appropriate command to ~/.profile or some similar login-hook file.
    • On some systems, automatic startup of ssh-agent might already be configured in a similar way.
    • On Mac OS X, ssh-agent starts automatically when the first SSH connection is made.
  • Use ssh-add to add the desired keys to ssh-agent
    • ssh-agent will prompt you for the passphrase (is this true? or is it ssh-add which does the prompting?)
    • On success, ssh-agent caches the decrypted key
  • Make an SSH connection
    • When ssh would normally require the private key for its operation, it will first query ssh-agent whether or not it has the required key
    • ssh-agent never gives out the key itself. Instead, ssh tells ssh-agent to perform the required operation(s) on its behalf, and ssh-agent returns the operation's result back to ssh
  • ssh-add -L lists all keys cached by ssh-agent
  • ssh-add can also be used to remove keys from ssh-agent


Authenticating Agent Forwarding can be used to create an "authentication chain" that spans multiple systems. If you are logged in to a remote system A and from there would like to make another connection to remote system B, you can setup a forwarding mechanism so that ssh-agent on your local machine will be queried when you make the connection attempt to remote system B. In this way, the private authenticating RSA key never has to leave your local machine. This forwarding mechanism is enabled like this:

ssh -A <host>


In the configuration file, the following enables forwarding:

ForwardAgent yes


X11 Forwarding

The following command logs into a remote system and forwards X11 traffic from that system to the local system (which acts as X server):

ssh -X <host>

Note: It appears that X11 forwarding circumvents access control set up with xhost (at least this is the case on my Mac OS X box). It becomes clearer why this is the case if we look at how ssh sets the DISPLAY variable on the remote system: localhost:10.0. This means that the X11 connection is not made through a normal X11 network connection (which would be protected by xhost), but the connection is made through the SSH connection. To the local X server it appears that a locally launched program (= ssh) wants to display stuff.


X11 forwarding may be enabled by default by adding the following to the local config file (either globally or for specific hosts only):

ForwardX11 yes


Port Forwarding

Port forwarding (tunneling) is similar to X11 forwarding, but more generalized. The following command establishes port forwarding:

ssh -L 9110:mail.example.net:110 shell.example.net

From now on, all connections to localhost:9110 are routed via shell.example.net to port 110 at the destination host mail.example.net. Notes:

  • mail.example.net sees the connection as coming from shell.example.net
  • Traffic between shell.example.net and mail.example.net is not encrypted!!!
  • All locally logged in users can see and use port 9110; this can be either useful or dangerous...
  • Users that are logged in via a remote connection cannot see or use port 9110, unless the user establishing the forwarding tunnel has specified the -g option
  • Ports below 1024 are privileged and can be used for forwarding only with root privileges; this makes sense if you think of a multi-user system where it is not desirable that one user can change an important port such as 25 (SMTP) or 53 (DNS) into a forwarding tunnel, without the other users noticing
  • On the server side, port forwarding can be disallowed by specifying AllowTcpForwarding no in the server config file /etc/ssh/sshd_config. I have read somewhere, though, that this may be circumvented if someone is really determined


Port forwarding may also be enabled through the local config file:

Hostname shell.example.com
LocalForward 9110 mail.example.com:110

Note: Use RemoteForward to establish a "reverse-forwarding" connection, i.e. when you connect to a remote system, a port is forwarded from that remote system back to your local system.


Compression

Useful on a slow network connection: Data transferred over the SSH connection can be gzip compressed with the following command:

ssh -C <host>

Compression may also be enabled by adding the following to the local config file:

Compression yes
CompressionLevel <lvl>

Possible compression levels are 1 (fast, worst compression) to 9 (slow, best compression). The default level is 4.


Cipher selection

It is possible to select the Cipher that should be used for encrypting the SSH connection. Selecting a different cipher is probably most useful for SSH1 connections where the default cipher is the slow 3DES and it is desirable to select a faster cipher such as Blowfish.

The command to select a specific cipher is

ssh -c <cipher_spec> <host>

The cipher can be specified using one of the allowed keywords, or a comma-separated list of such keywords. The allowed keywords differ between SSH1 and SSH2. See the man page for details.


The cipher to use can also be specified in the configuration file (different options for SSH1 and SSH2):

Cipher <cipher>        # SSH1 connections
Ciphers cipher_spec>   # SSH 2 connections


Running remote shell commands

Instead of running an interactive shell on the remote system, it is also possible to run a single command:

ssh <host> ls -l

It is possible to pipe data to the remote command:

tar cf - <srcdir> | ssh <host> 'cat >dest.tar'

(the remote command in this case is enclosed in single quotes to prevent the local shell from evaluating the ">" character)


SSH on the Mac

Outgoing

When a user starts his first SSH session to a remote machine, launchd automatically starts an ssh-agent process in the background, which from then on captures all private keys that are used to login to remote machines. If a private key is protected with a passphrase, a GUI dialog pops up where you have to enter the passphrase (instead of a command line prompt in Terminal.app). Optionally, you can allow the passphrase to be stored in your personal Mac OS X keychain, in which case you will not have to enter the passphrase in the future (the entry into the keychain is made so that ssh-agent, ssh-add and ssh always have access to the passphrase).

Note: If you change or delete a private key file, ssh-agent continues to cache the old key (no doubt with surprising results) until you remove the cached key using ssh-add -d.


X11.app is launched automatically when an SSH connection is made with X11 Forwarding.


Incoming

To allow SSH login to a Macintosh machine, go to Systemsettings->Sharing and enable "remote login" ("Entfernte Anmeldung" on German systems). You must provide admin privileges to do so.

Personal tools
francesca