VPN Policy-Based Routing + Web UI -- Discussion

Thanks. If one day I were to want to install a torrent client on lede, could I use this addon to direct that traffic out the tunnel? Or would I be better off trying to find a package that binds to an interface (I'm not sure if any of the lede packages exist that can do this, I haven't checked)?

You will need to enable OUTPUT chain in advanced settings to affect external traffic from the router itself.

1 Like

What criteria would I use to identify the torrent package traffic?

Uhm, good question, I don't know really. Doesn't it bind to a local port?

Hey mate, just wanted to say first up this thing is awesome, usually open source linuxy things just don't work for me but this has been great!

I have a bit of an odd issue at the moment, have only noticed it on latest update to 0.0.1-16. What appears to be happening is if I make a change in the GUI on an existing rule to change which interface it will use, the entry in the PREROUTING chain doesn't seem to get updated. If i restart the vpn-policy-routing service in CLI then it works fine, so it seems at least for me that hitting save in the GUI doesn't actually update iptables.

I can probably put all the config up but an example is as below. I have two nordvpn tunnels setup, tun0 and tun1, which in LEDE are interface names nordvpntun and nordvpntun1 respectively.
What I have done to arrive at the below output is config for kuja working as expected on tun0, then in the GUI I change kuja to use tun1, which updates in /etc/config/vpn-policy-routing but seems nowhere else.
After making the change I would expect the PREROUTING rule for kuja to change from 0x30000 to 0x40000, but this will only happen if I manually restart the vpn-policy-routing service on the CLI.

/etc/config/vpn-policy-routing:
config vpn-policy-routing 'config'
option verbosity '2'
option strict_enforcement '1'
option dnsmasq_enabled '1'
option enabled '1'

config policy
option comment 'Kuja'
option local_addresses '192.168.1.253'
option interface 'nordvpntun1'

Relevant lines from /etc/init.d/vpn-policy-routing support:
IP Rules
32742: from all fwmark 0x40000 lookup 204
32743: from all fwmark 0x30000 lookup 203

IP Route Tables
IPv4 Table 203: default via 10.x.x.x dev tun0
IPv4 Table 204: default via 10.x.x.x dev tun1

iptables rules
-A VPR_PREROUTING -s 192.168.1.253/32 -m comment --comment Kuja -c 5157 717410 -j MARK --set-xmark 0x30000/0xff0000
-A VPR_PREROUTING -m set --match-set nordvpntun1 dst -c 0 0 -j MARK --set-xmark 0x40000/0xff0000
-A VPR_PREROUTING -m set --match-set nordvpntun dst -c 0 0 -j MARK --set-xmark 0x30000/0xff0000

I have a question for anyone who's used this great service (and @stangri too):

I am aware we need to use

option route_nopull '1'

In the configuration file to prevent the VPN from adding default routes to the routing table.

However, I just encountered an issue where basically due to the option above, the VPN server isn't pushing the DNS to the client (my router) either, causing a DNS leak.

Has anyone come accross this problem or knows of a solution?

EDIT: To make it clearer, I would like to use the DNS that's pushed by the openvpn server (using dhcp-option), and not a custom OpenDNS/Google DNS.
However, dhcp-option are not applied when using route_nopull.

Thanks!

1 Like

You can push manually your favourite DNS server to go through the tunnel.

route 8.8.8.8 255.255.255.255 vpn_gateway

in your openvpn client config for the google dns server.

1 Like

Thanks.
I understand that, however, I want to use the DNS that's pushed by the OpenVPN server on the tun0/tun1 interfaces (but it's prevented from being pushed due to route_npull 1).

Any ideas?

I have the same issue and never really figured it out. It would be great if someone could provide a quick guide on how to do this.

Another option is to use

route-noexec

instead of

route-nopull

The OpenVPN manual does state

--route-noexec
Don't add or remove routes automatically. Instead pass routes to --route-up script using environmental variables.

I tested this without specifying any route script and it has pulled settings such as DNS server, but not routes.

1 Like

Wow, just discovered this today and it's great! One issue, the DSCP field doesn't seem to make an iptables rule.

