Я настроил экземпляр HAProxy, который должен:
- разгрузить SSL на внешнем интерфейсе
- onload SSL на внутреннем интерфейсе
- использовать SNI для соединенийи проверки работоспособности в направлении апстрима
Для этой демонстрации я создал укороченную HAProxy-конфигурацию, которая выглядит следующим образом:
global
log 127.0.0.1 local0
maxconn 8000
user nobody
group nogroup
daemon
debug
#quiet
stats socket /var/run/haproxy.sock mode 600 level admin
ssl-default-bind-options no-sslv3
ssl-default-bind-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-server-options no-sslv3
ssl-default-server-ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
tune.ssl.default-dh-param 2048
defaults
log global
mode http
balance roundrobin
option dontlognull
option abortonclose
option redispatch
retries 3
maxconn 18000
timeout connect 30s
timeout client 30s
timeout server 30s
frontend test.local
bind 0.0.0.0:8443
reqadd X-Forwarded-Proto:\ https
option forwardfor
acl api_statusio path_beg -i /status/1.0
use_backend api_statusio if api_statusio
backend api_statusio
option httpchk GET / HTTP/1.1\r\nHost:\ letsencrypt.status.io
http-request set-header Host letsencrypt.status.io
server test2 143.204.101.51:443 ssl check ca-file /etc/ssl/certs/ca-certificates.crt sni str(letsencrypt.status.io) check-ssl check-sni str(letsencrypt.status.io)
Это работает, например, с использованием google.com в качестве апстрима,но без ресурса status.io (letsencrypt.status.io приведен здесь только в качестве примера):
root@edc5cab629ae:/# haproxy -f ./haproxy.cfg
[WARNING] 274/160954 (2642) : parsing [./haproxy.cfg:37] : The 'reqadd' directive is deprecated in favor of 'http-request add-header' and will be removed in next version.
[WARNING] 274/160954 (2642) : <debug> mode incompatible with <quiet> and <daemon>. Keeping <debug> only.
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result FAILED
Total: 3 (2 usable), will use epoll.
Available filters :
[SPOE] spoe
[COMP] compression
[CACHE] cache
[TRACE] trace
Using epoll() as the polling mechanism.
fd[0013] OpenSSL error[0x14094410] ssl3_read_bytes: sslv3 alert handshake failure
[WARNING] 274/160955 (2642) : Server api_statusio/test2 is DOWN, reason: Socket error, info: "SSL handshake failure", check duration: 111ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[ALERT] 274/160955 (2642) : backend 'api_statusio' has no server available!
fd[0014] OpenSSL error[0x14094410] ssl3_read_bytes: sslv3 alert handshake failure
fd[0014] OpenSSL error[0x14094410] ssl3_read_bytes: sslv3 alert handshake failure
Если я использую openssl s_client в качестве быстрой проверки, это работает нормально.
Это было проверено с:
- HAProxy 2.0.3 + OpenSSL 1.1.1c 28 мая 2019 г. (Docker haproxy: последнее на сегодня)
- HAProxy 1.8.8 + OpenSSL 1.1.1 11 сентября 2018 г. (Ubuntu 18.04)
Есть идеи?