SSH Configuration Notes:
Val Schmidt
February, 2002
These notes are compiled to
provide guidance regarding configuration of ssh, and intended to further
clarify those provided in the O'Reilly manual.
Corrections and comments are apreciated and may be sent to vschmidt@ldeo.columbia.edu.
These notes are tailored for
SSH2 and OpenSSH server and client software.
Note the definitions of the
terms below as they will greatly aid in what are sometimes difficult
discussions of exchanges between client and server..
Server:
The computer on which the ssh daemon is running, and the daemon itself..
Client:
The ssh client software through which users connect to the ssh daemon
User: a person.
Also note that serious
confusion can result from not being entirely clear regarding protocol versions
(ssh1 and ssh2) and server and client software (SSH1, SSH2, OpenSSH, etc). For
example, SSH1 software only supports the ssh1 protocol. SSH2 and OpenSSH support the ssh2 protocol
and optionally are backward compatable with the ssh1 protocol. Don't be confused by the fact the most
current version of OpenSSH is v3.0 (Mar 2002) and is often written OpenSSH3.0. There is currently no ssh3 protocol.
I have made every effort to use
lower case when refering to protocols and some combination of lower and upper
case for software.
There is much more than can
be very confusing for a first time user.
SSH1, SSH2 and OpenSSH all have different, but very similar
configuration file locations and names.
Having multiple types of software installed on a single machine, while
possible, is not recommended to reduce the inevitable confusion that
results.
File Permissions for User Configuration Files:
File permissions have caused
so much hair pullying that I'm putting it here right at the top to ensure it's
not missed. All implementations of SSH
have the option to require strict access permissions regarding user
configuration files. This requirement is
on by default and is set with the following line in the sshd config file
/etc/ssh/ssh_config:
StrictModes yes
It is a good idea to leave
the default setting as it provides considerable enhanced security. However, you must have your file permissions
set as described below for features such as Public Key Authorization to
work. IF YOUR PERMISIONS ARE NOT
CORRECT, PUBLIC KEY AUTHENTICATION FAIL AND WILL FALLBACK TO PASSWORD
AUTHENTICATION WITH NO HELPFUL INDICATION WHY.
The following server
configuration files and/or directories must be owned by the account owner or by
root and GROUP and WORLD write permission must be disabled.
$HOME
$HOME/.rhosts
$HOME/.shosts
$HOME/.ssh
$HOME/.ssh.authorized-keys
$HOME/.ssh/authorized-keys2 #Openssh specific for ssh2 protocol.
HINT: On confuguring a new machine through an ssh
session I once set permissions for the .ssh directory in my home directory on the ssh server as specified above. Afterward, I found that I no longer had
access to the .ssh directory. The
problem was that my GROUPID on the server did not match that of the client
computer.
Generating Key Pairs:
Once ssh client software is
installed on a user's machine the user, logged in as him/herself, may run ssh-keygen to create a public and
private key pair. These keys are, by
default, located in the users $HOME/.ssh
directory. Note the following results with varying ssh software:
OpenSSH:
# Create an OpenSSH, RSA-type
key pair called identity and identity.pubfor the ssh1 protocol.
>ssh-keygen
# Create an OpenSSH, RSA-type
key pair called id_rsa and id_rsa.pub for the ssh2 protocol..
>ssh-keygen -t rsa
# Create an OpenSSH, DSA-type
key pair called id_dsa and id_dsa.pub for the ssh2 protocol..
>ssh-keygen -t dsa
# Reformat an OpenSSH key
such that it can be read by an SSH2 client or server. This is required when an OpenSSH client is
configured for public key authentication on an SSH2 server.
>ssh-keygen -e <publickeyfile> >
<newSSH2formattedpublickeyfilename>
SSH2:
Unlike OpenSSH, SSH2 client
software stores keys and configuration files in $HOME/.ssh2. Also unlike OpenSSH, SSH2 client software
requires an implicit list of the keys used for identification and authorization
($HOME/.ssh2/identification and $HOME/.ssh2/authroization respectfully). For example, the contents of $HOME/.ssh2/identification
might look like the following:
IdKey id.dsa
IdKey my_second_private_key
Similarly,
$HOME/.ssh2/authroization might contain:
Key id.dsa.pub
Key my_second_public_key
Not specifying a pass phrase
when prompted will result in your private key being stored in an unencrypted
format on your local computer. In
general you should specify a pass phrase to prevent unfrettered access to other
computers should your client computer be compromised. Note however that scripts written envoking
ssh commands providing a secure version of rsh type commands, require an
unencrypted password. For client
computers operating in this kind of scenario do not enter a pass phrase.
Authentication:
Ssh authentication comes in
two forms – authentication of the server to the client and authentication of
the client to the server.
Authentication of the Server to the Client:
When a client attempts a
connection to a server, the server sends to the client, among other things,
it's host public key, it's server key (different from the host key), and a list
of encryption, compression, and authentication methods the server
supports. The client compares the
server's host key to the user's database of known hosts. This file can be found in $HOME/.ssh/known_hosts (or known_hosts2). If the
server's host key is not found, you will be told that the server is not a
“known” host and asked if you would like to add this server to your list of
known hosts. If you say yes, the server
will send you its host key which will be added to your “known_hosts” file.
In general saying “yes” is
not the best thing to do. The key that
is sent is not encrypted. Anyone
listening will be able to capture the server's host key which might be sufficient
for a knowledgeable person to impersonate that server. A more secure method would be for the system
administrator to gingerly distribute, in some secure way, the host key for the
server which you could then copy into your known_hosts file. All that said, the hassle of securely
distributing a server's public key must be weighed with the relative difficulty
of pulling off a “man-in-the-middle” attack.
In general, unless you're working on classified or mission-critical
things, allowing transfer of the server's host key is probably ok.
In the ssh connection
process, the client and server now negotiate and build a secure encrypted
link. Refer to your handy ssh guide for
the gory details. The next step,
authentication of the client to the server, passes over this encrypted link.
Authentication of the Client to the Server:
There are several different
ways the client (and user) can authenticate with the server. Discussed here are Password Authentication,
and Public-key Authentication.
1. Password Authentication:
Password Authentication, is
simply passing one's server password over an encrypted link. Ssh created the encrypted link and the user
passes the password of his or her account on the server, which uses it's own
standard authenticatoin mechanism (often PAM on Unix systems). This is the default method of client authentication and this is what is
happening when ssh next prompts you for your server password.
2. Public-key Authentication:
Public-key Authentication
differs from Password Authentication in that, rather than passing to the server
the user's server account password, during initial setup, the user's public key
is placed in the user's authorized_keys
file on the server which serves to authenticate the user. Here's how it works:
In initial setup, the user
places a copy of his or her public key on the server by copying the text from
within his or her $HOME/.ssh/id_rsa.pub file
on the client computer to her or her $Home/.ssh/authorized_keys
file on the server. Ensure the
authorized_keys file has the correct ownership and permissions as specifed
above.
During authentication the ssh
client sends to the ssh daemon on the server a unique index of the user's
key. The server uses the index to look
up the user's key in the user's authroized_keys
file described above. If a key is
found, the server generates a challenge in the form of a random string
encrypted with the users public key, and
sends it back to the client. To answer
the challenge, the client must unencrypt the challenge with the user's private
key. However the key itself is encrypted
with the user's pass phrase, therefore the user is prompted to enter it. Once the pass phrase is entered the client
unencrypts the private key, which then unencryptes the challenge string. The challenge string is combined with a
session id and the result is hashed by the client who finally sends the result
back to the server. The server does the
same calculation with it's own copy of the encrypted challenge string and the
session id and if the results match the user is authenticated. Crazy eh?
Ssh agents:
In the discussion described
above regarding public-key authentication, the user was prompted to enter his
or her private key pass phrase which was used to unencrypt their private key
which was in turn used to unencrypt the challenge sent by the server. The would be required for every ssh
connection and might be considered a hassle.
Ssh-agents allow the user to enter his or her pass phrase just a single
time.
An ssh agent is a small piece
of software into which a user's private keys are loaded. With each private key the user authenticates
themselves with the key's corresponding passphrase. Once initially configured, for subsequent ssh
connections, the agent automatically doles out unencrypted forms of the user's
private key for authentication purposes in an automated way.
If a key pair is generated
without a pass phrase, while not the most secure scenario, ssh agents can be
used to automate the connection and authentication processes for scripts that
might run in cron jobs or other such automated functions.
Ssh agents are quirky in that
they are applicable only to the shell in which they are run and child
shells. When an ssh agent is created, it
requires that two environmental variables be set, which are in fact returned
(but not set) by the ssh-agent software when it is initially invoked. To automatically set these variables, these
ssh-agent software can be invoked with the following:
eval `ssh-agent`
#note the backward single quotes
You can see that the
environmental variables are set with the following:
echo $SSH_AUTH_SOCK
echo $SSH_AGENT_PID
Killing the ssh-agent process
does not also unset these environmental variables, however it is important that
they are unset for proper operation. To
ensure these variables are unset, and not have to do it manually, kill
ssh-agents with the following:
eval `ssh-agent -k`
Once an ssh-agent is running,
the user need only add ssh keys to it with the ssh-add command. If none are specified the command wiill add
the user's default ssh key.
Ssh-add
Xforwarding:
Xforwarding is the process by
which a remote computer displays Xwindows on the client computer allowing
client users the ability to interact with the server computer via a windows
interface. Without getting into the
details, Xforwarding requires that the client computer be configured to
external connections to its own Xwindows server, and that the server computer
is configured to send all Xwindows displays to the client computer. The first requirment is met by the user
specifying, for his client computer, that external Xwindows hosts may connect
using the xhosts command.
Xhosts + #Allows connections from any external
compluter
The second requirement is met by the user
logging into the server and setting the DISPLAY environmental variable such
that Xwindows displays point to his client computer, for example:
export
DISPLAY=129.236.95.154:0.0
Now that the two requirements
are met, the user can invoke any X based application from the command line of
their logged in shell and the X windows will display on their local client
computer.
Ssh allows for Xforwarding
over an encrypted link. For ssh server
software to provide encryption for Xforwarding, the software must be explicitly
compiled to support Xforwarding. Luckily
for us Openssh includes this capacity by default with the standard rpm
installation. There's plenty of further
instruciton regarding this in the O'Reilly ssh manual.
Xforwarding is off by default
in Openssh. To enable it generally add
the following line to the server's /etc/ssh/ssh_config
file:
X11Forwarding yes
Disable it on a per user basis by adding the
following to the user's $HOME/.ssh/authorized_keys
file at the beginning of the key for which it applies:
no-X11-forwarding
.....rest of key.....
Finally, on the user's client
computer, the following line must be added to the user's $HOME/.ssh/config file:
X11Forwarding yes
Once configured, any
subsequent ssh sesssions will result in the ssh server software automatically
resetting the user's DISPLAY environmental variable to a value such that any
Xwindows sessions will be forwarded over the encrypted link. Note that the client must still configure the
client computer to allow xhost connections as with unencrypted xforwarding.
Compression:
Openssh allows for the dynamic
compresion of data before it is encrypted, sent over a link where it is then
unencrypted and uncompressed on the other side.
Behind the scenes, the gzip compresion utility is used and the user may
specify one of 9 different compression levels.
Higher compression levels (near 9) result in a smaller number of bytes
sent, but may increase the overall time required to send the information. Consider that for fast connections or
connections in which the user is charged by the minute, compression will be the
limiting factor and should be set to lower numbers. Conversely for connections that are slow or
are charged by the byte transferred, data transfer itself will be the limiting
factor and compression values should be set ot higher numbers. There's a nice table of values for reference
on page 281 of the O'Reilly manual. If
unspecified, the default compression leveel is 6.
Compression in Openssh is off
by default. It may be invoked on a
per-session basis with the -C flag as below:
ssh -C grampus.ewing.ldeo.columbia.edu
Or turn on compresssion for
all sessions by addding the following line to the ssh sever's configuration
file /etc/ssh/ssh_config:
Compression yes
Specify compresssion level
with:
CompressionLevel 2
Port Forwarding:
Port Forwarding is a great
trick to allow standard tcp based services to be tunnelled over an encrypted
ssh link. Local forwarding is used when
the client appplication connection is initiated from the ssh client computer,
while Remote forwarding is used when the client application connection is
initiated from the ssh server computer.
Port Forwarding is enabled by
default in Openssh, however it may be globally diabled on the ssh server by
specifying the following in the /etc/ssh/ssh_config
file:
AllowTCPForwarding no
As an example, lets look at
port forwarding for secure imap connections to an imap mail server that is also
an ssh server. Since the imap client
software initiates the connection to the imap server we use local port
fowarding. The general syntax to create
the ssh tunnel for an IMAP client looks like this:
ssh -L2001:localhost:143 targetsshserver.edu
This lines says “Listen for
connections to my local machine (implied) on port 2001, create a tunnel from port
2001 on my local machine to the sshd target server using the ssh server's
standard ssh port – 22 (implied), then map this connection to port 143 (the
IMAP server port) on the target sshd server, in this case also the imap server (specified by 'localhost').” This is confusing, but note that the
localhost entry in the line above refers not to the client computer, but to the
imap server (and in this case the ssh server as they are one and the same). One could replace 'localhost' with the ip
address of the target ssh server or it's domain name, however for reasons
discussed in the O'Reilly manual localhost is recommended. Alternatively, it is possible that the imap
server could be located on another computer altogether. In this case 'localhost' would be replaced
with the domain name of the imap server computer and the result would be a
secure connection between the imap client computer, and the ssh server with a
non-secure connection on to the imap server.
This scenario is provided in the O'Reilly manual as ideal for remote
login to an imap server located on a secure network through a firewall/bastion
host.
With the line above executed,
an ssh session is created between your local computer and the ssh server, and a
shell prompt is returned from the ssh server.
For the purposes of this IMAP tunnel, this shell is not really
necessary, however to terminate it would also terminate the ssh session and
your tunnel. While other versions of ssh
have a built in way to push this shell into the background, Openssh only
provides for pushing connections into the background if a remote command is
executed with the connection. So one
needs a command that does nothing and takes a long time (at least the duration
of the required imap connection) to execute.
The following will push the ssh session into the background sucessfully:
ssh -f L2001:localhost:143 targetsshserver.edu sleep
1000000
Now that the tunnel is
created and your client software is listening for connections on your local
computer's port 2001, you need only to configure your imap client software to
look to your local computer port 2001 for it's imap connections. Place localhost:2001 in the 'imap server'
enrty in your imap client software and you're all set.
Note: An incompatibility
exists between OpenSSH client software versions <3.0 and SSH2 server
software such that connections over forwarded ports fail. If you find this to be the case upgrade your
OpenSSH client software – it's has a security hole and should be upgraded
anyway.
In a nutshell:
Basic Configuration:
1.Install Openshh client software, ssh-keygen, ssh-add,
ssh-askpass and ssh-server (on the server)
2.Generate a public/private key pair for your user
account and ssh version.
ssh-keygen -r #for
ssh2 with rsa key
3.Copy the server's host key to your $HOME/.ssh/known_hosts file. (Done automatically the first time you log
in, but by passing it over the network in a non-secure way. Best to do via disk.)
4.For Public-key Authentication, copy your public key
(in $HOME/.ssh/id_rsa.pub or id_dsa.pub) to
the server. Put it in your $HOME/.ssh/authorized_keys file.
Agents:
5.Add an ssh-agent for a shell
eval `ssh-agent`
#note backward single quote
or delete an agents
eval `ssh-agent -k`
6.Add your private key to that agent.
ssh-add
or add another specific key to
that agent:
ssh-add id_rsa_key2
or remove a key from the
agent
ssh-add -d id_rsa_key2
or remove all the keys from
the agent
ssh-add -D
7.Modify your .profile (.bash_profile) and .bashrc files
to automatically add an agent at login and have it effective for all shells,
xwindows, etc. spawned from that login.
.bash_profile:
#Create a default ssh agent if ther's not an agent
running already.
#This should be the last line in your .profile
(.bash_profile) unless .bashrc
#is invoked explicitly, in which case this line should
proceed it.
test -z “$SSH_AUTH_SOCK” && exec ssh-agent
$SHELL
.bashrc
# SSH CONFIG
# The following checks to see if the shell is attached
to a tty.
# If so, and if the currently running ssh-agent has no
identities loaded
# (see .bash_profile), it loads my default private
key.
if /usr/bin/tty > /dev/null
then
ssh-add -l |
grep 'no identities' > /dev/null
if [ $? -eq 0 ]
then
ssh-add # Load default identity
fi
fi
8.Create a key pair with no pass phrase to allow spawned
processes or cron jobs to ability to run in an automatic fashion without
requiring a pass phrase from a user.
ssh-keygen -N “” -r id_rsa_2
Copy the public version
(id_rsa_2.pub) to the server's authorized_keys
file (see 4 above).
Create an agent in the cron
job or process
...
exec ssh-agent $SHELL
....
Add the new key
ssh-add id_rsa_2
9.Configure secure email via ssh tunnel to an IMAP
server
# Create an ssh tunnel
between a random port on the local host and the IMAP port on the server. This could be made an alias to facilitate
easy connections,but should not typically be part of a login script as it will create a persistant tunnel to the
server. WILL MANY MULTIPLE SSH TUNNELS
TO AN IMAP SERVER CAUSE PROBLEMS? HOW TO CONNECT AND NOT SPAWN SHELL.
ssh -L2001:localhost:143 imapserverFQDN
#Configure email clients to
use IMAP server 'localhost 2001'
10.Configure X11 Forwarding (tunneling of the X windows
display of applications running on a remote server)
Server:
Xforwarding is off by default
in Openssh. To enable it generally add
the following line to the server's /etc/ssh/ssh_config
file:
X11Forwarding yes
Disable it on a per user basis by adding the
following to the user's $HOME/.ssh/authorized_keys
file at the beginning of the key for which it applies:
no-X11-forwarding
.....rest of key.....
Client:
Add the following line to the
user's $HOME/.ssh/config file:
X11Forwarding yes
To connect:
The following lines are taken
from an actual connection and xterm.
This connection used private-key authentication with an ssh-agent
running with the user's private key loaded.
(note the user was not prompted for his account password, nor his
private key passphrase). The
X11Forwarding configuration above caused the server software to automatically
set the DISPLAY environmental variable to one reserved for X11 tunneling via
ssh (the echo line is included only to demonstrate this fact). The ensuring
xterm passes through the tunnel.
% ssh grampus.ewing.ldeo.columbia.edu
Last
login: Mon Feb 11 04:31:11 2002 from ewing-dhcp-154
Sun
Microsystems Inc. SunOS 5.8 Generic February 2000
---------------------------------------------------------------
Try
the ewing web page: http://www/
---------------------------------------------------------------
% echo $DISPLAY
grampus:12.0
% xterm