Sunday, August 22, 2010

Installing OpenSSH from Source

I've got a cluster of Fedora 9 machines that run Apache web servers. Since they run Apache 2.2, there is no reason to upgrade the OS. Unfortunately, I stumbled on a bug with Fedora 9's implementation of key authentication with OpenSSH. It was apparently fixed in F10, but as is one of the inherent dangers of Fedora not patched in F9. Rather than kluge around with patching the RPM, I decided to install OpenSSH from source.

When you visit the OpenSSH website you want to get the portable source. I downloaded that onto the box and extracted it to /usr/local to create the openssh-5.1p1 sub. Normally the README file explains the compile sequence but in this case I had to get the instructions from the FAQ.

The first few attempts failed until I installed zlib-devel and openssl-devel. Then it was a simple case of the standard:
make; make install
This placed the binary in /usr/local/sbin, but messed up the etc structure.

All the config files were in etc and not a sub, so I created /usr/local/etc/openssh and moved all the files into the sub. This required an update to the sshd_config, however. I had to edit he HostKey parameters to include the sub in the path.

To test, we execute:
/usr/local/sbin/sshd -Dd \
  -f /usr/local/etc/openssh/sshd_config
Connect from remote. Test the keys. Bug gone. All good.

Now to symlink everything
cd /etc/
mv ssh ssh-redhat
ln -s /usr/local/etc/openssh ssh-openssh
ln-s ssh-openssh ssh
ls -ld ssh*
cd /etc/init.d
cp sshd sshd-openssh
mv sshd sshd-redhat
ln -s sshd-openssh sshd
This gives us a SysV startup script that points to the correct config files, but the wrong binaries. We need to change all the /usr/ entries to /usr/local/:
sed -i "s~/usr/~/usr/local/~" sshd-openssh
(There's actually only two lines, and the first shouldn't count.)

Oddly, on first try, it fails. The reason is that RedHat built the SysV script to check for the path of the config, but didn't provide the path. This means it fails and uses the default. Since we moved the config... it fails. The solution, which makes everything portable is the put the config path where RedHat expects it:
echo 'OPTIONS="-f /etc/ssh/sshd_config" ' > /etc/sysconfig/sshd
Optionally, recompile with the --sysconfdir=/etc/ssh such that both binaries point to the same sub.

One downside is that the binary is running unconfined by SELinux. If you're really ambitious:
chcon -t sshd_exec_t /usr/local/sbin/sshd
chcon -u system_u /etc/init.d/sshd*
chcon -t initrc_exec_t /etc/init.d/sshd*
Restart the service to confine.

No comments:

Post a Comment