Feature Request: Policy Based Routing

Policy Based Routing :

Allow Routing to a Specific Interface - WAN or VPN , by Client (Ip address or MAC), Network (Subnet) or ALL Traffic.

Allow by Single IP, a list of IP addresses, Subnet, ALL, Also allow routing of a List of FQDN to a specific WAN interface/VPN.

Blockquote

4 Likes

You can do this via CLI (not sure if it sticks) but would be great to do it via UI tbh.

2 Likes

How can you configure it via CLI?

Wouldn’t happen to have any kind of write up to do this via cli would you?

1 Like

Create rc.local under /cfg. So path for file would be /cfg/rc.local/

And this is my config to route over mullvad.

#!/bin/ash

# === WireGuard Interface ===
if ! uci show network | grep -q "^network.wg0="; then
    uci set network.wg0='interface'
    uci set network.wg0.proto='wireguard'
    uci set network.wg0.private_key='YOUR_PRIVATE_KEY_HERE'
    uci set network.wg0.addresses='YOUR_VPN_ADDRESS/32'
    uci set network.wg0.peerdns='0'
    uci add_list network.wg0.dns='YOUR_DNS_SERVER'
fi

# === WireGuard Peer ===
if ! uci show network | grep -q "network.@wireguard_wg0"; then
    uci add network wireguard_wg0
    uci set network.@wireguard_wg0[-1].public_key='PEER_PUBLIC_KEY_HERE'
    uci set network.@wireguard_wg0[-1].allowed_ips='0.0.0.0/0'
    uci set network.@wireguard_wg0[-1].endpoint_host='VPN_SERVER_HOST'
    uci set network.@wireguard_wg0[-1].endpoint_port='51820'
    uci set network.@wireguard_wg0[-1].persistent_keepalive='25'
fi

uci commit network
/etc/init.d/network reload
ifup wg0

# === Firewall Zone for WireGuard ===
if ! uci show firewall | grep -q "firewall.wg0_zone"; then
    uci set firewall.wg0_zone="zone"
    uci set firewall.wg0_zone.name="wg0"
    uci set firewall.wg0_zone.network="wg0"
    uci set firewall.wg0_zone.input="ACCEPT"
    uci set firewall.wg0_zone.output="ACCEPT"
    uci set firewall.wg0_zone.forward="REJECT"
    uci set firewall.wg0_zone.masq="1"
    uci set firewall.wg0_zone.mtu_fix="1"
fi

if ! uci get firewall.@zone[2].network | grep -q 'wg0'; then
    uci add_list firewall.@zone[2].network='wg0'
fi

# === Example Custom Firewall Rule (LAN subnet blocked from WAN) ===
if ! uci show firewall | grep -q "Block_LAN_Subnet_to_WAN"; then
    uci add firewall rule
    uci set firewall.@rule[-1].name='Block_LAN_Subnet_to_WAN'
    uci set firewall.@rule[-1].src='lan'
    uci set firewall.@rule[-1].src_ip='YOUR_SUBNET/24'
    uci set firewall.@rule[-1].dest='wan'
    uci set firewall.@rule[-1].proto='all'
    uci set firewall.@rule[-1].target='REJECT'
    uci set firewall.@rule[-1].enabled='1'
fi

uci commit firewall
/etc/init.d/firewall restart

# === Routing Table and Rules ===
grep -q "wgroute" /etc/iproute2/rt_tables || echo "200 wgroute" >> /etc/iproute2/rt_tables

ip route show table wgroute | grep -q "^default" || ip route add default dev wg0 table wgroute

ip rule | grep -q "from YOUR_SUBNET/24.*table wgroute" || ip rule add from YOUR_SUBNET/24 table wgroute priority 300
ip rule | grep -q "to YOUR_LOCAL_NET/24.*lookup main" || ip rule add to YOUR_LOCAL_NET/24 lookup main

# === Custom Restart on Firewall Reload ===
grep -q "/cfg/rc.local restart" /etc/init.d/firewall || sed -i '/reload_service()/a\        /cfg/rc.local restart' /etc/init.d/firewall

exit 0

I have the if statements in there because everytime you make a change in the ui it reloads this and it will just keep adding the same interface over and over but with the if statements it checks if its already there. Ive had this running for a few months with no issues, its persistent with every reboot and update.

3 Likes

I really appreciate this. I have been trying to get code from openwrt working but failing every time. If this works I can finally move to a route 10. Really wish it was just native..

1 Like

No problem, you can verify the link with wg show once you set it up.

1 Like

@dalewhlrr Thanks for the script. I tried it and I got the following errors. I have IPv6 on my WAN.

