Friday, January 23, 2015

Switching to OpenSSL from ports in FreeBSD

The intended audience is people who build their own ports or packages.  Switching ports to use openssl from ports is pretty straightforward.  These steps were summarized from my efforts several months ago.

Put WITH_OPENSSL_PORT=yes in the appropriate make.conf, then make sure all affected ports are recompiled.  I'm pretty sure poudriere bulk would take care of that.  (See end about libressl notes).

Nothing from the base system will compile against libraries from ports, at least without making ugly hacks.  I wanted openssh to use openssl (or libressl) from ports, so I had to switch my systems to openssh-portable:

Install openssh from my custom pkg repo:
pkg install openssh-portable

Copy existing SSH host keys:
cp /etc/ssh/*host* /usr/local/etc/ssh/

View config differences and manually resolve any issues:
diff -u /etc/ssh/sshd_config /usr/local/etc/ssh/sshd_config

Switch to openssh server from ports:
service sshd stop
sysrc sshd_enable=NO
sysrc openssh_enable=YES
service openssh start

If you are doing this remotely your SSH connection will not be dropped, but leave it open and test using a new connection before you disconnect the first.

In our setup, some systems depend on Kerberos which introduced a number of other issues I had to solve but I'll skip that unless someone requests it.  Dealing with Kerberos was at least half of my effort.

Since I'm now using openssh, openssl, and kerberos from ports and I do my own buildworlds, I desired to use WITHOUT_OPENSSH=yes, WITHOUT_KERBEROS=yes, WITHOUT_KERBEROS_SUPPORT=yes, and WITHOUT_OPENSSL=yes in src.conf to avoid having two installs of each.  Unfortunately, I can't use WITHOUT_OPENSSL=yes because it will break buildworld.  The source tree isn't prepared to cleanly skip SSL support in a number of places such as Kerberos and fetch.  That is open to experimentation if you want a custom build.  You'll have to put effort into replacing or compensating non-building portions of the source tree.

WITHOUT_OPENSSH=yes works pretty well and if you do your own buildworlds, you'll want to get rid of the old binaries so they aren't sitting insecure, unupdated, and possibly broken in the future.  make delete-old and delete-old-libs appeared to work but left behind a now-broken scp binary in my path. Since I do a delete-old as part of my standard upgrade procedure, I knew I had to fix before upgrading my systems.  I determined missing files from and filed a patch:
I just sent a reminder to encourage someone to commit it.

When initially switching over or upgrading the openssl port, it is important to remember to restart enough daemons that still have the libraries open so they use new copies.  These commands are helpful:

lsof | grep libcrypto
lsof | grep libssl

Make sure lsof is up to date enough for your system so it produces accurate results.  (pkg install -f lsof).  For example, sometimes lsof compiled on 10.0 may not work on 10.1.  You'll probably see some false positives from shells, ntpd, etc because some binaries appear to inherit libraries from their parent process.  Processes such as Apache, postfix, openssh definitely need to be restarted.  If you are doing the initial switch from base to ports openssl, the paths of the binaries in lsof output will make it clear which are being used. However, in the future any time the openssl port is upgraded (replaced), active filehandles in lsof dissapear since the old files were deleted.  If you want to avoid rebooting, run lsof before upgrade so you know which processes to restart afterwards. The best way is to reboot after upgrading the openssl port/package.

At this stage, you've done most of the groundwork for switching to libressl if you prefer.  Just add OPENSSL_PORT=security/libressl to your make.conf (alongside WITH_OPENSSL_PORT=yes) and make sure your packages get rebuilt.  In the past you had to override OPENSSL_SHLIBVER but I think ports has been fixed to handle that automatically.

No comments:

Post a Comment