Loading...
Real Time Concepts

HTTP2 Support and Install – Part 1

HTTP1.1 vs HTTP/2

Limitations of HTTP/1.1

The HTTP/1.1 protocol is fraught with the following shortcomings that make it less ideal especially when running high-traffic web servers:

1.Delays in loading web pages due to long HTTP headers.
2.HTTP/1.1 is only able to send one request for each file per TCP connection.

3. Given that HTTP/1.1 processes one request for every TCP connection, browsers are forced to send a deluge of parallel TCP connections to simultaneously process the requests. This leads to TCP congestion and ultimately bandwidth wastage and network degradation.

The above-mentioned problems often led to performance degradation and high overhead costs in bandwidth usage.
address these problems and is now the future for HTTP protocols.

Advantages of Using HTTP/2

It offers the following advantages:

HTTP/2
came into the picture to
1.Header compression that minimizes client requests and thereby lowers bandwidth consumption. The resultant effect is fast page load speeds.
2.Multiplexing several requests over one TCP connection. Both the server and the client can break down an HTTP request into multiple framesand regroup them at the other end.
3.Faster web performances which consequently lead to better SEO ranking.
4.Improved security since most mainstream browsers loads HTTP/2 over HTTPS.
5.HTTP/2 is considered more mobile-friendly thanks to the header compression feature

HTTP/2 is the fourth version of the HTTP protocol that was released in 2015. The performance enhancements over the HTTP/1.1 protocol include:

  • End-user perceived latency improvements
  • Network overhead improvements
  • Server resource usage improvements

Drawbacks of HTTP/2

  • Nonetheless, there are also some limitations businesses should take into account before switching to the new protocol.
  • Be aware of your audience: Although 75% of UK users are using browsers than can take advantage of the protocol, a number of people continue to use older browsers which don’t. Additionally, not all web servers out there support HTTP/2. Therefore, current page speed optimization techniques will remain necessary.
  • HTTPS Prerequisite: Switching from HTTP/1.1 will be more difficult if a site isn’t already using HTTPS, since HTTP/2 has the prerequisite of the site already being on HTTPS. Migrating a website to HTTPS will need some work, requiring all HTTP URLs to be redirected to the HTTPS secure version of the protocol. However, HTTPS is a positive ranking factor for Google and, since security is a top priority for the search engine, we expect them to apply more weight to this signal in the future. Therefore, it would be a good idea to upgrade your site as and when you can.
  • Performance impact could be minimal: Switching from HTTP/1.1 to HTTP/2 could take a lot of time and resources so it’s important to be sure that the impact in site speed worth it. If a website is already well-optimized for speed, the performance improvements might be smaller than expected.
    HTTP/2 Unknowns: The protocol is still relatively new; a lot of studies will have to be conducted in order to determine best practices and possible pitfalls.

Multiplexing

One of the limitations of HTTP/1.1 is that it is only able to request files one by one on a single connection – this means requesting the file, waiting for a response, downloading the file and then requesting the next one.

This process can significantly increase page load time, especially for pages with a high number of requests. As illustrated in the image below, HTTP/2 changes how requests and responses travel between browser and server by “multiplexing” multiple files over one single connection

Header Compression

HTTP/1.1 requests and responses are transmitted in plain text (causing a lot of unnecessary bytes being downloaded) but with HTTP/2, each bit of information is compressed and transmitted in binary code, making it more compact and efficient which avoids the user’s computer to wasting time translating the information into a format it understands.

This means that the overhead of each request will be smaller than the uncompressed HTTP/1.1 equivalent, saving significant bandwidth in some user sessions. Page load speed is critical upon mobile users, where the benefits of this feature become even more important.

Requirements and OS Compatibility Matrix

As you click on the tab the page content will also change for that particular technology

