10.6. Configuring Remote Login and Execution
It's
often very useful to execute a command on a remote host and have
input or output from that command be read from, or written to, a
network connection. The traditional commands used for
executing commands on remote hosts are rlogin,
rsh, and rcp. We briefly
discussed the security issues associated with it in Chapter 1 and suggested ssh as a
replacement. The ssh package provides
replacements called ssh and
scp.Each of these commands spawns a shell on the remote host and allows
the user to execute commands. Of course, the client needs to have an
account on the remote host where the command is to be executed. Thus,
all these commands use an authentication process. The
r commands use a simple username and password
exchange between the hosts with no encryption, so anyone listening
could easily intercept the passwords. The ssh
command suite provides a higher level of security: it uses a
technique called Public Key Cryptography, which provides
authentication and encryption between the hosts to ensure that
neither passwords nor session data are easily intercepted by other
hosts.
It is possible to relax authentication checks for certain users even
further. For instance, if you frequently have to log in to other
machines on your LAN, you might want to be admitted without having to
type your password every time. This was always possible with the
r commands, but the ssh
suite allows you to do this a little more easily.
It's still not a great idea because it means that if
an account on one machine is breached, access can be gained to all
other accounts that user has configured for password-less login, but
it is very convenient and people will use it.Let's talk about removing the r
commands and getting ssh to work instead.
10.6.1. Disabling the r Commands
Start by removing the
r commands if they're
installed. The easiest way to disable the old r
commands is to comment out (or remove) their entries in the
/etc/inetd.conf file. The relevant entries will
look something like this:
# Shell, login, exec and talk are BSD protocols.You can comment them by placing a
shell stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rshd
login stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rlogind
exec stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.rexecd
# character at the start of each line, or delete
the lines completely. Remember, you need to restart the
inetd daemon for this change to take effect.
Ideally, you should remove the daemon programs themselves, too.
10.6.2. Installing and Configuring ssh
OpenSSH is a free version of the
ssh suite of programs; the Linux port can be
found at [3] We won't
describe compilation here; good instructions are included in the
source. If you can install it from a precompiled package, then
it's probably wise to do so.[3] OpenSSH was
developed by the OpenBSD project and is a fine example of the benefit
of free software.
There are two parts to an ssh session. There is
an ssh client that you need to configure and run
on the local host and an ssh daemon that must be running on the
remote host.
10.6.2.1 The ssh daemon
The sshd
daemon is the program that listens for network connections from
ssh clients, manages authentication, and
executes the requested command. It has one main configuration file
called /etc/ssh/sshd_config and a special file
containing a key used by the authentication and encryption processes
to represent the host end. Each host and each client has its own key. A utility called
ssh-keygen is supplied to generate a random key.
This is usually used once at installation time to generate the host
key, which the system administrator usually stores in a file called
/etc/ssh/ssh_host_key. Keys can be of any length
of 512 bits or greater. By default, ssh-keygen
generates keys of 1,024 bits in length, and most people use the
default. Using OpenSSH with SSH Version 2, you will need to generate
RSA and DSA keys. To generate the keys, you would invoke the
ssh-keygen command like this:
# ssh-keygen -t rsa1 -f /etc/openssh/ssh_host_key -N "You will
# ssh-keygen -t dsa -f /etc/openssh/ssh_host_dsa_key -N "
# ssh-keygen -t rsa -f /etc/openssh/ssh_host_rsa_key -N "
be prompted to enter a passphrase if you omit the
-N option. However, host keys must not use a
passphrase, so just press the return key to leave it blank. The
program output will look something like this:
Generating public/private dsa key pair.
Your identification has been saved in sshkey.
Your public key has been saved in sshkey.pub.
The key fingerprint is:
fb:bf:d1:53:08:7a:29:6f:fb:45:96:63:7a:6e:04:22 tb@eskimo 1024
You've
probably noticed that three different keys were created. The first
one, type rsa1, is used for SSH protocol Version 1, the next two
types, rsa and dsa, are used for SSH protocol Version 2. It is
recommended that SSH protocol Version 2 be used in place of SSH
protocol Version 1 because of potential man-in-the-middle and other
attacks against SSH protocol Version 1.
You will find
at the end that two files have been created for each key. The first
is called the private key, which must be kept secret and will be in
/etc/openssh/ssh_host_key. The second is called
the public key and is one that you can share; it will be in
/etc/openssh/ssh_host_key.pub.Armed with the keys for ssh communication, you
need to create a configuration file. The ssh
suite is very powerful and the configuration file may contain many
options. We'll present a simple example to get you
started; you should refer to the ssh
documentation to enable other features. The following code shows a
safe and minimal sshd configuration file. The
rest of the configuration options are detailed in the
sshd(8) manpage:
# $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $It's important to make sure the permissions of the
#Port 22
Protocol 2
#ListenAddress 0.0.0.0
#ListenAddress ::
# HostKeys for protocol version 2
HostKey /etc/openssh/ssh_host_rsa_key
HostKey /etc/openssh/ssh_host_dsa_key
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 3600
#ServerKeyBits 768
# Authentication:
#LoginGraceTime 120
#PermitRootLogin yes
#StrictModes yes
#RSAAuthentication yes
#PubkeyAuthentication yes
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#KeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
MaxStartups 10
# no default banner path
#Banner /some/path
#VerifyReverseMapping no
# override default of no subsystems
Subsystem sftp /usr/lib/misc/sftp-server
configuration files are correct to ensure that system security is
maintained. Use the following commands:
# chown -R root:root /etc/sshThe final stage of
# chmod 755 /etc/ssh
# chmod 600 /etc/ssh/ssh_host_rsa_key
# chmod 600 /etc/ssh/ssh_host_dsa_key
# chmod 644 /etc/ssh/sshd_config
sshd administration daemon is to run it.
Normally you'd create an rc
file for it or add it to an existing one, so that it is automatically
executed at boot time. The daemon runs standalone and
doesn't require any entry in the
/etc/inetd.conf file. The daemon must be run as
the root user. The syntax is very simple:
/usr/sbin/sshdThe sshd daemon will automatically place itself
into the background when being run. You are now ready to accept
ssh connections.
10.6.2.2 The ssh client
There are a number of
ssh client programs:
slogin, scp, and
ssh. They each read the same configuration file,
usually called /etc/openssh/ssh_config. They
each also read configuration files from the .ssh
directory in the home directory of the user executing them. The most
important of these files is the .ssh/config
file, which may contain options that override those specified in the
/etc/openssh/ssh_config file, the
.ssh/identity file, which contains the
user's own private key, and the corresponding
.ssh/identity.pub file, containing the
user's public key. Other important files are
.ssh/known_hosts and
; we'll
talk about those in the next section, Section 10.6.2.3. First,
let's create the global configuration file and the
user key file./etc/ssh/ssh_config
is very similar to the server configuration file. Again, there are
lots of features that you can configure, but a minimal configuration
looks like that presented in Example 10-5. The rest
of the configuration options are detailed in the
sshd(8) manpage. You can add sections that match
specific hosts or groups of hosts. The parameter to the
"Host" statement
may be either the full name of a host or a wildcard specification, as
we've used in our example, to match all hosts. We
could create an entry that used, for example, Host
*.vbrew.com to match any host in the vbrew.com domain.
Example 10-5. Example ssh client configuration file
# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $
# Site-wide defaults for various options
# Host *
# ForwardAgent no
# ForwardX11 no
# RhostsRSAAuthentication no
# RSAAuthentication yes
# PasswordAuthentication yes
# HostbasedAuthentication no
# BatchMode no
# CheckHostIP yes
# AddressFamily any
# ConnectTimeout 0
# StrictHostKeyChecking ask
# IdentityFile ~/.ssh/identity
# IdentityFile ~/.ssh/id_rsa
# IdentityFile ~/.ssh/id_dsa
# Port 22
# Protocol 2,1
# Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes2
56-cbc
# EscapeChar ~
We mentioned in the server configuration
section that every host and user has a key. The
user's key is stored in his or her
~/.ssh/indentity file. To generate the key, use
the same ssh-keygen command we used to generate
the host key, except this time you do not need to specify the name of
the file in which you save the key. The
ssh-keygen defaults to the correct location, but
it prompts you to enter a filename in case you'd
like to save it elsewhere. It is sometimes useful to have multiple
identity files, so ssh allows this. Just as
before, ssh-keygen will prompt you to entry a
passphrase. Passphrases add yet another level of security and are a
good idea. Your passphrase won't be echoed on the
screen when you type it.
|
the ssh-keygen command just once to ensure their
key file is created correctly. The ssh-keygen will create their
~/.ssh/ directories for them with appropriate
permissions and create their private and public keys in
.ssh/identity and
.ssh/identity.pub, respectively. A sample
session should look like this:
$ ssh-keygenNow ssh is ready to run.
Key generation complete.
Enter file in which to save the key (/home/maggie/.ssh/identity):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/maggie/.ssh/identity.
Your public key has been saved in /home/maggie/.ssh/identity.pub.
The key fingerprint is:
1024 85:49:53:f4:8a:d6:d9:05:d0:1f:23:c4:d7:2a:11:67 maggie@moria
$
10.6.2.3 Using ssh
We should
now have the ssh command and its associated
programs installed and ready to run. Let's now take
a quick look at how to run them.First,
we'll try a remote login to a host. The first time
you attempt a connection to a host, the ssh
client will retrieve the public key of the host and ask you to
confirm its identity by prompting you with a shortened version of the
public key called a fingerprint.
The administrator at the remote
host should have supplied you in advance with its public key
fingerprint, which you should add to your
.ssh/known_hosts file. If the remote
administrator has not supplied you the appropriate key, you can
connect to the remote host, but ssh will warn
you that it does have a key and prompt you whether you wish to accept
the one offered by the remote host. Assuming that
you're sure no one is engaging in DNS spoofing and
you are in fact talking to the correct host, answer yes to the
prompt. The relevant key is then stored automatically in your
.ssh/known_hosts and you will not be prompted
for it again. If, on a future connection attempt, the public key
retrieved from that host does not match the one that is stored, you
will be warned, because this represents a potential security breach.A first-time login to a remote host will look something like this:
$ ssh vlager.vbrew.comYou will be prompted for a password, which
The authenticity of host `vlager.vbrew.com' can't be established.
Key fingerprint is 1024 7b:d4:a8:28:c5:19:52:53:3a:fe:8d:95:dd:14:93:f5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'vchianti.vbrew.com,172.16.2.3' to the list of/
known hosts.
maggie@vlager.vbrew.com's password:
Last login: Tue Feb 1 23:28:58 2004 from vstout.vbrew.com
$
you should answer with the password belonging to the remote account,
not the local one. This password is not echoed when you type it.Without any special arguments,
ssh will attempt to log in with the same user ID
used on the local machine. You can override this using the
-l argument, supplying an alternate login name on
the remote host. This is what we did in our example earlier in the
book. Alternately, you can use the
userid@hostname.ext format to specify a
different username.We can copy files to and from the remote
host using the scp program. Its syntax is
similar to the conventional cp with the exception that you may
specify a hostname before a filename, meaning that the file path is
on the specified host (It is also possible to use the
userid@hostname format previously mentioned).
The following example illustrates scp syntax by
copying a local file called /tmp/fred to the
/home/maggie/ of the remote host vlager.vbrew.com:
$ scp /tmp/fred vlager.vbrew.com:/home/maggie/Again, you'll be prompted for a password. The
maggie@vlager.vbrew.com's password:
fred 100% |*****************************| 50165 00:01 ETA
scp command displays useful progress messages by
default. You can copy a file from a remote host with the same ease;
simply specify its hostname and file path as the source and the local
path as the destination. It's even possible to copy
a file from a remote host to some other remote host, but it is
something you wouldn't normally want to do, because
all of the data travels via your host.You can execute commands on remote hosts using the
ssh command. Again, its syntax is very simple.
Let's have our user maggie
retrieve the root directory of the remote host vchianti.vbrew.com. She'd do
this with the following:
$ ssh vchianti.vbrew.com ls -CF /You can place ssh in a command pipeline and pipe
maggie@vchianti.vbrew.com's password:
bin/ ftp/ mnt/ sbin/ tmp/
boot/ home/ opt/ service/ usr/
dev/ lib/ proc/ stage3-pentium3-1.4-20030726.tar.bz2 var/
etc/ lost+found/ root/
program input/output to or from it just like any other command,
except that the input or output is directed to or from the remote
host via the ssh connection. Here is an example
of how you might use this capability in combination with the
tar command to copy a whole directory with
subdirectories and files from a remote host to the local host:
$ ssh vchianti.vbrew.com "tar cf - /etc/" | tar xvf -
maggie@vchianti.vbrew.com's password:
etc/GNUstep
etc/Muttrc
etc/Net
etc/X11
etc/adduser.conf
..
..
Here we surrounded the command we will
execute with quotation marks to make it clear what is passed as an
argument to ssh and what is used by the local
shell. This command executes the tar command on
the remote host to archive the /etc/ directory
and write the output to standard output. We've piped
to an instance of the tar command running on our
local host in extract mode reading from standard input. Again, we were prompted for the
password. Let's now configure our local
ssh client so that it won't
prompt for a password when connecting to the vchianti.vbrew.com host. We mentioned the
The public keys are a long
single line of plain text. If you use copy and
paste to duplicate the key into your local file, be sure to remove
any end of line characters that might have been introduced along the
way. The file may contain
many such keys, each on a line of its own.The ssh suite of tools is very powerful, and
there are many other useful features and options that you will be
interested in exploring. Please refer to the manpages and other
documentation that is supplied with the package for more
information.