What's new

Selective routing, DNS servers and opening ports with OpenVPN

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Bogey

Regular Contributor
Hi guys,

Selective routing is working brilliant with these two scripts route-up.sh and route-down.sh, both are defined in custom configuration (see below for the code). I found these scripts here, and they don't use the route-nopull directive.

As you can see I have only one 'real' rule active at the moment:
Code:
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.103 ! --dport 587 -j MARK --set-mark $MARK
So all traffic to and from my NAS goes through the VPN, except for port 587. These are notification emails via Gmail, and Gmail (temporarily) locks the account when the account is accessed from too different locations (e.g. at one time it's Switzerland, the next time it's from the US - all depending on the VNP server used).

This works, no problem there. Also torrenting with Transmission seems to work. However, I don't think it's done properly as my download speed is low. I suspect this is because there's no specific 'peer-port' assigned (the famous default port 51413). How can I do this? My VPN provider AirVPN offers port forwarding at their servers and I have one assigned. So now I need to open a port on my router and/or redirect traffic?
Q1) How can I get Transmission to see the peer-port as open?
By using port forwarding in the Asus-wrt interface or by adding these (or other) rules to firewall-start script?
Code:
iptables -D FORWARD -s 192.168.0.103 -p tcp --dport 51413 -j ACCEPT
iptables -D FORWARD -s 192.168.0.103 -p udp --dport 51413 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 -p tcp --dport 51413 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 -p udp --dport 51413 -j ACCEPT

It also seems there's no DNS assigned. So when I enter manually a DNS in the WAN DNS Setting, it can find websites, but... isn't this DNS leakage? My guess is, that it is.
My VPN provider AirVPN has DNS servers available, but these are in the 10.x.x.x range, so they only work when the VPN is active.
Q2) So how can I assign DNS servers only for the VPN and use my regular DNS for regular WAN traffic?

Speaking of leakage, I don't have any firewall settings yet. I read the Github page by Rmerlin to add the following to firewall-start:
Code:
#!/bin/sh
sleep 4
iptables -I FORWARD -i br0 -o tun11 -j ACCEPT
iptables -I FORWARD -i tun11 -o br0 -j ACCEPT
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 -j DROP
iptables -I INPUT -i tun11 -j REJECT
iptables -t nat -A POSTROUTING -o tun11 -j MASQUERADE
Q3) So my third question is, will these rules prevent all traffic or should I alter the 3rd line, so email notification via gmail is still possible, to this:
Code:
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 ! --dport 587 -j DROP

Thanks for your help,
Erwin


route-up.sh :
Code:
#!/bin/sh -x
(

TID="200"
MARK="0x88"
WS="[[:space:]]"
WAN_GTWY="$route_net_gateway"       # provided by OpenVPN at runtime
WAN_IF="$(route | grep -Em1 ^${WAN_GTWY}${WS} | awk '{print $NF}')"
VPN_GTWY="$route_vpn_gateway"       # provided by OpenVPN at runtime
VPN_IF="$dev"                       # provided by OpenVPN at runtime
REDIRECT_GTWY="$redirect_gateway"   # provided by OpenVPN at runtime

# copy default/main routing table (exclude all default gateways)
ip route flush table $TID > /dev/null 2>&1
ip route show table main | grep -Ev "^default|^0.0.0.0/1${WS}|^128.0.0.0/1${WS}" \
  | while read route; do
        ip route add $route table $TID
    done
# add VPN as default gateway
ip route add default via $VPN_GTWY table $TID

# add WAN back as default gateway in main/default routing table
if [ "$REDIRECT_GTWY" == "1" ]; then
    ip route add 0.0.0.0/2   via $WAN_GTWY
    ip route add 64.0.0.0/2  via $WAN_GTWY
    ip route add 128.0.0.0/2 via $WAN_GTWY
    ip route add 192.0.0.0/2 via $WAN_GTWY
fi

# disable WAN/VPN reverse path filtering
echo 0 > /proc/sys/net/ipv4/conf/$WAN_IF/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/$VPN_IF/rp_filter

# clear the routing cache (or else it won't recognize our changes)
ip route flush cache

# route over VPN based on source IP(s)/network(s) or network interface
#ip rule add from 192.168.0.103  table $TID
# ip rule add from 10.10.1.113  table $TID
# ip rule add from 10.10.2.0/24 table $TID
# ip rule add iif wl0.1 table $TID

# route over VPN based on other criteria (e.g., protocol, source/destination port)
# iptables -t mangle -A PREROUTING -p tcp -s 10.10.1.42 --sport 22 -j MARK --set-mark $MARK
# iptables -t mangle -A PREROUTING -p tcp -s 10.10.1.155 --sport 80 -j MARK --set-mark $MARK
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.103 ! --dport 587 -j MARK --set-mark $MARK
#iptables -t mangle -A PREROUTING -p tcp ! --dport 2095 -j MARK --set-mark $MARK
# iptables -t mangle -A PREROUTING -s jims-ipod -j MARK --set-mark $MARK
# iptables -t mangle -A PREROUTING -m mac --mac-source 00:11:22:33:44:55 -j MARK --set-mark $MARK

# start processing marked packets through the alternate routing table
ip rule add fwmark $MARK table $TID

) 2>&1 | logger -t $(basename $0)[$$]

