What's new

How is the VPN Killswitch implemented?

  • 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!

Homi79

New Around Here
Question for my own understanding.
How does the VPN Killswitch work in Merlin?
As i see when listing the iptables rules, its not implemented in iptables. Im i right?
So how does it work? (technically under the hood)
Is it 100% reliable ?

Thanks
 
Done at the routing table level, through RPDB.
 
Each OpenVPN client manages its own routing table (ovpnc1, ovpnc2, etc.). When the OpenVPN client gets connected to the OpenVPN server, it installs the VPN as the default gateway in its own routing table (as opposed to the main routing table, which always has the WAN as its default gateway). IP rules are then created and managed to control what does and doesn't use those alternative routing tables. The router monitors the OpenVPN client connection, and should it fail for any reason, replaces its default gateway w/ a "prohibit default" route. This denies all further access to a default gateway (VPN or WAN) by those bound to that OpenVPN client unless and until the OpenVPN connection is reestablished.

IOW, it's all driven by the routing system, NOT the firewall.

If you want to see it in action, you can dump/monitor the following data structures from SSH.

Code:
ip rule
ip route show table main
ip route show table ovpnc1
ip route show table ovpnc2
ip route show table ovpnc3
ip route show table ovpnc4
ip route show table ovpnc5

Purposely kill one of the OpenVPN client processes w/ the kill command (use the ps command to find the PID (process ID)), and you'll see the VPN gateway immediately replaced w/ the "prohibit default" route.

Is it 100% reliable? According to some, no. Or at least NOT everyone has been totally happy with it. For those users, I created an alternative kill switch based on the firewall.


As I've said many times, I still strongly recommend using the built-in killswitch unless and until it proves to be a problem. Many ppl use it w/o issue. But for those that do, you might want to consider the script.

P.S. I've also created a watchdog script to accompany it (still useful even if you use the built-in killswitch).

 
Last edited:
Each OpenVPN client manages its own routing table (ovpnc1, ovpnc2, etc.). When the OpenVPN client gets connected to the OpenVPN server, it installs the VPN as the default gateway in its own routing table (as opposed to the main routing table, which always has the WAN as its default gateway). IP rules are then created and managed to control what does and doesn't use those alternative routing tables. The router monitors the OpenVPN client connection, and should it fail for any reason, replaces its default gateway w/ a "prohibit default" route. This denies all further access to a default gateway (VPN or WAN) by those bound to that OpenVPN client unless and until the OpenVPN connection is reestablished.

IOW, it's all driven by the routing system, NOT the firewall.

If you want to see it in action, you can dump/monitor the following data structures from SSH.

Code:
ip rule
ip route show table main
ip route show table ovpnc1
ip route show table ovpnc2
ip route show table ovpnc3
ip route show table ovpnc4
ip route show table ovpnc5

Purposely kill one of the OpenVPN client processes w/ the kill command (use the ps command to find the PID (process ID)), and you'll see the VPN gateway immediately replaced w/ the "prohibit default" route.

Is it 100% reliable? According to some, no. Or at least NOT everyone has been totally happy with it. For those users, I created an alternative kill switch based on the firewall.


As I've said many times, I still strongly recommend using the built-in killswitch unless and until it proves to be a problem. Many ppl use it w/o issue. But for those that do, you might want to consider the script.

P.S. I've also created a watchdog script to accompany it (still useful even if you use the built-in killswitch).

As always thoroughly explained.
 
Thanks for the explanation.

Let me give you a little more information what I want to achieve.

I have an upstream ISP Router (192.168.2.0/24).
My Asus(Merlin) Router (192.168.3.0/24) is connected to that ISP Router.

Devices connected to this Asus Router should only! use the OpenVPN connection for internet access.

The devices connected to any of my routers should be able to communicate with each other.

I already had a router running dd-wrt for this setup.
Just a few IPtables rules satisfied all my needs.

It looked like this:

iptables -I FORWARD -o `nvram get wan_iface` -m state --state NEW -j DROP
iptables -I FORWARD -o `nvram get wan_iface` -d 192.168.2.0/24 -m state --state NEW -j ACCEPT
iptables -I FORWARD -s 192.168.2.0/24 -j ACCEPT

iptables -I FORWARD -i tun1 -m state --state NEW -j DROP
iptables -I INPUT -i tun1 -m state --state NEW -j DROP
iptables -I POSTROUTING -t nat -o tun1 -j MASQUERADE

