HiR's Secure OpenBSD, Apache, MySQL and PHP Guide

AS OF OPENBSD 5.6, APACHE IS NO LONGER IN THE BASE DISTRIBUTION. 

Consider using our handy nginx walk-through instead. This page will eventually be replaced with instructions for using Apache2 from the package repository.

OpenBSD is a great platform for hosting Apache/MySQL/PHP web apps.  It locks down Apache by default, and the version of PHP supplied by the OpenBSD team already has several security-enhancing patches in place. Combined, these create a web server environment that's a lot better prepared to withstand common attacks, but it's just a start. It can't completely protect you from poorly-written web applications or from threats that occur outside of the web application itself.

Our OAMP series of articles has always been quite popular, but we usually have to re-write it every six months or so. This new guide has been written so that it is not specific to a distinct architecture or version of OpenBSD, so long as the proper packages exist on the OpenBSD mirror sites. As of May 8, 2014, this has been tested on OpenBSD 5.4 and 5.5, i386 architecture only.  The only change between OpenBSD 5.4 and 5.5 is the version numbers of the packages. Adjust these as needed. I'm using OpenBSD 5.5 for the examples shown here.


We'll keep this guide up-to-date with the current version of OpenBSD as each release is made, and we'll include any refinements and improvements to our procedure that we encounter along the way.
Preparation
First, install OpenBSD. Be sure to create a user-level account for yourself during the installation process, and I'd recommend disabling remote root logins while you're at it. This user account will be added to the wheel group. On BSD systems, wheel group is comparable to an administrator group, granting access to use the su command, etc.  You can add other trusted users to this group later on.

As an extension to this privilege, we usually add the wheel group to /etc/sudoers with the ability to run any command. Once you've got OpenBSD installed, log in and su to root (with "su -") or log in as root and edit the sudoers file with the "visudo" command. Uncomment (or add) the line below. Optionally, there's a similar line that does not prompt the user for a password. We do not recommend using that option on a production system.

%wheel ALL=(ALL) SETENV: ALL

Now, set up the package manager by adding an installpath line in /etc/pkg.conf. For best results, you should pick an OpenBSD mirror that is near you both physically and network-wise. Try pinging and tracerouting different mirrors in your country and seeing which ones have the best response times or the fewest hops. Once you've picked a mirror, you can create /etc/pkg.conf with this quick one-liner that takes your OpenBSD version and architecture into account. I'm using ftp5.usa in this example. Put it all on one line.

echo installpath=ftp://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(uname -m) | sudo tee /etc/pkg.conf
If you bought the OpenBSD media and have packages on CD you'd like to use, you can add them to the installpath instead of the FTP mirror, or in addition to it.

Installing Packages
OpenBSD includes the Suhosin Hardened PHP patches in their default PHP package, which is nice. Since OpenBSD's package manager automatically installs dependencies, you can get away with this command, which should install everything else we need to get PHP up and running with the MySQL Client extension:
sudo pkg_add php-mysql
This will prompt you for which PHP version you wish to install. PHP 5.3 and 5.4 are both provided in the package repository (which is kind of sad given that PHP stable is up to 5.5.12 as of this writing, but I digress). As of this revision, PHP 5.4.24 is the latest version provided in the OpenBSD 5.5-Release package repsitority. pkg_add will display your options (php-mysql-5.3.x or php-5.4.x).

The installer will ask which package you want to install if your request is ambiguous (e.g. there are different versions in the repository to choose from).  I chose the latest versions available for all prompts.  Certain pre-packaged web applications may work better with specific versions of PHP and/or MySQL, though.

Note: "ap2" versions of PHP are built for (and include) apache2. We're still sticking with the patched, custom build of apache httpd shipped with OpenBSD's base distribution.

Install php-mysql and mysql-server. This will install all necessary dependencies, including php, libiconv and several perl modules needed by the MySQL scripts.

$ sudo pkg_add php-mysql mysql-server
Ambiguous: choose package for php-mysql
 a       0: 
         1: php-mysql-5.3.28p0
         2: php-mysql-5.4.24