Notes
  • NginX can do NPN with OpenSSL 1.0.1 only. You need EL7.4+ with OpenSSL 1.0.2 to work with both NPN and APN. See NginX blog post in reference section below
  • Ubuntu 14.04 LTS : Nginx version 1.4.x provided by Ubuntu does not support HTTP2. Install Nginx from ppa:nginx/stable which provided supported version 1.12.x
  • Ubuntu 16.04 LTS accidentally included http2 when it was still experimental, but removed it afterwards, even though the httpd version remains high enough
  • Ubuntu 18.04 LTS requires the http2 module be manually enabled
  • IUS http24u includes mod_http2
  • CentOS 8 has Apache with mod_http2 already compiled
  • Unsupported Repositories and ppa:
    Red Hat Software Collections – RHSCL – SCL rh-nginx110 or rh-nginx112 (RHEL 7)
    Red Hat Software Collections – RHSCL – SCL rh-nginx110 (RHEL6)
    Red Hat Software Collections – RHSCL – SCL http24 includes mod_http2
  • ondrej
  • Supported Repositories
  • Ubuntu 20.04 and CentOS 8 is not currently available in dedicated. Currently only in the cloud.

Apache

Red Hat Support

From https://access.redhat.com/solutions/2159801

  • Red Hat only supports http2 on JBoss Core Services Apache HTTP Server 2.4.23.
  • Red Hat only provides “experimental” support under RHSCL 2.2 or newer (which provides httpd24, which is httpd 2.4.18).
Ubuntu Support

Vendor support appears to be Ubuntu 18.04 LTS only.

RHEL6/CentOS 6

Not Supported – Don’t try. While IUS httpd24 for RHEL6/CentOS 6 is sufficient, we are unable to obtain any supported and continually patched version of OpenSSL

RHEL7/CentOS 7

Apache+PHP72u+PHP-FPM

I used Apache 2.4 with PHP-FPM#fpm-CentOS7:Apache2.4withphp-fpmusingTCPport

And works with additional Apache 2.4 with PHP-FPM#fpm-CentOS7:Apache2.4withphp-fpmusingaUNIXsocket

Prerequistites

[root@742027-RHEL7a ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)

