#!/bin/bash -e ACTING_AS_PID1="${ACTING_AS_PID1:-yes}" WG_TARGET="${WG_TARGET:-wg0}" REAL_PUBLIC_IP="$(curl -4 ifconfig.me)" CURRENT_PUBLIC_IP="${REAL_PUBLIC_IP}" DETECT_LEAK="${DETECT_LEAK:-yes}" wgs::log() { echo "[wgs]" "$(date -u +%Y-%m-%dT%H:%M:%S%Z)" "$@" } wgs::convert_wg_config() { # Some directives in a wg-config do not work well in containers, e.g. "DNS" # So, convert the ones we can to a container-safe equivalent. /wg-convert-config.sh "/etc/wireguard/${WG_TARGET}.conf" "/etc/wireguard/ctr${WG_TARGET}.conf" } wgs::up() { wgs::convert_wg_config wg-quick up "ctr${WG_TARGET}" # wg-quick's AllowedIPs=0.0.0.0/0 installs "lookup main suppress_prefixlength 0", # which hides the pod's default route so everything else falls into the tunnel. # That catches replies to inbound connections too, and the web UI goes dark for # any client outside this node's pod subnet. Replies are sourced from the pod # IP, so keying on that restores them without touching outbound traffic, which # is routed before a source is chosen and so never matches this rule. # Deleted first because the pod's netns outlives the container: on a restart # the previous rule is still installed and a second add would stack. ip -4 rule del from "$POD_IP" lookup main priority 100 2>/dev/null || true ip -4 rule add from "$POD_IP" lookup main priority 100 } wgs::refresh_public_ip() { CURRENT_PUBLIC_IP="$(curl -4 ifconfig.me)" } wgs::public_ip_is_masked() { wgs::refresh_public_ip [ "$CURRENT_PUBLIC_IP" != "$REAL_PUBLIC_IP" ] && return 0 || return 1 } wgs::down() { wgs::log "Cleaning up..." ip -4 rule del from "$POD_IP" lookup main priority 100 2>/dev/null || true wg-quick down "ctr${WG_TARGET}" || true rm -f /vpn-online.touch exit 0 } wgs::pid1() { wgs::log "Starting PID1..." trap wgs::down INT TERM wgs::log "Our real public IP is: ${REAL_PUBLIC_IP}" wgs::up wgs::refresh_public_ip wgs::log "Our new public IP is: ${CURRENT_PUBLIC_IP}" if [ "$DETECT_LEAK" = yes ] && [ "$CURRENT_PUBLIC_IP" = "$REAL_PUBLIC_IP" ]; then wgs::log "Failed to mask IP on startup" wgs::down fi touch /vpn-online.touch while :; do sleep 60 if [ "$DETECT_LEAK" = yes ] && ! wgs::public_ip_is_masked; then wgs::log "Detected a leak; stopping" wgs::down fi done } if [ "$ACTING_AS_PID1" = yes ]; then wgs::pid1 fi