config vpn-policy-routing 'config'
        option verbosity '2'
        option ipv6_enabled '0'
        option ipset_enabled '1'
        option dnsmasq_enabled '0'
        option strict_enforcement '1'
        option enabled '1'
        option vpn_dscp '22'

root@LEDE:~# /etc/init.d/vpn-policy-routing support                                                        vpn-policy-routing 0.0.1-16 running on LEDE 17.01.4. WAN (IPv4): wan/dev/65.XX.XX.XX. WAN (IPv6): wan/dev6/....
============================================================
Dnsmasq version 2.78  Copyright (c) 2000-2017 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-DNSSEC no-ID loop-detect inotify
============================================================
Routes/IP Rules
default         65.XX.XX.XX     0.0.0.0         UG    0      0        0 eth1
32533:  from all fwmark 0x20000 lookup 202
32534:  from all fwmark 0x10000 lookup 201
32613:  from all fwmark 0x30000 lookup 203
IPv4 Table 201: default via 65.XX.XX.XX dev eth1
IPv4 Table 202: default via 10.XX.XX.5 dev tun0
IPv4 Table 203: default via 10.XX.XX.5 dev tun0
============================================================
IP Tables PREROUTING
-N VPR_PREROUTING
-A VPR_PREROUTING -m set --match-set vpn dst -c 0 0 -j MARK --set-xmark 0x20000/0xff0000
-A VPR_PREROUTING -m set --match-set wan dst -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
============================================================

I set up the rule manually on the router to mark dscp=22 with the packet marking for tun0 then the traffic starts going through the VPN.
root@LEDE $ iptables -A VPR_PREROUTING -t mangle -m dscp --dscp 22 -j MARK --set-xmark 0x20000/0xff0000

Thank you @stangri !

1 Like

My bad, should be fixed in 0.0.1-17. If you have my repo, do opkg update/upgrade.

1 Like

Are IPsec based VPN using virtual tunnel interfaces (VTI) supported, for example Strongswan with VTI?

Hi all,

I am trying to get OpenVPN server and client to work at the same time using this guide, but not sure what or where the issue is. Both server and client work fine independently.

Config files included below.

/etc/config/vpn-policy-routing

config policy
	option comment 'OpenVPN Server'
	option local_ports '1194'
	option interface 'wan'

    config vpn-policy-routing 'config'
    	option verbosity '2'
    	option ipv6_enabled '1'
    	option strict_enforcement '1'
    	option dnsmasq_enabled '1'
    	option output_chain_enabled '1'
    	list ignored_interface 'vpnserver'
    	option enabled '1'

/etc/init.d/vpn-policy-routing support