route-down.sh:
Code:
#!/bin/sh -x
(

TID="200"
MARK="0x88"
WS="[[:space:]]"
WAN_GTWY="$route_net_gateway"       # provided by OpenVPN at runtime
WAN_IF="$(route | grep -Em1 ^${WAN_GTWY}${WS} | awk '{print $NF}')"
VPN_GTWY="$route_vpn_gateway"       # provided by OpenVPN at runtime
VPN_IF="$dev"                       # provided by OpenVPN at runtime
REDIRECT_GTWY="$redirect_gateway"   # provided by OpenVPN at runtime

# remove routes based on source IP(s)/network(s) or network interface
#ip rule del from 192.168.0.103  table $TID
# ip rule del from 10.10.1.113  table $TID
# ip rule del from 10.10.2.0/24 table $TID
# ip rule del iif wl0.1 table $TID

# remove routes based on other criteria (e.g., protocol, source/destination port)
# iptables -t mangle -D PREROUTING -p tcp -s 10.10.1.42 --sport 22 -j MARK --set-mark $MARK
# iptables -t mangle -D PREROUTING -p tcp -s 10.10.1.155 --sport 80 -j MARK --set-mark $MARK
iptables -t mangle -D PREROUTING -p tcp -s 192.168.0.103 ! --dport 587 -j MARK --set-mark $MARK
#iptables -t mangle -D PREROUTING -p tcp ! --dport 2095 -j MARK --set-mark $MARK
# iptables -t mangle -D PREROUTING -s jims-ipod -j MARK --set-mark $MARK
# iptables -t mangle -D PREROUTING -m mac --mac-source 00:11:22:33:44:55 -j MARK --set-mark $MARK

# stop processing marked packets through the alternate routing table
ip rule del fwmark $MARK table $TID

# remove WAN as default gateway in main/default routing table
if [ "$REDIRECT_GTWY" == "1" ]; then
    ip route del 0.0.0.0/2   via $WAN_GTWY
    ip route del 64.0.0.0/2  via $WAN_GTWY
    ip route del 128.0.0.0/2 via $WAN_GTWY
    ip route del 192.0.0.0/2 via $WAN_GTWY
fi

# re-enable WAN/VPN reverse path filtering
echo 1 > /proc/sys/net/ipv4/conf/$WAN_IF/rp_filter
echo 1 > /proc/sys/net/ipv4/conf/$VPN_IF/rp_filter > /dev/null 2>&1

# clear the alternate routing table and routing cache
ip route flush table $TID
ip route flush cache

) 2>&1 | logger -t $(basename $0)[$$]

custom configuration:
Code:
script-security 2

route-up /jffs/scripts/route-up.sh
route-pre-down /jffs/scripts/route-down.sh
 
iptables -I FORWARD -i tun11 -p udp -d 192.168.2.42 --dport 12345 -j ACCEPT

iptables -I FORWARD -i tun11 -p tcp -d 192.168.2.42 --dport 12345 -j ACCEPT

iptables -t nat -I PREROUTING -i tun11 -p tcp --dport 12345 -j DNAT --to-destination 192.168.2.42

iptables -t nat -I PREROUTING -i tun11 -p udp --dport 12345 -j DNAT --to-destination 192.168.2.42

