How-To

HTTP/2 SSL Offloading with Haproxy and Nginx

HTTP/2 SSL Offloading with Haproxy and Nginx

After HTTP/2 becoming more an more prominent regarding SSL enforcement, i will show you in this post how to setup HTTP/2 SSL Offloading with Haproxy and Nginx in few easy steps.

 

Prerequisites:

  • A working Haproxy 1.7.1.1+ Setup which Supports ALPN H2 and PROXY Protocol
  • OpenSSL 1.0.2+ that supports ALPN
  • Functional Nginx Setup behind Haproxy which supports H2 and PROXY Protocol
  • Texteditor (vi, joe, nano) of your choice

 

1. First of all we start with the Haproxy Global SSL Ciphers and tunings

Open your haproxy.cfg and if not already done we first set secure SSL Ciphers and SSL Options to our Global block which will give you an Grade A rating at SSLLabs:

tune.ssl.default-dh-param       2048
ssl-default-bind-options no-sslv3 no-tls-tickets
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA

The no-sslv3 Option prevents POODLE attacks while no-tls-tickets enables Session Resumption (caching)

2. Now we add our new HTTP/2 frontend to our Haproxy config

frontend http2-ssl
bind 10.1.1.1:443 ssl crt /etc/haproxy/certs/combined.yourcert.pem alpn h2,http/1.1
mode tcp
log global
option dontlog-normal
maxconn 6000
timeout client 2m
use_backend nginx-pool-http2 if { ssl_fc_alpn -i h2 }
default_backend nginx-pool-http2-fallback

Notes: Change the Bind IP, Cert Location, Maxconn, Timeout e.g. that it matches your Setup.

 

3. Next one is to setup our Haproxy Backends

backend nginx-pool-http2
        mode                    tcp
        balance                 roundrobin
        option                  tcpka
        timeout connect         2m
        timeout server          2m
        retries                 3
        server                  ngx-01 10.0.0.21:81 check send-proxy inter 2500  maxconn 2000
        server                  ngx-02 10.0.0.22:81 check send-proxy inter 2500  maxconn 2000
        server                  ngx-03 10.0.0.23:81 check send-proxy inter 2000  maxconn 2000
        server                  ngx-04 10.0.0.24:81 check send-proxy inter 2000  maxconn 2000
        server                  ngx-05 10.0.0.25:81 check send-proxy inter 1500  maxconn 2000
        server                  ngx-06 10.0.0.26:81 check send-proxy inter 1500  maxconn 2000

backend nginx-pool-http2-fallback
        mode                    tcp
        balance                 roundrobin
        option                  tcpka
        timeout connect         2m
        timeout server          2m
        retries                 3
        server                  ngx-01 10.0.0.21:82 check send-proxy inter 2500  maxconn 2000
        server                  ngx-02 10.0.0.22:82 check send-proxy inter 2500  maxconn 2000
        server                  ngx-03 10.0.0.23:82 check send-proxy inter 2000  maxconn 2000
        server                  ngx-04 10.0.0.24:82 check send-proxy inter 2000  maxconn 2000
        server                  ngx-05 10.0.0.25:82 check send-proxy inter 1500  maxconn 2000
        server                  ngx-06 10.0.0.26:82 check send-proxy inter 1500  maxconn 2000

Note: As you see, we set one Backend for HTTP/2 and another one for HTTP/1.1 and lower Protocol Versions as Fallback, which is important to support Clients which cannot speak HTTP/2.
The two Backends are very important and mandatory due to the fact that we are using TCP behind SSL Offloading, because Nginx cannot detect which HTTP Protocol (if its HTTP/2 or HTTP/1.0) the Client is initially using.
Change the backends server IPs that they will fit your loadbalancer setup.

 

4. In the final step we will prepare Nginx to speak the PROXY and HTTP/2 Protocol

In the Server Block of your Nginx sites-config create a new server block like shown bellow:

server {

listen   81 http2 proxy_protocol; # haproxy SSL termination + HTTP/2
listen   82 proxy_protocol;       # haproxy SSL termination for HTTP/1.1 and lower

add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'; # We want SSL A+ rating so we enable HSTS also.
set_real_ip_from 10.1.0.0/24;     # Set IP or subnet of your Loadbalancers here
real_ip_recursive on;
real_ip_header   proxy_protocol;  # This is mandatory to get Real IP from Proxy Protocol (other server block on port: 80 can continue use real_ip module with header: X-Forwarded-For)
.... and here comes your access_log, location settings e.g.

Note: Be careful with the “includeSubDomains” and “preload” response header. Set this only if you are hundered percent sure that you have SSL Certs for all your subdomains or you will get into trouble, because Browser which supports HSTS will force preload all your Domains and Subdomains by SSL if enabled and it is very hard to get removed from HSTS Preload List if activated once. If you want to get added/removed, you can visit the: HSTS Preload List Submission Page

Restart your Haproxy and Nginx and check your Logs for Errors.

Watch your Nginx Access Log, Connections with HTTP/2 should contain “HTTP/2.0” and Fallback Clients:  HTTP/1.1 now.

If all looks fine enjoy your new HTTP/2 capability!

Jules

Jules is the owner and author of ISPIRE.ME. He's a Linux System Engineer, Tech fanatic and an Open Source fan.

View Comments

    • No, since TCP mode is very straight forward Application Layer (layer 7) and doesn't inspect the content of its packets.
      The Transport Layer 4 (http mode) is required for ACLs, but since http mode doesn't support HTTP/2 yet,
      you cant apply routes like that.

Recent Posts

HTTP/2 SSL Offloading with Hitch and Varnish

HTTP/2 SSL Offloading with Hitch and Varnish Since Chrome browsers showing you insecure warning on…

7 years ago

File changed as we read it GlusterFS issue

File changed as we read it GlusterFS issue Recently i had trouble running Backups of…

8 years ago

Running multiple instances of varnish using systemd

Running multiple instances of varnish using systemd If you have not yet found a complete…

8 years ago

Get Real IP with Haproxy Tomcat Jira Confluence using x-forwarded-for

Get Real IP with Haproxy Tomcat Jira Confluence using x-forwarded-for Everyone knows the Problem. Get…

8 years ago

Review TDS2 How to backtest using tick data with Metatrader 4

Review TDS2 How to backtest using tick data with Metatrader 4 in this Review TDS2…

8 years ago

Fix Upgrading Nginx 1.10 fails error unknown directive

Fix Upgrading Nginx 1.10 fails error unknown directive In this short article i will show…

8 years ago

This website uses cookies.