Fix host routing: use nft for NAT, insert FORWARD rules before Cisco chains
Some checks failed
Test / test (push) Has been cancelled

- 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 <noreply@anthropic.com>
This commit is contained in:
2026-01-17 09:21:09 +00:00
parent 4c067c14d8
commit 0dca06fbc8
2 changed files with 19 additions and 10 deletions

View File

@@ -341,28 +341,29 @@ setup_forwarding() {
log DEBUG "NAT masquerade for container network already exists" log DEBUG "NAT masquerade for container network already exists"
fi 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 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 else
log DEBUG "Forward rule (to target) already exists" log DEBUG "Forward rule (to target) already exists"
fi fi
if ! iptables -C FORWARD -s "$TARGET_IP" -j ACCEPT 2>/dev/null; then 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 else
log DEBUG "Forward rule (from target) already exists" log DEBUG "Forward rule (from target) already exists"
fi fi
# Accept forwarding from container network # Accept forwarding from container network
if ! iptables -C FORWARD -s 172.31.0.0/24 -j ACCEPT 2>/dev/null; then 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 else
log DEBUG "Forward rule (from container network) already exists" log DEBUG "Forward rule (from container network) already exists"
fi fi
if ! iptables -C FORWARD -d 172.31.0.0/24 -j ACCEPT 2>/dev/null; then 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 else
log DEBUG "Forward rule (to container network) already exists" log DEBUG "Forward rule (to container network) already exists"
fi fi

View File

@@ -69,9 +69,13 @@ apply_routes() {
done done
# Masquerade traffic from LAN subnet to VPN bridge (so return traffic routes correctly) # 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 || \ # Use nft since iptables-nft backend doesn't support iptables -t nat commands
iptables -t nat -A POSTROUTING -o "$BRIDGE_NAME" -s "$LAN_SUBNET" -j MASQUERADE 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" 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)" 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 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 done
# Remove masquerade rule # Remove masquerade rule (using nft)
iptables -t nat -D POSTROUTING -o "$BRIDGE_NAME" -s "$LAN_SUBNET" -j MASQUERADE 2>/dev/null || true 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" log "All routing rules removed"
} }