this is how you port forward from the TUN device (openvpn client) to a LAN client. Not sure how you'll need to change it for the transmission client within the router. Of course, change tun device, port, and LAN client IP where applicable.
 
Thanks!

Indeed, it's Transmission on the NAS, not within the router.
And I put those rules in the firewall-start script, or just the FORWARD, and the PREROUTING in the route-up.sh script?

Btw, do these PREROUTING rules do double duty, when I have an 'all-forward-except-port-587' rule in my route-up.sh script? I mean, is:
Code:
iptables -t nat -I PREROUTING -i tun11 -p tcp --dport 12345 -j DNAT --to-destination 192.168.2.42
iptables -t nat -I PREROUTING -i tun11 -p udp --dport 12345 -j DNAT --to-destination 192.168.2.42
covered by:
Code:
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.103 ! --dport 587 -j MARK --set-mark $MARK
 
Last edited:
oh, I just ssh into the router and paste those iptables in whenever I need to. I don't know the answer to your questions otherwise.
 
iptables -I FORWARD -i tun11 -p udp -d 192.168.2.42 --dport 12345 -j ACCEPT

iptables -I FORWARD -i tun11 -p tcp -d 192.168.2.42 --dport 12345 -j ACCEPT

iptables -t nat -I PREROUTING -i tun11 -p tcp --dport 12345 -j DNAT --to-destination 192.168.2.42

iptables -t nat -I PREROUTING -i tun11 -p udp --dport 12345 -j DNAT --to-destination 192.168.2.42

this is how you port forward from the TUN device (openvpn client) to a LAN client. Not sure how you'll need to change it for the transmission client within the router. Of course, change tun device, port, and LAN client IP where applicable.
Works like a charm. I inserted the rules in the firewall script.

So that answered question 1 :)
On to the other two:
It also seems there's no DNS assigned. So when I enter manually a DNS in the WAN DNS Setting, it can find websites, but... isn't this DNS leakage? My guess is, that it is.
My VPN provider AirVPN has DNS servers available, but these are in the 10.x.x.x range, so they only work when the VPN is active.
Q2) So how can I assign DNS servers only for the VPN and use my regular DNS for regular WAN traffic?

Speaking of leakage, I don't have any firewall settings yet. I read the Github page by Rmerlin to add the following to firewall-start:
Code:
#!/bin/sh
sleep 4
iptables -I FORWARD -i br0 -o tun11 -j ACCEPT
iptables -I FORWARD -i tun11 -o br0 -j ACCEPT
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 -j DROP
iptables -I INPUT -i tun11 -j REJECT
iptables -t nat -A POSTROUTING -o tun11 -j MASQUERADE
Q3) So my third question is, will these rules prevent all traffic or should I alter the 3rd line, so email notification via gmail is still possible, to this:
Code:
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 ! --dport 587 -j DROP
Thanks for the help,
Erwin
 
Works like a charm. I inserted the rules in the firewall script.

So that answered question 1 :)
On to the other two:

Old school dnsmasq.conf.add can certainly force the use of a specific DNS by MAC address...

Code:
dhcp-host=xx:xx:xx:xx:xx:xx,set:vpndns
dhcp-host=yy:yy:yy:yy:yy:yy,set:vpndns
dhcp-option=tag:vpndns,option:dns-server, 10.xxx.xxx.xxx,10.xxx.xxx.xxx

or the use the custom DNS option on the Parental Controls GUI?
 
Thanks for your reply Martineau!
The funny thing is that old school dnsmasq.conf.add in one way or another interferes with the portforwarding. Both from within Transmission and outside through http://www.yougetsignal.com/tools/open-ports/ the peer-port is marked as closed.
However, when I put the 10.xxx.xxx.xxx on the first position of the static DNS and 208.67.222.220 and 208.67.222.222 on the 2nd and 3rd, then the peer-port is marked as open.
So even though I got it working, I wonder if having the 10.xxx.xxx.xxx as static DNS has any performance consequences for non-VPN users/clients?
 
just to get back to the original question about a DNS "leak".... no, you're not leaking either way. if you manually input DNS in the WAN section requests to those DNS will be sent through the VPN tunnel. That's why I use google public because no matter what VPN gateway I connect to there is a nearby google public.

