Skip to content

Reverse proxy in front

The edge can sit on an internal port behind an L4 reverse proxy that adds PROXY v2.

Terminal window
TOWONEL_EDGE_LISTEN_ADDR=0.0.0.0:8444
TOWONEL_EDGE_PROXY_PROTOCOL=true
# Optional — defaults to RFC1918 + loopback
TOWONEL_EDGE_PROXY_PROTOCOL_TRUSTED=10.0.0.0/8,172.16.0.0/12

Once enabled, the edge requires PROXY v2 on every TCP connection. Connections without it (or from a non-trusted source) are dropped — keep :8444 off the public internet.

iroh UDP :51820 bypasses the L4 proxy.

apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: towonel-passthrough
spec:
entryPoints: [websecure]
routes:
- match: HostSNI(`*.example.eu`)
services:
- name: towonel-edge
port: 8444
proxyProtocol:
version: 2
tls:
passthrough: true

Wildcard HostSNI requires Traefik 3.x. HostSNI(`*`) catches everything not matched elsewhere.

{
layer4 {
:443 {
@towonel tls sni *.example.eu
route @towonel {
proxy {
proxy_protocol v2
upstream localhost:8444
}
}
}
}
}

The bundled-Caddy hub image bakes this in — see Hub on Docker.

frontend tls_in
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend towonel if { req_ssl_sni -m end .example.eu }
backend towonel
mode tcp
server edge 127.0.0.1:8444 send-proxy-v2
stream {
map $ssl_preread_server_name $backend {
~\.example\.eu$ towonel;
default default_https;
}
upstream towonel { server 127.0.0.1:8444; }
server {
listen 443;
ssl_preread on;
proxy_protocol on;
proxy_pass $backend;
}
}

400 Bad Request from the edge or connection resets usually means the front proxy isn’t sending PROXY v2 or its source IP isn’t in TOWONEL_EDGE_PROXY_PROTOCOL_TRUSTED.