PHP 5.4 Configuration For Apache 2.4

PHP 5.4 InfoIn one of the systems we manage, we are running Apache httpd 2.4 with PHP and mod_fcgid.  We configure PHP 5.4 for compilation using this script:

#! /bin/sh
#
# Created by configure

'./configure' \
'--enable-intl' \
'--enable-cgi' \
'--enable-fpm' \
'--with-apxs2=/opt/apache/bin/apxs' \
'--with-fpm-user=daemon' \
'--with-fpm-group=daemon' \
'--with-pear' \
'--with-libdir=lib64' \
'--with-curl=shared' \
'--with-openssl=shared' \
'--prefix=/opt/php5' \
'--with-gdbm=shared' \
'--enable-dba=shared' \
'--with-db4=shared' \
'--enable-ftp' \
'--with-gd=shared' \
'--with-imap=shared' \
'--with-kerberos=/usr' \
'--with-imap-ssl=shared' \
'--enable-sockets' \
'--enable-zip' \
'--with-jpeg-dir=/usr' \
'--with-png-dir=/usr' \
'--with-xpm-dir=/usr' \
'--with-zlib' \
'--with-zlib-dir=/usr' \
'--with-bz2=shared' \
'--enable-exif' \
'--enable-soap' \
'--with-mcrypt=/usr/local' \
'--with-mhash' \
'--enable-mbstring' \
'--with-mysql=mysqlnd' \
'--with-mysqli=mysqlnd' \
'--with-pdo-mysql=mysqlnd' \
'--with-snmp=shared' \
'--enable-wddx' \
'--with-xmlrpc=shared' \
'--with-xsl=shared' \
'--with-ldap=shared' \
'--with-ldap-sasl' \
"[email protected]"

The above configuration is valid as long as the requisite software and libraries are installed. For our CentOS system, we use yum (which uses rpm) to install these software and libraries.

After running the above script to configure the PHP source, we compile and install PHP:

make
make test
sudo make install

Note that our PHP configuration for compilation lets us generate a command-line PHP binary (php), a FastCGI PHP binary (php-cgi), a FastCGI Process Manager-enabled binary (php-fpm) and an Apache httpd 2 module (libphp5.so).

As for the existing Apache httpd 2.4 installation, we configure /etc/opt/apache/httpd.conf to make use of php-cgi through mod_fcgid:

# Make sure mod_fcgid is enabled above.
# libphp5.so must be disabled.
# PHP5.4 - FCGI
<IfModule fcgid_module>
    <FilesMatch \.php$>
        AddHandler fcgid-script .php
        Options +ExecCGI
        FcgidWrapper /opt/php5/bin/php-wrapper  .php
    </FilesMatch>
</IfModule>

Now, /opt/php5/bin/php-wrapper is simply this script:

#!/bin/bash

PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_MAX_REQUESTS

# Disable PHP child process management. Let mod_fcgid
# handle it
PHP_FCGI_CHILDREN=0
export PHP_FCGI_CHILDREN 

exec /opt/php5/bin/php-cgi [email protected]

The above script is based on an example in http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#examples.

Be aware that, with the FilesMatch directive above, access controls applied to PHP files may get a bit tricky. Take note of the order of directives and refer to the Apache httpd 2.4 documentation for tips and for more information. See http://httpd.apache.org/docs/2.4/howto/access.html for example.

Using GnuTLS With Apache httpd 2.2

An alternative to using OpenSSL with Apache httpd is to use GnuTLS.  GnuTLS supports TLS 1.2 and TLS 1.1 aside from the cryptographic protocols supported by OpenSSL.  Note, however, that SSL 2.0 is not supported.

GnuTLS also supports secure renegotiation which stops attackers from intercepting and injecting data in a TLS connection.  Secure renegotiation is discussed in RFC5746

The following software are needed to get GnuTLS to work in Apache httpd:

The httpd module that enables GnuTLS in Apache httpd is mod_gnutls. One interesting feature is mod_gnutls’ support for Server Name Indication (SNI) which allows you to configure the web server to use one IP address for multiple TLS-enabled hostnames (just like the configuration for regular name-based virtual hosts).

The above software packages are to be installed in the same order.  These packages might be available for your favorite Linux distribution.  In our case, we simply compile and install from the original sources.

[GARD align=”center”]

Here are the configuration statements used:

GnuMP:

./configure
make
make check
make install

Nettle:

./configure --enable-shared
make
make check
make install

libgpg-error:

./configure
make
make check
make install

libgcrypt:

./configure
make
make check
make install

GnuTLS:

./configure
make
make check
make install

mod_gnutls:

./configure --with-apxs=/opt/apache2/sbin/apxs
make
make install

One thing to add to the Apache httpd configuration is the module specification:

LoadModule gnutls_module modules_dirname/mod_gnutls.so

The documentation for mod_gnutls is straightforward. You can find examples of configurations in the documentation.

A good way to test if your TLS-enabled site works properly is to use the testing tool of SSLLabs: http://www.ssllabs.com/. The test will determine the soundness of your security configuration. Take note that the test uses the features of Firefox 3.6.x to connect to your site. Apparently, this version of Firefox doesn’t seem to support SNI.

If you have trouble making the TLS cache to work for db/gdbm files, check the permissions on the filesystem to see if the web server is allowed to create, read, and write to the cache file. Make sure that Apache httpd, via the Apache Portable Runtime (APR), supports the use of the Berkeley DB and/or the GNU dbm libraries. In our case, we had to compile the APR to support db and gdbm explicitly.

Update:  25 Jul 2011

When installing the digital certificate for your site, make sure the certificate along with a certificate bundle from the issuer are in the proper order.  For example, for linuxunbound.com, the certificate hierarchy looks like this:

Linux Unbound Certificate Hierarchy

Linux Unbound Certificate Hierarchy

 

As for the actual certificate bundle, the certificates should be in the following order:

Digital Certificates In A Bundle

Sequence of Digital Certificates In A Bundle

As you can see above, the linuxunbound.com certificate comes first, followed by the rest in reverse order.  Compare this with the hierarchy as seen by the web browser.

In Apache httpd 2.x, the configuration shall look like this:

<IfModule gnutls_module>
  GnuTLSEnable on
  GnuTLSSessionTickets on
  GnuTLSPriorities NORMAL
  GnuTLSKeyFile /path_to_private/key
  GnuTLSCertificateFile /path_to_public/certificate_bundle.crt
</IfModule>

For performance reasons, a cache should be set up:

GnuTLSCache dbm "/path/to/tls-cache"
GnuTLSCacheTimeout 600

where tls-cache is the cache file. Note that in the above example, we use the BerkeleyDB format.