if you set the option "accept DNS configuration" to exclusive in the openvpn client then you'll use only Air DNS when connected to VPN. it'll switch back to your WAN DNS when disconnected. but I have learned that the line in AirVPN configs "explicit-exit-notify 5" screws up the DNS switching. I remove that line from the custom config and everything works well.

I have no experience with special routing so that some of your traffic isn't going through the VPN tunnel and what to do with DNS for that.
 
just to get back to the original question about a DNS "leak".... no, you're not leaking either way. if you manually input DNS in the WAN section requests to those DNS will be sent through the VPN tunnel. That's why I use google public because no matter what VPN gateway I connect to there is a nearby google public.
Aaha now I understand!
if you set the option "accept DNS configuration" to exclusive in the openvpn client then you'll use only Air DNS when connected to VPN. it'll switch back to your WAN DNS when disconnected. but I have learned that the line in AirVPN configs "explicit-exit-notify 5" screws up the DNS switching. I remove that line from the custom config and everything works well.
I followed their setup guide, but did not find the "explicit-exit-notify 5" line in that guide, nor did I add it manually to my custom config. Perhaps it's pushed? Any way to deny or overrule it?
 
the openvpn config files (.ovpn) that you download via their configuration generator have the line explicit-exit-notify 5 for UDP connections. TCP connections may not have it.

then those ovpn files can be uploaded and saved to the router through the openvpn client GUI. no setup required. the line is then seen in the custom config at the bottom of the page and I just delete it.
 
You're right, the explicit-exit-notify 5 is also in the TCP connection config file. I followed the manual setup for Tomato and that does not include the explicit-exit-notify 5 line.
I've now uploaded the config file and I'll give it a go with and without. I'll report back.
 
Guys, as promised my results:
- I've started with a clean slate: I abandoned the route-up/route-down scripts of post #1, reinstalled the firmware and used this guide by RMerlin:
https://github.com/RMerl/asuswrt-merlin/wiki/How-to-Direct-Traffic-over-VPN-and-Drop-connections-if-VPN-goes-down
I added these exception rules to firewall-start after the DROP rule:
Code:
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 443 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 587 -j ACCEPT
Note that they say: ! -o tun11
and not: -o ! tun11
as suggested in several posts.
(I guess this rule will also work instead? iptables -I FORWARD -s 192.168.0.0/24 ! -o tun11 -p tcp -m multiport --dport 80,443,587 -j ACCEPT)

I added the following rules to firewall-start for Transmission to open peer-port 12345 after the MASQUERADE rule.
Code:
iptables -I FORWARD -i tun11 -p udp -d 192.168.0.103 --dport 12345 -j ACCEPT
iptables -I FORWARD -i tun11 -p tcp -d 192.168.0.103 --dport 12345 -j ACCEPT
iptables -t nat -I PREROUTING -i tun11 -p tcp --dport 12345 -j DNAT --to-destination 192.168.0.103
iptables -t nat -I PREROUTING -i tun11 -p udp --dport 12345 -j DNAT --to-destination 192.168.0.103

For VPN I uploaded the config file generated by the AirVPN website, I uploaded the keys and certificate files.
And added to custom configuration of the VPN client #1:
Code:
tls-auth /jffs/openvpn/airvpn/ta.key 1
ca /jffs/openvpn/airvpn/ca.crt
cert /jffs/openvpn/airvpn/user.crt
key /jffs/openvpn/airvpn/user.key
I removed, as suggested by cosmoxl, from the custom configuration of the VPN client #1:
Code:
explicit-exit-notify 5
And of course rebooted :)
Everything SEEMS to work according to my wishes.

