Adventures in Mac OS X Server Administration

Last week I got an email from the nice people at IT security that my work machine (which I use as a web and development server) had multiple vulnerabilities that needed to be fixed ASAP. Since I have the (sometimes somewhat dubious) pleasure of running Mac OS X on said machine, this was not as easy as running a simple update command — especially, since the updates required included the Apache Webserver and SSH. However, bright eyed and bushy-tailed, I went down the rabbit hole. …And eventually came out the other end battered and bruised. Let me tell you one thing: fun? Not! While Mac OS X technically is a *nix, it certainly doesn’t have any of the things installed up front that you might expect from any run-of-the-mill Linux distribution. But thankfully, the update would last long enough for me to graduate without having to touch it again. Or so I thought… This blog post is about one of those “little did he know…” moments that life throws at you (speaking of: go watch “Stranger than Fiction” if you haven’t seen it already). Which happened this morning in the guise of an email. Here’s the important part:

“There is a new vulnerability they are calling the heartbleed bug.  It affects certain versions of openssl, and has the potential to be very serious.  Especially if you use TLS/SSL to secure a webhost or a private mail server. If you maintain your own system, patch it immediately. “

The tech-savvy among you will groan with me. For the rest of you, here’s what it means: mulligan. Do-over. Scrap it, rebuild from scratch. So, this time around, I decided to document the process for my future self (should this occasion arise once more) and anyone out there who faces a similar task. So, buckle up, grab the [caffeinated|alcoholic] drink of your choice, and enjoy the ride! Here’s the shopping list (in order of dependency starting at OpenSSL):

Thankfully, the OpenSSH version of the server was not built using a vulnerable version of OpenSSL (I’ll leave it to you, dear reader, to figure out why…) However, if you’re building Apache httpd from scratch, you’ll also need:

and potentially some build tools, namely:

Generally speaking, take a look at http://www.apple.com/opensource/, which contains a lot of fallback versions of the above libraries specifically for Mac OS. Alright. Let’s do this!

Assumptions

I will assume that the sources of every program on the list were downloaded into the /usr/src folder.
Installation target will be /usr/bin for binaries, /usr/lib for libraries, and /usr/include for includes.
Target libraries are ideally universal (i.e., both for 32 and 64 bit Darwin), or x64 as a fallback.

OpenSSL

For OpenSSL, you will need to specify the target and options manually to the ./Configure script (auto-detection defaults to x86).

tar xzvf openssl-1.0.1g.tar.gz
cd openssl-1.0.1g
./Configure darwin64-x86_64-cc --prefix=/usr threads zlib-dynamic shared
make
make test
sudo make install

This will compile OpenSSL into a multi-thread capable, dynamic library with zlib support and install it in the above-mentioned directories. Optionally, if you want to compile universal versions, refer to the instructions here.

libSSH2

For libSSH, you will only need to specify the desired crypto library (in our case, OpenSSL).

tar xzvf libssh2-1.4.3.tar.gz
cd libssh-1.4.3
CFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --with-openssl --with-libz
make
make check
sudo make install

This will compile libSSH2 as a universal binary using OpenSSL and zlib and install it in the above-mentioned directories.

wget

For wget, once again, you will only need to specify the desired crypto library (in our case, OpenSSL).

tar xzvf wget-1.15.tar.gz
cd wget-1.15
CFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --with-ssl=openssl
make
make check
sudo make install

This will compile wget as a universal binary using OpenSSL and zlib and install it in the above-mentioned directories.

apr

I decided to throw in apr for good measure, despite the fact that, technically, it does not have a dependency on OpenSSL. However, it might be interesting for some people (and future me) to see how to compile apr as a universal binary. Here is how:

tar xzvf apr-1.5.0.tar.gz
cd apr-1.5.0
CFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --enable-layout=Darwin --enable-threads
make
make test
sudo make install

Note the –enable-layout flag! This will save you much headache when building httpd later, since it will throw the modules etc. exactly in the directories that Mac OS X uses. There is a different flag for Mac OS Servers, so make sure to read the documentation in the config.layout file and/or in the httpd documentation for configure here.

apr-util

Given the build instructions for apr, apr-util becomes a piece of cake. Note that you can add more database libraries with the appropriate flags to the configure script! I just provided the MySQL and SQLite drivers here.

tar xzvf apr-util-1.5.3.tar.gz
cd apr-util-1.5.3
CFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --enable-layout=Darwin --with-crypto --with-openssl --with-ldap --with-mysql=/usr/local/mysql --with-sqlite3 --with-iconv=/usr --with-apr=/usr/bin/apr-1-config
make
make test
sudo make install

