How to enable HTTP/2 in Apache 2.4 on Gentoo Linux
I recently added support for the HTTP/2 protocol on this server and I am really pleased with the additional performance gains. This VPS was already running a functional LAMP stack, so the following steps describe the necessary configuration changes for my setup which relies on Apache with PHP-FPM.
This guide is more extensive than necessary. The USE flags will obviously pull in the needed dependencies so strictly speaking, there is really no need to split the process down to installing individual packages. The threads
USE flag can also be set globally instead of per package.
Additional packages
To build Apache with HTTP/2 support we need to add the HTTP/2 C library. Install the nghttp2
package and its dependencies with the command:
emerge -av net-libs/nghttp2
PHP-FPM
Before rebuilding Apache with HTTP/2 support, I’ll add the threads
USE flag to PHP. Add the threads USE flag to your existing list of PHP flags by editing /etc/portage/package.use/php
:
# /etc/portage/package.use/php dev-lang/php cli curl exif fpm ftp gd mysql mysqli pdo threads zip xmlwriter
The additional PHP USE flags I’ve selected are needed for my WordPress installation but your taste may differ.
Apache
To use HTTP/2, it’s necessary to switch from the default prefork implementation to the Apache event or worker MPM. The Gentoo Wiki provides additional details here.
With nghttp2 installed, let’s switch to the Apache event MPM and add http2 to the list of Apache modules we want to build. Edit /etc/portage/make.conf
:
# /etc/portage/make.conf # Profile used for building. USE="bindist mmx sse sse2 -pulseaudio -systemd apache2 php" # Build PHP extensions PHP_TARGETS="php7-0 php7-1" # Use Apache MPM event APACHE2_MPMS="event" # Build the following Apache modules APACHE2_MODULES="$APACHE2_MODULES http2 log_forensic proxy proxy_fcgi"
The proxy and proxy_fcgi Apache modules are needed for running Apache with PHP-FPM. Make sure PHP_TARGETS
reflects your installed PHP version(s) if needed. I also recommend having apache2
and php
defined as global USE flags.
We also need to enable the Apache threads
USE flag by adding the following directive to /etc/portage/package.use/apache
:
# /etc/portage/package.use/apache www-servers/apache threads
Rebuild and configure the system
Finally, the system has to be updated to reflect the necessary changes. Run the following emerge
command to rebuild packages with new USE flags:
emerge -avuND @world
For a fresh install, emerging PHP will also pull in Apache provided that apache2
is defined as a global USE flag.
emerge -av dev-lang/php
Enable the http2_module
The last step required is to edit /etc/conf.d/apache2
and to add the HTTP2 variable to your APACHE2_OPTS section.
APACHE2_OPTS="-D DEFAULT_VHOST -D SSL -D SSL_DEFAULT_VHOST -D LANGUAGE -D SECURITY -D PHP -D PROXY -D HTTP2"
Adding -D HTTP2
will toggle the following section to true and load the module:
# /etc/apache2/httpd.conf <IfDefine HTTP2> LoadModule http2_module modules/mod_http2.so </IfDefine>
You’ll find the configuration file for HTTP/2 located under /etc/apache2/modules.d/41_mod_http2.conf
. It enables the HTTP/2 protocol for all SSL enabled sites.
# /etc/apache2/modules.d/41_mod_http2.conf <IfDefine SSL> <IfModule http2_module> Protocols h2 h2c http/1.1 </IfModule> </IfDefine>
Restart Apache and verify that everything is working as intended.
/etc/init.d/apache2 restart
ModSecurity
Older implementations of ModSecurity might block HTTP/2 requests due to an unknown protocol versions. Let’s add a “fix” to the core rule set by modifying the section specifying allowed http versions. Modify /etc/apache2/modules.d/80_modsecurity-crs.conf
and append HTTP/2.0 to the allowed http version list:
# /etc/apache2/modules.d/80_modsecurity-crs.conf setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2.0', \
Restart Apache, and we should be good.