HAProxyでHTTP/2のTLS終端する際のALPN設定

HAProxy 1.5でALPNに対応していた。


HTTP/2 over TLSの通信を、HAProxyでTLSを終端することで、TLS対応を行わないであろうVarnishなどでもh2c接続が可能となる。
(HAProxy自体のhttp2対応はまだ先)


今回はバックエンドにNginxをh2cでリッスンさせて試してみた

構成

構成としては以下の図のとおりである。


HAproxyはTLSの終端のみを行い、中身のメッセージをそのままバックエンドに送信する。この時HAProxyはHTTP/2の処理は行わない。
バックエンドのNginxはh2cのダイレクトで通信を受け付ける。

HAProxyの設定

  • bindでalpn h2を指定する
  • if { ssl_fc_alpn -i h2 }で、h2ならh2cのバックエンドへ、そうでなければhttp/1.1のバックエンドへ

(opensslのバージョンが足りないとALPN使えません)


haproxy.cfg

frontend  tls_proxy
    bind *:443 name https ssl crt /etc/haproxy/ssl/server.pem alpn h2  ciphers AESGCM:HIGH:!aNULL:!MD5
    mode tcp
    use_backend nginx-h2c if { ssl_fc_alpn -i h2 }
    default_backend nginx

backend nginx
    balance roundrobin
    server nginx1 localhost:8080 check inter 2000 send-proxy
backend nginx-h2c
    balance roundrobin
    server nginx1 localhost:8081 check inter 2000 send-proxy

Nginxの設定

今回はnginx 1.9.4 http2パッチv3

  • 8080番ポートでhttp/1.1
  • 8081番ポートでh2cダイレクト


nginx.conf

    server {                                                                                                
        listen  8080 proxy_protocol;
        server_name localhost;                                                                              
                                                                                                            
        location / {                                                                                        
          root /usr/share/www;
        }                                                                                                   
    }                                                                                                       
    server {                                                                                                
        listen  8081 http2 proxy_protocol;
        server_name localhost;                                                                              
                                                                                                            
        location / {                                                                                        
          root /usr/share/www;
        }                                                                                                   
    }                                                                                                       
アクセスログ

http2対応ブラウザと、そうじゃないブラウザでHAProxyにhttpsでアクセスすると

127.0.0.1 - - [27/Aug/2015:01:10:47 +0900] "GET / HTTP/1.1" 404 640 "-" h2:h2c
127.0.0.1 - - [27/Aug/2015:01:10:49 +0900] "GET / HTTP/1.1" 404 570 "-" h2:


http2対応ブラウザではh2c側に振り分けられ
http2非対応ブラウザだとhttp/1.1側に振り分けられてる事が確認できる