Public traffic routed to LAN doesn't pick right return path

I have a problem routing traffic in Openwrt. I have a VPS in a datacenter and it forwards public traffic through Wireguard to my Openwrt router.

I can see this traffic in tcpdump incoming on my Openwrt Wireguard tunnel at home. Then the traffic is sent to my DMZ, my nodes respond to it, but then the traffic leaves my router through the WAN interface, while it was supposed to be sent back through the Wireguard tunnel.

The traffic isn't changing it's source before being processed, so the traffic stays "public" (0.0.0.0/0).

The question is: How can I route the traffic back through the Wireguard tunnel?

What do you mean "sent back through the Wireguard tunnel"?

  • Is this configured at the remote location?
  • You may have to show all SRC and DST, IPs, routing configs, etc.
1 Like

Forwarding config on my VPS:

root@ingress:~# cat /etc/wireguard/wg0.conf 
[Interface]
PrivateKey = *redacted*
ListenPort = 51820

PreUp = sysctl -w net.ipv4.ip_forward=1

PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 172.16.10.0:80
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 172.16.10.0:80

PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 172.16.10.0:443
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp --dport 443 -j DNAT --to-destination 172.16.10.0:443

[Peer]
PublicKey = *redacted*
Endpoint = home:51821
AllowedIPs = 172.16.10.0,172.16.10.25

Config on my OpenWRT router:

root@hive:~# cat /etc/config/network 

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fdc8:19f6:9f8c::/48'
	option packet_steering '1'

config interface 'wan'
	option device 'eth0'
	option proto 'dhcp'
	option hostname '*'
	option peerdns '0'

config device
	option type '8021q'
	option ifname 'eth4'
	option vid '40'
	option name 'eth4.40'

config interface 'dmz'
	option proto 'static'
	option device 'eth4.40'
	option ipaddr '192.168.40.254'
	option netmask '255.255.255.0'

config interface 'ingress'
	option proto 'wireguard'
	option private_key '*redacted*'
	option listen_port '51821'
	option nohostroute '1'
	option delegate '0'
	option defaultroute '0'

config wireguard_ingress
	option description 'ingress'
	option public_key '*redacted*'
	list allowed_ips '0.0.0.0/0'
	option endpoint_host '*ingress*'
	option endpoint_port '51820'
	option persistent_keepalive '25'

config device
	option name 'ingress'
	option acceptlocal '0'
	option multicast '0'
	option ipv6 '0'

172.16.10.0 is managed by BGP:

root@hive:~# cat /etc/quagga/bgpd.conf 
password *redacted*
!
access-list vty permit 127.0.0.0/8
access-list vty permit 192.168.40.0/24
access-list vty deny any

router bgp 64512
bgp router-id 192.168.40.254

network 192.168.40.100/24

neighbor 192.168.40.101 remote-as 64513
neighbor 192.168.40.101 soft-reconfiguration inbound
neighbor 192.168.40.101 distribute-list freenet in
neighbor 192.168.40.101 distribute-list freenet out

neighbor 192.168.40.102 remote-as 64513
neighbor 192.168.40.102 soft-reconfiguration inbound
neighbor 192.168.40.102 distribute-list freenet in
neighbor 192.168.40.102 distribute-list freenet out

neighbor 192.168.40.103 remote-as 64513
neighbor 192.168.40.103 soft-reconfiguration inbound
neighbor 192.168.40.103 distribute-list freenet in
neighbor 192.168.40.103 distribute-list freenet out

access-list freenet permit 172.16.10.0/24
access-list freenet deny any
!
line vty
 access-class vty

The problem is that the traffic coming back from the DMZ is routed over WAN, since the traffic isn't going through MASQUERADE and thus matches 0.0.0.0/0. I want to keep the SRC ADDR through the tunnel for rate limiting.

root@hive:~# tcpdump -i ingress -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on netcup, link-type RAW (Raw IP), snapshot length 262144 bytes
12:07:04.963856 IP 1.2.3.4.55064 > 172.16.10.0.443: Flags [S], seq 3527543566, win 64240, options [mss 1460,sackOK,TS val 1865449515 ecr 0,nop,wscale 7], length 0
12:07:05.289173 IP 1.2.3.4.53084 > 172.16.10.0.443: Flags [S], seq 3771608147, win 64240, options [mss 1460,sackOK,TS val 1865449841 ecr 0,nop,wscale 7], length 0
12:07:05.992871 IP 1.2.3.4.55064 > 172.16.10.0.443: Flags [S], seq 3527543566, win 64240, options [mss 1460,sackOK,TS val 1865450545 ecr 0,nop,wscale 7], length 0

ingress is the wg tunnel name. You can see the traffic comes through the tunnel.

root@hive:~# tcpdump -i eth4.40 -n
12:10:34.103171 IP 1.2.3.4.443 > 192.168.40.102.48916: Flags [P.], seq 3881:4018, ack 742, win 505, options [nop,nop,TS val 1136857779 ecr 1894851358], length 137
12:10:34.103242 IP 1.2.3.4.443 > 192.168.40.102.48916: Flags [P.], seq 4018:4233, ack 742, win 505, options [nop,nop,TS val 1136857779 ecr 1894851358], length 215
12:10:34.103439 IP 192.168.40.102.48916 > 1.2.3.4.443: Flags [.], ack 4018, win 501, options [nop,nop,TS val 1894851389 ecr 1136857778], length 0
12:10:34.103439 IP 192.168.40.102.48916 > 1.2.3.4.443: Flags [P.], seq 742:773, ack 4233, win 501, options [nop,nop,TS val 1894851390 ecr 1136857779], length 31

eth0 is my WAN interface:

root@hive:~# tcpdump -i eth0 -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:11:39.980732 IP 172.16.10.0.443 > 1.2.3.4.49576: Flags [R.], seq 0, ack 1886353253, win 0, length 0
12:11:39.980825 IP 172.16.10.0.443 > 1.2.3.4.49582: Flags [R.], seq 0, ack 1864873264, win 0, length 0
12:11:41.260978 IP 172.16.10.0.443 > 1.2.3.4.49588: Flags [R.], seq 0, ack 2792318429, win 0, length 0
12:11:41.513251 IP 172.16.10.0.443 > 1.2.3.4.49604: Flags [R.], seq 0, ack 951793684, win 0, length 0 

The packets leave over the WAN interface, while they should have gone through the ingress wireguard tunnel.