Almost two years ago I switched from HTTP/1.1 to HTTP/2 with Apache2. Here is what I did. If you want to know more about HTTP/2, read HTTP/1.1 vs HTTP/2: What’s the Difference?.
Setup HTTPS
As most of the browsers supports HTTP/2 over TLS only, we first need to setup HTTPS. For instance, Firefox claims:
Firefox will only be implementing HTTP/2 over TLS - and so far that means for https:// schemed URLs (…).
Therefore, we’ll use Let’s Encrypt, which is a free, automated and open certificate authority and Certbot a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.
First, install Certbot:
# aptitude install certbot
To obtain a SSL certificate, launch:
certbot --apache -d yourdomain -d www.yourdomain
Just let you guide, and at the question Redirect non secure connection to secure connection?, answer Yes.
Maybe you have a firewall on your server that blocks SSL connexions. In my case, I had to configure my ferm
firewall to open the 443 port:
# /etc/ferm/ferm.conf
domain (ip ip6) {
table filter {
chain INPUT {
policy DROP;
// ...
proto tcp dport 443 ACCEPT;
// ...
And that’s it, it works out of the box! Cerbot updated the Apache configuration and provides a cron task to renew the certificate automatically before it expires (check the file /etc/cron.d/certbot
).
For a more detailed guide about using Certbot with Apache, refer to How To Secure Apache with Let’s Encrypt on Debian 9.
Setup HTTP/2
OK, now we have HTTPS on our domain, we can set up HTTP/2.
First you need to enable the http2
mode for Apache:
# a2enmod http2
Then you need to configure your virtual host:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName yourdomain
ServerAlias yourdomain.com
Protocols h2 h2c http/1.1
# ...
Reload Apache:
# systemctl reload apache2
Yeah, it should work! Let’s check:
$ curl -I https://www.yourdomain
HTTP/1.1 200 OK
Date: Thu, 29 Nov 2018 22:45:14 GMT
Server: Apache
Cache-Control: no-cache, private
Upgrade: h2,h2c
Connection: Upgrade
Content-Type: text/html; charset=UTF-8
Houston, we’ve got a problem… The response tells us we are still using HTTP/1.1 🤔
Setup Apache2 with mpm-event
The answer is in the logs:
[Thu Nov 29 22:42:18.344846 2018] [http2:warn] [pid 2849] AH10034: The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive.
HTTP/2 is not “supported” by MPM Prefork. I chose to use Event instead:
a2dismod mpm_prefork
a2enmod mpm_event
systemctl restart apache2
Check again if it works 🤞
$ curl -I https://www.jjanvier.com
HTTP/2 200
date: Thu, 29 Nov 2018 22:51:20 GMT
server: Apache
cache-control: no-cache, private
content-type: text/html; charset=UTF-8
Perfect!
I didn’t try yet to tweak it further, thanks to the H2PushResource directive for instance. That’s enough for that blog.