0

I have an ipip tunnel, I want all the reply packets coming from ipip device also going through ipip. I have tried the following iptables rules

sysctl -w net.ipv4.ip_forward=1
ip rule add fwmark 1 lookup 100
ip route add default dev ipip0 table 100
iptables -t mangle -A PREROUTING -i ipip0 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -m mark --mark 0x1 -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -m connmark --mark 0x1 -j CONNMARK --restore-mark

I can see the prerouting rules working ok, but the output rule never triggered. I cannot figure out why.

1 Answers1

0

Outbound packets are generated by host and has no packet mark but sure has connection's mark. So mark inbound packets, copy packet mark to connection mark, then mark new outbound packets back with connection's mark.

iptables -t mangle -A PREROUTING -i ipip0  -m conntrack --ctstate NEW -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -m mark --mark 0x1 -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

or shorter

iptables -t mangle -A PREROUTING -i ipip0  -m conntrack --ctstate NEW -j CONNMARK --set-mark 1
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark

and use fwmark selector in ip rule for policy based routing.

You should loose Strict Reverse Path checks for interfaces without default route

sysctl -w net.ipv4.conf.ipip0.rp_filter=2

RFC3704 Strict Reverse Path
For each inbound packet kernel checks "reverse path". Kernel swapps inbound packet's source and destination and check via what interface it will be routed in reverse direction by consulting routing table. In this check kernel doesn't respect packet's mark (fwmark).

With rp_filter=1, if the return interface for a packet does not match the interface through which the packet entered, the packet will be dropped.

For example, a host has two interfaces:
eth0 with 192.168.37.3 and
eth1 with 192.168.39.5.
The default route is via eth0.

default via 192.168.37.1 dev eth0 onlink
192.168.37.0/24 dev eth0 proto kernel scope link src 192.168.37.3
192.168.39.0/24 dev eth1 proto kernel scope link src 192.168.39.5

According to the routing table, the return path for a packet with src ip 8.8.8.8 entering through eth1 will be through eth0.
eth0 and eth1 are different interfaces and packet will be dropped at first routing decision, right after PREROUTING and before INPUT/FORWARD and never reach Local processes.

At the same time return path for a packet with src ip 192.168.39.45 entering through eth1 will be through eth1 so interfaces matched and packet's processing will continue.

enter image description here

gapsf
  • 641
  • 1
  • 5
  • 12
  • If I remove ```-m connmark --mark 0x1``` filter, the output rule is triggered, but no effect at all, because it restores nothing, all triggered mark value is zero. If I use ```iptables -t mangle -A OUTPUT -m connmark ! --mark 0x0 -j CONNMARK --restore-mark```, ``` iptables -t mangle -L -v ``` still show nothing. – Hoping White Aug 11 '22 at 01:25
  • Is it a host or router? Why you enable net.ipv4.ip_forward? – gapsf Aug 11 '22 at 04:54
  • Also `ip route add default dev ipip0 table 100` replace with `ip route add default via ip_of_tunnel_remout_end dev ipip0 table 100` – gapsf Aug 11 '22 at 08:15
  • Try is it works with `sysctl -w net.ipv4.conf.ipip0.rp_filter=2` – gapsf Aug 11 '22 at 09:09
  • Thanks for the replies finally I use ```ip rule add from 10.10.11.3 lookup 100 ip route add table 100 to default dev ipip0 ``` to resolve the problem – Hoping White Aug 12 '22 at 05:17
  • I have tried to set rp_filter=0, It does not work. – Hoping White Aug 12 '22 at 05:19