Commit afaf417
committed
webserver: serve every configured TLS port, and DoH behind a reverse proxy
Three gaps in how the front terminator exposes TLS:
1. `split_terminator_ports()` only ever captured the *first* secure entry of
`webserver.port`. Every further "...s" entry was still dropped from the list
handed to CivetWeb, so nothing served it and nothing reported it. A
documented configuration such as "80or,443os,8080,4443s" - the example in the
`webserver.port` help text itself - silently lost 4443.
The terminator now takes an array of listeners and its accept thread polls
all of them, so every configured TLS port is served and reported in the API
port list. Entries that would bind the same socket are collapsed first: the
default "443os,[::]:443os" names one dual-stack socket and then its IPv6
half, and binding both is simply `EADDRINUSE`. A port outside 1-65535 is
rejected here, as a secure entry never reaches CivetWeb's own syntax check.
HTTP/3 stays on one port, the first that actually bound - Alt-Svc names the
HTTP/3 port explicitly, so advertising it from the others remains correct.
2. The IPv4 and IPv6 halves of one port could not coexist. `fill_bind_addr()`
maps "0.0.0.0" to the v4-mapped `::ffff:0.0.0.0`, which accepts IPv4 only,
while every socket was bound dual-stack - so "0.0.0.0:443s,[::]:443s" served
IPv4 only, with no way to express the split. `IPV6_V6ONLY` is now set for an
explicit IPv6 literal and cleared otherwise, so the two halves bind as
separate sockets.
A configuration naming *only* a bracketed TLS entry, e.g. "[::]:443s", no
longer answers over IPv4 through v4-mapped addresses. That is what
`webserver.port` documents ("[::]:80" is IPv6 only) and what CivetWeb does
for plaintext ports, and the terminator has never been in a release, so no
released behavior changes. The default port list is unaffected, as it names
both a bare and a bracketed entry.
3. Plaintext `/dns-query` was always refused with 426, leaving no way to put
Pi-hole's DoH behind an external TLS-terminating reverse proxy. Two new
settings cover that deployment:
- `webserver.proxySecret` is a shared secret authenticating such a proxy. It
is passed to CivetWeb as `proxy_protocol_secret`, so a PROXY protocol v2
header carrying it is believed and the client address and TLS status it
announces replace the transport peer. Our own terminator uses the same
secret instead of its per-boot token. Empty by default, in which case the
token stays per-boot and internal. Installing it does not depend on a local
TLS port, as the deployment it serves has none.
- `dns.dohReverseProxy` (off by default) serves DoH on such a connection.
Trust therefore rests on the proxy authenticating itself, not on the hop
being assumed safe: an unauthenticated plaintext `/dns-query` is still
refused with 426, so enabling this cannot expose cleartext DNS on a port
reachable by anything else. An unauthenticated `X-Forwarded-For` is never
consulted, as it is trivially spoofable and would let any host on that port
attribute its queries to a victim, taking over their rate-limit budget and
group policy. Because the announced address is authenticated, queries are
attributed to the real client rather than to the proxy.
Signed-off-by: DL6ER <dl6er@dl6er.de>1 parent 0af0d74 commit afaf417
7 files changed
Lines changed: 498 additions & 118 deletions
File tree
- src
- api/docs/content/specs
- config
- webserver
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
| 302 | + | |
| 303 | + | |
302 | 304 | | |
303 | 305 | | |
304 | 306 | | |
| |||
465 | 467 | | |
466 | 468 | | |
467 | 469 | | |
| 470 | + | |
| 471 | + | |
468 | 472 | | |
469 | 473 | | |
470 | 474 | | |
| |||
774 | 778 | | |
775 | 779 | | |
776 | 780 | | |
| 781 | + | |
777 | 782 | | |
778 | 783 | | |
779 | 784 | | |
| |||
879 | 884 | | |
880 | 885 | | |
881 | 886 | | |
| 887 | + | |
882 | 888 | | |
883 | 889 | | |
884 | 890 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
618 | 618 | | |
619 | 619 | | |
620 | 620 | | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
621 | 628 | | |
622 | 629 | | |
623 | 630 | | |
| |||
1083 | 1090 | | |
1084 | 1091 | | |
1085 | 1092 | | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
1086 | 1101 | | |
1087 | 1102 | | |
1088 | 1103 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
| 160 | + | |
160 | 161 | | |
161 | 162 | | |
162 | 163 | | |
| |||
263 | 264 | | |
264 | 265 | | |
265 | 266 | | |
| 267 | + | |
266 | 268 | | |
267 | 269 | | |
268 | 270 | | |
| |||
0 commit comments