fix: cap peer browse, containerise the cert section, serve LAN HTTPS

content.browse-all-peers had a per-peer timeout but no OVERALL budget. On this
node that meant >45s with no answer, which the assistant reported to the
operator as "having trouble accessing the peer content list". Measured cause:
16 federated peers, 1 reachable. Now bounded to 20s total, returning partial
results with peers_reached / peers_total / peers_unreachable / partial, so the
assistant can say "1 of 16 peers answered" instead of implying the rest have
nothing. Verified on the node: 20.015s, was >45s.

NodeCertificateSection had no container — I copied a section that sits INSIDE a
card rather than one that provides its own. Now uses the same
`glass-card px-6 py-6 mb-6` shell and heading level as every other settings
section, so it matches on desktop and mobile.

setup-node-ca.sh now also ensures the nginx HTTPS listener, because a CA is
useless if nothing serves TLS. It binds LAN addresses ONLY: tailscaled already
owns :443 on the tailnet addresses with its own Let's Encrypt cert, so a plain
`listen 443 default_server` binds 0.0.0.0 and fails EADDRINUSE — and nginx then
keeps running the OLD config while the reload reports success. Hit exactly that
on archi-dev-box. Port 80 keeps serving: nodes are reached by IP on LANs where
forcing a redirect would strand anyone who has not installed the CA.

Live now: https://192.168.63.240/ and https://<host>.local/ both 200 with
verify=0 against the node CA, http still 200, tailscaled's 443 untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-07 03:52:57 -04:00
co-authored by Claude Opus 5
parent 0a23c99463
commit 75919a2071
3 changed files with 82 additions and 7 deletions
+53
View File
@@ -154,6 +154,59 @@ install -m 644 "$CA_CRT" "$SSL_DIR/ca-download.crt"
FP="$(openssl x509 -in "$CA_CRT" -noout -fingerprint -sha256 | cut -d= -f2)"
log "CA fingerprint (SHA-256): $FP"
# --- nginx HTTPS listener -----------------------------------------------------
# The CA is only useful if something actually serves TLS. Bind the dashboard's
# HTTPS on this host's LAN addresses ONLY: tailscaled already owns :443 on the
# tailnet addresses (with its own Let's Encrypt cert), so a plain
# `listen 443 default_server` binds 0.0.0.0 and fails with EADDRINUSE — nginx
# then keeps running the OLD config and the reload looks like it worked.
# Observed exactly that on archi-dev-box.
#
# Port 80 keeps serving: nodes are reached by IP on LANs where forcing a
# redirect would strand anyone who has not installed the CA yet.
ensure_nginx_https() {
local site="${ARCHY_NGINX_SITE:-/etc/nginx/sites-enabled/archipelago}"
[ -f "$site" ] || { log "No nginx site at $site — skipping HTTPS listener"; return; }
local addrs
addrs="$(ip -o -4 addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 \
| grep -vE '^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.' | sort -u)"
[ -z "$addrs" ] && { log "No LAN address — skipping HTTPS listener"; return; }
if grep -q 'listen .*:443 ssl' "$site"; then
log "nginx HTTPS listener already present"
return
fi
log "Adding nginx HTTPS listener on: $(echo "$addrs" | tr '\n' ' ')"
python3 - "$site" "$addrs" <<'PYEOF'
import sys, re, pathlib
site, addrs = pathlib.Path(sys.argv[1]), sys.argv[2].split()
s = site.read_text(); lines = s.split('\n')
start = next(i for i,l in enumerate(lines) if l.strip() == 'server {')
depth = 0; end = None
for i in range(start, len(lines)):
depth += lines[i].count('{') - lines[i].count('}')
if depth == 0 and i > start:
end = i; break
block = lines[start:end+1]
https = []
for l in block:
if re.match(r'\s*listen 80 default_server;', l):
https += [f' listen {a}:443 ssl;' for a in addrs]
https += [' ssl_certificate /etc/archipelago/ssl/archipelago.crt;',
' ssl_certificate_key /etc/archipelago/ssl/archipelago.key;',
' ssl_protocols TLSv1.2 TLSv1.3;']
continue
if re.match(r'\s*listen \[::\]:80 default_server;', l):
continue
https.append(l)
lines = lines[:end+1] + [''] + https + lines[end+1:]
site.write_text('\n'.join(lines))
PYEOF
}
ensure_nginx_https
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet nginx; then
if nginx -t >/dev/null 2>&1; then
systemctl reload nginx && log "nginx reloaded"