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.
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..
@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?
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.
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.
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.
# 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"
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.
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.