<div dir="ltr"><div>Hello all, I have a routing problem on my server regarding WireGuard incoming connections and I managed to solve it using strange (at least for me) iptables rules.</div><div><br></div><div>This is the setup: one server with two interfaces (eth0 with IP 192.168.0.1 and eth1 with IP 192.168.1.1), both of them connected to an external router so both of them can be used to reach internet. The default route is through eth1 except for some connections that need to pass through eth0. I accomplished this behavior with a new routing table and fwmark on packets as follow:</div><div><br></div><div>    # new routing table to eth0<br></div><div>    ip rule add fwmark 11 table adsl</div><div>    ip route add default via 192.168.0.1 dev eth0 table adsl</div><div><br></div><div>    # set mark 11 on incoming packets from eth0 and for some outgoing packets<br></div><div>    iptables -t mangle -A PREROUTING -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark</div><div>    iptables -t mangle -A INPUT -i eth0 -m conntrack --ctstate NEW -j MARK --set-xmark 11</div><div>    iptables -t mangle -A INPUT -m conntrack --ctstate NEW -j CONNMARK --save-mark</div><div>    iptables -t mangle -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark<br>    iptables -t mangle -A OUTPUT [...] --ctstate NEW -j MARK --set-xmark 11<br></div><div>
    iptables -t mangle 

-A POSTROUTING -m conntrack --ctstate NEW -j CONNMARK --save-mark</div><div><br></div><div>    # change source IP for new connections that need to bo routed to eth0<br></div><div>    iptables -t nat -A POSTROUTING -s <a href="http://192.168.1.1/32">192.168.1.1/32</a> -m conntrack --ctstate NEW -m mark --mark 11 -j SNAT --to-source 192.168.0.1</div><div><br></div><div>This works well for any other connection but not for WireGuard incoming connections. If I cat the connection tracking I get two "unreplied" connections instead of a successful one</div><div><br></div><div>    cat /proc/net/nf_conntrack | grep 44<br>    ipv4     2 udp      17 26 src=192.168.1.1 dst=37.160.28.111 sport=44 dport=1503 [UNREPLIED] src=37.160.28.111 dst=192.168.0.1 sport=1503 dport=1024 mark=11 zone=0 use=2<br>    ipv4     2 udp      17 26 src=37.160.28.111 dst=192.168.0.1 sport=1503 dport=44 [UNREPLIED] src=192.168.0.1 dst=37.160.28.111 sport=44 dport=1503 mark=11 zone=0 use=2</div><div><br></div><div>where 44 is the UDP WireGuard port.<br></div><div>The first line seams an outgoing connection from 192.168.1.1 (eth1) to an external IP that waits for a reply on IP 192.168.0.1 (why different??) and port 1024 (?! where does it come from??), the second line is the real incoming connection from outside to port 44. The incoming connection is correctly marked with mark 11, as the outgoing "reply", but not a working "reply".<br></div><div><br></div><div>To make WireGuard work I need to add the following iptables pre-routing rule</div><div><br></div><div>    iptables -t nat -A PREROUTING -d <a href="http://192.168.0.1/32">192.168.0.1/32</a> -p udp -m udp --dport 44 -m conntrack --ctstate NEW -j DNAT --to-destination 192.168.1.1</div><div><br></div><div>that is change the destination address of new WireGuard connections from 192.168.0.1 (eth0, where they actually come from) to 192.168.1.1 (eth1) where they should not transit. Adding this rule the connection tracking is as follow:</div><div><br></div><div>    cat /proc/net/nf_conntrack | grep 44<br>    ipv4     2 udp      17 167 src=37.160.28.111 dst=192.168.0.1 sport=1503 dport=44 src=192.168.0.1 dst=37.160.28.111 sport=44 dport=1503 [ASSURED] mark=11 zone=0 use=2</div><div><br></div><div>a single established connection to IP 192.168.0.1 even I set a dnat to 192.168.1.1.</div><div><br></div><div>Is there a reason for this behavior or could it be a bug in WireGuard?</div><div>Or, perhaps, I set something odd and the dnat is a workaround?</div><div><br></div><div><br></div><div>Thanks, bye</div><div>Simone<br></div></div>