Getting Ready: Initial Setup
We now embark on a detailed discussion of SSH server configuration, using both keywords and command-line options. Please keep in mind that SSH2 and OpenSSH are still evolving products and their features may change. Be sure to read their documentation for the latest information. SSH1 is no longer actively developed, so its feature set is unlikely to change.We begin with initial setup decisions, such as: where should important files be kept? What should their permissions be? What TCP/IP settings should be used? What are the properties of the server key? Which encryption algorithms are supported?File Locations
sshd
expects certain files to exist, containing the server's host key, the random seed, and other data. The server looks for these files in default locations, or you may override them with keywords and command-line options as described later.Although you may place these files anywhere you like, we strongly recommend keeping them on a local disk on your server machine, not on a remotely mounted disk (e.g., via NFS). This is for security reasons, as NFS will gleefully transmit your sensitive files unencrypted across the network. This would be especially disastrous for the unencrypted private host key!As a running example, we use an invented directory, /usr/local/ssh, as our preferred (nondefault) location for the SSH server's files.
Host key files
The host key ofsshd
uniquely identifies a server to SSH clients. The host key is stored in a pair of files, one containing the private key and the other the public key. For SSH1 and OpenSSH, the private key is stored in /etc/ssh_host_key and is readable only by privileged programs such as the SSH server and clients. Its location may be changed with the HostKey
keyword:
# SSH1, OpenSSH HostKey /usr/local/ssh/key
The server's public key is stored in a second file with the same name but with pub appended. So the default for SSH1 and OpenSSH is /etc/ssh_host_key.pub, and the preceding
HostKey
example implies /usr/local/ssh/key.pub.The OpenSSH server also has an SSH-2 host key, located by default in /etc/ssh_host_dsa_key, and its location may be moved with the HostDsaKey
keyword:
# OpenSSH only HostDsaKey /usr/local/openssh/key2
For SSH2, the default private key file is /etc/ssh2/hostkey if the server is run by the superuser or ~/.ssh2/hostkey if run by any other user. To specify a different private key file, use the
HostKeyFile
keyword:
# SSH2 only HostKeyFile /usr/local/ssh/key
The server's public key file, normally /etc/ssh2/hostkey.pub for superusers or ~/.ssh2/hostkey.pub for others, may be changed independently with the
Public-HostKeyFile
keyword:
# SSH2 only PublicHostKeyFile /usr/local/ssh/pubkey
If you prefer command-line options,
sshd
supports the -h command-line option to specify the private key file:
# SSH1, SSH2, OpenSSH $ sshd -h /usr/local/ssh/key
Once again, the public key filename is derived by appending pub to the private key filename, in this case, /usr/local/ssh/key.pub.
Random seed file
The SSH server generates pseudo-random numbers for cryptographic operations. ["Randomness"] It maintains a pool of random data for this purpose, derived either from the operating system if provided (e.g., /dev/random on some Unix flavors) or from various bits of changing machine state (e.g., clock time, statistics on resource use by processes, etc.). This pool is called the random seed. SSH1 stores it in /etc/ssh_random_seed, and its location may be changed with theRandomSeed
keyword:
# SSH1 only RandomSeed /usr/local/ssh/seed
Likewise for SSH2, the random seed is stored in /etc/ssh2/random_seed, and the location may be overridden with the
RandomSeedFile
keyword:
# SSH2 only RandomSeedFile /usr/local/ssh/seed2
If running on a system with a random-bit source, such as /dev/urandom, OpenSSH doesn't create a random seed file.
Process ID file
We said earlier that the SSH1 server's pid is stored in /etc/ssh.pid, and this location may be overridden with thePidFile
keyword:
# SSH1, OpenSSH PidFile /usr/local/ssh/pid
There is no corresponding keyword for SSH2. Its pid file is always named /var/run/sshd2_Npid, where N is the TCP port number of the server. Since the default port is 22, the default pid file is /var/run/sshd2_22.pid. If multiple
sshd2
processes are run simultaneously on different ports of the same machine, their pid files can be distinguished by this naming convention.
Server configuration file
The server configuration file is normally /etc/sshd_config for the SSH1 and OpenSSH servers and /etc/ssh2/sshd2_config for the SSH2 server. An alternative configuration file can be specified with the -f command-line option:# SSH1, SSH2, OpenSSH $ sshd -f /usr/local/ssh/config
This is useful when testing a new server configuration: create a new file and instruct
sshd
to read it. It is also necessary if you are running multiple sshd
s on the same machine and want them to operate with different configurations.
User SSH directory
sshd1
expects a user's SSH-related files to be found in the directory ~/.ssh. This location can't be changed by serverwide configuration. (You have to modify the source code.)sshd2
expects user files to be in the directory ~/.ssh2 by default, but this can be changed with the UserConfigDirectory
keyword. The directory name may be literal, as in:
# SSH2 only UserConfigDirectory /usr/local/ssh/my_dir
or it may be specified with
printf
-like patterns, as in:
# SSH2 only UserConfigDirectory %D/.my-ssh
The
%D
pattern expands to the user's home directory. So the preceding example expands to ~/.my-ssh. The following table shows the available patterns:
Pattern | Meaning |
---|---|
%D | User's home directory |
%U | User's login name |
%IU | User's uid (Unix user ID) |
%IG | User's gid (Unix group ID) |
For the system administrator, the UserConfigDirectory
keyword provides a quick way to override all users' SSH2 preferences. Specifically, you can cause sshd2
to ignore everybody's ~/.ssh2 directories, substituting your own instead. For instance, the line:
# SSH2 only UserConfigDirectory /usr/sneaky/ssh/%IU/
tells
sshd2
to seek the preferences for each user in /usr/sneaky/ssh/<username> instead of ~/.ssh. This powerful feature can also be misused if your machine is compromised. If an intruder inserted the following line into sshd2_config :
# SSH2 only UserConfigDirectory /tmp/hack
and uploaded his own public key file into /tmp/hack, he would gain SSH2 access to every user's account.
Per-account authorization files
The SSH1 and OpenSSH servers expect to find a user's public-key authorization file in ~/.ssh/authorized_keys (and ~/.ssh/authorized_keys2 for OpenSSH/2). These locations can't be changed by serverwide configuration.The SSH2 server uses a different key file layout. ["SSH2 Identities"] The authorization file, normally ~/.ssh2/authorization, contains names of separate public key files, rather than the keys themselves.sshd2
can be instructed to find the authorization file elsewhere via the keyword AuthorizationFile
.
# SSH2 only AuthorizationFile my_public_keys
Filenames can be absolute or are relative to the user's SSH2 directory. The preceding lines specifies the file ~/.ssh2/my_public_keys.
File Permissions
As security products, SSH1, SSH2, and OpenSSH require certain files and directories on the server machine to be protected from unwanted access. Imagine if your authorized_keys or rhosts file were world-writable; anyone on that host could modify them and gain convenient access to your account.sshd
has several configuration keywords for reducing this risk.
Acceptable permissions for user files
Users aren't always careful to protect important files and directories in their accounts, such as their rhosts file or personal SSH directory. Such lapses can lead to security holes and compromised accounts. To combat this, you can configuresshd
to reject connections to any user account that has unacceptable permissions.The StrictModes
keyword, with a value of yes
(the default), causes sshd
to check the permissions of important files and directories. They must be owned by the account owner or by root, and group and world write permission must be disabled. For SSH1, StrictModes
checks:
- User's home directory
- User's ~/.rhosts and ~/.shosts file
- User's SSH configuration directory, ~/.ssh
- User's SSH ~/.ssh/authorized_keys file
StrictModes
checks the same files as for SSH1, plus the user's authorization file for SSH-2 connections, ~/.ssh/authorized_keys2.For SSH2, the list is smaller and is checked only for trusted-host authentication:[57] ["Trusted-host authentication (Rhosts and RhostsRSA)"]
[57]The sshd2_config manpage for SSH2 2.2.0 says that StrictModes
isn't implemented, but this statement is obsolete.
- User's home directory
- User's ~/.rhosts and ~/.shosts file
StrictModes
is given the value no
, these checks aren't performed.
# SSH1, SSH2, OpenSSH StrictModes no
However, we strongly suggest you leave these checks enabled.Even if
StrictModes
is enabled, though, it can be defeated in two ways. First, sshd
can be compiled with the flag -- enable-group-writeability
["Installation, files, and directories"], which makes group-writable files acceptable to StrictModes
. This can be useful for shared accounts, permitting all members of a group to modify SSH-related files in an account. Second, you can use POSIX ACLs, which are supported in Solaris and some other flavors of Unix, to set file permissions with greater precision. sshd
doesn't check ACLs, so one could argue that StrictModes
is an incomplete test.
Permissions for newly created files
The umask of a Unix process determines the default permissions for files and directories that the process creates.sshd1
's umask may be specified with the keyword Umask
, so any files it creates have the desired permissions. The value is an ordinary Unix umask value, usually given in octal:
# SSH1 only # Create files rw-r -- r -- and directories rwx-r-xr-x: Umask 022
Remember that a leading zero is necessary for
sshd1
to interpret the value as octal. For more information on umasks, see the Unix manpages for umask
or for most shells.sshd1
creates a pid file ( /etc/sshd.pid or the value of PidFile
) and a random seed file ( /etc/ssh_random_seed or the value of RandomSeed
). Only the pid file is affected by the server's umask. The random seed file is explicitly created with mode 0600, readable and writable only by the owner. Strictly speaking, this umask also applies to other processes spawned by sshd1
-- specifically, user shells -- but the value is typically overridden by shells.
TCP/IP Settings
Since the SSH protocol operates over TCP/IP,sshd
permits control over various parameters related to TCP/IP.
Port number and network interface
By default,sshd
listens on TCP port 22. The port number may be changed with the Port
keyword:
# SSH1, SSH2, OpenSSH Port 9876
or the -p command-line option:
# SSH1, SSH2, OpenSSH $ sshd -p 9876
The SSH1 and OpenSSH servers accept integers in decimal, octal, or hexadecimal, while the SSH2 server reads all numbers as decimal. See the sidebar "Numeric Values in Configuration Files".You may also configure
sshd
to bind its listening port on a particular network interface. By default, the port is bound on all active network interfaces on the host. The ListenAddress
keyword limits sshd
to listen on only one interface, with default value 0.0.0.0.For example, suppose a computer has two Ethernet cards and is attached to two different networks. One interface has the address 192.168.10.23, and the other, 192.168.11.17. By default, sshd
listens on both interfaces; therefore, you can reach the server by connecting to port 22 at either address. However, this may not always be what you want; perhaps you want to provide SSH service only to hosts on one network and not the other:
# SSH1, SSH2, OpenSSH ListenAddress 192.168.10.23
Of course, this represents a real restriction only if the two networks aren't otherwise connected together (say, by a router), so that port 22 on 192.168.10.23 is not reachable from the network 192.168.11/24.OpenSSH permits more than
ListenAddress
line in the configuration file, permitting listening on selected multiple interfaces:
# OpenSSH only ListenAddress 192.168.10.23 ListenAddress 192.168.11.17
Invocation by inetd
sshd
normally runs as a daemon, spawning child processes to handle connections. Alternatively, the server may be invoked by inetd
as are many other network daemons. In this case, inetd invokes a new instance of the server for each connection.If the inetd
behavior is desired, you must have an entry for SSH in the server machine's TCP/IP services map, either /etc/services or /etc/inet/services, such as:
ssh tcp/22
and an appropriate line in the
inetd
configuration file, /etc/inetd.conf, for the SSH service. This line must invoke sshd with the -i command-line option, which turns on inetd behavior:
ssh stream tcp nowait root /usr/local/sbin/sshd sshd -i
What this means, exactly, is that sshd simply starts up and expects to handle a single connection on a TCP socket attached to its standard input and output. This is opposed to its behavior without -i, where it becomes a master server listening for TCP connections and starting subprocesses to handle individual connections.The
inetd
approach has advantages and disadvantages. On the down side, inetd
-based SSH connections are slower to start up if the session uses a server key, because sshd
generates a new key each time. This applies to connections using the SSH-1 protocol, i.e., the servers of SSH1 and OpenSSH/1. ["Session key exchange and the server key"] Whether that's an issue, of course, depends on the speed of the server machine in question. On the up side, the inetd
approach allows using a wrapper program to invoke sshd
, should that be needed. Also, inetd provides a single, centralized point of control for all types of network connections, which simplifies maintenance. If you want to forbid all types of TCP/IP connections, for example, you can simply disable inetd
instead of running around killing other daemons.
Idle connections
Suppose an SSH connection is established between a server and a client, but no data passes over the connection for a long time. What should the server do: keep the connection alive, or terminate it?SSH1 provides theIdleTimeout
keyword, which tells the server what to do if a connection is idle, i.e., if the user doesn't transmit any data in a given period. If IdleTimeout
is zero (the default), the server does nothing, leaving idle connections intact:
# SSH1 only IdleTimeout 0
Otherwise, the server terminates the connection after a specified interval of idleness. In this case, the value of
IdleTimeout
is a positive integer, optionally followed by letter: s
for seconds, m
for minutes, h
for hours, d
for days, or w
for weeks. If no letter is given, the number represents seconds.Here are several ways to set an IdleTimeout
of exactly one day:
# SSH1 only IdleTimeout 1d IdleTimeout 24h IdleTimeout 1440m IdleTimeout 86400s IdleTimeout 86400
The idle timeout can also be set for a given key in a user's authorized_keys file using the idle-timeout option. ["Setting Idle Timeout "] Notably, this option overrides the server's
IdleTimeout
value but only for that key. This is a rare instance of a per-account option overriding a serverwide option.
KeepAlive
KeepAlive
is a related but distinct feature to IdleTimeout
. Where IdleTimeout
detects and ends healthy but unused connections, KeepAlive
is concerned with recognizing when a connection has failed. Suppose a client establishes an SSH connection, and some time later, the client host crashes abruptly. If the SSH server has no reason to send unsolicited messages to the client, it may never notice the half-dead TCP connection to its partner, and the sshd remains around indefinitely, using up system resources such as memory and a process slot (and making the sysadmin's ps
output messy).The KeepAlive
keyword instructs sshd how to proceed if a connection problem occurs, such as a prolonged network outage or a client machine crash:
# SSH1, SSH2, OpenSSH KeepAlive yes
The value
yes
(the default) tells the server to set the TCP keepalive option on its connection to the client. This causes TCP to periodically transmit and expect keepalive messages. If it doesn't receive responses to these messages for a while, it returns an error to sshd, which then shuts down the connection. The value no
means not to use keepalive messages.The TCP keepalive feature, and hence SSH's KeepAlive
, is intended to prevent half-dead connections from building up over time. The keepalive message interval and timeout period reflect this: they are quite long, typically on the order of hours. This is to minimize the network load imposed by the keepalive messages and also to prevent connections from being unnecessarily torn down because of transient problems, such as a temporary network outage or routing flap. These timers aren't set in SSH; they are properties of the host's TCP stack. They shouldn't be altered lightly, since they affect every TCP connection using keepalives on that host.
KeepAlive and connection timeouts
It's important to note thatKeepAlive
isn't intended to deal with the problem of losing connections due to firewall, proxying, NAT, or IP masquerading timeouts. This problem occurs when your SSH connection is going across one of these entities, which decides to tear it down because it's been idle for a while. Since this is done to conserve shared resources (such as a limited pool of external, routable IP addresses), these timeouts are typically quite short, perhaps a few minutes to an hour or so. The name "KeepAlive" suggests that it might be the right thing to use, since that's what you want to do -- keep your connection alive. But really, KeepAlive
is the wrong name for it; it would be better named "DetectDead" (but that sounds like a spell a second-level cleric would use to avoid being eaten by zombies). In order for KeepAlive
to deal with this problem, you have to dramatically shorten the TCP keepalive interval on the SSH host. This is contrary to its purpose and unwise because it affects not only SSH connections, but every TCP connection using keepalives, even those that don't need it. Doing this on the server side is an especially bad idea as a general principle, since a busy server may be using lots of TCP connections, and enabling KeepAlive
on many of them since it's supposed to be an inexpensive feature. This can impose an unnecessary and damaging additional network load, especially if it becomes a widespread practice.It's good to remember that the timeout annoying you so much is there for a reason. You may like to leave an SSH connection up for a long time unused, but if it's occupying one of a limited number of simultaneous outbound Internet TCP connections for your company, perhaps it's better if you just suck it up for the common good. Typing ssh
again once in a while is really not that hard; use your shell's alias feature if you find the number of keystrokes onerous. If you genuinely think the timeout is inappropriate or unnecessary, argue the case with the network administrator, and try to get it changed.For the occasions when it's really necessary, the right way to accomplish this sort of keepalive behavior is with an application-level mechanism implemented in SSH -- having it periodically send SSH protocol messages over the connection to make it appear nonidle. This feature isn't available in any SSH implementation we know of, but we encourage its addition. NAT, etc., timeouts are a common problem, and we would like to discourage the misuse of TCP keepalives as a solution. In the meantime, the better low-tech solution is simply to have something that sends characters over your connection once in a while. Run Emacs and have it display the time in the mode line. Run a program in the background that prints "Boo!" to your terminal if it's been idle for 20 minutes. You get the idea.
Failed logins
Suppose a user attempts to log in via SSH but fails to authenticate. What should the server do? The keywordsLoginGraceTime
and PasswordGuesses
control the server's response.Users are given a limited time to authenticate successfully, 10 minutes by default. This timeout is controlled by the LoginGraceTime
keyword, given a value in seconds:
# SSH1, SSH2, OpenSSH LoginGraceTime 60
or the -g command-line option:
# SSH1, SSH2, OpenSSH $ sshd -g 60
To disable this feature, provide a
LoginGraceTime
value of zero:
# SSH1, SSH2, OpenSSH LoginGraceTime 0
or by command-line option:
# SSH1, SSH2, OpenSSH $ sshd -g 0
If password authentication is used for a connection request,
sshd2
permits a client only three tries to authenticate before dropping the connection. This restriction may be modified with the PasswordGuesses
keyword:
# SSH2 only PasswordGuesses 5
The situation with public-key authentication is slightly more complicated. There are two sorts of requests a client can make in this regard: a query whether a particular public key is authorized to log into the target account, and an actual authentication attempt including a signature of the corresponding private key. It's good to allow an unlimited number of queries, since otherwise it limits the number of keys one can have in an agent, for example. But it's reasonable to limit the number of failed attempts. None of the current SSH servers do what we consider to be the right thing. SSH1 and SSH2 simply allow an unlimited number of public-key queries or attempts. OpenSSH, on the other hand, limits the overall number of authentication attempts or queries of any kind, and it uses a built-in, nonconfigurable limit of 5 (the source code says 6, but the way it's coded it comes out to 5). So if you have five keys in your agent, you never get to use password authentication with the OpenSSH server, because it rejects your connection after determining that you can't use any of those keys. Or if you have six keys and the sixth is the one you need to use, you're out of luck; you have to remove some keys from your agent (or not use the agent) to get it to work (these numbers are one fewer for OpenSSH/2, by the way).Of course, there's a security argument to be made here. It's better in a sense to not allow queries and always force the client to perform an attempt. That way, if it fails, the client doesn't know whether it was because the signature was wrong or the key is simply not authorized. This makes it harder for an attacker to determine which keys are the ones to try to steal. But in normal use it's computationally expensive for legitimate clients to do this, and so the protocol does allow queries.
Limiting simultaneous connections
sshd
can handle an arbitrary number of simultaneous connections by default. SSH2 provides the MaxConnections
keyword for limiting this number, say, if you want to conserve resources on the server machine:
# SSH2 only MaxConnections 32
To specify an unlimited number of connections, provide a value of zero:
# SSH2 only MaxConnections 0
Of course, the number of connections can also be limited by available memory or other operating system resources.
MaxConnections
has no effect on these other factors. (Sorry, you can't increase your CPU speed by setting a keyword!)
Reverse IP mappings
The SSH2 server optionally does a reverse DNS lookup on a client's IP address. That is, it looks up the name associated with the address, then looks up the addresses for that name and makes sure that the client's address is among them. If this check fails, the server refuses the connection.sshd2
uses the gethostbyname( )
and gethostbyaddr( )
system services to perform these mappings, so the databases that are consulted depend on the host operating system configuration. It might use the DNS, the Network Information Service (NIS or YP), static files on server machine, or some combination.To enable this check, use the RequireReverseMapping
keyword with a value of yes
or no
(the default):
# SSH2 only RequireReverseMapping yes
This feature is a bit of security-oriented consistency checking. SSH uses cryptographic signatures to determine a peer's identity, but the list of peer public keys (the known hosts database) is often indexed by hostname, and so SSH must translate the address to a name in order to check the peer's identity. Reverse mapping tries to ensure that someone isn't playing games with the naming service in a cracking attempt. There is a tradeoff, however, since in today's Internet, the DNS reverse-address mappings aren't always kept up to date. The SSH server might reject legitimate connection attempts because of poorly maintained reverse-address mappings over which you have no control. In general, we recommend turning off this feature; it isn't usually worth the hassle.
Controlling TCP_NODELAY
TCP/IP has a feature called the Nagle Algorithm, which is designed to reduce the number of TCP segments sent with very small amounts of data (e.g., one byte), usually as part of an interactive terminal session. Over fast links such as Ethernet, the Nagle algorithm generally isn't needed. Over a wide-area network, however, it can cause noticeable delays in the responsiveness of X clients and character terminal displays, as multibyte terminal control sequences may be transmitted inconveniently by the algorithm. In such cases, you should turn off the Nagle Algorithm using theNoDelay
keyword:
# SSH2 only NoDelay yes
NoDelay
disables the Nagle Algorithm by toggling the TCP_NODELAY bit when requesting a TCP connection from the Unix kernel. Legal values are yes
(to disable) and no
(to enable; the default).In order to work, this feature must be enabled at compile time using -- enable-tcp-nodelay
. ["TCP/IP support"] Note also that NoDelay
can be enabled or disabled by the SSH2 client, rather than serverwide, using the client configuration keyword NoDelay
. ["Controlling TCP_NODELAY"]
Discovering other servers
SSH2 2.1.0 adds a feature for seeking out and discovering SSH2 servers automatically. The keywordMaxBroadcastsPerSecond
, when given an integer value greater than zero, causes an SSH2 server to listen to UDP broadcasts sent to port 22:
# SSH2 only MaxBroadcastsPerSecond 10
A new program supplied with SSH2,
ssh-probe2
, sends broadcast queries and prints the locations and versions of any SSH2 servers it finds. The server only responds to this many queries per second; the rate-limiting prevents a denial-of-service attack that floods the server with queries, causing it to spend all its time replying to them.MaxBroadcastsPerSecond
and ssh-probe2
are a rather ad hoc solution for locating SSH2 servers. Perhaps when Dynamic DNS and SRV records become more widely used, such tricks won't be necessary.
Agent forwarding
Agent forwarding permits a series of SSH connections (from one machine to another to another, ...) to operate seamlessly using a single agent. ["Agent Forwarding"] Agent forwarding may be enabled or disabled in the SSH2 server using the keywordForwardAgent
or AllowAgentForwarding
with a value of yes
(the default) or no
:
# SSH2 only ForwardAgent no
It may also be enabled or disabled by the client. ["Enabling agent forwarding"]Agent forwarding is convenient, but in a security-sensitive environment, it might be appropriate to disable this feature. Because forwarded agent connections are implemented as Unix domain sockets, an attacker can conceivably gain access to them. These sockets are just nodes in the filesystem, protected only by file permissions that can be compromised.For example, suppose you maintain a network of exposed, untrusted machines that you access from a more secure network using SSH. You might consider disabling agent forwarding on the untrusted machines. Otherwise, an attacker can compromise an untrusted machine; take control of a forwarded agent from a legitimate, incoming SSH connection; and use the agent's loaded keys to gain access to the secure network via SSH. (The attacker can't retrieve the keys themselves in this way, however.)
Forwarding
SSH's forwarding or tunneling feature protects other TCP/IP-based applications by encrypting their connections. We cover forwarding in great detail in "Port Forwarding and X Forwarding", but we introduce here the serverwide configuration keywords for enabling and disabling it.TCP port forwarding can be enabled or disabled by the keywordAllowTcp-Forwarding
with the value yes
(the default) or no
:
# SSH1, SSH2, OpenSSH AllowTcpForwarding no
or more selectively for particular users or Unix groups:
# SSH2 only AllowTcpForwardingForUsers smith jones roberts AllowTcpForwardingForGroups students faculty DenyTcpForwardingForUsers badguys DenyTcpForwardingForGroups bad*
Forwarding for X, the popular window system, can be separately enabled or disabled with the keyword
X11Forwarding
(SSH1, SSH2, OpenSSH), or ForwardX11
or AllowX11Forwarding
(SSH2 synonyms for X11Forwarding
). The default value is yes
, to enable forwarding:
# SSH1, SSH2, OpenSSH X11Forwarding no # SSH2 only: either will work ForwardX11 no AllowX11Forwarding no
Server Key Generation
All SSH servers maintain a host key, which is persistent, generated by the system administrator when installing SSH, and identifies the host for authentication purposes. ["Host key files"]Separately, an SSH-1 server maintains another key while running, called the server key, which protects client/server communications. This key is temporary and never explicitly stored on disk. The server generates it at startup, and regenerates it at regular intervals. SSH1 and OpenSSH can specify the length of the server key in bits. The key length is 768 bits by default, 512 bits at a minimum, and you may choose another length using theServerKeyBits
keyword:
# SSH1, OpenSSH ServerKeyBits 1024
or the -b command-line option:
# SSH1, OpenSSH $ sshd -b 1024
You may also specify the lifetime or regeneration interval of the server key. When the lifetime ends, another server key is generated and the process repeats, say, every 10 minutes. This is a security feature: if an intruder captures a server key, it can decrypt transmissions for only a limited time (10 minutes in our example). Likewise, if an encrypted transmission is captured by a sniffer, the server key necessary to decrypt the session is destroyed in the server after 10 minutes.Key regeneration is specified in seconds. Regeneration occurs every 3600 seconds (one hour) by default. The interval is specified with the
KeyRegeneration-Interval
keyword:
# SSH1, OpenSSH KeyRegenerationInterval 1200
or the -k command-line option:
# SSH1, OpenSSH $ sshd -k 1200
A zero value turns off the key regeneration feature:
# SSH1, OpenSSH KeyRegenerationInterval 0
or:
# SSH1, OpenSSH $ sshd -k 0
The
RekeyIntervalSeconds
keyword specifies how often (in seconds) sshd2
performs key exchange with the client to replace the session data-encryption and integrity keys. The default is 3600 seconds (one hour), and a zero value disables rekeying:[58]
[58]Note that at press time, you must disable session rekeying in the SSH2 server if you wish to use it with many other SSH clients, since the latter don't yet support session rekeying; the connection dies with an error once the rekeying interval expires.
# SSH2 only RekeyIntervalSeconds 7200
Encryption Algorithms
The SSH server supports a number of data-encryption algorithms for its secure connection; the client selects a cipher to use from the list the server supports. SSH2 has a server configuration option to set the list of allowable ciphers, selected from those the server software supports. TheCiphers
keyword serves this purpose. Its value may have two different forms:
- A comma-separated list of algorithm names (strings), indicating which algorithms are permissible. The following table displays the supported values.
Value | Meaning |
---|---|
des-cbc
| The 3DES (Triple DES) algorithm |
blowfish-cbc
| The Blowfish algorithm |
twofish-cbc
| The TwoFish algorithm |
arcfour
| The ARCFOUR algorithm |
none
| No encryption |
- The
none
algorithm is available only when SSH is compiled with the-- with-none
flag. The-cbc
suffixes indicate cipher block chaining. These algorithms are in a class called block ciphers, which may operate in a variety of modes; CBC is one of them. - A single string indicating a set of algorithms. The following table displays the supported values:
Value | Meaning |
---|---|
none
| Unencrypted transmission |
any
| Any algorithm implemented in the server, including none
|
anycipher
| Same as any , but excluding none
|
anystd
| Any standard algorithm found in the IETF SecSH draft (assuming it is implemented in the server), including none
|
anystdcipher
| Same as anystd , but excluding none |
Here are some examples:
# SSH2, OpenSSH/2 Ciphers 3des-cbc Ciphers 3des-cbc,blowfish-cbc,arcfour Ciphers any
Individual algorithms and sets of algorithms can't be mixed:
# This is ILLEGAL Ciphers 3des,anystd
The
Ciphers
keyword is useful for quickly disabling individual encryption algorithms, say, if a security hole is discovered in one of them. Just omit that algorithm from the Ciphers
list and restart the server.Support for some algorithms can be omitted from the SSH1 server at compile time. ["Encryption and ciphers"] In particular, support for the none
cipher type is not compiled in by default. This omission is a security feature to make insecure SSH sessions more difficult to create. Otherwise, if an attacker gained access to your account for a few moments, he could add "Ciphers none" to your SSH client configuration file. You might never notice this small change, but all of your future SSH connections would be insecure.[59]
[59]If you do connect using theUse thenone
cipher,ssh
prints a warning message, "WARNING: Encryption is disabled!" Even so, an attacker can enableQuietMode
in your clients and suppress this message. ["SSH1 Quiet mode"]
none
cipher only for testing. Using the SSH-1 protocol with no encryption seriously weakens it: not only do you lose data privacy, but also you effectively lose server authentication and integrity protection. SSH-2 doesn't suffer from these problems. In either case, however, password authentication isn't available, since the password would be sent in the clear.
MAC algorithms
TheMAC
keyword lets you select the allowed integrity-checking algorithms, known as the Message Authentication Code, used by sshd2
. ["Hash Functions"] Here are the available algorithms: ["Hash Functions"]
hmac-sha1 hmac-md5 hmac-md5-96
The following table shows keywords with special meanings that can also be used:
Value | Meaning |
---|---|
any
| Any supported algorithm |
anymac
| Any supported algorithm, except none
|
anystd
| Any standard algorithm; that is, one defined in the current working draft of the SSH-2 protocol |
anystdmac
| Same as anystd , but excludes none
|
none
| No MAC; this is insecure |
SSH Protocol Selection
OpenSSH lets you limit its protocol support to SSH-1, SSH-2, or both, using the Protocol keyword. Permissible values are (for SSH-1, the default), (for SSH-2), or both and separated by a comma:# OpenSSH only Protocol 1,2