So my question would be:

What is the easiest way to achieve this in a Merlin Router?
At the moment I have switched off the firewall (which is just iptables, right?) in Merlin completely.
Enabled my VPN tunneling all internet traffic through the VPN with the merlin killswitch enabled.

So what would be the easiest way to implement the rules shown above?

Also this:
`nvram get wan_iface`
does not seem to work in Merlin.

Thanks for your help!
 
maybe as simple as that:

?
 
Thanks for the explanation.

Let me give you a little more information what I want to achieve.

I have an upstream ISP Router (192.168.2.0/24).
My Asus(Merlin) Router (192.168.3.0/24) is connected to that ISP Router.

Devices connected to this Asus Router should only! use the OpenVPN connection for internet access.

The devices connected to any of my routers should be able to communicate with each other.

I already had a router running dd-wrt for this setup.
Just a few IPtables rules satisfied all my needs.

It looked like this:

iptables -I FORWARD -o `nvram get wan_iface` -m state --state NEW -j DROP
iptables -I FORWARD -o `nvram get wan_iface` -d 192.168.2.0/24 -m state --state NEW -j ACCEPT
iptables -I FORWARD -s 192.168.2.0/24 -j ACCEPT

iptables -I FORWARD -i tun1 -m state --state NEW -j DROP
iptables -I INPUT -i tun1 -m state --state NEW -j DROP
iptables -I POSTROUTING -t nat -o tun1 -j MASQUERADE

So my question would be:

What is the easiest way to achieve this in a Merlin Router?
At the moment I have switched off the firewall (which is just iptables, right?) in Merlin completely.
Enabled my VPN tunneling all internet traffic through the VPN with the merlin killswitch enabled.

So what would be the easiest way to implement the rules shown above?

Also this:
`nvram get wan_iface`
does not seem to work in Merlin.

Thanks for your help!

If we assume you're using the GUI to manage the OpenVPN client, most of what you've described is unnecessary. The GUI takes care of most of it, either automatically, or as a consequence of how you set various options.

For example, the Inbound Firewall option when set to Block (the default) prevents connections from being initiated from the remote side of the tunnel. Also, NAT is an option on the GUI. Even DD-WRT supports similar options in its OpenVPN client GUI.

The only thing that *won't* work w/o your intervention is having devices on the ISP's local IP network initiate connections into ASUS router's IP network, since the WAN denies all such access by default. But I'm not even sure this is something you need. I'm suspicious you *believe* you need it due to the killswitch. But if you use the built-in kill switch, this will *only* deny access to the internet, NOT the upstream local IP network of the ISP's router.

Finally, take caution in disabling the firewall as a whole when it comes to third-party firmware. This typically does NOT simply flush all the tables and chains.

Because these are NOT just pure routers, but applications platforms, such actions can sometimes cause problems. For example, in the case of DD-WRT, this also disables connection tracking (presumably done for performance reasons). That means anything remaining in the firewall that relies on checking the state of a packet or connection will no longer work!

As far as I know, this is NOT the case w/ Merlin. But I bring it up as a cautionary tale about turning OFF firewalls without considering the FULL implications. Unless a router is being used solely in a bridged configuration (e.g., AP mode), I recommend NEVER disabling the firewall using the GUI. Better to make a firewall exception to meet some specific/narrow need then disable it entirely.
 
The only thing that *won't* work w/o your intervention is having devices on the ISP's local IP network initiate connections into ASUS router's IP network, since the WAN denies all such access by default. But I'm not even sure this is something you need. I'm suspicious you *believe* you need it due to the killswitch. But if you use the built-in kill switch, this will *only* deny access to the internet, NOT the upstream local IP network of the ISP's router.
It's not the ISPs local Ip network. Its my local IP network that is used by my local devices that are plugged into the ISP router.
And yes i need to establish connections into the Asus routers IP network. For example to access administrative WEB UIs on devices plugged into the Asus Router.

I inserted

#!/bin/sh
iptables -I FORWARD -o eth0 -m state --state NEW -j DROP
iptables -I FORWARD -o eth0 -d 192.168.2.0/24 -m state --state NEW -j ACCEPT

into the custom firewall start script and everything seems to work now as expected.
 

Similar threads

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