mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
ci: create a more realistic network setup (#10301)
Currently, the setup we have in docker-compose does not reflect real-world scenarios very well because most components share the same subnet. In reality, Clients, Gateways, relays and the backend are all in separate subnets, connected via multiple routers on the Internet. The current setup makes it hard to properly test relayed connections. To fix this, we move all components into their own subnet with a dedicated router container that performs source and destination NAT as well as acts as a firewall for the client and gateway containers to not allow inbound traffic. This setup will allow us to more easily test #10286 which requires port randomization for outgoing traffic on the Client and Gateway side.
This commit is contained in:
@@ -17,13 +17,13 @@ DOWNLOAD_PID=$!
|
||||
|
||||
sleep 3 # Download a bit
|
||||
|
||||
docker network disconnect firezone_app firezone-client-1 # Disconnect the client
|
||||
docker network disconnect firezone_client-internal firezone-client-1 # Disconnect the client
|
||||
sleep 3
|
||||
docker network connect firezone_app firezone-client-1 --ip 172.28.0.200 # Reconnect client with a different IP
|
||||
docker network connect firezone_client-internal firezone-client-1 --ip 172.30.0.200 --ip6 172:30::200 # Reconnect client with a different IP
|
||||
|
||||
# Re-add static route to relays through router
|
||||
client ip route add 172.29.0.0/24 via 172.28.0.254 dev eth0
|
||||
client ip -6 route add 172:29:0::/64 via 172:28:0::254 dev eth0
|
||||
# Add static route to internet subnet via router; they get removed when the network interface disappears
|
||||
client ip -4 route add 203.0.113.0/24 via 172.30.0.254
|
||||
client ip -6 route add 203:0:113::/64 via 172:30:0::254
|
||||
|
||||
# Send SIGHUP, triggering `reconnect` internally
|
||||
sudo kill -s HUP "$(ps -C firezone-headless-client -o pid=)"
|
||||
|
||||
@@ -18,55 +18,6 @@ function relay2() {
|
||||
docker compose exec -T relay-2 "$@"
|
||||
}
|
||||
|
||||
# Takes two optional arguments to force the client and gateway to use a specific IP stack.
|
||||
# 1. client_stack: "ipv4", "ipv6"
|
||||
# 2. gateway_stack: "ipv4", "ipv6"
|
||||
#
|
||||
# By default, the client and gateway will use happy eyeballs to use pick the first working IP stack.
|
||||
function force_relayed_connections() {
|
||||
# Install `iptables` to have it available in the compatibility tests
|
||||
client apk add --no-cache iptables
|
||||
|
||||
# Execute within the client container because doing so from the host is not reliable in CI.
|
||||
client iptables -A OUTPUT -d 172.28.0.105 -j DROP
|
||||
client ip6tables -A OUTPUT -d 172:28:0::105 -j DROP
|
||||
|
||||
local client_stack="${1:-}"
|
||||
local gateway_stack="${2:-}"
|
||||
|
||||
# If both are empty, we don't care which stack they use; just return
|
||||
if [[ -z "$client_stack" && -z "$gateway_stack" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
gateway apk add --no-cache iptables
|
||||
|
||||
if [[ "$client_stack" == "ipv4" && "$gateway_stack" == "ipv4" ]]; then
|
||||
client ip6tables -A OUTPUT -d $RELAY_1_PUBLIC_IP6_ADDR -j DROP
|
||||
client ip6tables -A OUTPUT -d $RELAY_2_PUBLIC_IP6_ADDR -j DROP
|
||||
gateway ip6tables -A OUTPUT -d $RELAY_1_PUBLIC_IP6_ADDR -j DROP
|
||||
gateway ip6tables -A OUTPUT -d $RELAY_2_PUBLIC_IP6_ADDR -j DROP
|
||||
elif [[ "$client_stack" == "ipv4" && "$gateway_stack" == "ipv6" ]]; then
|
||||
client ip6tables -A OUTPUT -d $RELAY_1_PUBLIC_IP6_ADDR -j DROP
|
||||
client ip6tables -A OUTPUT -d $RELAY_2_PUBLIC_IP6_ADDR -j DROP
|
||||
gateway iptables -A OUTPUT -d $RELAY_1_PUBLIC_IP4_ADDR -j DROP
|
||||
gateway iptables -A OUTPUT -d $RELAY_2_PUBLIC_IP4_ADDR -j DROP
|
||||
elif [[ "$client_stack" == "ipv6" && "$gateway_stack" == "ipv4" ]]; then
|
||||
client iptables -A OUTPUT -d $RELAY_1_PUBLIC_IP4_ADDR -j DROP
|
||||
client iptables -A OUTPUT -d $RELAY_2_PUBLIC_IP4_ADDR -j DROP
|
||||
gateway ip6tables -A OUTPUT -d $RELAY_1_PUBLIC_IP6_ADDR -j DROP
|
||||
gateway ip6tables -A OUTPUT -d $RELAY_2_PUBLIC_IP6_ADDR -j DROP
|
||||
elif [[ "$client_stack" == "ipv6" && "$gateway_stack" == "ipv6" ]]; then
|
||||
client iptables -A OUTPUT -d $RELAY_1_PUBLIC_IP4_ADDR -j DROP
|
||||
client iptables -A OUTPUT -d $RELAY_2_PUBLIC_IP4_ADDR -j DROP
|
||||
gateway iptables -A OUTPUT -d $RELAY_1_PUBLIC_IP4_ADDR -j DROP
|
||||
gateway iptables -A OUTPUT -d $RELAY_2_PUBLIC_IP4_ADDR -j DROP
|
||||
else
|
||||
echo "Invalid stack combination: client_stack=$client_stack, gateway_stack=$gateway_stack"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function client_curl_resource() {
|
||||
client curl --connect-timeout 30 --fail "$1" >/dev/null
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
--time 30 \
|
||||
--udp \
|
||||
--bandwidth 600M \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
force_relayed_connections ipv4 ipv4
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
--time 30 \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "relay-1" "S"
|
||||
assert_process_state "relay-2" "S"
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
force_relayed_connections ipv6 ipv4
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
--time 30 \
|
||||
--reverse \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "relay-1" "S"
|
||||
assert_process_state "relay-2" "S"
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
force_relayed_connections ipv6 ipv6
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
--time 30 \
|
||||
--udp \
|
||||
--bandwidth 300M \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "relay-1" "S"
|
||||
assert_process_state "relay-2" "S"
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
force_relayed_connections ipv4 ipv6
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
--time 30 \
|
||||
--reverse \
|
||||
--udp \
|
||||
--bandwidth 300M \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "relay-1" "S"
|
||||
assert_process_state "relay-2" "S"
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
15
scripts/tests/perf/udp-client2server.sh
Executable file
15
scripts/tests/perf/udp-client2server.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c "iperf3 \
|
||||
--time 30 \
|
||||
--udp \
|
||||
--bandwidth ${UDP_BITRATE:-450M} \
|
||||
--client 172.20.0.110 \
|
||||
--json" >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -4,13 +4,13 @@ set -euox pipefail
|
||||
|
||||
source "./scripts/tests/lib.sh"
|
||||
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c 'iperf3 \
|
||||
docker compose exec --env RUST_LOG=info -it client /bin/sh -c "iperf3 \
|
||||
--time 30 \
|
||||
--reverse \
|
||||
--udp \
|
||||
--bandwidth 600M \
|
||||
--bandwidth ${UDP_BITRATE:-450M} \
|
||||
--client 172.20.0.110 \
|
||||
--json' >>"${TEST_NAME}.json"
|
||||
--json" >>"${TEST_NAME}.json"
|
||||
|
||||
assert_process_state "gateway" "S"
|
||||
assert_process_state "client" "S"
|
||||
@@ -13,6 +13,7 @@ debug_exit() {
|
||||
docker compose ps -a
|
||||
resolvectl dns tun-firezone || true
|
||||
systemctl status "$SERVICE_NAME" || true
|
||||
journalctl -eu "$SERVICE_NAME" || true
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ resolvectl query "$HTTPBIN" || debug_exit
|
||||
# Accessing a resource should succeed after the client is up
|
||||
# Block off Docker's DNS.
|
||||
sudo resolvectl dns "$DOCKER_IFACE" ""
|
||||
curl -v $HTTPBIN/get
|
||||
curl -v $HTTPBIN/get || debug_exit
|
||||
|
||||
# Make sure it's going through the tunnel
|
||||
nslookup "$HTTPBIN" | grep "100\\.96\\.0\\."
|
||||
|
||||
Reference in New Issue
Block a user