Your choice: 2
Ambiguous: choose dependency for php-mysql-5.4.24: 
 a       0: php-5.4.24
         1: php-5.4.24-ap2
Your choice: 0


Some messages will be displayed that cover creating symbolic links to the sample configuration files. I prefer to copy them instead. Make sure you mind the version numbers here if you're installing something other than php-5.4.
sudo cp /var/www/conf/modules.sample/php-5.4.conf \ 
/var/www/conf/modules/php.conf
sudo cp /etc/php-5.4.sample/mysql.ini \ 
/etc/php-5.4/mysql.ini

Then, run a few commands to initialize MySQL and set a strong password for the MySQL root user. Be sure you can remember it, though. You'll need it later.
sudo /usr/local/bin/mysql_install_db 
sudo /etc/rc.d/mysqld start
sudo /usr/local/bin/mysqladmin \
     -u root password '
your-password'

I highly recommend running this the mysql_secure_installation script after you have performed the above. This will perform a few simple changes to MySQL's default install in the name of security.
sudo /usr/local/bin/mysql_secure_installation

MySQL and PHP should now be set up in such a way that they should work with most web apps, but it's about to get a little trickier...

Chroot Setup
Chroot means "change root" and what it does is re-define the apparent root directory for a running process so that it cannot access resources elsewhere on the system. This is desirable for web servers, because it minimizes the impact that a web-based attack can have on the system as a whole.  The version of Apache web server that ships with OpenBSD is designed to run in a chroot of /var/www, meaning that anything outside of /var/www is inaccessible to the web server, its modules and web applications in general. This includes access to the MySQL socket. I suggest adding MySQL users with "127.0.0.1" as the allowed host (instead of localhost) and configuring your Apache/MySQL/PHP apps to use 127.0.0.1 as the database server. This forces a TCP connection instead of relying on sockets.

Enable index.php (Optional)

You may wish to add "index.php" to the DirectoryIndex line of /var/www/conf/httpd.conf to enable index.php as a directory index. Several web apps expect this functionality.

DirectoryIndex index.php index.html


Start OAMP services automatically
Add the following to /etc/rc.conf.local to make Apache and MySQL start by default. It's that simple:

mysqld_flags=""
httpd_flags=""
pkg_scripts="mysqld"

Once everything is installed and configured to start automatically, reboot to make sure everything: starts up as expected.
sudo reboot
Testing
The most basic test of Apache, PHP and MySQL is to create a phpinfo script.
echo "<?php phpinfo(); ?>" | sudo tee /var/www/htdocs/phpinfo.php
Then pull up your OpenBSD's phpinfo web page in a browser, at http://your.openbsd.ip.address/phpinfo.php - You should see a nice-looking document containing the details about your PHP configuration. If you see this page, Apache and PHP are working just fine. Look for details about MySQL in the output. You can (and likely should) delete phpinfo.php once you're certain things are working properly. The below screen shot doesn't show the MySQL configuration, but as long as you see a MySQL section from phpinfo, you should be good.


To truly test the "AMP Stack" viability of my OAMP, we used to grab the latest version of Wordpress and do the "five minute install", but WP has a pretty bad reputation for security problems. We wouldn't recommend using it unless you really know how to lock it down or don't care if it gets owned. Again, I made sure to set it up with 127.0.0.1 as the database server, as opposed to localhost.

Generally speaking, I've had very few problems making the usual cadre of popular LAMP packages work under OAMP. Problems that arise are often easily fixed by adding something to the virtual root environment in /var/www or changing permissions (often temporarily) on some files.

I plan on keeping this page up-to-date with the latest version of OpenBSD as time goes on. Note that in about 6 months, the process is going to get a little trickier, as OpenBSD claims to be dropping apache from the base distribution in favor of nginx. Apache will likely need to be installed and configured from packages. We'd recommend brushing up on our nginx guide if you haven't gotten familiar with the OpenBSD/Nginx/MySQL/PHP-FPM stack yet. It's pretty slick, and it's "the new style" so to speak.