From 0dca06fbc84b693f1d8e24c47ce7dfb490e7789a Mon Sep 17 00:00:00 2001 From: alexz Date: Sat, 17 Jan 2026 09:21:09 +0000 Subject: [PATCH] Fix host routing: use nft for NAT, insert FORWARD rules before Cisco chains - host-routing.sh: Use nft instead of iptables for NAT masquerade (iptables-nft backend doesn't support iptables -t nat commands) - cisco-vpn: Use -I FORWARD 1 instead of -A FORWARD to insert rules BEFORE Cisco VPN chains (which have catch-all DROP rules) Co-Authored-By: Claude Opus 4.5 --- apps/rego-tunnel/shared/cisco-vpn | 11 ++++++----- apps/rego-tunnel/shared/host-routing.sh | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/apps/rego-tunnel/shared/cisco-vpn b/apps/rego-tunnel/shared/cisco-vpn index 508981e..70dca5f 100755 --- a/apps/rego-tunnel/shared/cisco-vpn +++ b/apps/rego-tunnel/shared/cisco-vpn @@ -341,28 +341,29 @@ setup_forwarding() { log DEBUG "NAT masquerade for container network already exists" fi - # Forward rules + # Forward rules - MUST be inserted at position 1 to run BEFORE cisco VPN chains + # The cisco VPN chains have catch-all DROP rules that would block our traffic if ! iptables -C FORWARD -d "$TARGET_IP" -j ACCEPT 2>/dev/null; then - run_cmd "Adding forward rule (to target)" iptables -A FORWARD -d "$TARGET_IP" -j ACCEPT + run_cmd "Inserting forward rule (to target)" iptables -I FORWARD 1 -d "$TARGET_IP" -j ACCEPT else log DEBUG "Forward rule (to target) already exists" fi if ! iptables -C FORWARD -s "$TARGET_IP" -j ACCEPT 2>/dev/null; then - run_cmd "Adding forward rule (from target)" iptables -A FORWARD -s "$TARGET_IP" -j ACCEPT + run_cmd "Inserting forward rule (from target)" iptables -I FORWARD 1 -s "$TARGET_IP" -j ACCEPT else log DEBUG "Forward rule (from target) already exists" fi # Accept forwarding from container network if ! iptables -C FORWARD -s 172.31.0.0/24 -j ACCEPT 2>/dev/null; then - run_cmd "Adding forward rule (from container network)" iptables -A FORWARD -s 172.31.0.0/24 -j ACCEPT + run_cmd "Inserting forward rule (from container network)" iptables -I FORWARD 1 -s 172.31.0.0/24 -j ACCEPT else log DEBUG "Forward rule (from container network) already exists" fi if ! iptables -C FORWARD -d 172.31.0.0/24 -j ACCEPT 2>/dev/null; then - run_cmd "Adding forward rule (to container network)" iptables -A FORWARD -d 172.31.0.0/24 -j ACCEPT + run_cmd "Inserting forward rule (to container network)" iptables -I FORWARD 1 -d 172.31.0.0/24 -j ACCEPT else log DEBUG "Forward rule (to container network) already exists" fi diff --git a/apps/rego-tunnel/shared/host-routing.sh b/apps/rego-tunnel/shared/host-routing.sh index 1a28bb5..be818f9 100644 --- a/apps/rego-tunnel/shared/host-routing.sh +++ b/apps/rego-tunnel/shared/host-routing.sh @@ -69,9 +69,13 @@ apply_routes() { done # Masquerade traffic from LAN subnet to VPN bridge (so return traffic routes correctly) - iptables -t nat -C POSTROUTING -o "$BRIDGE_NAME" -s "$LAN_SUBNET" -j MASQUERADE 2>/dev/null || \ - iptables -t nat -A POSTROUTING -o "$BRIDGE_NAME" -s "$LAN_SUBNET" -j MASQUERADE - log "NAT masquerade rule added for $LAN_SUBNET -> $BRIDGE_NAME" + # Use nft since iptables-nft backend doesn't support iptables -t nat commands + if ! nft list chain ip nat POSTROUTING 2>/dev/null | grep -q "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade"; then + nft add rule ip nat POSTROUTING ip saddr "$LAN_SUBNET" oifname "$BRIDGE_NAME" counter masquerade + log "NAT masquerade rule added for $LAN_SUBNET -> $BRIDGE_NAME" + else + log "NAT masquerade rule already exists for $LAN_SUBNET -> $BRIDGE_NAME" + fi log "OK: Host routing applied - $TARGET_IP via $CONTAINER_IP ($BRIDGE_NAME)" } @@ -88,8 +92,12 @@ remove_all() { iptables -D DOCKER-USER -i "$BRIDGE_NAME" -o "$lan_if" -s "$TARGET_IP" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true done - # Remove masquerade rule - iptables -t nat -D POSTROUTING -o "$BRIDGE_NAME" -s "$LAN_SUBNET" -j MASQUERADE 2>/dev/null || true + # Remove masquerade rule (using nft) + local handle + handle=$(nft -a list chain ip nat POSTROUTING 2>/dev/null | grep "saddr $LAN_SUBNET.*oifname.*$BRIDGE_NAME.*masquerade" | grep -oP 'handle \K\d+' | head -1) + if [ -n "$handle" ]; then + nft delete rule ip nat POSTROUTING handle "$handle" 2>/dev/null || true + fi log "All routing rules removed" }