名詞解釋
h2 指的是建立在 LTS 之上的 HTTP/2 協議,即 HTTP/2 Over LTS。
h2c 指的是建立在 TCP 之上的 HTTP/2 協議, 即 HTTP/2 Over TCP。
HAProxy 配置
關鍵在於接受前端的 h2 請求,以及轉發到後端的 h2c 請求,請看關鍵配置:
frontend fe_example_test
# 下面一行指定了:
# 1. 監聽當前機器的 443 端口
# 2. 使用 ssl,且證書爲 /etc/haproxy/ssl/g4n32u.xyz.pem,協商協議爲 ALPN
# 3. HTTP 版本爲 2,即 h2
bind *:443 ssl crt /etc/haproxy/ssl/g4n32u.xyz.pem alpn h2
mode http # 指定入口是 http 模式
default_backend be_example_test
backend be_example_test
mode http # 指定轉發到後端是 http 模式
# 下面一行指定了:
# 1. 後端應用別名:backend_server
# 2. 後端應用的地址和端口號
# 3. 轉發到後端使用的協議,這裏是 h2(即h2c),因爲流量已被 HAProxy 解密
server backend_server 127.0.0.1:60002 proto h2
關於 HTTPS 證書
如果你的證書像我一樣是用 acme.sh 生成的,那要注意一下 HAProxy 對證書格式的要求和 Nginx 略有區別。對於 Nginx 來說,使用 acme.sh 生成的 fullchain-file 即可,但是對於 HAProxy,你必須將證書和私鑰合併起來,也就是將 acme.sh 生成的 cert-file 和 key-file 合併起來,用命令描述上面這句話就是:
acme.sh --installcert -d example.com \
--cert-file /etc/haproxy/ssl/example.com.cer \
--key-file /etc/haproxy/ssl/example.com.key \
--fullchain-file /etc/haproxy/ssl/example.com.fullchain.cer \
--reloadcmd "cat /etc/haproxy/ssl/example.com.cer /etc/haproxy/ssl/example.com.key | tee /etc/haproxy/ssl/example.com.pem && systemctl restart haproxy"
我注意到在目錄 ~/.acme.sh/example.com/
這個目錄下,存在 example.com.pem
,裏面已經包含了證書和密鑰合併的結果,但是 acme.sh
並沒有提供安裝該文件的命令入口。所以只能退而求其次的在 --reloadcmd
命令中拼接。