apr-iconv

apr-iconv is even easier:

tar xzvf apr-iconv-1.2.1.tar.gz
cd apr-iconv-1.2.1.tar.gz
CFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --enable-layout=Darwin --with-apr=/usr/bin/apr-1-config
make
sudo make install

httpd

Now to the juicy part! The httpd server has a myriad of configuration options, which change version to version and go beyond the scope of this blog post. So find the relevant documentation of your httpd version and look up what you may need. The documentation for the 2.4 branch can be found here.

sudo apachectl graceful-stop
tar xzvf httpd-2.4.9.tar.gz
cd httpd-2.4.9
CFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --enable-layout=Darwin --enable-modules=reallyall --with-apr=/usr/bin/apr-1-config --with-apr-util=/usr/bin/apu-1-config --with-ssl
make
sudo make install
sudo apachectl start

mod_hfs_apple

This module for Apache httpd is the least automated to build. Not to mention, you’ll have to download three files (APPLE_LICENSE, Makefile, and mod_hfs_apple2.c) instead of a tarred or zipped file. I’ll assume that you have downloaded all of them and placed them into a folder called /usr/src/mod_hfs_apple.

The first thing you may want to do, in case you would like universal binaries again, is edit the Makefile as follows. Replace the following line

28
MORE_FLAGS = -Wc,"$(RC_CFLAGS) -Wall -Wextra -Os -g "

with the following line:

28
MORE_FLAGS = -Wc,"$(RC_CFLAGS) -Wall -Wextra -Os -arch i386 -arch x86_64 -g "

Then you can simply build:

make
sudo make install

php5

Surprisingly, php5 turns out to be the most involved of the programs we have to rebuild. One thing to make sure of (when building universal binaries) is to check whether the libraries we want to link against have symbols both for i386 and x86_64! Also note that you shouldn’t run make clean after configure, since it will delete some required files, and the build will fail! Now, here’s the lengthy configuration for php5:

tar xjvf php-5.5.11.tar.bz2
cd php-5.5.11
CXXFLAGS="-arch x86_64 -arch i386 -Wl,-read_only_relocs,suppress -I/opt/X11/include" CFLAGS="-Wl,-read_only_relocs,suppress -arch x86_64 -arch i386 -I/opt/X11/include" LDFLAGS="-arch x86_64 -arch i386 -Wl,-read_only_relocs,suppress" ./configure --prefix=/usr --exec-prefix=/usr --with-config-file-path=/etc --with-apxs2=/usr/bin/apxs  --with-openssl --with-pcre-regex --with-zlib --with-bz2 --enable-calendar --with-curl --enable-dba=shared --enable-exif --enable-ftp --with-openssl-dir=/usr --with-imap-ssl --enable-intl --with-ldap --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-zlib-dir=/usr --with-snmp --with-openssl-dir=/usr --enable-soap --enable-sockets --enable-zip --with-pear --with-gd --with-vpx-dir=/usr --with-jpeg-dir=/usr --with-png-dir=/usr --with-xpm-dir=/opt/X11/include --enable-mbstring
make
make test
sudo make install

serf

Serf uses the SCons build system, so make sure it’s installed on your machine. This also makes building quite simple:

tar xjvf serf-1.3.4.tar.bz2
cd serf-1.3.4
CFLAGS="-arch x86_64 -arch i386" CXXFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" scons PREFIX=/usr
scons check
scons install

subversion

Subversion is another program with a lot of configuration flags. Your environment is most likely different from this! Modify as needed.

tar xjvf subversion-1.8.8.tar.bz2
cd subversion-1.8.8.tar.bz2
CXXFLAGS="-arch x86_64 -arch i386" CFLAGS="-arch x86_64 -arch i386" LDFLAGS="-arch x86_64 -arch i386" ./configure --prefix=/usr --exec-prefix=/usr --enable-javahl --with-apr=/usr/bin/apr-1-config --with-apr-util=/usr/bin/apu-1-config --with-serf=/usr --with-apxs=/usr/bin/apxs --with-sqlite=/usr --with-apache-libexecdir=/usr/libexec/apache2 --with-openssl --with-editor=/usr/bin/vim --with-zlib=/usr --with-jdk --with-junit=~/.m2/repository/junit/junit/4.11/ --with-swig=/usr
make
make check
make install

And that is it! Hope you enjoyed the ride!