Verbindungen zu Webmin über HAProxy werden an Port 10000 weitergeleitet (HAProxy lauscht auf 443)

Verbindungen zu Webmin über HAProxy werden an Port 10000 weitergeleitet (HAProxy lauscht auf 443)

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/

verwandte Informationen