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:# SSH1, OpenSSH HostKey /usr/local/ssh/key
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:# OpenSSH only HostDsaKey /usr/local/openssh/key2
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 HostKeyFile /usr/local/ssh/key
If you prefer command-line options, sshd supports the -h command-line option to specify the private key file:# SSH2 only PublicHostKeyFile /usr/local/ssh/pubkey
Once again, the public key filename is derived by appending .pub to the private key filename, in this case, /usr/local/ssh/key.pub.# SSH1, SSH2, OpenSSH $ sshd -h /usr/local/ssh/key
Likewise for SSH2, the random seed is stored in /etc/ssh2/random_seed, and the location may be overridden with the RandomSeedFile keyword:# SSH1 only RandomSeed /usr/local/ssh/seed
If running on a system with a random-bit source, such as /dev/urandom, OpenSSH doesn't create a random seed file.# SSH2 only RandomSeedFile /usr/local/ssh/seed2
There is no corresponding keyword for SSH2. Its pid file is always named /var/run/sshd2_N.pid, 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.# SSH1, OpenSSH PidFile /usr/local/ssh/pid
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.# SSH1, SSH2, OpenSSH $ sshd -f /usr/local/ssh/config
or it may be specified with printf-like patterns, as in:# SSH2 only UserConfigDirectory /usr/local/ssh/my_dir
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:# SSH2 only UserConfigDirectory %D/.my-ssh
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:
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 /usr/sneaky/ssh/%IU/
and uploaded his own public key file into /tmp/hack, he would gain SSH2 access to every user's account.# SSH2 only UserConfigDirectory /tmp/hack
Filenames can be absolute or are relative to the user's SSH2 directory. The preceding lines specifies the file ~/.ssh2/my_public_keys.# SSH2 only AuthorizationFile my_public_keys
[57]The sshd2_config manpage for SSH2 2.2.0 says that StrictModes isn't implemented, but this statement is obsolete.
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 [Section 4.1.5.2, "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.# SSH1, SSH2, OpenSSH StrictModes no
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.# SSH1 only # Create files rw-r -- r -- and directories rwx-r-xr-x: Umask 022
or the -p command-line option:# SSH1, SSH2, OpenSSH Port 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 $ sshd -p 9876
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:# SSH1, SSH2, OpenSSH ListenAddress 192.168.10.23
# OpenSSH only ListenAddress 192.168.10.23 ListenAddress 192.168.11.17
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 tcp/22
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. [Section 3.5.1.2, "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.ssh stream tcp nowait root /usr/local/sbin/sshd sshd -i
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 0
The idle timeout can also be set for a given key in a user's authorized_keys file using the idle-timeout option. [Section 8.2.7, "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.# SSH1 only IdleTimeout 1d IdleTimeout 24h IdleTimeout 1440m IdleTimeout 86400s IdleTimeout 86400
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.# SSH1, SSH2, OpenSSH KeepAlive yes
or the -g command-line option:# SSH1, SSH2, OpenSSH LoginGraceTime 60
To disable this feature, provide a LoginGraceTime value of zero:# SSH1, SSH2, OpenSSH $ sshd -g 60
or by command-line option:# SSH1, SSH2, OpenSSH LoginGraceTime 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:# SSH1, SSH2, OpenSSH $ sshd -g 0
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.# SSH2 only PasswordGuesses 5
To specify an unlimited number of connections, provide a value of zero:# SSH2 only MaxConnections 32
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!)# SSH2 only MaxConnections 0
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.# SSH2 only RequireReverseMapping 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. [Section 4.1.5.3, "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. [Section 7.4.4.4, "Controlling TCP_NODELAY"]# SSH2 only NoDelay yes
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.# SSH2 only MaxBroadcastsPerSecond 10
It may also be enabled or disabled by the client. [Section 6.3.5.3, "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.)# SSH2 only ForwardAgent no
or more selectively for particular users or Unix groups:# SSH1, SSH2, OpenSSH AllowTcpForwarding no
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:# SSH2 only AllowTcpForwardingForUsers smith jones roberts AllowTcpForwardingForGroups students faculty DenyTcpForwardingForUsers badguys DenyTcpForwardingForGroups bad*
# SSH1, SSH2, OpenSSH X11Forwarding no # SSH2 only: either will work ForwardX11 no AllowX11Forwarding no
or the -b command-line option:# SSH1, OpenSSH ServerKeyBits 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 $ sshd -b 1024
or the -k command-line option:# SSH1, OpenSSH KeyRegenerationInterval 1200
A zero value turns off the key regeneration feature:# SSH1, OpenSSH $ sshd -k 1200
or:# SSH1, OpenSSH KeyRegenerationInterval 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]# SSH1, OpenSSH $ sshd -k 0
[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
Value | Meaning |
---|---|
3des-cbc | The 3DES (Triple DES) algorithm |
blowfish-cbc | The Blowfish algorithm |
twofish-cbc | The TwoFish algorithm |
arcfour | The ARCFOUR algorithm |
none | No encryption |
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:
Individual algorithms and sets of algorithms can't be mixed:# SSH2, OpenSSH/2 Ciphers 3des-cbc Ciphers 3des-cbc,blowfish-cbc,arcfour Ciphers any
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. [Section 4.1.5.6, "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]# This is ILLEGAL Ciphers 3des,anystd
[59]If you do connect using the none cipher, ssh prints a warning message, "WARNING: Encryption is disabled!" Even so, an attacker can enable QuietMode in your clients and suppress this message. [Section 5.8.1.3, "SSH1 Quiet mode"]Use the 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.
The following table shows keywords with special meanings that can also be used:hmac-sha1 hmac-md5 hmac-md5-96
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 |
# OpenSSH only Protocol 1,2
5.3. Server Configuration: An Overview | 5.5. Letting People in: Authentication and Access Control |
Copyright © 2002 O'Reilly & Associates. All rights reserved.