WireGuard Archive on lore.kernel.org
 help / color / Atom feed
* Strange firewall dnat rule to make WireGuard work on dual-interface server
@ 2019-09-01  8:27 Simone Rossetto
  0 siblings, 0 replies; only message in thread
From: Simone Rossetto @ 2019-09-01  8:27 UTC (permalink / raw)
  To: wireguard

[-- Attachment #1.1: Type: text/plain, Size: 3391 bytes --]

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.

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:

    # new routing table to eth0
    ip rule add fwmark 11 table adsl
    ip route add default via 192.168.0.1 dev eth0 table adsl

    # set mark 11 on incoming packets from eth0 and for some outgoing
packets
    iptables -t mangle -A PREROUTING -m conntrack --ctstate
RELATED,ESTABLISHED -j CONNMARK --restore-mark
    iptables -t mangle -A INPUT -i eth0 -m conntrack --ctstate NEW -j MARK
--set-xmark 11
    iptables -t mangle -A INPUT -m conntrack --ctstate NEW -j CONNMARK
--save-mark
    iptables -t mangle -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED
-j CONNMARK --restore-mark
    iptables -t mangle -A OUTPUT [...] --ctstate NEW -j MARK --set-xmark 11
    iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -j
CONNMARK --save-mark

    # change source IP for new connections that need to bo routed to eth0
    iptables -t nat -A POSTROUTING -s 192.168.1.1/32 -m conntrack --ctstate
NEW -m mark --mark 11 -j SNAT --to-source 192.168.0.1

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

    cat /proc/net/nf_conntrack | grep 44
    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
    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

where 44 is the UDP WireGuard port.
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".

To make WireGuard work I need to add the following iptables pre-routing rule

    iptables -t nat -A PREROUTING -d 192.168.0.1/32 -p udp -m udp --dport
44 -m conntrack --ctstate NEW -j DNAT --to-destination 192.168.1.1

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:

    cat /proc/net/nf_conntrack | grep 44
    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

a single established connection to IP 192.168.0.1 even I set a dnat to
192.168.1.1.

Is there a reason for this behavior or could it be a bug in WireGuard?
Or, perhaps, I set something odd and the dnat is a workaround?


Thanks, bye
Simone

[-- Attachment #1.2: Type: text/html, Size: 4101 bytes --]

<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 &quot;unreplied&quot; 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 &quot;reply&quot;, but not a working &quot;reply&quot;.<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>

[-- Attachment #2: Type: text/plain, Size: 148 bytes --]

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, back to index

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-01  8:27 Strange firewall dnat rule to make WireGuard work on dual-interface server Simone Rossetto

WireGuard Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/wireguard/0 wireguard/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 wireguard wireguard/ https://lore.kernel.org/wireguard \
		wireguard@lists.zx2c4.com zx2c4-wireguard@archiver.kernel.org
	public-inbox-index wireguard


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/com.zx2c4.lists.wireguard


AGPL code for this site: git clone https://public-inbox.org/ public-inbox