diff --git a/_posts/2018-11-18-how-to-enable-http2-on-apache-debian-9.md b/_posts/2018-11-18-how-to-enable-http2-on-apache-debian-9.md new file mode 100644 index 0000000..55f4cb7 --- /dev/null +++ b/_posts/2018-11-18-how-to-enable-http2-on-apache-debian-9.md @@ -0,0 +1,168 @@ +--- +title: "How to enable HTTP2 on Apache (Debian 9) ?" +date: 2018-11-18 +url: how-to-enable-http2-on-apache-debian-9_1 +layout: post +category: Tutorials +image: /img/blog/how-to-enable-http2-on-apache-debian-9_1.png +description: "A complete guide to enable HTTP/2 on Apache (httpd) and Debian 9" +--- + +[](/img/blog/how-to-enable-http2-on-apache-debian-9_1.png) + +### Introduction + +The [release notes of Debian 9 (Stretch)](https://www.debian.org/News/2017/20170617) announced an interesting major upgrade among the others : Apache 2.4.25 . + +Why "interesting" though ? :thinking: +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`](https://httpd.apache.org/docs/2.4/mod/mod_http2.html). + +If you are still wondering whether your web servers or reverse proxies should propose this protocol, I invite you to read [this famous FAQ](https://http2.github.io/faq/). + +> Pro hint : Have you ever wonder why Google or YouTube are _that_ fast ? :smirk: + +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 :wink:) : + +`# nano /etc/apache2/conf-available/http2.conf` + +... and copy-paste this configuration : + +{% highlight apache %} +<IfModule http2_module> + Protocols h2 h2c http/1.1 + H2Direct On +</IfModule> +{% 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 :woman_shrugging:). +And guess what ? **MPM** is not compatible with HTTP/2 :joy: + +So, as we really really want HTTP/2 to be proposed, we will be using the PHP's **FPM** interpreter, standing for **FastCGI Process Manager**... 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](https://packages.debian.org/stretch/php7.0)) : `# aptitude 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](https://httpd.apache.org/docs/current/mod/event.html), as a substitute to `prefork` : `# a2enmod mpm_event` + +Now, you can restart your web server with more guarantees :relieved: + +`# 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. + +[](/img/blog/how-to-enable-http2-on-apache-debian-9_2.png) + +**TL;DR** : Click on the link and write down your URL :smirk: + +#### 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>) : + +[](/img/blog/how-to-enable-http2-on-apache-debian-9_3.png) + +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` :heart_eyes: + +#### 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](https://addons.mozilla.org/en-US/firefox/addon/http2-indicator/). + +> 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 :man_shrugging: + +But this is what I can tell you : [HTTP/2 requires TLS 1.2, without compression, without renegotiation, and without some holed ciphers](https://tools.ietf.org/html/rfc7540#section-9.2). + +Anyway, I invite you to take a look to my Apache hardening guide [here](/blog/security/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](https://www.zdnet.com/article/http-over-quic-to-be-renamed-http3/). + +I hope (as always) this helped you, don't hesitate to send a feedback or a fix below :bow: + +### Sources (additionally to all the links above) + +* [how to h2 in apache](https://icing.github.io/mod_h2/howto.html) + +* [How to enable HTTP/2 support in Apache](https://http2.pro/doc/Apache) diff --git a/img/blog/how-to-enable-http2-on-apache-debian-9_1.png b/img/blog/how-to-enable-http2-on-apache-debian-9_1.png new file mode 100644 index 0000000..a373e15 --- /dev/null +++ b/img/blog/how-to-enable-http2-on-apache-debian-9_1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c135196bcca8a936e729a702b066ea36427ef291f4db76634774b04018320e7 +size 14400 diff --git a/img/blog/how-to-enable-http2-on-apache-debian-9_2.png b/img/blog/how-to-enable-http2-on-apache-debian-9_2.png new file mode 100644 index 0000000..5cded8e --- /dev/null +++ b/img/blog/how-to-enable-http2-on-apache-debian-9_2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffeaf8cb7a5225ab11b9b9bd54bd7f44c7d0ed32b26379da3b57e43d33c42bad +size 69254 diff --git a/img/blog/how-to-enable-http2-on-apache-debian-9_3.png b/img/blog/how-to-enable-http2-on-apache-debian-9_3.png new file mode 100644 index 0000000..4125b5a --- /dev/null +++ b/img/blog/how-to-enable-http2-on-apache-debian-9_3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:296c099f0d4af8750e94bf3e4c3ff6dc7cef7b7ffea6317aa00a6450dbc81953 +size 150128