Haproxy

Haproxy ssl passthrough 中斷 curl 請求

  • July 7, 2019

我在 TCP 模式下配置了 Haproxy 以平衡 2 個伺服器並通過 https 連接到它們。問題是當我的前端處於 tcp 模式時,curl 請求無法正常進行。

這就是我得到的:

* Rebuilt URL to: https://HOSTNAME/
*   Trying IP...
* Connected to HOSTNAME (IP) port 443 (#0)
* found 173 certificates in /etc/ssl/certs/ca-certificates.crt
* found 697 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*    server certificate verification OK
*    server certificate status verification SKIPPED
*    common name: HOSTNAME (matched)
*    server certificate expiration date OK
*    server certificate activation date OK
*    certificate public key: RSA
*    certificate version: #3
*    subject: CN=HOSTNAME
*    start date: Sun, 03 Jul 2016 13:07:00 GMT
*    expire date: Sat, 01 Oct 2016 13:07:00 GMT
*    issuer: C=US,O=Let's Encrypt,CN=Let's Encrypt Authority X3
*    compression: NULL
* ALPN, server accepted to use http/1.1
> GET / HTTP/1.1
> Host: HOSTNAME
> User-Agent: curl/7.47.0
> Accept: */*
> 
* Connection #0 to host HOSTNAME left intact
����%

這是我的 haproxy.cfg:

global
   log 127.0.0.1 local0 notice
   maxconn 2000
   user haproxy
   group haproxy
   stats socket /etc/haproxy/sock.stat level admin
   ssl-default-bind-options no-sslv3
   ssl-default-bind-ciphers kEECDH+AESGCM+AES128:kEECDH+AES128:kRSA+AESGCM+AES128:kRSA+AES128:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2
   tune.ssl.default-dh-param 2048
defaults
   log global
   retries 3
   option redispatch
   timeout connect 5000
   timeout client 5000
   timeout server 5000
frontend https
   mode tcp
   option tcplog
   bind :443 ssl crt /etc/letsencrypt/live/HOSTNAME/haproxy.pem ciphers TLSv1.2 alpn h2,http/1.1
   default_backend nodes
   backend nodes
   mode tcp
   option tcplog
   server node-nginx 172.17.0.73:9999 check
   server node-maint 172.17.0.74:9999 backup
frontend http
   bind :80
   mode http
   redirect scheme https code 301 if !{ ssl_fc }

有什麼我可以做的嗎?我需要 OpenGraph 預覽,但它因此而失敗。

問題是配置根本不處理 HTTP 1.1 請求。您必須為 HTTP1.1 請求定義一個新的後端塊。由於我的伺服器是由 nginx 驅動的,所以我是這樣實現的:

listen 9999 default_server;
listen 9998 default_server http2;

這就是我的後端的樣子:

backend nodes-http2
   mode tcp
   option tcplog
   server node-nginx 172.17.0.73:9998 check
   server node-maint 172.17.0.74:9998 backup

為了重定向 HTTP2 使用者,我將其添加到frontend https部分:

use_backend nodes-http2 if { ssl_fc_alpn -i h2 }

引用自:https://serverfault.com/questions/791046