* Populating IPv6 nat table
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_lan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_lan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_wan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_wan_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_vpn_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_vpn_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_vpnMasq_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_vpnMasq_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_wg0_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_wg0_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'prerouting_rule'
Warning: fw3_ipt_rule_append(): Can't find target 'postrouting_rule'
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'vpn'
   * Zone 'vpnMasq'
   * Zone 'wg0'
 * Populating IPv6 mangle table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'vpn'
   * Zone 'vpnMasq'
   * Zone 'wg0'
 * Populating IPv6 raw table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'vpn'
   * Zone 'vpnMasq'
   * Zone 'wg0'
 * Set tcp_ecn to off
 * Set tcp_syncookies to on
 * Set tcp_window_scaling to on
 * Running script '/etc/firewall.user'
 * Running script '/etc/firewall.d/qca-nss-ecm'
 * Running script '/etc/firewall.d/ndpi'
iptables v1.8.7 (legacy): Couldn't load target `ndpi':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.
iptables: No chain/target/match by that name.
iptables: No chain/target/match by that name.
ip6tables v1.8.7 (legacy): Couldn't load target `ndpi':No such file or directory

Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables: No chain/target/match by that name.
ip6tables: No chain/target/match by that name.
iptables v1.8.7 (legacy): Couldn't load target `ndpi-pr':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.
iptables: No chain/target/match by that name.
iptables: No chain/target/match by that name.
ip6tables v1.8.7 (legacy): Couldn't load target `ndpi-pr':No such file or directory

Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables: No chain/target/match by that name.
ip6tables: No chain/target/match by that name.
 * Running script '/etc/firewall.d/ndpi-filter'
iptables v1.8.7 (legacy): Couldn't load target `ndpi-filter':No such file or directory

Try `iptables -h' or 'iptables --help' for more information.
iptables: No chain/target/match by that name.
iptables: No chain/target/match by that name.
ip6tables v1.8.7 (legacy): Couldn't load target `ndpi-filter':No such file or directory

Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables: No chain/target/match by that name.
ip6tables: No chain/target/match by that name.
   ! Failed with exit code 1
 * Running script '/usr/share/miniupnpd/firewall.include'
Dump terminatedtype or paste code here

Also what is the difference of YOUR_SUBNET and YOUR_LOCAL_NET? The subnet that I want to use Surfshark to, for example, is 10.10.10.0/24 (YOUR_SUBNET), what will be the value of YOUR_LOCAL_NET?

1 Like

Oh those two lines of rules you don’t necessarily need, I have those in there so the network going over the vpn can still reach my nas. So your subnet would be the vlan thats going over the vpn and local subnet would be another subnet you want that network to still be able to access.

2 Likes

I know a user has given us an excellent script but I was just wondering if this is even being worked? Also if it is it would be nice if each quarter that alta would state what feature requests they are willing to take up and work. Then perhaps provide a quarterly status update of the progress. I’ve been waiting for built in policy based routing for over a year at this point but also really hoping it comes with domain based routing. So you can have the router keep a list of domain ips to route over the VPN. Anyways I’ve been using alta on and off and this is one of the last features I really need. If you are wondering “why not just run the VPN all the time?” It’s because so many places are abused these days that vpn is heavily blocked or you have to go over many hoops. So I only want the VPN for specific domains.

1 Like

This is a good feature to add to the wg-pbr project that I shared to the community. Let me see if I can work on it.

2 Likes

This is what I use in Asus Merlin on an axe16000. It works really well.

https://raw.githubusercontent.com/Ranger802004/asusmerlin/main/domain_vpn_routing/domain_vpn_routing.sh

Here you go, domain based routing. I’ve been testing this feature. I’m not ready to merge this to the main branch. Send me a private message if you find bugs, or open an issue in Github.

https://github.com/unflawed-code/route10-wireguard-client/tree/feature/split-tunnel-domain

# Split-Tunnel (Domain-based): Route specific domains through wg0
# Works for VPNs that support IPv4 and/or IPv6
# Affects clients that are not routed to another VPN

./wg-pbr.sh wg0 -c /path/to-your/wg.conf -d "whatismyipaddress.com,ipleak.net"
2 Likes

Why do I have to drop to CLI to configure this?

Honestly seems like most things on Alta are CLI or editing the post-cfg.sh file #_# well if you want 3rd party stuff I guess. Would be neat to see something like asus-merlin has with AMTM. Like a package manager of sorts.

My busness and enterprise clients have no time for that. Its for this reason I use UniFi ZBF and pfSense/OPNsense.

The days of CLI are over we use SDNs like UniFi instead for deployments. Time is money in my industry.

Yeah.. it was weird for me when I started trying to force myself to change over to the route10. Don’t get me wrong I use SSH sometimes on my old router but it was mostly because it was faster to get the information I wanted but yeah I wish the gui was more filled out as it seems kind of the same for a long time as I started testing alta route 10 a little after release. I will say the script that @Unflawed made works really well but I also would prefer to use the GUI for things. I’m pretty experienced in a lot of different things but since the documentation doesn’t cover certain things like how I had to enable UDP hardware acceleration. It was weird that there isn’t an option for that in the GUI but there is an option to enable/disable hardware acceleration.

You don’t say this because you don’t have time. Vyos is pure cli and they have enterprise customers. Power users use the cli to make some things work in pfSense, OPNSense or Unifi OS.

1 Like

Agreed Vyos is great, We don’t use that here. So, ease of deployment, administration is crucial.