[root@742027-RHEL7a ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017

[root@742027-RHEL7a ~]# httpd -v
Server version: Apache/2.4.34 (IUS)
Server built: Aug 7 2018 19:41:14

[root@742027-RHEL7a ~]# php -v
PHP 7.2.9 (cli) (built: Aug 17 2018 08:23:28) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

[root@742027-RHEL7a ~]# php-fpm -v
PHP 7.2.9 (fpm-fcgi) (built: Aug 17 2018 08:25:26)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

Load the mod_http2 in /etc/httpd/conf.modules.d/00-base.conf

echo “LoadModule http2_module modules/mod_http2.so” >> /etc/httpd/conf.modules.d/00-base.conf

Enforce TLS only in /etc/http/conf.d/ssl.conf

echo “protocols h2 http/1.1” >> /etc/httpd/conf.d/ssl.conf

Enable TLS and cleartext(HTTP) in /etc/httpd/conf/httpd.conf

# Probably not a good idea
Protocols h2 h2c http/1.1

Verify http2 functionality

Before

[root@742027-RHEL7a ~]# curl -I -v http://127.0.0.1/index.php
* About to connect() to 127.0.0.1 port 80 (#0)
* Trying 127.0.0.1…
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /index.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Fri, 21 Sep 2018 14:08:09 GMT
Date: Fri, 21 Sep 2018 14:08:09 GMT
< Server: Apache
Server: Apache
< X-Powered-By: PHP/7.2.9
X-Powered-By: PHP/7.2.9
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 127.0.0.1 left intact
### After

[root@742027-RHEL7a ~]# systemctl restart httpd
[root@742027-RHEL7a ~]# curl -I -v http://127.0.0.1/index.php
* About to connect() to 127.0.0.1 port 80 (#0)
* Trying 127.0.0.1…
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> HEAD /index.php HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.0.0.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Fri, 21 Sep 2018 14:12:17 GMT
Date: Fri, 21 Sep 2018 14:12:17 GMT
< Server: Apache
Server: Apache
< X-Powered-By: PHP/7.2.9
X-Powered-By: PHP/7.2.9
< Upgrade: h2
Upgrade: h2
< Connection: Upgrade
Connection: Upgrade
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
<
* Connection #0 to host 127.0.0.1 left intact

RHEL8/CentOS 8

In RHEL/CentOS 8 when the Apache module is installed it also installs the http2 module and loads by default. Next is just to enable http2 at the vhost. I tested both html and php.

The domain example.com pointed to the local ip via “/etc/hosts”. As you can see from the the below, Apache is responding with “HTTP/1.1”.

before enabling http2

# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/1.1 200 OK
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/1.1 200 OK

To enable http2 add the line “Protocols h2 http/1.1” to the vhost as below and restart Apache.

Enable http2

<VirtualHost *:443>
Protocols h2 http/1.1
DocumentRoot /var/www/vhost
ServerName example.com
SSLEngine on
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
# Proxy declaration
<Proxy “unix:/run/php-fpm/www.sock|fcgi://php-fpm”>
# we must declare a parameter in here (doesn’t matter which) or
# it’ll not register the proxy ahead of time
ProxySet disablereuse=off
# Note: If you configure php-fpm to use the “pm = ondemand”
#then use “ProxySet disablereuse=on”
</Proxy>
<FilesMatch \.php$>
SetHandler proxy:fcgi://php-fpm
</FilesMatch>
</VirtualHost>

After enabling http2 you will now notice that Apache is responding with “HTTP/2”

http2 Enabled

# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/2 200
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/2 200

At the time of testing:

Testing performed using the following

# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
# openssl version
OpenSSL 1.1.1c FIPS 28 May 2019
# php -v
PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
# php-fpm -v
PHP 7.2.24 (fpm-fcgi) (built: Oct 22 2019 08:28:36)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
# httpd -v
Server version: Apache/2.4.37 (centos)
Server built: Jun 8 2020 20:14:33

Ubuntu 14.04 LTS

Don’t do it. This OS will EOL in April 2019. Neither OpenSSL nor Apache versions are high enough.

Ubuntu 16.04 LTS

OpenSSL is a high enough version, but the included Apache version does not include http2 functionality (though it was once accidentally included, before being removed since Ubuntu doesn’t want to support “experimental” technology in LTS releases).

Apache 2 PPA

sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/apache2
sudo apt update
sudo apt install apache2

Otherwise, its a custom compile task. Again, Rackspace should never do this on a customer’s behalf.

Custom Compile (for reference only, do not do this for customers)

# To proceed anyways building http2 from source, it can be done by:
Install lamp stack normally, then:
vim /etc/apt/sources.list
<uncomment>
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main restricted
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
# Now build http2.so from source and copy it into /usr/lib/apache2/modules:
apt-get update
apt-get install libnghttp2-dev
mkdir /root/apache2
cd /root/apache2
apt-get source apache2
apt-get build-dep apache2
cd apache2-2.4.18
fakeroot debian/rules binary
cp debian/apache2-bin/usr/lib/apache2/modules/mod_http2.so /usr/lib/apache2/modules/
echo “LoadModule http2_module /usr/lib/apache2/modules/mod_http2.so” > /etc/apache2/mods-available/http2.load
# Then install php-fpm as mod_php will not work with mpm-event… and mod_http2 only works with mpm-event or
mpm-worker:
apt-get install php7.0-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.0-fpm
a2dismod php7.0
a2dismod mpm_prefork
a2enmod mpm_event
# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2
a2enmod http2
systemctl restart apache2
vim /etc/apache2/sites-enabled/example.com.conf
<VirtualHost *:443>
Protocols h2 http/1.1

apachectl restart
# Test with:
curl -I -v https://example.com/test.html –insecure

< Upgrade: h2
Upgrade: h2
< Connection: Upgrade
Connection: Upgrade

Ubuntu 18.04 LTS

Enable HTTP2 on Ubuntu 18.04 LTS

The mpm module (prefork.c) is not supported by mod_http2. So have to figure out how to use mpm worker or
event… which means php7.2 will need to use something like php-fpm
# Install lamp stack normally, then:
apt-get update
apt-get install php7.2-fpm
a2enmod proxy_fcgi setenvif
a2enconf php7.2-fpm
a2dismod php7.2
a2dismod mpm_prefork
a2enmod mpm_event
# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2
# Enable module
a2enmod http2
systemctl restart apache2
vim /etc/apache2/sites-enabled/example.com.conf

<VirtualHost *:443>
Protocols h2 http/1.1

# Restart Apache
apachectl restart
# Test with:
curl -I -v https://example.com/test.html –insecure

* ALPN, offering h2

* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2

< HTTP/2 200
HTTP/2 200

Ubuntu 20.04 LTS

The following is the check to verify if http2 is already enable. The domain example.com pointed to the local ip via “/etc/hosts”. As you can see from  the the below, Apache is responding with “HTTP/1.1”.

Before http2

# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/1.1 200 OK
# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/1.1 200 OK

Set TLS to TLSV1.2

set TLSV1.2

# Update config to use TLS1.2:
vim /etc/apache2/mods-enabled/ssl.conf
SSLProtocol -all TLSv1.2

Enable the following modules

Enable module

a2enmod actions alias proxy_fcgi setenvif http2

Add the line “Protocols h2 http/1.1” to the vhost configuration to enable it for the domain, as in the following example. Afterwards you need to restart Apache

Enable http2

<VirtualHost *:443>
Protocols h2 http/1.1
DocumentRoot /var/www/vhost
ServerName example.com
SSLEngine on
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
# Proxy declaration
<FilesMatch \.php$>
SetHandler “proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost”
</FilesMatch>
</VirtualHost>

After enabling http2 you will now notice that Apache is responding with “HTTP/2”

Verify http2

# curl -I -s https://example.com/index.html –insecure |grep HTTP
HTTP/2 200
# curl -I -s https://example.com/index.php –insecure |grep HTTP
HTTP/2 200

The configuration at the time of testing

during testing

~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal
~# openssl version
OpenSSL 1.1.1f 31 Mar 2020
~# php -v
PHP 7.4.3 (cli) (built: May 26 2020 12:24:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
~# php-fpm7.4 -v
PHP 7.4.3 (fpm-fcgi) (built: May 26 2020 12:24:22)
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
~# apache2ctl -v
Server version: Apache/2.4.41 (Ubuntu)
Server built: 2020-08-12T19:46:17

Nginx

HTTP2 is available by default and is fully supported on servers running Nginx. Nginx has had HTTP2 support built in as of Nginx 1.9.5.

The table below outlines which packages support HTTP2 on Nginx

Verify that http2 has been compiled in nginx

Verify module

# strings /usr/sbin/nginx | grep _module | grep -v configure| sort | grep ^ngx_http_v2_module
ngx_http_v2_module
ngx_http_v2_module

Enable HTTP2 on Nginx is as simple as modifying an existing Nginx vhost to enable HTTP2 as shown below:

[root@web01 ~]# vim /etc/nginx/sites-enabled/example.com.conf

server {
listen 443 ssl http2;
server_name example.com www.example.com;

[root@web01 ~]# nginx -t
[root@web01 ~]# service nginx restart

Test to confirm HTTP2 is working by:

[user@workstation ~]# curl -IL https://www.example.com –insecure
HTTP/2 200 <—
server: nginx/1.14.0 (Ubuntu)
date: Mon, 22 Oct 2018 18:46:25 GMT

Leave a Reply

Your email address will not be published. Required fields are marked *