diff --git a/.github/workflows/_integration_tests.yml b/.github/workflows/_integration_tests.yml index 6ba3e61c4..b848a4bbc 100644 --- a/.github/workflows/_integration_tests.yml +++ b/.github/workflows/_integration_tests.yml @@ -106,8 +106,14 @@ jobs: direct-download-roaming-network, dns-etc-resolvconf, dns-nm, + dns-failsafe, # Uses the default DNS control method systemd/dns-systemd-resolved, ] + include: + - test: direct-download-roaming-network + dns-control: etc-resolv-conf + - test: dns-etc-resolvconf + dns-control: etc-resolv-conf steps: - uses: actions/checkout@v4 - uses: ./.github/actions/gcp-docker-login @@ -118,12 +124,16 @@ jobs: run: docker compose run elixir /bin/sh -c 'cd apps/domain && mix ecto.seed' - name: Start docker compose in the background run: | + # Overrides the Client's env var in docker-compose.yml + echo "FIREZONE_DNS_CONTROL=${{ matrix.dns-control }}" >> .env + # Start one-by-one to avoid variability in service startup order docker compose up -d dns.httpbin httpbin download.httpbin docker compose up -d api web domain --no-build docker compose up -d relay --no-build docker compose up -d gateway --no-build docker compose up -d client --no-build + docker compose exec -it client env - run: ./scripts/tests/${{ matrix.test }}.sh diff --git a/docker-compose.yml b/docker-compose.yml index 6ee47a1ba..b3dbb4fa9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -283,7 +283,7 @@ services: client: environment: - FIREZONE_DNS_CONTROL: "etc-resolv-conf" + FIREZONE_DNS_CONTROL: "${FIREZONE_DNS_CONTROL}" FIREZONE_TOKEN: "n.SFMyNTY.g2gDaANtAAAAJGM4OWJjYzhjLTkzOTItNGRhZS1hNDBkLTg4OGFlZjZkMjhlMG0AAAAkN2RhN2QxY2QtMTExYy00NGE3LWI1YWMtNDAyN2I5ZDIzMGU1bQAAACtBaUl5XzZwQmstV0xlUkFQenprQ0ZYTnFJWktXQnMyRGR3XzJ2Z0lRdkZnbgYAGUmu74wBYgABUYA.UN3vSLLcAMkHeEh5VHumPOutkuue8JA6wlxM9JxJEPE" RUST_LOG: firezone_linux_client=trace,wire=trace,connlib_client_shared=trace,firezone_tunnel=trace,connlib_shared=trace,boringtun=debug,snownet=debug,str0m=debug,info FIREZONE_API_URL: ws://api:8081 diff --git a/scripts/tests/dns-failsafe.sh b/scripts/tests/dns-failsafe.sh new file mode 100755 index 000000000..20f26a064 --- /dev/null +++ b/scripts/tests/dns-failsafe.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# If we set the DNS control to `systemd-resolved` but that's not available, +# we should still boot up and allow IP / CIDR resources to work + +set -euo pipefail + +source "./scripts/tests/lib.sh" + +function client() { + docker compose exec -it client "$@" +} + +function client_nslookup() { + # Skip the first 3 lines so that grep won't see the DNS server IP + # `tee` here copies stdout to stderr + client timeout 30 sh -c "nslookup $1 | tee >(cat 1>&2) | tail -n +4" +} + +function gateway() { + docker compose exec -it gateway "$@" +} + +# Re-up the gateway since a local dev setup may run this back-to-back +docker compose up -d gateway --no-build + +echo "# make sure resolv.conf was not changed" +client sh -c "cat /etc/resolv.conf" + +echo "# Make sure gateway can reach httpbin by DNS" +gateway sh -c "curl --fail dns.httpbin/get" + +echo "# Access httpbin by IP" +client_curl_resource + +echo "# Stop the gateway and make sure the resource is inaccessible" +docker compose stop gateway +client sh -c "curl --connect-timeout 15 --fail 172.20.0.100/get" && exit 1 + +# Needed so that the previous failure doesn't bail out of the whole script +exit 0