blog/_posts/2018-11-18-how-to-enable-ht...

7.2 KiB

title date url layout category image description
How to enable HTTP2 on Apache (Debian 9) ? 2018-11-18 how-to-enable-http2-on-apache-debian-9 post Tutorials /img/blog/how-to-enable-http2-on-apache-debian-9_1.png A complete guide to enable HTTP/2 on Apache (httpd) and Debian 9

A missing blog post image

Introduction

The release notes of Debian 9 (Stretch) announced an interesting major upgrade among the others : Apache 2.4.25 .

Why "interesting" though ? πŸ€”
Mostly because it was the first release containing an Apache package >= 2.4.17, the pivot version introducing HTTP/2 (SPDY) support, with mod_http2.

If you are still wondering whether your web servers or reverse proxies should offer this protocol, I invite you to read this famous FAQ.

Pro hint : Have you ever wonder why Google or YouTube are that fast ? 😏

At the end of this post, you will have (I hope) a running Apache with HTTP/2 enabled globally (on all your served websites).

Ready ? Let's go then !

Setup procedure

One new module, one new configuration

Before anything else, let's check that you are running a decent Apache version for HTTP/2 :

# apache2ctl -v

This should give you (at the very least) something like :

Server version: Apache/2.4.25 (Debian)

Now, we will enable the mod_http2 module presented above :

# a2enmod http2

Before restarting Apache (as the command output has just advised you), we will indicate to use the new protocol through configuration (as good sysadmins, we will preserve the modularity πŸ˜‰) :

# nano /etc/apache2/conf-available/http2.conf

... and copy-paste this configuration :

{% highlight apache %} Protocols h2 h2c http/1.1 H2Direct On {% endhighlight %}

And here, we only have to enable our new configuration :

# a2enconf http2

Pro tip : The configuration above would enable HTTP/2 globally.
If you want to enable it for a specific VHOST only, please do paste the configuration above inside it directly !

Pro tip 2 : h2 is for HTTP/2 over TLS & ALPN, and h2c is for clear text HTTP/2 negotiation (usually you won't need it, but who knows ?).

So, now, you could already restart your web server (# systemctl restart apache2) and check the results, but I tell you this : The odds might not be good.

[http2:warn] [pid XXXX] 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.

The MPM problem

Apache 2.4 works by default with the MPM prefork module, which stands for Multi-Processing Module prefork module (yeah I know, there is "module" two times within the sentence πŸ€·β€β™€οΈ).
And guess what ? MPM is not compatible with HTTP/2 πŸ˜‚

So, as we really really want to offer HTTP/2, we will be using the PHP's FPM interpreter (standing for FastCGI Process Manager) which is... compatible with HTTP/2 !

The FPM "solution"

Below is the recipe to follow (see sources at the end of the post) :

  1. Install the PHP's FPM package (I assume here that you have kept the official Stretch PHP version) : # apt install php7.0-fpm

  2. Enable some required modules : # a2enmod proxy_fcgi setenvif

  3. Enable the PHP's FPM new configuration : # a2enconf php7.0-fpm

  4. Disable the old modules that won't be used anymore : # a2dismod php7.0 mpm_prefork

  5. Enable the MPM event module, as a substitute to prefork : # a2enmod mpm_event

Now, you can restart your web server with more guarantees 😌

# systemctl restart apache2

Verification time !

At this step, I assume you have enforced the HTTP/2 configuration above and correctly restarted Apache !

Now is the time to verify our setup, this is X-mas, so many ways to achieve so :

Basic curl queries

With a verbose curl, assuming it has been compiled against HTTP/2 module of course, you may easily check that HTTP/2 is being (or will be) used :

$ curl -v https://your.domain.name/

Just watch for HTTP version written down along verbs or status codes.
For a HTTPS VHOST, this is a typical output that you may expect :

{% highlight text %} [...]

  • ALPN, offering h2
  • ALPN, offering http/1.1 [...]
  • ALPN, server accepted to use h2 [...]
  • Using HTTP2, server supports multi-use [...]

GET / HTTP/2 [...] < HTTP/2 200 [...] {% endhighlight %}

A pretty handy web tool available anywhere

https://http2.pro/ allows you to check remotely whether HTTP/2 is enforced or not.
It is also able to check if ALPN and PUSH are well-supported.

A missing blog post image

TL;DR : Click on the link and write down your URL 😏

Firefox Developer's toolbox

Open your favorite developer tool panel, and jump into the Network category. Then, reload your page, and click on a request (example with https://peertube.xyz) :

A missing blog post image

You should watch for the X-Firefox-Spdy response header (with a h2 value over TLS), or the Version field specified under the Status code 😍

A Firefox add-on !

Generally, if you want to know during your browsing whether your hosts run HTTP/2 or not, I advise you this browser extension.

The image of this very blog post has been taken from their source code repository ; All credits go to its authors !

"It still does not work..."

Yeah it's possible, you may have a custom specific configuration πŸ€·β€β™‚οΈ

But this is what I can tell you : HTTP/2 requires TLS 1.2, without compression, without renegotiation, and without some holed ciphers.

Anyway, I invite you to take a look at my Apache hardening guide [here]({% post_url 2017-11-14-hardening-apache-all-in-one-place %}) !

Conclusion

To conclude, I'd say that we had to wait for a 2018 Linux distribution to enable HTTP/2, whereas its RFC has been drafted in 2015.

Nevertheless, I couldn't publish this post without mentioning the fact that HTTP/3 (QUIC) again originally designed by Google is currently in the process of being accepted by the IETF.

I hope (as always) this helped you, don't hesitate to send a feedback or a fix below πŸ™‡