root@LEDE:~# /etc/init.d/vpn-policy-routing support
vpn-policy-routing 0.0.1-16 running on Lede SNAPSHOT. WAN (IPv4): wan/dev/172.16                                                                                        .0.1. WAN (IPv6): wan/dev6/fe80::/64.
============================================================
Dnsmasq version 2.78  Copyright (c) 2000-2017 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua                                                                                         TFTP conntrack ipset auth DNSSEC no-ID loop-detect inotify
============================================================
Routes/IP Rules
default         172.21.32.1     128.0.0.0       UG    0      0        0 tun0
default         172.16.0.1      0.0.0.0         UG    0      0        0 eth1.2
32760:  from all fwmark 0x20000 lookup 202
32761:  from all fwmark 0x10000 lookup 201
IPv4 Table 201: default via 172.16.0.1 dev eth1.2
IPv4 Table 202: default via 172.21.32.1 dev tun0
============================================================
IP Tables PREROUTING
-  ARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -p tcp -m multiport --sports 1194 -m comment --comment OpenVPN                                                                                        _Server -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -m set --match-set VPN_FW dst -c 0 0 -j MARK --set-xmark 0x200                                                                                        00/0xff0000
-A VPR_PREROUTING -m set --match-set wan dst -c 140 15962 -j MARK --set-xmark 0x                                                                                        10000/0xff0000
============================================================
IP6 Tables PREROUTING
-N VPR_PREROUTING
-A VPR_PREROUTING -p tcp -m multiport --sports 1194 -m comment --comment OpenVPN                                                                                        _Server -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_PREROUTING -m set --match-set VPN_FW6 dst -c 0 0 -j MARK --set-xmark 0x20                                                                                        000/0xff0000
-A VPR_PREROUTING -m set --match-set wan6 dst -c 0 0 -j MARK --set-xmark 0x10000                                                                                        /0xff0000
============================================================
IP Tables OUTPUT
-N VPR_OUTPUT
-A VPR_OUTPUT -p tcp -m multiport --sports 1194 -m comment --comment OpenVPN_Ser                                                                                        ver -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_OUTPUT -m set --match-set VPN_FW dst -c 0 0 -j MARK --set-xmark 0x20000/0                                                                                        xff0000
-A VPR_OUTPUT -m set --match-set wan dst -c 0 0 -j MARK --set-xmark 0x10000/0xff                                                                                        0000
============================================================
IPv6 Tables OUTPUT
-N VPR_OUTPUT
-A VPR_OUTPUT -p tcp -m multiport --sports 1194 -m comment --comment OpenVPN_Ser                                                                                        ver -c 0 0 -j MARK --set-xmark 0x10000/0xff0000
-A VPR_OUTPUT -m set --match-set VPN_FW6 dst -c 0 0 -j MARK --set-xmark 0x20000/                                                                                        0xff0000
-A VPR_OUTPUT -m set --match-set wan6 dst -c 0 0 -j MARK --set-xmark 0x10000/0xf                                                                                        f0000
============================================================
Current ipsets
create wan hash:net family inet hashsize 1024 maxelem 65536 comment
add wan X.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
add wan x.x.x.x
create wan6 hash:net family inet6 hashsize 1024 maxelem 65536 comment
create VPN_FW hash:net family inet hashsize 1024 maxelem 65536 comment
create VPN_FW6 hash:net family inet6 hashsize 1024 maxelem 65536 comment
============================================================
DNSMASQ ipsets
============================================================
Your support details have been logged to '/var/vpn-policy-routing-support'. [✓]

/etc/init.d/vpn-policy-routing reload

root@LEDE:~# /etc/init.d/vpn-policy-routing reload
Creating table 'wan/eth1.2/172.16.0.1/fe80::/64' [✓]
Creating table 'VPN_FW/tun0/172.21.32.1/fe80::779f:5d7e:6b50:1' [✓]
Routing 'OpenVPN Server' via wan [✓]
vpn-policy-routing 0.0.1-16 started on wan/eth1.2/172.16.0.1/fe80::/64 VPN_FW/tun0/172.21.32.1/fe80::779f:5d7e:6b50:1 [✓]
vpn-policy-routing 0.0.1-16 monitoring interfaces: wan VPN_FW [✓]

/etc/config/firewall

config defaults
	option syn_flood '1'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

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

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

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 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option src_ip 'fc00::/6'
	option dest_ip 'fc00::/6'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config zone
	option forward 'REJECT'
	option output 'ACCEPT'
	option name 'Guest'
	option input 'REJECT'
	option network 'Guest'

config rule
	option target 'ACCEPT'
	option proto 'tcp udp'
	option dest_port '53'
	option name 'Guest DNS'
	option src 'Guest'

config rule
	option target 'ACCEPT'
	option proto 'tcp udp'
	option dest_port '67-68'
	option name 'Guest DHCP'
	option src 'Guest'

config forwarding
	option dest 'wan'
	option src 'Guest'

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

config include 'miniupnpd'
	option type 'script'
	option path '/usr/share/miniupnpd/firewall.include'
	option family 'any'
	option reload '1'

config rule
	option name 'Allow-OpenVPN-Inbound'
	option target 'ACCEPT'
	option src '*'
	option proto 'tcpudp'
	option dest_port '1194'

config zone
	option name 'vpnserver'
	option input 'ACCEPT'
	option forward 'REJECT'
	option output 'ACCEPT'
	option masq '1'
	option network 'vpnserver'

config forwarding
	option src 'vpnserver'
	option dest 'wan'

config forwarding
	option src 'vpnserver'
	option dest 'lan'

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

