Pin deployment images and refresh docs
Configuration validation / lint (push) Has been cancelled
Configuration validation / smoke (push) Has been cancelled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
auto-ci
2026-05-02 15:23:53 -04:00
parent ec4aff6cfe
commit b6d49549fe
7 changed files with 851 additions and 459 deletions
+73 -27
View File
@@ -29,16 +29,36 @@ else
echo "[validate-config] docker binary not found; skipping compose validation"
fi
# CoreDNS syntax check (use local binary or container fallback)
if command -v coredns >/dev/null 2>&1; then
echo "[validate-config] checking PopuraDNS/Corefile with local coredns"
coredns -conf PopuraDNS/Corefile -dns.port=0
elif command -v docker >/dev/null 2>&1; then
echo "[validate-config] checking PopuraDNS/Corefile with container"
docker run --rm -v "${PWD}/PopuraDNS/Corefile:/etc/coredns/Corefile:ro" \
coredns/coredns:latest -conf /etc/coredns/Corefile -dns.port=0
# CoreDNS syntax check must use the compiled image because the Corefile relies
# on custom plugins (meshname/meship) that are not present in the stock binary.
if command -v docker >/dev/null 2>&1; then
echo "[validate-config] checking PopuraDNS/Corefile with compiled coredns image"
docker compose build coredns >/dev/null
COREDNS_IMAGE="$(docker compose images -q coredns | head -n1)"
if [ -z "$COREDNS_IMAGE" ]; then
echo "[validate-config] error: failed to resolve compiled coredns image" >&2
exit 1
fi
set +e
timeout 8s docker run --rm "$COREDNS_IMAGE" -conf /Corefile -dns.port=0
COREDNS_STATUS=$?
set -e
if [ "$COREDNS_STATUS" -ne 0 ] && [ "$COREDNS_STATUS" -ne 124 ]; then
echo "[validate-config] error: compiled coredns failed to load PopuraDNS/Corefile" >&2
exit "$COREDNS_STATUS"
fi
elif command -v coredns >/dev/null 2>&1 && coredns -plugins 2>/dev/null | grep -q '^meshname$'; then
echo "[validate-config] checking PopuraDNS/Corefile with local compiled coredns"
set +e
timeout 8s coredns -conf PopuraDNS/Corefile -dns.port=0
COREDNS_STATUS=$?
set -e
if [ "$COREDNS_STATUS" -ne 0 ] && [ "$COREDNS_STATUS" -ne 124 ]; then
echo "[validate-config] error: local compiled coredns failed to load PopuraDNS/Corefile" >&2
exit "$COREDNS_STATUS"
fi
else
echo "[validate-config] cannot check Corefile syntax (no coredns or docker)"
echo "[validate-config] cannot check Corefile syntax (need docker or a compiled local coredns with meshname plugin)"
fi
# ensure onion and i2p zones are present in Corefile
@@ -49,13 +69,18 @@ for zone in "onion.:53" "i2p.:53" "eth.:53" "bit.:53" "alt.:53" "loki.:53" "zil.
fi
done
# verify i2pd DNS server is enabled in its config
if grep -q "\[dns\]" i2pd_yggdrasil_docker/src/i2pd.conf; then
if ! awk '/\[dns\]/,/\[/{if($0~/enabled/ && $0~/true/) ok=1} END{exit !ok}' i2pd_yggdrasil_docker/src/i2pd.conf; then
echo "[validate-config] warning: i2pd DNS section present but not enabled"
if ! grep -A6 '^\.:53 {' PopuraDNS/Corefile | grep -q 'acl {'; then
echo "[validate-config] error: Corefile catch-all zone must include an ACL to avoid open recursion" >&2
exit 1
fi
# verify the current .i2p DNS architecture is documented in config
if grep -q '^\[dns\]' i2pd_yggdrasil_docker/src/i2pd.conf; then
if ! awk '/^\[dns\]/,/^\[/{if($0~/enabled/ && $0~/true/) ok=1} END{exit !ok}' i2pd_yggdrasil_docker/src/i2pd.conf; then
echo "[validate-config] warning: i2pd [dns] section exists but is disabled; the stack currently expects the separate i2pdns bridge service"
fi
else
echo "[validate-config] warning: i2pd.conf missing [dns] section"
elif ! grep -qE 'i2pdns bridge|local i2pdns bridge service' i2pd_yggdrasil_docker/src/i2pd.conf; then
echo "[validate-config] warning: i2pd.conf should document that .i2p DNS is served by the separate i2pdns bridge service"
fi
# tor configuration should expose DNSPort for onion resolution
@@ -78,14 +103,19 @@ if command -v dig >/dev/null 2>&1; then
fi
# ensure referenced secrets exist
for s in ./secrets/tz.txt ./secrets/YGGDRASIL_GENERATE_KEYS.txt; do
for s in \
./secrets/tz.txt \
./secrets/YGGDRASIL_GENERATE_KEYS.txt \
./secrets/pihole_webpassword.txt \
./secrets/3proxy_users.txt \
./secrets/namecoin_rpc_password.txt; do
if [ ! -f "$s" ]; then
echo "[validate-config] error: secret file $s is missing" >&2
exit 1
fi
done
# check for :latest tags (discouraged in prod)
# check for mutable :latest tags in deployment compose files
if grep -qE 'image: .*:latest' docker-compose.yml; then
echo "[validate-config] warning: some services use the ':latest' image tag;" \
"pin to a specific version before deploying to production."
@@ -96,10 +126,6 @@ if ! grep -q 'healthcheck:' docker-compose.yml; then
echo "[validate-config] warning: no healthcheck definitions found in docker-compose.yml"
fi
echo "[validate-config] warning: some services use the ':latest' image tag;" \
"pin to a specific version before deploying to production."
fi
# verify every service has a restart policy
if ! grep -q "restart:" docker-compose.yml; then
echo "[validate-config] warning: some services lack a restart policy."
@@ -112,13 +138,19 @@ if [ -n "$(echo "$ports" | uniq -d)" ]; then
fi
# unbound configuration syntax check
if command -v unbound-checkconf >/dev/null 2>&1; then
if command -v docker >/dev/null 2>&1; then
echo "[validate-config] checking unbound configuration in compiled repo image"
UNBOUND_IMAGE="$(docker build -q -f unbound_arm/Dockerfile unbound_arm | tail -n1)"
docker run --rm --entrypoint /bin/sh \
-v "${PWD}/unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf:ro" \
-v "${PWD}/unbound/forward-records.conf:/opt/unbound/etc/unbound/forward-records.conf:ro" \
-v "${PWD}/unbound/a-records.conf:/opt/unbound/etc/unbound/a-records.conf:ro" \
-v "${PWD}/unbound/srv-records.conf:/opt/unbound/etc/unbound/srv-records.conf:ro" \
"$UNBOUND_IMAGE" -lc \
'getent passwd _unbound >/dev/null || useradd -r -s /usr/sbin/nologin _unbound; unbound-checkconf /opt/unbound/etc/unbound/unbound.conf'
elif command -v unbound-checkconf >/dev/null 2>&1; then
echo "[validate-config] checking unbound configuration locally"
unbound-checkconf -c unbound/unbound.conf
elif command -v docker >/dev/null 2>&1; then
echo "[validate-config] checking unbound configuration in container"
docker run --rm -v "${PWD}/unbound/unbound.conf:/etc/unbound/unbound.conf:ro" \
mvance/unbound:latest unbound-checkconf -c /etc/unbound/unbound.conf
unbound-checkconf unbound/unbound.conf
else
echo "[validate-config] cannot check unbound config (no unbound-checkconf or docker)"
fi
@@ -134,6 +166,20 @@ for cfg in 3proxy/first-instanse.cfg 3proxy/second-instanse.cfg; do
fi
done
if grep -q '^auth none$' 3proxy/first-instanse.cfg; then
echo "[validate-config] error: dark3proxy must not expose a public proxy with 'auth none'" >&2
exit 1
fi
if grep -q 'CHANGE_ME_NAMECOIN_RPC_PASSWORD' docker-compose.yml; then
echo "[validate-config] error: replace inline Namecoin RPC password placeholders with Docker secrets" >&2
exit 1
fi
if grep -q 'tskey-YOUR-AUTH-KEY-HERE' docker-compose.yml; then
echo "[validate-config] warning: tailscale is still configured with the placeholder auth key"
fi
# simple sanity checks
if grep -q "container_name: darkproxy" docker-compose.yml; then
echo "[validate-config] warning: 'container_name: darkproxy' appears in compose;" \