편집하다
질문에 대한 자체 솔루션.
집에서 실행 중인 일부 애플리케이션에 연결할 수 있도록 임대한 가상 머신에서 HAProxy를 사용하고 있습니다. 이것은 거의 모든 백엔드에서 완벽하게 작동합니다. 잘 작동하지 않는 것은 다음 설정입니다. http 모드에서 포트 443에서 실행되는 HAProxy는 연결이 작동하기 때문에 서버 포트 10000(Webmin)이 있는 백엔드를 가지고 있지만 로그인한 후 포트 10000으로 전달되고 포트를 다시 변경한 후입니다. 443까지 Webmin을 사용할 수 있습니다. 이는 예상된 동작이 아닙니다.
HAProxy 기본값
defaults
mode http
log global
log /dev/log local0 info
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
#option forwardfor
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
balance leastconn
stats enable
stats hide-version
stats uri /haproxy/stats
stats refresh 10s
stats show-node
HAProxy 프런트엔드 정의 임대한 가상 머신에는 하나의 IP만 있고 호스트 헤더에 따라 다른 백엔드를 사용하고 있기 때문에 이는 포괄적인 프런트엔드입니다.
frontend catchall_http
bind *:80
bind *:443 ssl crt MY_CERT
acl letsencrypt path_beg /.well-known/acme-challenge/
acl app_ns1 req.hdr(host) -i ns1.example.com
http-response set-header Strict-Transport-Security max-age=31536000;\ includeSubDomains;\ preload; if { ssl_fc }
use_backend ns1.home.example.com if app_ns1
default_backend backend-not-found
HAProxy 백엔드 정의
http-request set-header X-Forwarded-Port %[dst_port]는 포함 여부에 관계없이 테스트했기 때문에 주석 처리되었습니다.
backend ns1.home.example.com
acl valid_http_method method GET HEAD POST
http-request deny unless valid_http_method
#http-request set-header X-Forwarded-Port %[dst_port]
redirect scheme https code 301 if !{ ssl_fc }
server ns1.home.example.com ns1.home.example.com:10000 ssl check check-ssl verify required ca-file CA_CERT
# just to get the initial necessary cookies for login
curl --request GET --cookie-jar webmin_curl_cookies --cookie webmin_curl_cookies https://ns1.example.com/
curl --request POST --data @webmin_request_payload --cookie-jar webmin_curl_cookies --cookie webmin_curl_cookies https://ns1.example.com/session_login.cgi
결과는 다음과 같습니다.
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying HAProxyIP:443...
* Connected to ns1.example.com (HAProxyIP) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=ns1.example.com
* start date: Aug 14 10:55:38 2020 GMT
* expire date: Nov 12 10:55:38 2020 GMT
* subjectAltName: host "ns1.example.com" matched cert's "ns1.example.com"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> POST /session_login.cgi HTTP/1.1
> Host: ns1.example.com
> User-Agent: curl/7.69.1
> Accept: */*
> Cookie: redirect=1; testing=1; sid=SESS_ID
> Content-Length: 31
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 31 out of 31 bytes
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 302 Moved Temporarily
< Date: Mon, 17 Aug 2020 09:40:48 GMT
< Server: MiniServ/1.953
* Replaced cookie sid="SESS_ID" for domain ns1.example.com, path /, expire 0
< Set-Cookie: sid=SESS_ID; path=/; secure; httpOnly
< Location: https://ns1.example.com:10000/
< Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;
<
* TLSv1.3 (IN), TLS alert, close notify (256):
* Closing connection 0
* TLSv1.3 (OUT), TLS alert, close notify (256):
나는 원치 않는 행동의 주요 원인이 다음과 같다고 생각합니다.위치응답의 헤더. 이 문제를 어떻게 해결할 수 있습니까?
내 질문에 대한 자신의 답변:
백엔드에서 추가
http-response replace-value Location ^https://ns1.example.com:10000/$ https://ns1.example.com/
그리고 그것은 작동합니다. 이것이 모범 사례 솔루션인지는 모르겠고 확실히 알고 싶지만 저에게는 효과가 있습니다.
답변1
여기에 내 자신의 질문에 대답합니다.
백엔드에 다음 줄을 추가해야했습니다
http-response replace-value Location ^https://ns1.example.com:10000/$ https://ns1.example.com/