From 32c738d4ce0336b16eb870419b4ed02af3d6c227 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelhalim Date: Sat, 24 Jan 2026 23:36:50 +0100 Subject: Add ipv6 support to gateway VPN role After finding issues that vpn ip6 wasn't working reliably (which was obvious over VPN) Needed to add the VPN routing table support (similar to ipv4) This together with disabling ssh (for github and sr.ht) over ipv6 makes the vpn reliable again Will test and see, since I saw that the archlinux machine wasn't working properly over the vpn, but it could be due to the VPN ipv6 wasn't resolving. --- roles/gateway/defaults/main.yml | 1 + roles/gateway/meta/argument_specs.yml | 5 ++++ roles/gateway/templates/gateway-apply-rules.sh.j2 | 34 ++++++++++++++++++----- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/roles/gateway/defaults/main.yml b/roles/gateway/defaults/main.yml index ebe33a12..dad64685 100644 --- a/roles/gateway/defaults/main.yml +++ b/roles/gateway/defaults/main.yml @@ -1,3 +1,4 @@ --- gateway_enabled: false gateway_router_interface: "eth0" +gateway_local_ipv6_subnet: "" diff --git a/roles/gateway/meta/argument_specs.yml b/roles/gateway/meta/argument_specs.yml index e5d14e35..4ee6ddb6 100644 --- a/roles/gateway/meta/argument_specs.yml +++ b/roles/gateway/meta/argument_specs.yml @@ -13,6 +13,11 @@ argument_specs: description: "Local subnet CIDR for NAT and routing rules (e.g., '192.168.178.0/24')" type: "str" required: true + gateway_local_ipv6_subnet: + description: "Local IPv6 subnet CIDR for NAT and routing rules (e.g., '2a02:3102:4ced:ec00::/64')" + type: "str" + required: false + default: "" gateway_router_interface: description: "Default route interface for direct routing mode" type: "str" diff --git a/roles/gateway/templates/gateway-apply-rules.sh.j2 b/roles/gateway/templates/gateway-apply-rules.sh.j2 index d79f2279..2e6bfb70 100644 --- a/roles/gateway/templates/gateway-apply-rules.sh.j2 +++ b/roles/gateway/templates/gateway-apply-rules.sh.j2 @@ -6,7 +6,8 @@ SCRIPT_NAME="gateway-apply-rules" LOG_FACILITY="local0.info" # Ansible template variables - configured at deployment time -GATEWAY_SUBNET="{{ gateway_local_ipv4_subnet }}" +GATEWAY_SUBNET_V4="{{ gateway_local_ipv4_subnet }}" +GATEWAY_SUBNET_V6="{{ gateway_local_ipv6_subnet }}" GATEWAY_INTERFACE="{{ gateway_router_interface }}" log_message() { echo "[$SCRIPT_NAME] $1" | logger -t "$SCRIPT_NAME" -p "$LOG_FACILITY" @@ -20,28 +21,47 @@ detect_vpn_interfaces() { clear_rules() { log_message "Clearing existing gateway rules" iptables -F FORWARD 2>/dev/null || true - iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET" -o wg+ -j MASQUERADE 2>/dev/null || true - iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true + iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V4" -o wg+ -j MASQUERADE 2>/dev/null || true + iptables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V4" -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true iptables -D OUTPUT -o wg+ -j ACCEPT 2>/dev/null || true iptables -D OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT 2>/dev/null || true + if [ -n "$GATEWAY_SUBNET_V6" ]; then + ip6tables -F FORWARD 2>/dev/null || true + ip6tables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V6" -o wg+ -j MASQUERADE 2>/dev/null || true + ip6tables -t nat -D POSTROUTING -s "$GATEWAY_SUBNET_V6" -o "$GATEWAY_INTERFACE" -j MASQUERADE 2>/dev/null || true + ip6tables -D OUTPUT -o wg+ -j ACCEPT 2>/dev/null || true + ip6tables -D OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT 2>/dev/null || true + fi } apply_vpn_mode() { local vpn_interfaces="$1" log_message "Applying VPN mode rules for interfaces: $vpn_interfaces" - iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET" -o wg+ -j MASQUERADE + iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET_V4" -o wg+ -j MASQUERADE iptables -A OUTPUT -o wg+ -j ACCEPT - iptables -A FORWARD -s "$GATEWAY_SUBNET" -o wg+ -j ACCEPT + iptables -A FORWARD -s "$GATEWAY_SUBNET_V4" -o wg+ -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + if [ -n "$GATEWAY_SUBNET_V6" ]; then + ip6tables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET_V6" -o wg+ -j MASQUERADE + ip6tables -A OUTPUT -o wg+ -j ACCEPT + ip6tables -A FORWARD -s "$GATEWAY_SUBNET_V6" -o wg+ -j ACCEPT + ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + fi log_message "VPN mode rules applied - traffic routed through VPN" } apply_direct_rules() { log_message "Applying direct mode rules" - iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j MASQUERADE + iptables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET_V4" -o "$GATEWAY_INTERFACE" -j MASQUERADE iptables -A OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT - iptables -A FORWARD -s "$GATEWAY_SUBNET" -o "$GATEWAY_INTERFACE" -j ACCEPT + iptables -A FORWARD -s "$GATEWAY_SUBNET_V4" -o "$GATEWAY_INTERFACE" -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + if [ -n "$GATEWAY_SUBNET_V6" ]; then + ip6tables -t nat -A POSTROUTING -s "$GATEWAY_SUBNET_V6" -o "$GATEWAY_INTERFACE" -j MASQUERADE + ip6tables -A OUTPUT -o "$GATEWAY_INTERFACE" -j ACCEPT + ip6tables -A FORWARD -s "$GATEWAY_SUBNET_V6" -o "$GATEWAY_INTERFACE" -j ACCEPT + ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + fi log_message "Direct mode rules applied - normal routing active" } -- cgit v1.2.3