config forwarding
	option dest 'VPN_FW'
	option src 'lan'

config forwarding
	option src 'vpnserver'
	option dest 'VPN_FW'

/etc/config/openvpn

config openvpn 'custom_config'
	option config '/etc/openvpn/my-vpn.conf'

config openvpn 'vpnserver'
	option enabled '1'
	option dev_type 'tun'
	option dev 'ovpns0'
	option port '1194'
	option comp_lzo 'yes'
	option keepalive '10 120'
	option persist_key '1'
	option persist_tun '1'
	option ca '/etc/openvpn/ca.crt'
	option cert '/etc/openvpn/my-server.crt'
	option key '/etc/openvpn/my-server.key'
	option dh '/etc/openvpn/dh2048.pem'
	option tls_auth '/etc/openvpn/tls-auth.key 0'
	option mode 'server'
	option tls_server '1'
	option server '192.168.200.0 255.255.255.0'
	option topology 'subnet'
	option route_gateway 'dhcp'
	option client_to_client '1'
	option log '/tmp/openvpn.log'
	option verb '5'
	list push 'comp-lzo yes'
	list push 'persist-key'
	list push 'persist-tun'
	list push 'topology subnet'
	list push 'route-gateway dhcp'
	list push 'redirect-gateway def1'
	list push 'route 192.168.200.0 255.255.255.0'
	list push 'dhcp-option DNS 192.168.1.1'
	option proto 'tcp'

I can probably do a custom build for you to test, but I'll need some information from you first. PM me for details.

Without having seen complete /etc/config/openvpn file, my only suggestion would be to disable IPv6 for vpn-policy-routing.

Are you saying you have not had a chance to fully look at my etc/config/openvpn I posted, or what I have posted is incorrect? I disabled IPv6 but still the same issue.

Changed the connecting port to TCP and it now works fine.

Thanks for the guide write up.

I tried this and it still didn't work.

The only option that works is manually pushing the OpenVPN Server's DNS to the clients. This will work in cases where you have traffic routed through the VPN tunnel from a whole interface/DHCP range. But for Domain-based policies, the only DNS that gets used is the WAN's DNS.

Sorry, I keep missing a post here or there and only come to find them again a week or so later.

Please confirm that you're clicking "SAVE & APPLY" when you finish making changes in Web UI and that still doesn't result in the service being reloaded with the new changes taking effect?

Hi @stangri, apologies, should have tagged you in the post.

I meant to reply sooner, I also found the same situation when using uci so it's not specific to using the GUI. I've also just updated vpn-policy-routing and luci-app-vpn-policy-routing with the same results.

Please see below output, hopefully shows what I'm experiencing. Steps are:
-Show commands for uci config and iptables being in line
-uci update and commit
-Show commands for updated uci config but iptables has not updated.
-Restarting the service then another show of iptables being updated correctly.

