iptables INVALID use case

This article describes a use case of iptables INVALID state.

LAN 192.168.0.0/24 is connected to the gateway 192.168.0.1 eth1.
VPN server 192.168.0.100 offers VPN services on network 10.0.0.0/24, for example a client will have the address 10.0.0.237.
VPN server has two interfaces 192.168.0.100 and 10.0.0.1, forwarding is enabled.
All routes are maintained ONLY on the gateway 192.168.0.1.

When VPN client 10.0.0.237 wants to reach a server located on the LAN, 192.168.0.50 for example, it does not work !!!

Let’s have a look at routes.
Way to go:
VPN client 10.0.0.237 wants to reach 192.168.0.50.
First it goes to its gateway 10.0.0.1,
then it reach the 192.168.0.100 still on the gateway
and 192.168.0.50 is on the connected interface 192.168.0.100, then it reaches the server
Way back:
server 192.168.0.100 has a default gateway 192.168.0.1,
and then nothing happen, packet are stopped on the gateway 192.168.0.1, it means packet are not sent back and it does not work.

Why ?
This is because LAN server 192.168.0.100 send returns packet back to the default gateway 192.168.0.1 instead of VPN server 192.168.0.100.
Default gateway does not accept this: packet are not NEW nor ESTABLISHED. This is asymetric routing.

In order to make this possible there are several solutions:
– add on all LAN server a route like 10.0.0.0/24 via 192.168.0.100, but I do not want this solution since I only maintain routes on the gateway
– other solution is to make gateway accept packets that are not NEW or ESTABLISHED:

$I -A FORWARD -i eth1 -o eth1 -s 192.168.0.0/24 -d 10.0.0.0/24 -m state --state INVALID -j ACCEPT

This rule says packet coming from LAN (on 192.168.0.1) exiting on LAN (from 192.168.0.1) to destination VPN network (10.0.0.0/24) are accepted even though they do not have a normal state (INVALID).
You are accepting asymetric routing on your network and now it works: VPN clients do have access to all LAN servers.

And to not forget legitim trafic:

$I -A FORWARD -i eth1 -o eth1 -s 192.168.0.0/24 -d 10.0.0.0/24 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables FORWARD with and without NAT

Simple forward from network 192.168.0.0/24 to network 172.16.0.0/24. GW 192.168.0.1 and 172.16.0.1

iptables -A FORWARD -i eth1 -o eth0 -s 192.168.0.0/24 -d 172.16.0.0/24 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -s 172.16.0.0/24 -d 192.168.0.0/24 -m state --state ESTABLISHED,RELATED -j ACCEPT

On the gateway tcpdump will show:

05:58:48.316239 IP 192.168.0.22 > 172.16.0.33: ICMP echo request, id 1, seq 2193, length 40
05:58:48.349553 IP 172.16.0.33 > 192.168.0.22: ICMP echo reply, id 1, seq 2193, length 40

Forward from network 192.168.0.0/24 to network 172.16.0.0/2 and source nating:

iptables -A FORWARD -i eth1 -o eth0 -s 192.168.0.0/24 -d 172.16.0.0/24 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -s 172.16.0.0/24 -d 192.168.0.0/42 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -d 172.16.0.0/2 -j MASQUERADE

On the gateway tcpdump will show:

05:58:48.316239 IP 172.16.0.1 > 172.16.0.33: ICMP echo request, id 1, seq 2193, length 40
05:58:48.349553 IP 172.16.0.33 > 172.16.0.1: ICMP echo reply, id 1, seq 2193, length 40