This is an old revision of the document!
Routing example: PBR with netifd
See also: How it works: Policy-based routing
Introduction
- This how-to provides most common scenarios for PBR with netifd.
- It contains both IPv4 and IPv6 routing rules to prevent traffic leaks.
- Enable IPv6 NAT or NPT and disable IPv6 source filter if necessary.
Guidelines
- Assign each interface to a separate routing table.
- It makes netifd create essential rules automatically to simplify the setup.
- This isolates each default route resolving possible routing conflicts.
- Keep the default route enabled for each upstream interface.
- Multiple interfaces can be connected and used simultaneously by different clients.
- Do not duplicate static routes in different routing tables.
- Duplicating the same routes in different tables is redundant and pointless.
- Create custom routing rules for each assigned routing table.
- Elevate routing decision on the level of routing rules for easier troubleshooting.
- Avoid adding routes on different interfaces to the same table.
- Use a specific custom priority for each routing rule.
- A priority of about 30000 can override the
maintable. - A priority of about 40000-80000 follows after the
maintable.
- Arrange more specific rules before less specific ones.
- Preferably use the
maintable only for tunnel endpoints. - Optionally use the
maintable for one of the upstream interfaces.- This can be useful in a trivial case to minimize configuration.
- It makes problematic to utilize rules with high numeric priority values.
Instructions
Route LAN to VPN and DMZ to WAN
Use custom routing tables and rules to prioritize routing LAN to VPN. Route DMZ to WAN by default.
for IPV in 4 6 do uci set network.lan.ip${IPV}table="1" uci set network.vpn.ip${IPV}table="2" uci set network.dmz.ip${IPV}table="3" uci -q delete network.lan_vpn${IPV%4} uci set network.lan_vpn${IPV%4}="rule${IPV%4}" uci set network.lan_vpn${IPV%4}.in="lan" uci set network.lan_vpn${IPV%4}.lookup="2" uci set network.lan_vpn${IPV%4}.priority="30000" done uci commit network /etc/init.d/network restart
Route LAN to VPN with failover to WAN
Use custom routing tables and rules to prioritize routing LAN to VPN. Route LAN to WAN as fallback when VPN is down.
for IPV in 4 6 do uci set network.lan.ip${IPV}table="1" uci set network.wan${IPV%4}.ip${IPV}table="2" uci -q delete network.lan_wan${IPV%4} uci set network.lan_wan${IPV%4}="rule${IPV%4}" uci set network.lan_wan${IPV%4}.in="lan" uci set network.lan_wan${IPV%4}.lookup="2" uci set network.lan_wan${IPV%4}.priority="40000" done uci commit network /etc/init.d/network restart
Route LAN to VPN by IP set
Route LAN traffic to VPN except destinations matching IP set. Mark LAN traffic with firewall to apply custom routing.
for IPV in 4 6 do uci -q delete firewall.wan_set${IPV%4} uci set firewall.wan_set${IPV%4}="ipset" uci set firewall.wan_set${IPV%4}.name="wan${IPV%4}" uci set firewall.wan_set${IPV%4}.family="ipv${IPV}" uci set firewall.wan_set${IPV%4}.match="net" uci -q delete firewall.lan_mark${IPV%4} uci set firewall.lan_mark${IPV%4}="rule" uci set firewall.lan_mark${IPV%4}.name="Mark-LAN-VPN" uci set firewall.lan_mark${IPV%4}.src="lan" uci set firewall.lan_mark${IPV%4}.dest="*" uci set firewall.lan_mark${IPV%4}.ipset="!wan${IPV%4} dest" uci set firewall.lan_mark${IPV%4}.proto="all" uci set firewall.lan_mark${IPV%4}.family="ipv${IPV}" uci set firewall.lan_mark${IPV%4}.set_mark="0x1" uci set firewall.lan_mark${IPV%4}.target="MARK" uci set network.lan.ip${IPV}table="1" uci set network.vpn.ip${IPV}table="2" uci -q delete network.lan_vpn${IPV%4} uci set network.lan_vpn${IPV%4}="rule${IPV%4}" uci set network.lan_vpn${IPV%4}.in="lan" uci set network.lan_vpn${IPV%4}.mark="1" uci set network.lan_vpn${IPV%4}.lookup="2" uci set network.lan_vpn${IPV%4}.priority="30000" done uci commit firewall uci commit network /etc/init.d/firewall restart /etc/init.d/network restart
Route LAN to VPN with WAN port forwarding
Route all traffic to VPN except a webserver running in LAN and serving to WAN. Mark the webserver traffic with firewall to apply custom routing.
uci -q delete firewall.lan_web uci set firewall.lan_web="rule" uci set firewall.lan_web.name="Mark-HTTPS" uci set firewall.lan_web.src="lan" uci set firewall.lan_web.src_mac="00:11:22:33:44:55" uci set firewall.lan_web.src_port="443" uci set firewall.lan_web.dest="*" uci set firewall.lan_web.proto="tcp" uci set firewall.lan_web.set_mark="0x1" uci set firewall.lan_web.target="MARK" for IPV in 4 6 do uci set network.lan.ip${IPV}table="1" uci set network.wan${IPV%4}.ip${IPV}table="2" uci -q delete network.lan_web${IPV%4} uci set network.lan_web${IPV%4}="rule${IPV%4}" uci set network.lan_web${IPV%4}.in="lan" uci set network.lan_web${IPV%4}.mark="1" uci set network.lan_web${IPV%4}.lookup="2" uci set network.lan_web${IPV%4}.priority="30000" done uci commit firewall uci commit network /etc/init.d/firewall restart /etc/init.d/network restart
Route LAN to OpenVPN
Use custom routing tables and rules to prioritize routing LAN to OpenVPN. Be sure to declare VPN interface and disable gateway redirection.
for IPV in 4 6 do uci set network.lan.ip${IPV}table="1" uci set network.vpn.ip${IPV}table="2" uci -q delete network.vpn_rt${IPV%4} uci set network.vpn_rt${IPV%4}="route${IPV%4}" uci set network.vpn_rt${IPV%4}.interface="vpn" uci -q delete network.lan_vpn${IPV%4} uci set network.lan_vpn${IPV%4}="rule${IPV%4}" uci set network.lan_vpn${IPV%4}.in="lan" uci set network.lan_vpn${IPV%4}.lookup="2" uci set network.lan_vpn${IPV%4}.priority="30000" done uci set network.vpn_rt.target="0.0.0.0/0" uci set network.vpn_rt6.target="::/0" uci commit network /etc/init.d/network restart
Kill switch using IP routes
Create prohibitive routes in the target routing table to prevent traffic leaks. Assuming the loopback interface is always up and the default route has a lower metric.
for IPV in 4 6 do uci set network.vpn.ip${IPV}table="2" uci -q delete network.vpn_ks${IPV%4} uci set network.vpn_ks${IPV%4}="route${IPV%4}" uci set network.vpn_ks${IPV%4}.interface="loopback" uci set network.vpn_ks${IPV%4}.type="prohibit" uci set network.vpn_ks${IPV%4}.metric="9000" uci set network.vpn_ks${IPV%4}.table="2" done uci set network.vpn_ks.target="0.0.0.0/0" uci set network.vpn_ks6.target="::/0" uci commit network /etc/init.d/network restart
Kill switch using IP rules
Create prohibitive rules to prevent traffic leaks. Assuming the custom rules use a lower numeric priority to override the prohibitive ones.
for IPV in 4 6 do uci -q delete network.lan_ks${IPV%4} uci set network.lan_ks${IPV%4}="rule${IPV%4}" uci set network.lan_ks${IPV%4}.in="lan" uci set network.lan_ks${IPV%4}.action="prohibit" uci set network.lan_ks${IPV%4}.priority="32000" done uci commit network /etc/init.d/network restart