diff --git a/test/client-entrypoint.sh b/test/client-entrypoint.sh index de23a13..e4e9234 100755 --- a/test/client-entrypoint.sh +++ b/test/client-entrypoint.sh @@ -12,6 +12,123 @@ fi echo "TUN device ready" +WAIT_TIMEOUT_SIGNAL="${WAIT_TIMEOUT_SIGNAL:-300}" +WAIT_TIMEOUT_VPN="${WAIT_TIMEOUT_VPN:-120}" +WAIT_TIMEOUT_GATEWAY="${WAIT_TIMEOUT_GATEWAY:-120}" +WAIT_TIMEOUT_REVOKE="${WAIT_TIMEOUT_REVOKE:-60}" + +wait_until() { + local description="$1" + local timeout="$2" + local interval="$3" + shift 3 + + local start elapsed + start=$(date +%s) + until "$@"; do + elapsed=$(($(date +%s) - start)) + if [ "$elapsed" -ge "$timeout" ]; then + echo "FAIL: Timed out after ${timeout}s waiting for $description" + return 1 + fi + echo "Waiting for $description... (${elapsed}/${timeout}s)" + sleep "$interval" + done +} + +wait_for_file() { + local path="$1" + local description="$2" + local timeout="${3:-$WAIT_TIMEOUT_SIGNAL}" + + wait_until "$description" "$timeout" 2 test -f "$path" +} + +tun_has_ipv4() { + ip addr show tun0 2>/dev/null | grep -q "inet " +} + +wait_for_tun_ipv4() { + local description="$1" + local log_file="$2" + local timeout="${3:-$WAIT_TIMEOUT_VPN}" + local elapsed=0 + + until tun_has_ipv4; do + if [ "$elapsed" -ge "$timeout" ]; then + echo "FAIL: Timed out after ${timeout}s waiting for $description" + ip addr show 2>&1 || true + if [ -f "$log_file" ]; then + echo "OpenVPN log tail:" + tail -50 "$log_file" + fi + exit 1 + fi + echo "Waiting for tun0... (${elapsed}/${timeout}s)" + if [ -f "$log_file" ]; then + tail -3 "$log_file" + fi + sleep 2 + elapsed=$((elapsed + 2)) + done +} + +gateway_ping_ok() { + ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1 +} + +gateway_unreachable() { + ! ping -c 1 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1 +} + +wait_for_gateway_ping() { + local description="$1" + + if ! wait_until "$description" "$WAIT_TIMEOUT_GATEWAY" 3 gateway_ping_ok; then + echo "FAIL: Cannot ping $VPN_GATEWAY" + ip addr show 2>&1 || true + ip route show 2>&1 || true + exit 1 + fi + echo "PASS: Can ping $description" +} + +wait_for_revoked_reconnect_rejected() { + local log_file="$1" + local timeout="${2:-$WAIT_TIMEOUT_VPN}" + local elapsed=0 + + while [ "$elapsed" -le "$timeout" ]; do + if tun_has_ipv4; then + echo "FAIL: Connection succeeded with revoked certificate!" + cat "$log_file" 2>/dev/null || true + exit 1 + fi + + if [ -f "$log_file" ] && grep -qi "certificate verify failed\|TLS Error\|AUTH_FAILED\|certificate revoked" "$log_file"; then + echo "Connection correctly rejected (certificate revoked)" + return 0 + fi + + if [ "$elapsed" -ge "$timeout" ]; then + echo "FAIL: Timed out after ${timeout}s waiting for revoked certificate rejection" + cat "$log_file" 2>/dev/null || true + exit 1 + fi + + echo "Checking revoked connection status... (${elapsed}/${timeout}s)" + if [ -f "$log_file" ]; then + tail -3 "$log_file" + fi + sleep 2 + elapsed=$((elapsed + 2)) + done + + echo "FAIL: Timed out after ${timeout}s waiting for revoked certificate rejection" + cat "$log_file" 2>/dev/null || true + exit 1 +} + test_dns_resolution() { local label="$1" local success=false @@ -37,10 +154,7 @@ test_dns_resolution() { # Wait for client config to be available echo "Waiting for client config..." -while [ ! -f /shared/client.ovpn ]; do - sleep 2 - echo "Waiting for client config..." -done +wait_for_file /shared/client.ovpn "client config" echo "Client config found!" cat /shared/client.ovpn @@ -67,14 +181,7 @@ openvpn --config /shared/client.ovpn --daemon --log /var/log/openvpn.log # Wait for connection echo "Waiting for VPN connection..." -while ! ip addr show tun0 2>/dev/null | grep -q "inet "; do - sleep 2 - echo "Waiting for tun0..." - # Show recent log for debugging - if [ -f /var/log/openvpn.log ]; then - tail -3 /var/log/openvpn.log - fi -done +wait_for_tun_ipv4 "VPN connection" /var/log/openvpn.log echo "=== VPN Connected! ===" ip addr show tun0 @@ -113,13 +220,9 @@ if [ "${CLIENT_IPV6:-n}" = "y" ]; then fi fi -# Test 2: Ping VPN gateway (IPv4) (retries indefinitely, relies on job timeout) +# Test 2: Ping VPN gateway (IPv4) echo "Test 2: Pinging VPN gateway (IPv4) ($VPN_GATEWAY)..." -while ! ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; do - echo "Ping failed, retrying..." - sleep 3 -done -echo "PASS: Can ping VPN gateway (IPv4)" +wait_for_gateway_ping "VPN gateway (IPv4)" # Test 2b: Ping VPN gateway (IPv6, if enabled) if [ "${CLIENT_IPV6:-n}" = "y" ]; then @@ -146,10 +249,7 @@ touch /shared/initial-tests-passed # ===================================================== echo "" echo "=== Waiting for post-renewal config ===" -while [ ! -f /shared/renewal-config-ready ]; do - sleep 2 - echo "Waiting for renewal config..." -done +wait_for_file /shared/renewal-config-ready "renewal config" echo "Renewal config ready, reconnecting..." pkill openvpn || true @@ -158,13 +258,7 @@ sleep 2 openvpn --config /shared/client.ovpn --daemon --log /var/log/openvpn-renewal.log echo "Waiting for VPN connection after renewal..." -while ! ip addr show tun0 2>/dev/null | grep -q "inet "; do - sleep 2 - echo "Waiting for tun0..." - if [ -f /var/log/openvpn-renewal.log ]; then - tail -3 /var/log/openvpn-renewal.log - fi -done +wait_for_tun_ipv4 "VPN connection after renewal" /var/log/openvpn-renewal.log echo "=== VPN Connected after renewal! ===" ip addr show tun0 @@ -173,11 +267,7 @@ echo "Waiting for routing to stabilize..." sleep 5 echo "Test: Pinging VPN gateway after renewal ($VPN_GATEWAY)..." -while ! ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; do - echo "Ping failed, retrying..." - sleep 3 -done -echo "PASS: Can ping VPN gateway after renewal" +wait_for_gateway_ping "VPN gateway after renewal" test_dns_resolution "Test: Post-renewal DNS" @@ -195,10 +285,7 @@ REVOKE_CLIENT="revoketest" # Wait for revoke test client config echo "Waiting for revoke test client config..." -while [ ! -f /shared/revoke-client-config-ready ]; do - sleep 2 - echo "Waiting for revoke test config..." -done +wait_for_file /shared/revoke-client-config-ready "revoke test config" if [ ! -f "/shared/$REVOKE_CLIENT.ovpn" ]; then echo "FAIL: Revoke test client config file not found" @@ -218,23 +305,13 @@ openvpn --config "/shared/$REVOKE_CLIENT.ovpn" --daemon --log /var/log/openvpn-r # Wait for connection echo "Waiting for VPN connection with revoke test client..." -while ! ip addr show tun0 2>/dev/null | grep -q "inet "; do - sleep 2 - echo "Waiting for tun0..." - if [ -f /var/log/openvpn-revoke.log ]; then - tail -3 /var/log/openvpn-revoke.log - fi -done +wait_for_tun_ipv4 "VPN connection with revoke test client" /var/log/openvpn-revoke.log echo "PASS: Connected with '$REVOKE_CLIENT' certificate" ip addr show tun0 -# Verify connectivity (retries indefinitely, relies on job timeout) -while ! ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; do - echo "Ping failed, retrying..." - sleep 3 -done -echo "PASS: Can ping VPN gateway with revoke test client" +# Verify connectivity +wait_for_gateway_ping "VPN gateway with revoke test client" # Signal server that we're connected with revoke test client touch /shared/revoke-client-connected @@ -242,18 +319,8 @@ touch /shared/revoke-client-connected # Wait for server to revoke and auto-disconnect us via management interface # We detect disconnect by checking if ping to VPN gateway fails echo "Waiting for server to revoke certificate and disconnect us..." -DISCONNECT_DETECTED=false -for i in $(seq 1 60); do - if ! ping -c 1 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; then - echo "Disconnect detected: cannot ping VPN gateway" - DISCONNECT_DETECTED=true - break - fi - sleep 1 - echo "Still connected, waiting for revoke/disconnect ($i/60)..." -done - -if [ "$DISCONNECT_DETECTED" = true ]; then +if wait_until "server to revoke and disconnect client" "$WAIT_TIMEOUT_REVOKE" 1 gateway_unreachable; then + echo "Disconnect detected: cannot ping VPN gateway" echo "PASS: Client was auto-disconnected by revoke" # Kill openvpn process to clean up pkill openvpn 2>/dev/null || true @@ -268,9 +335,7 @@ touch /shared/revoke-client-disconnected # Wait for server to signal us to try reconnecting echo "Waiting for server to signal reconnect attempt..." -while [ ! -f /shared/revoke-try-reconnect ]; do - sleep 2 -done +wait_for_file /shared/revoke-try-reconnect "reconnect signal" # Try to reconnect with the now-revoked certificate (should fail) echo "Attempting to reconnect with revoked certificate (should fail)..." @@ -280,31 +345,7 @@ openvpn --config "/shared/$REVOKE_CLIENT.ovpn" --daemon --log /var/log/openvpn-r # Wait and check if connection fails # The connection should fail due to certificate being revoked echo "Waiting to verify connection is rejected..." -CONNECT_FAILED=false -while true; do - sleep 2 - - # Check if tun0 came up (would mean revocation didn't work) - if ip addr show tun0 2>/dev/null | grep -q "inet "; then - echo "FAIL: Connection succeeded with revoked certificate!" - cat /var/log/openvpn-revoke-fail.log || true - exit 1 - fi - - # Check for certificate verification failure in log - if [ -f /var/log/openvpn-revoke-fail.log ]; then - if grep -qi "certificate verify failed\|TLS Error\|AUTH_FAILED\|certificate revoked" /var/log/openvpn-revoke-fail.log; then - echo "Connection correctly rejected (certificate revoked)" - CONNECT_FAILED=true - break - fi - fi - - echo "Checking connection status..." - if [ -f /var/log/openvpn-revoke-fail.log ]; then - tail -3 /var/log/openvpn-revoke-fail.log - fi -done +wait_for_revoked_reconnect_rejected /var/log/openvpn-revoke-fail.log # Kill any remaining openvpn process pkill openvpn 2>/dev/null || true @@ -316,13 +357,7 @@ if ip addr show tun0 2>/dev/null | grep -q "inet "; then exit 1 fi -if [ "$CONNECT_FAILED" = true ]; then - echo "PASS: Connection with revoked certificate was correctly rejected" -else - echo "PASS: Connection with revoked certificate did not succeed (no tun0)" - echo "OpenVPN log:" - cat /var/log/openvpn-revoke-fail.log || true -fi +echo "PASS: Connection with revoked certificate was correctly rejected" # Signal server that reconnect with revoked cert failed touch /shared/revoke-reconnect-failed @@ -335,10 +370,7 @@ echo "=== Testing connection with recreated certificate ===" # Wait for server to create new cert and signal us echo "Waiting for new client config with same name..." -while [ ! -f /shared/new-client-config-ready ]; do - sleep 2 - echo "Waiting for new config..." -done +wait_for_file /shared/new-client-config-ready "new client config" if [ ! -f "/shared/$REVOKE_CLIENT-new.ovpn" ]; then echo "FAIL: New client config file not found" @@ -354,23 +386,13 @@ openvpn --config "/shared/$REVOKE_CLIENT-new.ovpn" --daemon --log /var/log/openv # Wait for connection echo "Waiting for VPN connection with new certificate..." -while ! ip addr show tun0 2>/dev/null | grep -q "inet "; do - sleep 2 - echo "Waiting for tun0..." - if [ -f /var/log/openvpn-new.log ]; then - tail -3 /var/log/openvpn-new.log - fi -done +wait_for_tun_ipv4 "VPN connection with new certificate" /var/log/openvpn-new.log echo "PASS: Connected with new '$REVOKE_CLIENT' certificate" ip addr show tun0 -# Verify connectivity (retries indefinitely, relies on job timeout) -while ! ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; do - echo "Ping failed, retrying..." - sleep 3 -done -echo "PASS: Can ping VPN gateway with new certificate" +# Verify connectivity +wait_for_gateway_ping "VPN gateway with new certificate" # Signal server that we connected with new cert touch /shared/new-client-connected @@ -388,10 +410,7 @@ PASSPHRASE_CLIENT="passphrasetest" # Wait for passphrase test client config echo "Waiting for passphrase test client config..." -while [ ! -f /shared/passphrase-client-config-ready ]; do - sleep 2 - echo "Waiting for passphrase test config..." -done +wait_for_file /shared/passphrase-client-config-ready "passphrase test config" if [ ! -f "/shared/$PASSPHRASE_CLIENT.ovpn" ]; then echo "FAIL: Passphrase test client config file not found" @@ -416,23 +435,13 @@ openvpn --config "/shared/$PASSPHRASE_CLIENT.ovpn" --askpass "/shared/$PASSPHRAS # Wait for connection echo "Waiting for VPN connection with passphrase-protected client..." -while ! ip addr show tun0 2>/dev/null | grep -q "inet "; do - sleep 2 - echo "Waiting for tun0..." - if [ -f /var/log/openvpn-passphrase.log ]; then - tail -3 /var/log/openvpn-passphrase.log - fi -done +wait_for_tun_ipv4 "VPN connection with passphrase-protected client" /var/log/openvpn-passphrase.log echo "PASS: Connected with passphrase-protected '$PASSPHRASE_CLIENT' certificate" ip addr show tun0 -# Verify connectivity (retries indefinitely, relies on job timeout) -while ! ping -c 3 -W 2 "$VPN_GATEWAY" >/dev/null 2>&1; do - echo "Ping failed, retrying..." - sleep 3 -done -echo "PASS: Can ping VPN gateway with passphrase-protected client" +# Verify connectivity +wait_for_gateway_ping "VPN gateway with passphrase-protected client" # Signal server that we connected with passphrase client touch /shared/passphrase-client-connected diff --git a/test/server-entrypoint.sh b/test/server-entrypoint.sh index 8136a39..1c3b23c 100755 --- a/test/server-entrypoint.sh +++ b/test/server-entrypoint.sh @@ -12,6 +12,37 @@ fi echo "TUN device ready" +WAIT_TIMEOUT_SIGNAL="${WAIT_TIMEOUT_SIGNAL:-300}" +WAIT_TIMEOUT_CONNECT="${WAIT_TIMEOUT_CONNECT:-180}" +WAIT_TIMEOUT_REVOKE="${WAIT_TIMEOUT_REVOKE:-60}" + +wait_until() { + local description="$1" + local timeout="$2" + local interval="$3" + shift 3 + + local start elapsed + start=$(date +%s) + until "$@"; do + elapsed=$(($(date +%s) - start)) + if [ "$elapsed" -ge "$timeout" ]; then + echo "FAIL: Timed out after ${timeout}s waiting for $description" + return 1 + fi + echo "Waiting for $description... (${elapsed}/${timeout}s)" + sleep "$interval" + done +} + +wait_for_file() { + local path="$1" + local description="$2" + local timeout="${3:-$WAIT_TIMEOUT_SIGNAL}" + + wait_until "$description" "$timeout" 2 test -f "$path" +} + # Configuration for install export FORCE_COLOR=1 VPN_SUBNET_IPV4=10.9.0.0 # Custom subnet to test configurability @@ -371,10 +402,7 @@ echo "=== TLS 1.3 Configuration Verified ===" # ===================================================== echo "" echo "=== Waiting for initial client connectivity tests ===" -while [ ! -f /shared/initial-tests-passed ]; do - sleep 2 - echo "Waiting for initial tests..." -done +wait_for_file /shared/initial-tests-passed "initial client connectivity tests" echo "Initial client tests passed, proceeding with renewal tests" # ===================================================== @@ -564,10 +592,7 @@ echo "Updated client config with renewed certificates" # ===================================================== echo "" echo "=== Waiting for post-renewal client connectivity tests ===" -while [ ! -f /shared/renewal-tests-passed ]; do - sleep 2 - echo "Waiting for renewal tests..." -done +wait_for_file /shared/renewal-tests-passed "post-renewal client connectivity tests" echo "Post-renewal client tests passed" # ===================================================== @@ -806,10 +831,7 @@ touch /shared/revoke-client-config-ready # Wait for client to confirm connection with revoke test client echo "Waiting for client to connect with '$REVOKE_CLIENT' certificate..." -while [ ! -f /shared/revoke-client-connected ]; do - sleep 2 - echo "Waiting for revoke test connection..." -done +wait_for_file /shared/revoke-client-connected "revoke test client connection" "$WAIT_TIMEOUT_CONNECT" echo "PASS: Client connected with '$REVOKE_CLIENT' certificate" # ===================================================== @@ -884,14 +906,7 @@ fi # Wait for client to confirm it was disconnected by the revoke echo "Waiting for client to confirm auto-disconnect..." -DISCONNECT_WAIT=0 -while [ ! -f /shared/revoke-client-disconnected ] && [ $DISCONNECT_WAIT -lt 60 ]; do - sleep 2 - DISCONNECT_WAIT=$((DISCONNECT_WAIT + 2)) - echo "Waiting for disconnect confirmation... ($DISCONNECT_WAIT/60s)" -done - -if [ -f /shared/revoke-client-disconnected ]; then +if wait_for_file /shared/revoke-client-disconnected "disconnect confirmation" "$WAIT_TIMEOUT_REVOKE"; then echo "PASS: Client was auto-disconnected by revoke command" else echo "FAIL: Client was not disconnected within 60 seconds" @@ -903,10 +918,7 @@ touch /shared/revoke-try-reconnect # Wait for client to confirm that connection with revoked cert failed echo "Waiting for client to confirm revoked cert connection failure..." -while [ ! -f /shared/revoke-reconnect-failed ]; do - sleep 2 - echo "Waiting for reconnect failure confirmation..." -done +wait_for_file /shared/revoke-reconnect-failed "revoked cert reconnect failure confirmation" "$WAIT_TIMEOUT_CONNECT" echo "PASS: Connection with revoked certificate correctly rejected" echo "=== Certificate Revocation Tests PASSED ===" @@ -1080,10 +1092,7 @@ touch /shared/new-client-config-ready # Wait for client to confirm successful connection with new cert echo "Waiting for client to connect with new '$REVOKE_CLIENT' certificate..." -while [ ! -f /shared/new-client-connected ]; do - sleep 2 - echo "Waiting for new cert connection..." -done +wait_for_file /shared/new-client-connected "new certificate connection" "$WAIT_TIMEOUT_CONNECT" echo "PASS: Client connected with new '$REVOKE_CLIENT' certificate" echo "=== Reuse of Revoked Client Name Tests PASSED ===" @@ -1151,10 +1160,7 @@ touch /shared/passphrase-client-config-ready # Wait for client to confirm connection with passphrase client echo "Waiting for client to connect with '$PASSPHRASE_CLIENT' certificate..." -while [ ! -f /shared/passphrase-client-connected ]; do - sleep 2 - echo "Waiting for passphrase client connection..." -done +wait_for_file /shared/passphrase-client-connected "passphrase client connection" "$WAIT_TIMEOUT_CONNECT" echo "PASS: Client connected with passphrase-protected certificate" echo "=== PASSPHRASE Support Tests PASSED ==="