Apache

From Segfault
Jump to navigation Jump to search

Installation

Source

TBD!
 svn co https://svn.apache.org/repos/asf/httpd/httpd/trunk httpd-trunk
 svn co https://svn.apache.org/repos/asf/apr/apr/trunk srclib/apr
 ./buildconf
 ./configure --prefix=/opt/apache --localstatedir=/var/run/apache --enable-mods-shared=all
 make
 sudo make install

Packages

The Apache webserver comes usually with your distribution of choice:

apt-get install apache2-mpm-worker                # Debian, Ubuntu

Modules

3rd party modules can be installed with apxs. For mod_proxy_html, this would look something like this:

apxs2 -c -I/usr/include/libxml2 mod_proxy_html.c
cp .libs/mod_proxy_html.so /opt/apache2/modules/

Configuration

PHP

PHP support can be installed in different ways:

  • mod_php - Can be fast & stable. No need to call external processes (CGI) or use sockets to communicate with external processes (FastCGI). Opcode caches (APC, Xcache, eAccelerator) are shared! Can become quite bloated when modules are used. Also, if mod_php crashes, possibly the whole webserver goes down.
  • CGI - Legacy. Spawns a new process for every request to execute a PHP script
  • FastCGI - An external program is running and providing a socket, where the webservers sends requests to execute PHP code. The socket can also be a network socket. However, its last release happened long ago and there hasn't been a commit since 2007.

mod_php5

Since our apache2-mpm-worker is a multi-threaded server and PHP is usually not built threaded, we have to use another MPM:

apt-get install apache2-mpm-prefork libapache2-mod-php5

This should be it, the installation should provide /etc/apache2/mods-enabled/php5.conf, containing something like this:

LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
<FilesMatch ".+\.ph(p[345]?|t|tml)$">
   SetHandler application/x-httpd-php
</FilesMatch>

php5-cgi & mod_fcgid

When used as a FastCGI application, we can use apache2-mpm-worker again:

apt-get install apache2-mpm-worker libapache2-mod-fcgid php5-cgi

The configuration should look something like this:

# mods-enabled/fcgid.conf
<IfModule mod_fcgid.c>
  AddHandler    fcgid-script .fcgi .php
  FcgidConnectTimeout   20
  MaxRequestsPerProcess 1000
  MaxProcessCount       10
  FCGIWrapper  /usr/bin/php-cgi .php
</IfModule>

Defaults:

Disable other CGI modules; enable mod_fcgid:

a2dismod php5_cgi fastcgi && a2enmod fcgid
service apache2 restart

Also, we need to enable ExecCGI for our document root:

$ cat sites-enabled/example.org
[...]
      <Directory "/var/www/">
               Options Indexes FollowSymLinks MultiViews ExecCGI
               AllowOverride None
               Order allow,deny
               Allow from all
       </Directory>

php-fpm & mod_fcgid

Install and enable mod_fcgid along with Apache:

apt-get install apache2 php-fpm libapache2-mod-fcgid
a2enmod fcgid

Configure:

$ cat /etc/apache2/mods-enabled/fcgid.conf 
<IfModule mod_fcgid.c>
  FcgidConnectTimeout 20

  <IfModule mod_mime.c>
    AddHandler fcgid-script .fcgi
  </IfModule>

  <FilesMatch \.php$>
  #   SetHandler "proxy:unix:/var/run/php/php7.0-fpm.sock"
      SetHandler "proxy:fcgi://127.0.0.1:9000"
  </FilesMatch>
</IfModule>

With php-fpm running, .php scripts should now be executed.

php-fpm & mod_proxy_fcgi

Supposedly the easiest way[3] to accomplish this - mod_proxy_fcgi is part of Apache and can be configured to work with PHP-FPM[3] like this:

ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/var/run/php5-fpm.sock|fcgi://127.0.0.1:9000/var/www

However, if PHP-FPM is configured as a socket only, we have to provide a pseudo-entry for fcgi[4]:

ProxyPassMatch ^/(.*\.php(/.*)?)$ unix:/var/run/php5-fpm.sock|fcgi://localhost/var/www

Note: adjust /var/www to your DocumentRoot!

php-fpm & mod_fastcgi

The libapache2-mod-fastcgi package in Debian is currently in bad shape (see Debian #592937 or Debian #504132), other distributions might still support it. We'd have to build it from source. Since the Git repository is even older than their last "release", we should use the latter.

TBD...

php-fpm is alive and kicking and has been shipped with PHP since 5.4.0RC2:

apt-get install php5-fpm

Configure php5-fpm:

$ grep ^[a-z] /etc/php5/fpm/php-fpm.conf
pid       = /var/run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
include   = /etc/php5/fpm/pool.d/*.conf
$ cat /etc/php5/fpm/pool.d/www.conf
[...]
user                 = www-data
group                = www-data
; listen             = 127.0.0.1:9000
listen               = /var/run/php/php5-fpm.sock
listen.mode          = 0660
pm                   = dynamic
pm.max_children      = 5
pm.start_servers     = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /

Make the socket directory SGID, so that the socket will be owned by the webserver.

chown www-data:www-data /var/run/php
chmod 2750 /var/run/php

Start php-fpm:

php5-fpm -c /etc/php5/fpm/php-fpm.conf

Configure apache (be sure to disable mod_fastcgi and mod_php):

Restart apache and PHP should be available :)

SSL

A simple SSL stanza would be:

SSLEngine on
SSLCertificateFile       /etc/ssl/private/server.pem
# SSLCertificateKeyFile  /etc/ssl/private/server.key
  • SSLCertificateFile[5] should point to the certificate in PEM format.
  • It can include the server's key too - if it's not included, SSLCertificateKeyFile has to be used
  • With Apache 2.4.7 (and OpenSSL 1.0.2) dhparam and ecparam parameters can be added as well.[6]

We can also specify which protocols and ciphers to use:

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"

If our CA is providing a Class-3 certificate, we could use that as well[7]. E.g., for CAcert:

wget https://www.cacert.org/certs/{class3,root}.crt
cat class3.crt root.crt > chain.pem

The Apache config for this:

SSLCertificateFile      /etc/ssl/private/server.crt
SSLCertificateKeyFile   /etc/ssl/private/server.key
SSLCertificateChainFile /usr/local/share/ca-certificates/cacert.org/chain.pem

See also

Links

References