Skip to content

Commit b7d144e

Browse files
committed
fix(dstack-ingress): reject tls-alpn-01 wildcards at startup, not per pass
A wildcard under tls-alpn-01 can never succeed -- RFC 8737 forbids the challenge for wildcard identifiers -- so it is a configuration error, not a runtime failure. tlsalpn.sh did reject it, but only once the certificate loop reached that domain, by which point the container had generated a placeholder certificate for a name that will never get a real one, started haproxy serving it, and settled into retrying an unsatisfiable config every 60s to 1800s forever. Check it alongside the other startup validation instead. A wildcard anywhere in DOMAIN/DOMAINS now fails the container immediately, naming the offending entry. This is deliberately fatal for the whole container rather than skipping the one domain. Mixed configs did already contain the damage -- the other domains were issued normally -- but the operator was left with a self-signed certificate served for the wildcard indefinitely and a permanently failing loop, which reads as a TLS bug rather than the config error it is. The per-domain checks in tlsalpn.sh and legoman.py stay as defence in depth. dns-01 wildcards are unaffected.
1 parent 4d54843 commit b7d144e

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

custom-domain/dstack-ingress/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ Encrypt dropping expiry mail, and the container passes it for you.
325325
### Limitations
326326

327327
- **No wildcards.** RFC 8737 forbids tls-alpn-01 for wildcard identifiers, and
328-
the CA will not offer the challenge. Use `dns-01` for `*.example.com`.
328+
the CA will not offer the challenge. The container refuses to start rather
329+
than serve a name it can never obtain a certificate for, so a wildcard
330+
anywhere in `DOMAIN`/`DOMAINS` is a startup error even if the other names are
331+
fine. Use `dns-01` for `*.example.com`.
329332
- **The gateway must be reachable on port 443.** The CA connects to port 443 of
330333
whatever the CNAME resolves to; the port is fixed by the protocol.
331334
- **CAA must permit `tls-alpn-01`.** A record left over from a `dns-01`

custom-domain/dstack-ingress/scripts/entrypoint.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,23 @@ done
7373
export PORT DOMAIN DOMAINS TARGET_ENDPOINT ROUTING_MAP TXT_PREFIX MAXCONN
7474
export TIMEOUT_CONNECT TIMEOUT_CLIENT TIMEOUT_SERVER EVIDENCE_SERVER EVIDENCE_PORT ALPN
7575

76+
# A wildcard under tls-alpn-01 can never succeed -- RFC 8737 forbids the
77+
# challenge for wildcard identifiers -- so treat it as the configuration error it
78+
# is rather than a runtime failure. tlsalpn.sh does reject it per domain, but by
79+
# then the container has generated a placeholder certificate for a name that will
80+
# never get a real one, started serving it, and settled into retrying an
81+
# unsatisfiable config forever. Catching it here fails the container at start,
82+
# where the operator is looking.
83+
if [ "$CHALLENGE_TYPE" = "tls-alpn-01" ]; then
84+
wildcards=$(get-all-domains.sh | grep '^\*\.' || true)
85+
if [ -n "$wildcards" ]; then
86+
echo "Error: tls-alpn-01 cannot issue wildcard certificates (RFC 8737)." >&2
87+
echo "$wildcards" | sed 's/^/ /' >&2
88+
echo "Use CHALLENGE_TYPE=dns-01 for wildcards, or list the names individually." >&2
89+
exit 1
90+
fi
91+
fi
92+
7693
case "$CHALLENGE_TYPE" in
7794
dns-01)
7895
exec /scripts/dns01.sh "$@"

0 commit comments

Comments
 (0)