Protecting sshd using spiped
Slightly over a year ago, I announced the release of the spiped secure pipe daemon. The purpose of spiped was to provide a more robust and vastly simpler alternative to 'ssh -L' in cases where a pre-shared secret key could be securely established between hosts. SSH's host key fingerprints are great when one person is setting up a system and wants to broadcast a public value to a large number of users; but a far more common scenario for me is that I am setting up multiple systems and want to allow daemons running on them to talk to each other.In addition to spiped's ability to replace 'ssh -L', there's another way in which spiped can supplement SSH: To restrict access to the SSH daemon. Like many system administrators, I used to restrict access to port tcp/22 on most of my servers based on source IP address; this provided some protection from "zero-day" exploits against OpenSSH, as well as eliminating the annoying "log spam" caused by brute force attacks. This worked fine as long as I always connected from the same location, but heading off to conferences meant that I needed to either tunnel SSH connections over other SSH connections or make temporary changes to my firewall rules.
By running spiped on a server, configured to accept connections on port 8022 and connect to port 22 on the same host, it becomes possible to firewall off port tcp/22 completely and yet still be able to connect over SSH from anywhere in the world — as long as you have the spiped secret key, of course. This approach has one disadvantage however: Since spiped involves a pair of daemons — one running on the server, receiving encrypted connections and establishing unencrypted connections to the target service, and one running on the client, receiving unencrypted connections and establishing encrypted connections to the first spiped dameon — if you want to be able to SSH to N servers via spiped, you need to be running N copies of spiped on your local system. These days, I find myself running a sufficiently large number of systems (a quick count comes to 17, but I've probably forgotten some) that this approach is a bit unwieldy.
Enter spipe, a "client" for the spiped protocol, which I committed to the spiped SVN repository yesterday and released as part of spiped 1.2.0 today. Rather than listening on a socket and encrypting or decrypting many connections, as spiped does, spipe encrypts a single connection — and as the unencrypted end of that connection, uses the standard input and output. In other words, spipe acts like 'netcat' or 'openssl s_client' — or an OpenSSH ProxyCommand.
Setting up spiped to guard access to SSH is now easy: On your server, run
# dd if=/dev/urandom bs=32 count=1 of=/etc/ssh/spiped.key
# spiped -d -s '[0.0.0.0]:8022' -t '[127.0.0.1]:22' -k /etc/ssh/spiped.key
and make sure that the spiped process is restarted after the system reboots
— on FreeBSD, this can be done by adding the lines
spiped_enable="YES" # if not already present
spiped_pipes="SSH" # and any other pipes you have already configured
spiped_pipe_SSH_mode="decrypt"
spiped_pipe_SSH_source="[0.0.0.0]:8022"
spiped_pipe_SSH_target="[127.0.0.1]:22"
spiped_pipe_SSH_key="/etc/ssh/spiped.key"
to the server's /etc/rc.conf if you're using the
sysutils/spiped port.
Now copy the /etc/ssh/spiped.key file from the server to ~/.ssh/spiped_HOSTNAME_key on your local system, and add the lines
Host HOSTNAME
ProxyCommand spipe -t %h:8022 -k ~/.ssh/spiped_%h_key
to your ~/.ssh/config file (creating the file if it didn't already
exist, and replacing HOSTNAME with the appropriate host name, of course).
Now when you run "ssh HOSTNAME", OpenSSH will launch spipe to handle the
task of connecting through to the target SSH server daemon; and instead of
adjusting firewall rules every time you want to connect from a different IP
address, you can block incoming tcp/22 once and for all.
It is often said that the UNIX model of software involves writing simple components which each solve one small problem but are versatile enough that they can can be easily assembled to solve more larger and more complex problems. At 4000 lines, spiped is certainly simple, and it's hard to imagine any way that spiped could be useful by itself; but for its ability to be integrated with other daemons to add additional encryption and authentication to them, I think spiped might well qualify as the best UNIX software I've ever written.