How-to: OpenBSD 3.8+Apache+PHP+MySQL

Updated January 31, 2007

top

What this document is

This document aims to be a tutorial for easily getting an OpenBSD 3.8 installation up and running with Apache+PHP+MySQL. It is a collection of various information I've found on the Internet (see References) and my own personal experiences. I will be covering installation and initial setup of the MySQL and PHP packages along with several PHP extensions. I also briefly touch on a few security topics and then how to get OpenBSD to start Apache and MySQL at boot.

top

What this document isn't

This document is not intended to be a tutorial on how to install OpenBSD. This has already been covered more than sufficiently by the OpenBSD team and any attempt I make at duplicating it here would be redundant. This document is also not a complete reference for using Apache, PHP, or MySQL. Each of these projects has its own independent documentation which I could not begin to cover here. This document is in no way a total solution to securing a system. OpenBSD comes fairly secure and has an excellent track record of security, but security is a not a destination. It is a journey. It is up to you, the person at the keyboard, to keep the system patched, up to date, and to use good judgement when making system changes.

top

Installing OpenBSD 3.8

The OpenBSD Team has made excellent documentation on how to do this. I don't see much point in duplicating it here. Come back here when you are done installing OpenBSD and I'll help get you set up installing the rest of the system.
OpenBSD installation instructions

top

Installing PHP and MySQL

The pkg_add command is the preferred method of installing software on OpenBSD systems as it will automatically find and resolve any package dependencies (and there will be some here). Packages can be removed with pkg_delete. You'll need to be root to do all of this. First, we need to setup the environment for pkg_add. The following command tells pkg_add where to look for the packages we are going to tell it to get:

# export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/3.8/packages/i386/

Now onto adding the packages. I use the "-v" switch with pkg_add. This tells pkg_add to be verbose about what it's doing. I also redirect this output to the file packages for reviewing later if needed.

We'll start with MySQL 4 Server:

# pkg_add -v mysql-server-4.0.27.tgz > packages

Install PHP4:

# pkg_add -v php4-core-4.4.1p0.tgz >> packages

The ">>" appends to the end of the previously created file packages.

Enable the PHP4 module:

# /usr/local/sbin/phpxs -s
# cp /usr/local/share/examples/php4/php.ini-recommended /var/www/conf/php.ini

Install and enable PHP4_MySQL connectivity:

# pkg_add -v php4-mysql-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a mysql

Install and enable MCRYPT:

# pkg_add -v php4-mcrypt-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a mcrypt

Install and enable MHASH:

# pkg_add -v php4-mhash-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a mhash

Install and enable DOMXML:

# pkg_add -v php4-domxml-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a domxml

Install and enable IMAP:

# pkg_add -v php4-imap-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a imap 

Install PEAR libraries:

# pkg_add -v php4-pear-4.4.1p0.tgz >> packages

Install and enable GD to use PHP to manipulate graphics:

If you didn't install the X11 libraries when you installed the base system (it's a good idea not to install these if you're running a web server), use these commands: (Thanks to Craig McCormick for pointing out this previous oversight.)

# pkg_add -v php4-gd-4.4.1p0-no_x11.tgz >> packages
# /usr/local/sbin/phpxs -a gd

If you did install X11, then use these to install and enable GD:

# pkg_add -v php4-gd-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a gd
		

Install and enable CURL:

# pkg_add -v php4-curl-4.4.1p0.tgz >> packages
# /usr/local/sbin/phpxs -a curl

top

Setting up MySQL

Now we need to secure MySQL a little bit. We do this by setting out root password for the MySQL server and then setting passwords for the two anonymous accounts that ship with MySQL with no password.

First start the server daemon:

# /usr/local/bin/mysqld_safe &

Set root password:

# /usr/local/bin/mysqladmin -u root password mypassword

Access the server with your new password:

# /usr/local/bin/mysql -u root -p

After you enter your MySQL root password, you'll be at a prompt. We'll enter a command to show us the users and hosts that exist so far. Then, we'll set the passwords. Enter the following at the prompt:

mysql> SELECT Host, User FROM mysql.user;
mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd');

Change @'host_name' to the value that corresponds to the name you gave your system, displayed on your screen under Host where User = root (i.e., www.freeyourbox.org)

It will be good practice for us to create a test database and a new user for that database:

mysql> CREATE DATABASE testdb;
mysql> GRANT SELECT ON testdb.* TO 'testacct'@'localhost'
    -> IDENTIFIED BY 'l33tp4ssw0rd';
Query OK, 0 rows affected (0.03 sec)
    

Now make a table for the testacct user to select from later:

mysql> USE testdb
Database changed
mysql> CREATE TABLE new_table (
    -> id int not null primary key auto_increment,
    -> name varchar (50) not null );
Query OK, 0 rows affected (0.04 sec)

View the table:

mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| new_table        |
+------------------+
1 row in set (0.00 sec) 
     

Now we need to insert some data:

mysql> INSERT into new_table values ('NULL', 'h4x0r');
Query OK, 1 row affected (0.00 sec)
     

Select our data from the database to make sure everything is working ok:

mysql> SELECT id, name from new_table;
+----+-------+
| id | name  |
+----+-------+
|  1 | h4x0r |
+----+-------+
1 row in set (0.00 sec)
     

Now exit MySQL by typing:

mysql> exit

On OpenBSD, apache comes chrooted in the /var/www directory. MySQL's default socket location is in /var/run/mysql/mysql.sock. This causes a problem since apache can't "see" the /var/run directory. To overcome this, we need to make a hard link to the mysql.sock socket file. This is achieved by typing the following at the command prompt:

