Pin deployment images and refresh docs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
+73
-27
@@ -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;" \
|
||||
|
||||
Reference in New Issue
Block a user