The following problem:
I have a server that is, in addition to other tasks not relevant for the problem at hand, supposed to act as an IPsec gateway. When I'm using the Ethernet interface pointing to the 'Net for handling IPsec traffic and sending out and receiving any forwarded traffic, everything works just fine: The traffic is sent through the IPsec tunnel, reaches the server, then gets decrypted and is sent out to its intended destination, and any replies are received, encrypted and passed through the IPsec tunnel.
However, once I set up an Ethernet bridge, attach aforementioned Ethernet card to it (I have duplicated its MAC address on the bridge, otherwise all outbound traffic would be dropped by the router to which the server is connected) and remap everything (both the entries in /etc/network/interfaces and the relevant iptables
statements) and then try to use the server as a gateway, nothing is forwarded. By doing some checking I found that the gateway itself can be reached via IPsec, and other hosts can be reached from the gateway.
In the former case no additional stations are listed between the client and the gateway so they are definitely passing the tunnel (there would be more hops in between otherwise) when doing a traceroute
, and in the latter case doing a traceroute
shows that the packets leave the box as usual.
When placing a TRACE on both ipencap and icmp on both -t raw PREROUTING and -t raw OUTPUT, when the IPsec tunnel is up only the outbound packets (both the packets bound for the virtual IP of the client and the public IP address of the recipient, the latter being a firewall) are showing up in xtables-monitor
; anything inbound isn't even noticed.
Also, the counters on the relevant firewall rules on the gateway keep increasing throughout the entire ruleset, however, nothing seems to be sent out (I've even logged things on ebtables
's OUTPUT chain in filter to verify what SNAT is doing, and everything looked just fine: The source IP address had been mapped to the IP address of the bridge, the destination IP address had been what it was supposed to be, and the source MAC address was set to the one I had duplicated on the bridge. As far as forwarded traffic is concerned, no responses are ever received, and doing a traceroute
from my IPsec client (the one that I'm working on right now) only elicits a response from the gateway. All other stations beyond that fail to respond, which in turn tells me that the router to which the sever is connected is dropping the forwarded packets.
Any ideas on how this could be fixed?
The relevant netfilter rules (iptables) - analogous for IPv6:
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
# Additional chains
/usr/sbin/iptables -N block_ext_in # Blocks unsolicited inbound traffic (Bogons, Spamhaus's DROP/EDROP)
/usr/sbin/iptables -N block_ext_out # Blocks undesired outbound traffic (Bogons, Spamhaus's DROP/EDROP)
/usr/sbin/iptables -N zone_ext_in # Accepts certain inbound traffic
/usr/sbin/iptables -N zone_ext_out # Permits certain outbound traffic (currently empty)
/usr/sbin/iptables -N ipsec_in # Handles inbound IPsec traffic
/usr/sbin/iptables -N drop_icmp # Kills deprecated ICMP messages
iptables -t raw -A PREROUTING -p ipencap -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
iptables -t raw -A OUTPUT -p ipencap -j TRACE
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t mangle -A PREROUTING -p tcp -s <virtual-ip-range>/24 -m policy --pol ipsec --dir in -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
iptables -t mangle -A POSTROUTING -p tcp -d <virtual-ip-range>/24 -m policy --pol ipsec --dir out -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j tCPMSS --set-mss 1360
iptables -A INPUT -i br0 -m policy --pol ipsec --dir in -j ipsec_in
iptables -A INPUT -i br0 -s <virtual-ip-range>/24 -m policy --pol ipsec --dir in -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate INVALID -j DROP
iptables -A INPUT -p tcp -m tcp ! --tcp-flags SYN,ACK,FIN,RST SYN -m conntrack --ctstate NEW -j DROP
iptables -A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
iptables -A INPUT -i br0 -p icmp -j drop_icmp
iptables -A INPUT -i br0 -s <server-vip> -j ACCEPT
iptables -A INPUT -i eth0 -m policy --pol none --dir in -j block_ext_in
iptables -A INPUT -i br0 -p udp --dport isakmp -j ACCEPT
iptables -A INPUT -i br0 -p udp --dport 4500 -j ACCEPT
iptables -A INPUT -i br0 -p esp -j ACCEPT
iptables -A INPUT -p icmp -m conntrack --ctdir REPLY -j ACCEPT
iptables -A INPUT -i br0 -p icmp --icmp-type 8 -j ICMP_ECHO
iptables -A INPUT -i br0 -p icmp --icmp-type 3/4 -j ACCEPT
iptables -A INPUT -i br0 -j zone_ext_in
iptables -A INPUT -p icmp -j DROP
iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable
iptables -A OUTPUT -d <virtual-ip-range>/24 -m policy --pol ipsec --dir out -j ACCEPT
iptables -A OUTPUT -o br0 ! -p icmp -j block_ext_out
# Safeguards against transmitting unencrypted traffic!
iptables -A OUTPUT -o br0 -d 10.0.0.0/8 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A OUTPUT -o br0 -d 172.16.0.0/12 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A OUTPUT -o br0 -d 192.168.0.0/16 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A OUTPUT -o eth0 ! -p icmp -j zone_ext_out
iptables -A FORWARD -o br0 -s <virtual-ip-range>/24 -m policy --pol ipsec --dir in -j ACCEPT
iptables -A FORWARD -p tcp -m conntrack --ctstate INVALID -j DROP
iptables -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
iptables -A FORWARD -i br0 -p tcp -m physdev --physdev-in eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i br0 -p icmp -m physdev --physdev-in eth0 -m conntrack --ctdir REPLY -j ACCEPT
iptables -A FORWARD -i br0 -p udp -m physdev --physdev-in eth0 -m conntrack --ctdir REPLY -j ACCEPT
# Safeguards against forwarding unencrypted traffic!
iptables -A FORWARD -o br0 -d 10.0.0.0/8 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A FORWARD -o br0 -d 172.16.0.0/12 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A FORWARD -o br0 -d 192.168.0.0/16 -m policy --pol none --dir out -j REJECT --reject-with icmp-net-unreachable
iptables -A FORWARD -j REJECT --reject-with icmp-net-unreachable
iptables -t nat -A POSTROUTING -s <server-ip> -j ACCEPT
iptables -t nat -A POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
iptables -t nat -A POSTROUTING -o br0 -j SNAT --to-source <server-ip> --persistent
From /etc/network/interfaces:
allow-hotplug eth0
iface eth0 inet manual
auto br0
iface br0 inet dhcp
hwaddress <mac-cloned-from-eth0>
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
iface br0 inet static
address <server-virtual-ipv4>/24
iface br0 inet6 static
address <public-ipv6>/128
gateway fe80::1
iface br0 inet6 static
address <server-virtual-ipv6>/64
Rules added by StrongSwan (show up first in their respective chains):
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT all -- <client-virtual-ipv4> anywhere policy match dir in pol ipsec reqid 3 proto esp
ACCEPT all -- anywhere <client-virtual-ipv4> policy match dir out pol ipsec reqid 3 proto esp
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT ipencap-- <recipient-ip> <public-ipv4> policy match dir in pol ipsec reqid 3 proto esp