Limit outgoing wan traffic from router itself

I'm having a bit of trouble with outgoing traffic from the router itself.

The goal:
I want all traffic from the router itself, eg: dns, updates, packages, blocklists, ipsets.. to go over a vpn. So I created the following firewall rules:

  • allow vpn-connections to wan
  • mark 0x10 ipv4/6 from this device to wan
  • block everything from this device to wan

and added a routing rule:

  • mark '0x10' lookup '21' priority '30000'

somehow this does not work, and im breaking my brain over what it could be.

From superfluous description it looks like you mark then drop packets and they never reach routing. mark action is not final like accept/reject/drop, next rule(s) count

Can you show:

ubus call system board
cat /etc/config/network
cat /etc/config/firewall
nft list ruleset # only {} brackets , hook lines and mark and drop lines

Obviously edit away static IP addresses and all other secrets.

Did you make a route from SRC loopback (i.e., this device) to 0.0.0.0/0 via interface VPN?

Not sure why making firewall rules would work.

ahh, i did not know that.

mark with firewall 0x10, then routing rule based on mark.

The data requested (i did not know how to filter nft list, so i removed drop rule entirely):

system:

# ubus call system board
{
	"kernel": "6.6.73",
	"hostname": "router",
	"system": "ARMv8 Processor rev 0",
	"model": "FriendlyElec NanoPi R6C",
	"board_name": "friendlyarm,nanopi-r6c",
	"rootfs_type": "squashfs",
	"release": {
		"distribution": "OpenWrt",
		"version": "24.10.0-rc7",
		"revision": "r28417-daef29c75d",
		"target": "rockchip/armv8",
		"description": "OpenWrt 24.10.0-rc7 r28417-daef29c75d",
		"builddate": "1738018409"
	}
}

/etc/config/network:

# awk -F"'" '!/description|macaddr/ {if (/_key|_host/) $2 = "'\''<redacted>'\''"; print}' network

config globals 'globals'
	option packet_steering '1'

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

config device
	option name 'eth1'

config interface 'lan'
	option device 'eth1'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'
	option delegate '0'

config device
	option name 'eth0'

config interface 'wan'
	option device 'eth0'
	option proto 'dhcp'
	option hostname '*'
	option peerdns '0'
	option delegate '0'
	option ip4table '10'
	option ip6table '10'

config interface 'vpn1'
	option proto 'wireguard'
	option private_key  '<redacted>' 
	list addresses '10.10.11.2/32'
	list dns '10.10.11.1'
	option delegate '0'
	option ip4table '11'
	option ip6table '11'

config wireguard_vpn1
	option public_key  '<redacted>' 
	list allowed_ips '0.0.0.0/0'
	option endpoint_host  '<redacted>' 
	option endpoint_port '51820'
	option route_allowed_ips '1'

config rule
	option in 'lan'
	option mark '10'
	option lookup '10'
	option priority '30000'

config rule
	option in 'lan'
	option mark '11'
	option lookup '11'
	option priority '30001'

config device
	option name 'phy0-ap0'

config interface 'wlan'
	option proto 'static'
	option force_link '0'
	option device 'radio0.network1'
	option ipaddr '192.168.2.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'vpn2'
	option proto 'wireguard'
	option private_key  '<redacted>' 
	list addresses '10.10.12.2/32'
	list dns '10.10.12.1'
	option delegate '0'
	option ip4table '12'
	option ip6table '12'

config wireguard_vpn2
	option public_key  '<redacted>' 
	list allowed_ips '0.0.0.0/0'
	option endpoint_host  '<redacted>' 
	option endpoint_port '51820'
	option route_allowed_ips '1'

config rule
	option in 'wlan'
	option lookup '12'
	option priority '30000'

config interface 'vpn3'
	option proto 'wireguard'
	option private_key  '<redacted>' 
	list addresses '10.10.13.2/32'
	list dns '10.10.13.1'
	option delegate '0'
	option ip4table '13'
	option ip6table '13'

config wireguard_vpn3
	option public_key  '<redacted>' 
	list allowed_ips '0.0.0.0/0'
	option endpoint_host  '<redacted>' 
	option endpoint_port '51820'
	option route_allowed_ips '1'

/etc/config/firewall:

# cat /etc/config/firewall

config defaults
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option synflood_protect '1'
	option drop_invalid '1'

config zone
	option name 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'lan'

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'

config forwarding
	option src 'lan'
	option dest 'wan'

config zone
	option name 'vpn1'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'vpn1'

config forwarding
	option src 'lan'
	option dest 'vpn1'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Mark-LAN-VPN'
	option dest '*'
	option family 'ipv4'
	option set_mark '11'
	option target 'MARK'
	list proto 'all'
	option src 'lan'

config rule
	option name 'Mark-LAN-WAN (ipset)'
	option dest '*'
	option ipset 'wan dest'
	option family 'ipv4'
	option set_mark '10'
	option target 'MARK'
	option src 'lan'
	list proto 'all'

config zone
	option name 'wlan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	list network 'wlan'

config ipset 'wan'
	option name 'wan'
	option family 'ipv4'
	option match 'net'
	option loadfile '/var/ipset-wan'

config zone
	option name 'vpn2'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'vpn2'

config forwarding
	option src 'wlan'
	option dest 'vpn2'

config ipset 'wan6'
	option name 'wan6'
	option family 'ipv6'
	option match 'net'
	option loadfile '/var/ipset-wan6'

config zone
	option name 'vpn3'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'vpn3'

You cannot route all traffic from the router itself (OUTPUT) via the VPN you have to make an exception for the VPN endpoint.

Why not make it easier for yourself and make the VPN default and then route e.g. the lan inter face out via the WAN?

I use the PBR app you can do all those things but it is perhaps overkill in your situation, see:
https://openwrt.org/docs/guide-user/network/routing/pbr_app

Yes, that's what I had, before vpn1 as default and exceptions for wan, however i found out that vpn2 and vpn3 would travel over vpn1 even if they have their own tables. I saw the counters from vpn1 growing equally to vpn3 when something was d/l over vpn3.

I'm pretty green when it comes to routing :blush:

Its just not for me.

Then do it manually:

To be clear, you can't merely "firewall" traffic to make it "route" elsewhere.

Typical setup is to leave wan/wan6 with only route to vpn server(s) and make default route via vpn.

Thanks, I'll read up on those now.

For lan I cannot setup a static rule, because I need some exclusions to go through wan, hence the dynamic rule.

So what am I missing then ?

  1. traffic goes to firewall
  2. firewall rule marks traffic matching conditions with a value
  3. traffic goes to routing
  4. routing rule matches traffic marked value and routes to specified table

I feel so lost :blush:

If I setup a vpn without a zone it would be for router only ?, and then make exceptions end-points. Because as far as I understand each subsequent vpn would need to bypass the first because of the change in default route ?

edit:

I looked at the routes, and its messed up:

# ip route
default dev vpn proto static scope link 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 
<endpoint_vpn_ip> dev vpn1 proto static scope link 
<endpoint_vpn_ip> dev vpn1 proto static scope link 

I thought I would get something like this:

default dev vpn proto static scope link 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 
<endpoint_vpn_ip> via <modem-ip> dev eth0 proto static 

You can set static routes for the various VPN endpoints going out via WAN or not?

1 Like

Yes, that's it!, thank you.
My VPNs appear stable now.

I will try to make the first VPN default, to solve my problem i started this topic for :blush:

1 Like

Yes, the backend connections don5 belong to zones, default output accept handles them cf pppoe.