23 Jul 2020
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?.
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.
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 🤔
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.