root@jenova:~# uci show vpn-policy-routing.@policy[0]
vpn-policy-routing.cfg036ff5=policy
vpn-policy-routing.cfg036ff5.comment='Kuja'
vpn-policy-routing.cfg036ff5.local_addresses='192.168.1.253'
vpn-policy-routing.cfg036ff5.interface='nordvpntun'
root@jenova:~# iptables -L VPR_PREROUTING -t mangle
Chain VPR_PREROUTING (1 references)
target     prot opt source               destination
MARK       all  --  ps4.midgar           anywhere             /* PS4 */ MARK xset 0x10000/0xff0000
MARK       all  --  192.168.1.0/24       10.1.0.0/28          /* LAN_to_VPN_Clients */ MARK xset 0x20000/0xff0000
MARK       all  --  192.168.1.64/26      anywhere             /* DHCP_LAN_Clients */ MARK xset 0x10000/0xff0000
MARK       all  --  samsunght.midgar     anywhere             /* Samsung_HT */ MARK xset 0x10000/0xff0000
MARK       all  --  kuja.midgar          anywhere             /* Kuja */ MARK xset 0x30000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun1 dst MARK xset 0x40000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun dst MARK xset 0x30000/0xff0000
MARK       all  --  anywhere             anywhere             match-set vpnsvr0 dst MARK xset 0x20000/0xff0000
MARK       all  --  anywhere             anywhere             match-set wan dst MARK xset 0x10000/0xff0000
root@jenova:~# uci set vpn-policy-routing.@policy[0].interface=nordvpntun1
root@jenova:~# uci commit
root@jenova:~# uci show vpn-policy-routing.@policy[0]
vpn-policy-routing.cfg036ff5=policy
vpn-policy-routing.cfg036ff5.comment='Kuja'
vpn-policy-routing.cfg036ff5.local_addresses='192.168.1.253'
vpn-policy-routing.cfg036ff5.interface='nordvpntun1'
root@jenova:~# iptables -L VPR_PREROUTING -t mangle
Chain VPR_PREROUTING (1 references)
target     prot opt source               destination
MARK       all  --  ps4.midgar           anywhere             /* PS4 */ MARK xset 0x10000/0xff0000
MARK       all  --  192.168.1.0/24       10.1.0.0/28          /* LAN_to_VPN_Clients */ MARK xset 0x20000/0xff0000
MARK       all  --  192.168.1.64/26      anywhere             /* DHCP_LAN_Clients */ MARK xset 0x10000/0xff0000
MARK       all  --  samsunght.midgar     anywhere             /* Samsung_HT */ MARK xset 0x10000/0xff0000
MARK       all  --  kuja.midgar          anywhere             /* Kuja */ MARK xset 0x30000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun1 dst MARK xset 0x40000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun dst MARK xset 0x30000/0xff0000
MARK       all  --  anywhere             anywhere             match-set vpnsvr0 dst MARK xset 0x20000/0xff0000
MARK       all  --  anywhere             anywhere             match-set wan dst MARK xset 0x10000/0xff0000
root@jenova:~#
root@jenova:~# service vpn-policy-routing restart
vpn-policy-routing 0.0.1-17b07 stopped [✓]
Creating table 'wan/eth1/<snip>' [✓]
Creating table 'vpnsvr0/tunsvr0/10.1.0.1' [✓]
Creating table 'nordvpntun/tun0/10.8.8.33' [✓]
Creating table 'nordvpntun1/tun1/10.8.8.5' [✓]
Routing 'Kuja' via nordvpntun1 [✓]
Routing 'Samsung HT' via wan [✓]
Routing 'DHCP LAN Clients ' via wan [✓]
Routing 'LAN to VPN Clients' via vpnsvr0 [✓]
Routing 'PS4' via wan [✓]
vpn-policy-routing 0.0.1-17b07 started on wan/eth1/<snip> vpnsvr0/tunsvr0/10.1.0.1 nordvpntun/tun0/10.8.8.33 nordvpntun1/tun1/10.8.8.5 [✓]
vpn-policy-routing 0.0.1-17b07 monitoring interfaces: wan vpnsvr0 nordvpntun nordvpntun1 [✓]
root@jenova:~# iptables -L VPR_PREROUTING -t mangle
Chain VPR_PREROUTING (1 references)
target     prot opt source               destination
MARK       all  --  ps4.midgar           anywhere             /* PS4 */ MARK xset 0x10000/0xff0000
MARK       all  --  192.168.1.0/24       10.1.0.0/28          /* LAN_to_VPN_Clients */ MARK xset 0x20000/0xff0000
MARK       all  --  192.168.1.64/26      anywhere             /* DHCP_LAN_Clients */ MARK xset 0x10000/0xff0000
MARK       all  --  samsunght.midgar     anywhere             /* Samsung_HT */ MARK xset 0x10000/0xff0000
MARK       all  --  kuja.midgar          anywhere             /* Kuja */ MARK xset 0x40000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun1 dst MARK xset 0x40000/0xff0000
MARK       all  --  anywhere             anywhere             match-set nordvpntun dst MARK xset 0x30000/0xff0000
MARK       all  --  anywhere             anywhere             match-set vpnsvr0 dst MARK xset 0x20000/0xff0000
MARK       all  --  anywhere             anywhere             match-set wan dst MARK xset 0x10000/0xff0000
1 Like