Bestiary of Special-purpose sshds

 in
Need management software on your Linux boxes? It might already be in /usr/sbin.

OpenSSH is a standard part of the system administrator's toolbox. Although sshd, the OpenSSH daemon, is versatile, sometimes, you need more than one to meet your security goals.

Why would you want to run an extra sshd?

First of all, there's the emergency scenario. You mess something up, try to restart sshd, and it doesn't come back. That means either go visit the system in person, and it may be a long ways away, or if you have another sshd running, use that to get back in and fix the regular one.

Second, there are security policy considerations. You can always run one sshd and have it listen on two interfaces, but that's probably going to be inappropriate for a "bastion host" system where you want to be as secure as possible for the outward-facing network interface and give more features to people coming in from the inward-facing one.

For example, you might want everyone to be able to ssh to the shell box from their desktop systems, but only allow the sysadmin and webmaster to get in from the outside. Unfortunately, you can't do an AllowUsers that only applies to one interface. If you want two sets of AllowUsers users, you'll need two sshds.

The same is true for PermitRootLogin.

Another simple but useful security measure to protect daemons that send sensitive information as plaintext is to configure them to listen only on the loopback interface, so only localhost can connect to it. What good does this do, if you want to provide services to the network? Simple. By making the daemon bind only to the loopback interface (with Apache's BindAddress or similar configuration directives) you mandate that remote users have to use an ssh tunnel. At the same time, though, you might want to prevent ordinary users from getting a shell on that host.

You can prevent users from setting up ssh port forwarding with AllowTcpForwarding no in sshd_config. (As the man page mentions, this isn't foolproof if the user can install his or her own port forwarding software on the system.) But how do you make it so that a user can only do port forwarding, not log in?

Use the old Un*x trick of setting the user's shell to /bin/false. You can create as many tunnel-only accounts as you like. To allow a user access to one, just copy that user's ssh public key into the tunnel-only account's .ssh/authorized_keys.

An extra init script

The simplest way to have two copies of sshd running is to have two init scripts and two configuration files. Fortunately, this is simple. Just cd to /etc/ssh, or whereever your sshd_config file lives, and cp it to /etc/ssh/extra_sshd_config, or something descriptive like admin_group_sshd_config. In the new file, change either the Port line or the ListenAddress line so your extra sshd won't be on the same port/interface combination as your regular one. (Here, I use port 22222, but you can also use the hopefully unused telnet port, port 23) If your system has two or more network interfaces, you can have two sshd instances, both on Port 22, but different interfaces. You can test this step with sshd -f /etc/ssh/extra_sshd_config. Now make a copy of your ssh init script, which might live in /etc/init.d/ or /etc/rc.d/init.d. Call the copy extra_sshd, or something descriptive like admin_group_sshd. In the copy, add the command-line option -f /etc/ssh/extra_sshd_config to any mention of sshd. Run the script with the argument of "start" and you should be able to do an ssh -p 22222 localhost.

You can now use your distribution's standard tools to add the new init script to the appropriate runlevels, or just do it by hand with ln -s.

Started from /etc/inittab

Jim Dennis of Linux Gazette has pointed out that on a seriously messed-up system, the "dreaded OOM killer", a kernel feature that kills off processes to try to recover from an out of memory condition, might take out the sshd that gets started from the init script in /etc/init.d/ or /etc/init.d/rc.d. This leaves you with no way to get into the messed-up system that needs it most. The answer is to start a second, emergency sshd, directly from /etc/inittab. If a process started from /etc/iniittab dies, init will restart it.

In order to run sshd directly from inittab, add a line like this: ss:12345:respawn:/usr/sbin/sshd -D -f /etc/ssh/extra_sshd_config

and do a kill -HUP 1 to make init reread /etc/inittab.

Wait a minute! Why the -D for "don't become a daemon?" When a process started from an init script becomes a daemon, it goes through a little dance, in which the original sshd process exits, and one of its descendants runs in the background as a child of init. Since we're starting sshd directly from /etc/inittab, the original process is already a child of init, so we don't need to do this. Doing so will confuse init horribly, when the original process it's keeping track of dies and it thinks it has to keep restarting sshd.

The advantage of this approach is that init will restart the extra sshd if the OOM killer kills it, or if by some chance there's a bug that causes it to die. The latter has never happened to me, but you never know. To stop this started-from-inittab sshd, just comment out the /etc/inittab line and do a kill -HUP 1.

By now you might have some ideas for interesting things you could do if you just had another sshd running on your system. The important thing is to start with the security policy you want to enforce, and use ssh as a tool to help do that, not just tweak it until it works.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Re: Bestiary of Special-purpose sshds

Anonymous's picture

Using /bin/false as shell doesn't permit to create tunnels with ssh.

Diaolin(diaolin@diaolin.com)

Re: Bestiary of Special-purpose sshds

Anonymous's picture

Here's an example of when you might need 2 sshds on the same box.

I want to be able to ssh from any of the machines on my test network to the box that does masquerading for the test network, with only a password (it's a test network and I don't have my ssh keys on the machines under test). But I don't want people to be able to get into the masquerading box from the rest of the company, or from outside, without a key. So I should run one sshd on the internal interface (10.4.0.1 in my case) and another on the other interfaces of the box -- and only allow password authentication on the first one.

Since they're on different interfaces they can both use the standard ssh port.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix