problem with netfilter, ipsec and gre combination

Aleksandar Milivojevic alex at
Sat Aug 6 07:09:38 CEST 2005

I've run into the problem where Netfilter is not putting packets into 
established state (where they should be).

Basically, I have a setup that consist of two testing machines acting as 
VPN gateways.  Machine A with IP addresses of and, and machine B with IP address of and  The 1.1 and 3.1 act as "external" IP addresses.  2.1 and 
4.1 are on the "local networks" that I want to connect with a tunnel.

I've setup GRE tunnel between them like this (on machine A, machine B 
has the same thing in opposite direction, the route is to, and the interface name is neta):

# modprobe ip_gre
# ip tunnel add netb mode gre remote local ttl 255
# ip link set netb up
# ip addr add dev netb
# ip route add dev netb src

Then I defined IPSec policy between and, 
transport mode, required, using racoon for automatic keying.

If I ping from everything works fine.  Packets 
go into the GRE tunnel, which than goes over IPSec.

If I ping from, things do not work.  After lots 
of debugging (basically logging all traffic in all tables/chains, and 
looking at the output of iptables -nvxL), it seems that returning 
packets are not placed into established state.

On machine B, I have this set of rules:

# standard stuff to handle established connections


# gre/ipsec/ike stuff

-A INPUT -i eth0 -p esp -s -d -j ACCEPT
-A OUTPUT -o eth0 -p esp -s -d -j ACCEPT
-A INPUT -i eth0 -p gre -s -d -j ACCEPT
-A OUTPUT -o eth0 -p gre -s -d -j ACCEPT
-A INPUT -i eth0 -p udp --sport 500 --dport 500 -s -d -j ACCEPT
-A INPUT -i eth0 -p udp --sport 500 --dport 500 -s -d -j ACCEPT

# rules to allow ping from the other end (direct and through the tunnel)

-A INPUT -i eth0 -p icmp --icmp-type ping -s -d 
-m state --state NEW -j ACCEPT
-A INPUT -i neta -p icmp --icmp-type ping -s -d 
-m state --state NEW -j ACCEPT

# log everything before dropping it

-A INPUT -j LOG --log-prefix "INPUT "
-A OUTPUT -j LOG --log-prefix "OUTPUT "
-A FORWARD -j LOG --log-prefix "FORWARD "

As I wrote, when I do "ping -c 1" from machine A using as source address, and looking at the output of iptables 
-nvxL, I can see counter incremented for ESP packet, counter for ICMP 
ping is incremented, but the ICMP pong is not cought by the second rule 
(accept all established/related), and falls to the bottom of the chain 
(gets logged and dropped).

On the other hand, if I'm doing "ping -c" from machine A 
using as source address, everything just works (and I see 
counters incremented as expected).

I'm not using IPSec in tunneling mode to get around some other problems 
I have.  This approach also gives me interfaces that represent tunnel 
endpoints that I can use for routing, something I don't have with native 
Linux IPSec in tunneling mode.  Plus it seems doing it this way might at 
the end simplify my firewall rules (again, because there's an interface 
representing tunnel endpoint).

More information about the netfilter mailing list