From 53bf7d57e54ba71d3b0633cc5a2f480100501bac Mon Sep 17 00:00:00 2001 From: Ashley Mensah Date: Mon, 16 Mar 2026 15:15:16 +0100 Subject: [PATCH] Document TLS-ALPN-01 challenge requirements for reverse proxy --- src/pages/manage/reverse-proxy/index.mdx | 12 ++++++++++++ .../selfhosted/migration/enable-reverse-proxy.mdx | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/pages/manage/reverse-proxy/index.mdx b/src/pages/manage/reverse-proxy/index.mdx index 7ad5eb7b..4fc546af 100644 --- a/src/pages/manage/reverse-proxy/index.mdx +++ b/src/pages/manage/reverse-proxy/index.mdx @@ -140,6 +140,18 @@ The proxy supports two modes for TLS certificate management: When a certificate is successfully issued, the proxy notifies the management server and the service status changes to `active`. +#### TLS-ALPN-01 requirements + +The default ACME challenge type (`tls-alpn-01`) validates domain ownership by responding on port 443 with a special TLS certificate containing the `acme-tls/1` ALPN protocol. For this challenge to succeed, the following conditions must be met: + +- **Port 443 must be publicly reachable** - Let's Encrypt connects to your server on port 443 to perform the challenge. If port 443 is blocked by a firewall or not forwarded correctly, certificate issuance will fail. +- **No geo-blocking** - Let's Encrypt validates from multiple global locations simultaneously. If your firewall or CDN blocks requests from non-local IP ranges, some or all validation attempts will fail and the certificate will not be issued. +- **ALPN protocol support** - If there is an additional proxy or load balancer in front of the NetBird proxy, it must support passing through the `acme-tls/1` ALPN protocol. Traefik and Caddy handle this natively through TLS passthrough. Nginx, Apache, and some CDN providers (such as Cloudflare) may strip or fail to negotiate the `acme-tls/1` protocol, causing the challenge to fail. + + +If any of these requirements cannot be met in your environment, switch to the `http-01` challenge type by setting `NB_PROXY_ACME_CHALLENGE_TYPE=http-01`. The HTTP-01 challenge validates over port 80 using a plain HTTP request and does not depend on ALPN protocol support. However, it requires port 80 to be accessible from the internet. + + **Static certificate mode** - Provide your own certificate and key files. This is useful for wildcard certificates or certificates from a corporate CA. Configure with: | Environment variable | Description | diff --git a/src/pages/selfhosted/migration/enable-reverse-proxy.mdx b/src/pages/selfhosted/migration/enable-reverse-proxy.mdx index 265f4346..fc52184c 100644 --- a/src/pages/selfhosted/migration/enable-reverse-proxy.mdx +++ b/src/pages/selfhosted/migration/enable-reverse-proxy.mdx @@ -422,6 +422,10 @@ If your self-hosted deployment currently uses Nginx, Caddy, or another reverse p 2. Ensure the wildcard DNS record resolves correctly: `dig myapp.proxy.example.com` 3. Check proxy logs for ACME errors: `docker compose logs proxy | grep -i acme` 4. If using `http-01` challenge type, ensure port 80 is also accessible +5. Ensure no geo-blocking is active on your firewall or CDN - Let's Encrypt validates from multiple global locations simultaneously, and blocking non-local IPs will cause validation to fail +6. If you have an additional proxy or load balancer in front of Traefik, verify it supports the `acme-tls/1` ALPN protocol required by the `tls-alpn-01` challenge. Some providers (such as Cloudflare) may not pass through this protocol. If this is an issue, switch to `NB_PROXY_ACME_CHALLENGE_TYPE=http-01` + +For a full explanation of TLS-ALPN-01 requirements, see [TLS-ALPN-01 requirements](/manage/reverse-proxy#tls-alpn-01-requirements). ### TLS passthrough not working