# mkdir -p /var/www/var/run/mysql
# ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock

top

Configuring Apache

Now that MySQL and PHP are ready to go, we need to configure Apache. For Apache to use PHP, you'll need to locate the following line in /var/www/conf/httpd.conf and uncomment it:

AddType application/x-httpd-php .php

You'll also need to edit the Directory Index line to say:

DirectoryIndex index.html index.php index.phtml index.php4 index.php3

Now you need to change the Listen directive to reflect your network setup. Mine says:

Listen 192.168.8.7:80
Listen 127.0.0.1:80

You don't need the 127.0.0.1 unless you want to be able to connect from the server using lynx or some similar web browser. You also should change the ServerAdmin and the ServerName directives. Since my apache installation is only for internal use, I will be using an internal IP address for ServerName. You will more than likely need to change this to something like www.yourdomain.com. For this to work, you need to have a valid DNS record for your hostname.

ServerName www.freeyourbox.org
ServerAdmin webmaster@freeyourbox.org

One thing I like to do to improve security is to disable directory listings if no index file is found. This can be done by inserting "Options -Indexes" between the DocumentRoot directory and the Directory / options and remove the Indexes option from Directory / like so: (Note: directory indexing IS already disabled by default on OpenBSD. I've put this in here as an example of how to do it)

DocumentRoot "/var/www/htdocs"

## Turn off directory listing by default and make allowed to only specific dirs
Options -Indexes

<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

With this setup you will have to explicitly allow directory listing in any directories you will want to be able to list files in. An example is in order:

# allow indexes to specific directory

<Directory /var/www/htdocs/allowedindexing>
    AllowOverride None
    Options +Indexes
</Directory>

Now save the httpd.conf file. Then stop and start apache to reread the config with the following:

# apachectl stop
# apachectl start

top

Testing MySQL and PHP

Ok, PHP and MySQL are installed. Apache is configured and running. Now we want to test our setup to make sure that it's really working. Create a new file in vi:

vi mysql_test.php

Enter the following into the file and save it:

<html>
<head>
<title>PHP MySQL connection test</title>
<body>
<?php
// Open the connection to mysql
$conn = mysql_connect('localhost', 'testacct', 'l33tp4ssw0rd');

// pick the database to use
mysql_select_db("testdb",$conn);

// create the SQL statement
$sql = "SELECT id, name from new_table";

// execute the SQL statement
$result = mysql_query($sql, $conn) or die(mysql_error());
// go through each row in the result set and display data
// we only have one row so this is not really needed, but it's good reference
// for the future
while ($array = mysql_fetch_array($result)) {
        // give name to the fields
        $id = $array['id'];
        $nameField = $array['name'];
        // echo the results to the screen
        echo "The ID is $id and the name is $nameField <br>";
}

// good form to close the connection
mysql_close($conn);
// close the php
?>
</body>
</html>

Run the script:

lynx http://127.0.0.1/mysql_test.php

You should see:

The ID is 1 and the name is h4x0r

top

Disabling and configuring Services

OpenBSD does come with a few unnecessary services enabled by default in my opinion. I like to turn these services off. This is completely optional and you must do so according to your own needs.

# vi /etc/inetd.conf

Comment out the following:

#ident           stream  tcp     nowait  _identd /usr/libexec/identd     identd -el
#ident           stream  tcp6    nowait  _identd /usr/libexec/identd     identd -el
#daytime         stream  tcp     nowait  root    internal
#daytime         stream  tcp6    nowait  root    internal
#time            stream  tcp     nowait  root    internal
#time            stream  tcp6    nowait  root    internal 

I also like to disable root login via ssh and only allow ssh version 2

vi /etc/ssh/sshd_config

Enter the following two lines:

Protocol 2
PermitRootLogin no

If you choose to do this, you need to create another user account to login in as and add this user needs to be part of the wheel group:

# useradd -m -G wheel "username"
# passwd "username"
# chmod 700 /home/"username"

top

Starting Apache and MySQL at boot

Apache and MySQL need to be set to start at boot time:

vi /etc/rc.conf

Set the following parameters for apache:

httpd_flags=""

If you disabled the services in /etc/inetd.conf above then you change this in /etc/rc.conf as well:

inetd=NO

To enable MySQL to run at boot enter the following line in /etc/rc.conf.local:

mysql=YES

Then enter the following in /etc/rc.local after the 'starting local daemons' and before the following echo '.' :

if [ X"${mysql}" == X"YES" -a -x /usr/local/bin/mysqld_safe ]; then

    echo -n " mysqld"; /usr/local/bin/mysqld_safe --user=_mysql --log --open-files-limit=256 &

    for i in 1 2 3 4 5 6; do
        if [ -S /var/run/mysql/mysql.sock ]; then
            break
        else
            sleep 1
            echo -n "."
        fi
    done
    #
    # Apache chroot Settings

    mkdir -p /var/www/var/run/mysql
    sleep 2
    ln -f /var/run/mysql/mysql.sock /var/www/var/run/mysql/mysql.sock
fi

Your OpenBSD 3.8 system with Apache, PHP, and MySQL is now ready! Reboot the machine and make sure everything is running as it should be.

Happy web serving and enjoy!

top

References:

Install OpenBSD to Secure Your Web Server
OpenBSD FAQ Ch. 15 - The OpenBSD packages and ports system
MySQL Database Server
MySQL Reference Manual
Sams Teach Yourself PHP, MySQL and Apache All in One, 2nd Edition