brain/03 Bereiche/Heimnetz/Zugriff aus dem Web/Home Assistant über HAProxy.md

12 KiB

tags
upnote-import

Home-Assistent über HAProxy

FAQs

Cert abgelaufen trotz erfolgreichem ACME-Renewal

Symptom: Browser meldet abgelaufenes Zertifikat (z.B. https://kbha.straso.com), obwohl ACME-Plugin Status 200 OK und Renewal-Datum aktuell zeigt.

Diagnose von extern:

openssl s_client -connect kbha.straso.com:443 -servername kbha.straso.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates -issuer

Zeigt altes notAfter → HAProxy liefert noch das alte Cert.

Ursache: ACME-Plugin hat zwar das neue Cert in /conf/config.xml und unter /var/etc/acme-client/certs/<refid>/ gespeichert, aber HAProxy hat seine SSL-Dateien in /tmp/haproxy/ssl/ nicht regeneriert. Grund: Im ACME-Cert war <restartActions/> leer → kein Reload-Trigger nach Renewal.

Verifikation per SSH auf OPNsense:

# Cert in config.xml prüfen (sollte aktuell sein)
awk '/<cert /{inc=1} inc{print} /<\/cert>/{if(inc){print "==="; inc=0}}' /conf/config.xml \
  | awk '/<refid>RRREEEFFFID/{f=1} f{print} /<\/cert>/{if(f){exit}}' \
  | sed -n 's|.*<crt>\(.*\)</crt>.*|\1|p' \
  | openssl base64 -d -A | openssl x509 -noout -dates -subject

# Cert in HAProxy SSL store prüfen (zeigt alten Stand bei nicht-getriggertem Reload)
openssl x509 -in /tmp/haproxy/ssl/RRREEEFFFID.pem -noout -dates -subject

RRREEEFFFID = certRefId aus dem ACME-Cert-Eintrag (z.B. 68fb9ea001876).

Sofortfix:

configctl haproxy restart

Regeneriert /tmp/haproxy/ssl/ aus config.xml.

Dauerhafte Lösung — Restart-Action im ACME-Cert verdrahten:

  1. Services > ACME Client > Settings > Actions → Add (oder existierende prüfen) → Name Restart HAProxy, Type Configd, Command HAProxy: restart
  2. Services > ACME Client > Certificates > straso.com editieren → Feld Automations / Restart ActionsRestart HAProxy auswählen → Save
  3. Verifikation in /conf/config.xml: im <certificate>-Block mit <name>straso.com</name> muss <restartActions> die UUID der Action enthalten (statt <restartActions/> leer).

Danach reloaded HAProxy nach jedem Renewal automatisch.

Status (2026-05-25): Aktion Restart HAProxy (UUID 92528912-3c23-4ede-8b75-72c50bb106c0) ist sowohl *.kbu.home64.de- als auch straso.com-Cert zugewiesen. Nächstes Renewal in ~60 Tagen sollte automatisch greifen.

NPM auf dem Pi — DNS-Challenge statt HTTP

Kontext: Auf dem HA-Pi läuft parallel ein Nginx Proxy Manager (Add-on a0d7b954_nginxproxymanager). Der wird zwar im aktuellen Setup nicht extern angesprochen (Port 443 endet auf der OPNsense-HAProxy), aber er hält ein eigenes Let's-Encrypt-Cert für kbha.straso.com. Wenn dort die HTTP-01-Challenge konfiguriert ist, scheitert das Renewal in ~60 Tagen, weil Port 80 nicht zum Pi durchgereicht wird.

Lösung: Cert in NPM neu anlegen mit DNS-Challenge IONOS:

  • DNS Provider: IONOS
  • API Token: aus IONOS Developer Portal
  • Propagation Seconds: 60

Renewal-Config-Pfad im Add-on:

/addon_configs/a0d7b954_nginxproxymanager/letsencrypt/renewal/npm-<N>.conf

Inhalt muss enthalten:

authenticator = dns-ionos
dns_ionos_propagation_seconds = 60
dns_ionos_credentials = /etc/letsencrypt/credentials/credentials-<N>

SSH-Zugang zum Pi: Frenck's "Advanced SSH & Web Terminal" Add-on, Public Key in den Add-on-Settings hinterlegen, dann ssh -p 22222 root@<pi-ip>.

Aufräumen: Alte HTTP-Challenge-Certs (z.B. Cert #7) in NPM löschen, sobald das DNS-Cert (Cert #8) aktiv ist und alle Proxy Hosts darauf zeigen.

Lessons learned:

  • HAProxy-SSL-Files liegen in /tmp/ (flüchtig) und werden aus config.xml regeneriert
  • configctl haproxy restart ist destruktiv-frei und lädt nur Config + SSL neu
  • NPM auf Pi parallel zu HAProxy bringt nichts, wenn Port 443 per NAT/HAProxy-Bind abgefangen wird — Reverse-Proxy-Stack einheitlich halten
  • Externes Cert prüfen mit openssl s_client zeigt sofort, ob Browser-Cache oder Server-Side-Problem

Seite zeigt Fehler Invalid method encountered

haproxy Invalid method encountered: b'' ^

Grund war, dass die bind-option „accept-proxy“ und ein Proxy-Protocol zugewiesen waren. Der HA ist aber dafür gemacht, hinter einem Proxy zu lafen. In dem Fall muss beides entfernt werden.

Google AI Analyse

The error "Received something which does not look like a PROXY protocol header" in OPNsense, likely when using HAProxy, means that a client connected to the proxy but sent data that doesn't conform to the PROXY protocol format. To fix this, you should check your HAProxy configuration to ensure the accept-proxy argument is present on the bind line of your frontend, or if you are sending the header, verify that the backend is configured correctly to receive it. 

Understanding the Error

  • What is PROXY Protocol? It's a standard text-based or binary-based protocol that proxies use to pass connection information (like the client's IP address) to the next proxy or the backend server.
  • What it Means: The error indicates that OPNsense's HAProxy expected to see a PROXY protocol header from the client, but the client sent something else (likely just regular HTTP or another protocol) instead. 

How to Fix It

  1. Check Your HAProxy Frontend Configuration:
    • Navigate to Services > HAProxy > Settings.
    • Edit the frontend section that is receiving the connection.
    • Ensure that the accept-proxy argument is added to the bind line for that frontend. This allows HAProxy to recognize both version 1 (text) and version 2 (binary) PROXY protocol headers.
  2. Verify Backend Configuration:
    • If your setup involves multiple HAProxy instances or a different type of backend server, check the configuration on that backend as well.
    • If the backend is not expecting the PROXY protocol, it might not understand the data it's receiving, leading to errors.
  3. Consider the Client's Request:
    • Is the client supposed to be sending a PROXY protocol header? If the client is just a regular HTTP client, it won't send this header, and the accept-proxy directive is what's needed on the HAProxy frontend to receive it.
    • If your client application is designed to send the PROXY protocol, then the error means its implementation is sending the header in an unexpected format. 

Example HAProxy Configuration Snippet (for reference):

frontend my_frontend
    bind *:80 accept-proxy # This is the key line
    # Other frontend settings
  • bind *:80 : This tells HAProxy to listen on port 80.
  • accept-proxy: This tells HAProxy to accept and process the PROXY protocol from the client. 

Lösung: 

attribut „accept-proxy“ wieder entfernt und Proxy Protocol auf „none“ geändert.

Im Frontend:


Im Backend:



weitere Einstellungen:

DNS-Override



FW-Regel


Files

running config file:

#
# Automatically generated configuration.
# Do not edit this file manually.
#

global
    uid                         80
    gid                         80
    chroot                      /var/haproxy
    daemon
    stats                       socket /var/run/haproxy.socket group proxy mode 775 level admin
    nbthread                    1
    hard-stop-after             60s
    no strict-limits
    httpclient.resolvers.prefer   ipv4
    tune.ssl.default-dh-param   4096
    spread-checks               2
    tune.bufsize                16384
    tune.lua.maxmem             0
    log                         /var/run/log local0 info
    lua-prepend-path            /tmp/haproxy/lua/?.lua

defaults
    log     global
    option redispatch -1
    maxconn 100
    timeout client 30s
    timeout connect 30s
    timeout server 30s
    retries 3
    default-server init-addr last,libc
    default-server maxconn 100

# autogenerated entries for ACLs

# autogenerated entries for config in backends/frontends

# autogenerated entries for stats

# Frontend (DISABLED): 0_SNI_frontend (Listening on 0.0.0.0:80, 0.0.0.0:443)

# Frontend (DISABLED): 1_HTTP_frontend (Listening on 127.4.4.3:80)

# Frontend (DISABLED): 1_HTTPS_frontend (Listening on 127.4.4.3:443)

# Frontend: kbha_frontend ()
frontend kbha_frontend
    http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    bind 0.0.0.0:443 name 0.0.0.0:443 ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/68e90ee37e8f60.01330497.certlist 
    bind 0.0.0.0:80 name 0.0.0.0:80 ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/68e90ee37e8f60.01330497.certlist 
    bind 192.168.178.106:443 name 192.168.178.106:443 ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/68e90ee37e8f60.01330497.certlist 
    bind 192.168.178.106:80 name 192.168.178.106:80 ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/68e90ee37e8f60.01330497.certlist 
    mode http
    option http-keep-alive
    default_backend kbha_backend
    option forwardfor

    # logging options
    # ACL: kbha
    acl acl_68e90f4b9c2340.62230672 hdr(host) -i kbha.straso.com

    # ACTION: kbha
    use_backend kbha_backend if acl_68e90f4b9c2340.62230672

# Backend (DISABLED): portainer_backend ()

# Backend: kbha_backend (Backend for HomeAssistant)
backend kbha_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    http-reuse safe
    server kbha_server 192.168.178.4:8123 

# statistics are DISABLED




gutes Tutorial:

Setup OPNsense with HAProxy and Let's Encrypt | Marcus Holtz

passend zum Thread im Forum Tutorial 2024/06: HAProxy + Let's Encrypt Wildcard Certificates + 100% A+ Rating

noch ein Tutorial, DE mit Zusatztipps

HAProxy auf OPNsense - Schritt für Schritt - blog.admin-intelligence.de