# /etc/relayd.conf — TLS terminator + reverse proxy to nullstone backend # # Listens on egress IP for 80 (redirect to https) + 443 (TLS termination) # Forwards decrypted requests to nullstone's WG IP on configured backend ports. # # Reload: rcctl reload relayd # Test config: relayd -n # === Macros === ext_addr = "egress:0" backend = "10.10.10.2" # nullstone over wg0 backend_port = "8443" # nullstone Traefik listens on this internal port # === Logging === log connection log state changes # === Tables === table { $backend } # === HTTP → HTTPS redirect === http protocol "http_redirect" { return error match request header set "Strict-Transport-Security" \ value "max-age=31536000; includeSubDomains" block pass quick path "/.well-known/acme-challenge/*" forward to } # === HTTPS terminator === http protocol "https_term" { return error match request header set "X-Forwarded-For" value "$REMOTE_ADDR" match request header set "X-Forwarded-Proto" value "https" match request header set "X-Forwarded-Port" value "443" match response header set "Strict-Transport-Security" \ value "max-age=31536000; includeSubDomains" match response header set "X-Frame-Options" value "DENY" match response header set "X-Content-Type-Options" value "nosniff" match response header set "Referrer-Policy" value "strict-origin-when-cross-origin" match response header remove "Server" tls keypair s8n.ru tls keypair veilor.uk pass } # === acme-client target (port 80 only, for HTTP-01 challenge if you ever need it; # DNS-01 challenge via Gandi is the primary path so this is a fallback) === table { 127.0.0.1 } # === Relay: HTTP redirect on 80 === relay www_http { listen on $ext_addr port 80 protocol "http_redirect" forward to port 8081 check tcp } # === Relay: HTTPS terminator forwarding to nullstone === relay www_https { listen on $ext_addr port 443 tls protocol "https_term" forward to port $backend_port check http "/" code 200 }