One question remains: I want to use different DNS servers than the ones provided by my ISP (for traffic outside of the VPN).
Where should I enter those? There is of course old school dnsmasq.conf.add or parenting control as suggested by Martineau.
But what about plain vanilla DNS server settings?
There's a DNS server field in LAN settings > DHCP server
(There's also an option "Forward local domain queries to upstream DNS" - what should I do with this?)
But there are also a hidden DNS server fields in WAN that show up after selecting 'No' for "Connect to DNS Server automatically"
Where o where do I enter the IP addresses of OpenNIC DNS servers?
 
Have you opened that port with AirVPN?

Why are you storing keys and certs in jffs? To avoid using nvram?
 
One question remains: I want to use different DNS servers than the ones provided by my ISP (for traffic outside of the VPN).
Where should I enter those? There is of course old school dnsmasq.conf.add or parenting control as suggested by Martineau.
But what about plain vanilla DNS server settings?
There's a DNS server field in LAN settings > DHCP server
(There's also an option "Forward local domain queries to upstream DNS" - what should I do with this?)
But there are also a hidden DNS server fields in WAN that show up after selecting 'No' for "Connect to DNS Server automatically"
Where o where do I enter the IP addresses of OpenNIC DNS servers?

Use the WAN 'hidden' DNS server fields. ASUS have commendably tried to make the dialog pages easy for novices by only showing relevant fields, but this isn't always the expected result.

I've often thought that if the message text was

Use default ISP DNS Servers

then this would be clearer - or perhaps maybe

Override ISP DNS Servers and use custom DNS servers but then the toggle would need to change from No to Yes :confused:
 
Have you opened that port with AirVPN?

Why are you storing keys and certs in jffs? To avoid using nvram?
I did not open that particular port number, but I did open a port with AirVPN. They assign a port number to you, you can not open a port number that you pick.
And yes, I'm storing the keys and certs in jffs to save nvram. See this article by RMerlin:
https://github.com/RMerl/asuswrt-merlin/wiki/reducing-nvram-for-openvpn-certs

Use the WAN 'hidden' DNS server fields. ASUS have commendably tried to make the dialog pages easy for novices by only showing relevant fields, but this isn't always the expected result.

I've often thought that if the message text was

Use default ISP DNS Servers

then this would be clearer - or perhaps maybe

Override ISP DNS Servers and use custom DNS servers but then the toggle would need to change from No to Yes :confused:
LOL and agreed ;)
 
Despite of what I've written that the exceptions to the DROP rule are working, I think they are not. Or at least, not consistent.
To test it I use telnet from a terminal like so: telnet www.google.com 80
The result is:
Trying 74.125.136.113...
Connected to google.com.
Escape character is '^]'.
I enter "quit" and I get see the raw code of an HTML page, followed by "Connection closed by foreign host."

However, when I close the VPN, the results vary. Doing the above (telnet google.com 80) and nothing happens, nor when I use the IP address.

Entering "telnet 173.xxx.xx.xxx 443" (my webserver) and I get "Connected to cf-173-xxx-xx-xxx.cloudflare.com" (the webserver's DNS).
But when I enter "telnet www.mydomain.com 443" nothing happens.

What am I doing wrong?
 
Objective: even though the VPN has gone down, no traffic is allowed to go over WAN except for ports 80,443 and 587.
In all cases the DROP rule does work! However, not any traffic whatsoever was allowed.
What didn't work:
Code:
LANIP=$(nvram get lan_ipaddr)
SUBNET_PREFIX=`echo $LANIP | awk 'BEGIN { FS = "." } {print $1"."$2"."$3}'` # Extract first three octets of I/P
iptables -I FORWARD -i br0 -s $SUBNET_PREFIX.0/24 -o eth0 -j DROP
iptables -I FORWARD -s $SUBNET_PREFIX.0/24 ! -o tun11 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s $SUBNET_PREFIX.0/24 ! -o tun11 -p tcp --dport 443 -j ACCEPT
iptables -I FORWARD -s $SUBNET_PREFIX.0/24 ! -o tun11 -p tcp --dport 587 -j ACCEPT
Code:
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -j DROP
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 80 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 443 -j ACCEPT
iptables -I FORWARD -s 192.168.0.103 ! -o tun11 -p tcp --dport 587 -j ACCEPT
Code:
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 -j DROP
iptables -I FORWARD -p tcp -m multiport --dports 80,443,587 -j ACCEPT
I also tried reverse: ACCEPT rules before the DROP rule - no luck there either.
Adding the following rule to openvpn-event, didn't work either.
Code:
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --dport 80,443,587 -j MARK --set-mark 1
Please do note that they didn't work for me - it could be different for you, dear reader ;)

So what DID work?
Code:
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 -m multiport ! --dports 80,443,587 -j DROP
And with that I can answer my initial 3rd question affirmative: "Yes, these rules will prevent all traffic and I should alter the 3rd line, so email notification via gmail is still possible, to this:
Code:
iptables -I FORWARD ! -o tun11 -s 192.168.0.103 ! --dport 587 -j DROP
"
 
Last edited:

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top