From 6349147d8d33f81b3310373a582c4988704d7981 Mon Sep 17 00:00:00 2001 From: nessi Date: Tue, 17 Mar 2026 19:21:39 +0100 Subject: [PATCH] feat: add backend DNS resolution check and improve gateway sync reliability Add wait_for_backend_dns function to verify backend hostname resolution before attempting bootstrap/sync operations. Configure NEXAVPN_BACKEND_HOST environment variable and net.ipv4.ip_forward sysctl in docker-compose. Use atomic write pattern for state.json via temporary file to prevent corruption on failed downloads. Make sysctl ip_forward call conditional on write permissions and non-fatal. --- deploy/docker-compose.yml | 3 +++ deploy/scripts/gateway-entrypoint.sh | 24 +++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 0d03cf4..b39df3e 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -57,6 +57,8 @@ services: dockerfile: gateway/Dockerfile depends_on: - backend + sysctls: + net.ipv4.ip_forward: "1" cap_add: - NET_ADMIN - SYS_MODULE @@ -75,6 +77,7 @@ services: NEXAVPN_GATEWAY_INTERFACE: ${NEXAVPN_GATEWAY_INTERFACE:-wg0} NEXAVPN_UPLINK_INTERFACE: ${NEXAVPN_UPLINK_INTERFACE:-eth0} NEXAVPN_ENABLE_MASQUERADE: ${NEXAVPN_ENABLE_MASQUERADE:-true} + NEXAVPN_BACKEND_HOST: ${NEXAVPN_BACKEND_HOST:-backend} volumes: - ./scripts/gateway-entrypoint.sh:/scripts/gateway-entrypoint.sh:ro - gateway-state:/var/lib/nexavpn diff --git a/deploy/scripts/gateway-entrypoint.sh b/deploy/scripts/gateway-entrypoint.sh index 46f3b40..867c987 100644 --- a/deploy/scripts/gateway-entrypoint.sh +++ b/deploy/scripts/gateway-entrypoint.sh @@ -9,7 +9,9 @@ UPLINK_IFACE="${NEXAVPN_UPLINK_INTERFACE:-eth0}" ENABLE_MASQUERADE="${NEXAVPN_ENABLE_MASQUERADE:-true}" GATEWAY_NAME="${NEXAVPN_GATEWAY_NAME:-primary-gateway}" BOOTSTRAP_URL="${NEXAVPN_GATEWAY_BOOTSTRAP_URL:-http://backend:8080/api/v1/gateway-agent/bootstrap}" +SYNC_BASE_URL="${NEXAVPN_GATEWAY_SYNC_URL:-http://backend:8080/api/v1/gateway-agent}" GATEWAY_ID_FILE="/var/lib/nexavpn/gateway-id" +BACKEND_HOST="${NEXAVPN_BACKEND_HOST:-backend}" if [ -z "${GATEWAY_BOOTSTRAP_TOKEN:-}" ]; then echo "GATEWAY_BOOTSTRAP_TOKEN is required." @@ -54,7 +56,18 @@ NFT_CONF="/var/lib/nexavpn/nftables.generated.conf" mkdir -p /etc/wireguard +wait_for_backend_dns() { + if getent hosts "${BACKEND_HOST}" >/dev/null 2>&1; then + return 0 + fi + + echo "Backend host ${BACKEND_HOST} is not resolvable yet." + return 1 +} + apply_bundle() { + wait_for_backend_dns || return 1 + if [ -z "${NEXAVPN_GATEWAY_ID:-}" ]; then bootstrap_gateway || return 1 fi @@ -64,12 +77,15 @@ apply_bundle() { return 1 fi - SYNC_URL="${NEXAVPN_GATEWAY_SYNC_URL}/${NEXAVPN_GATEWAY_ID}/sync" + SYNC_URL="${SYNC_BASE_URL}/${NEXAVPN_GATEWAY_ID}/sync" echo "Fetching bundle from ${SYNC_URL}" + TMP_STATE_JSON="${STATE_JSON}.tmp" + rm -f "${TMP_STATE_JSON}" curl -fsSL \ -H "X-Gateway-Bootstrap-Token: ${GATEWAY_BOOTSTRAP_TOKEN}" \ "${SYNC_URL}" \ - -o "${STATE_JSON}" + -o "${TMP_STATE_JSON}" || return 1 + mv "${TMP_STATE_JSON}" "${STATE_JSON}" INTERFACE_ADDRESS=$(jq -r '.interface.address' "${STATE_JSON}") NETWORK_CIDR=$(jq -r '.interface.network_cidr' "${STATE_JSON}") @@ -123,7 +139,9 @@ EOF echo "}" } > "${NFT_CONF}" - sysctl -w net.ipv4.ip_forward=1 >/dev/null + if [ -w /proc/sys/net/ipv4/ip_forward ]; then + sysctl -w net.ipv4.ip_forward=1 >/dev/null || true + fi nft -f "${NFT_CONF}"