BEARBEITEN
Eigene Lösung zur Beantwortung der Frage.
Ich verwende einen HAProxy (auf einer gemieteten virtuellen Maschine), um eine Verbindung zu einigen Anwendungen herstellen zu können, die ich zu Hause ausführe. Dies funktioniert für fast alle meine Backends einwandfrei. Was nicht so gut funktioniert, ist das folgende Setup: HAProxy läuft auf Port 443 im HTTP-Modus und hat ein Backend mit Serverport 10000 (Webmin), denn die Verbindung funktioniert, aber nach der Anmeldung werde ich zu Port 10000 weitergeleitet und nachdem ich den Port wieder auf 443 geändert habe, kann ich Webmin verwenden. Dies ist nicht das erwartete Verhalten.
HAProxy-Standardeinstellungen
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-Frontend-Definition Dies ist ein Catchall-Frontend, da ich auf der gemieteten virtuellen Maschine nur eine IP habe und je nach Host-Header unterschiedliche Backends verwende.
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-Backend-Definition
http-request set-header X-Forwarded-Port %[dst_port] ist auskommentiert, weil ich mit und ohne getestet habe.
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
Das Ergebnis ist:
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):
Ich denke, die Hauptursache für das unerwünschte Verhalten ist dieStandortHeader in der Antwort. Wie kann ich dieses Verhalten beheben?
Eigene Antwort auf meine Frage:
Fügen Sie im Backend hinzu
http-response replace-value Location ^https://ns1.example.com:10000/$ https://ns1.example.com/
und es funktioniert. Ich weiß nicht, ob das eine Best-Practice-Lösung ist und würde das auf jeden Fall gerne wissen, aber bei mir funktioniert es.
Antwort1
Ich beantworte hier meine eigene Frage.
Ich musste die folgende Zeile zum Backend hinzufügen
http-response replace-value Location ^https://ns1.example.com:10000/$ https://ns1.example.com/