What's new

Kill switch doesn't work

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

Horilka

Occasional Visitor
It seems to me kill switch stopped working for me. I had 386.1.x FW and noticed after router reboot that my OpenVPN client is down and despite I had setting to prevent client access to Internet when VPN is down, client still had access to Internet. I could not make kill switch work so updated to 386.3.2 and tried with backuped / restored setting. No luck. Factory reset and manually changing setting - still no luck to make kill switch work.
All I want is single client to be able access Internet ONLY via OpenVPN interface and if it's down then it should have no access.

I noticed in release notes that kill switch now supposed to be engaged only if OpenVPN client is set to autostart or when OpenOPN lost connection without manual intervention.
So I set OpenVPN "Automatic start at boot time" to ON, "Killswitch - Block routed clients if tunnel goes down" = ON, "Redirect Internet traffic through tunnel" = Redirector. Other OpenVPN setting are incorrect because I'm testing failed attemp to connect after reboot.
In Redirector I created two rules (one for device, second for my laptop to test it). Source = 192.168.50.2 (this is client), Remote IP = "[empty]', Interface = OVPN1. Similar rule for my laptop 192.168.50.39 to test if kill switch works.

So with these settings I supposed to have kill switch kick in and bock traffic from two IPs upon reboot and failed attempt to enable OpenVPN, right? Well, it does not work. After reboot both clients are able to access Inetrnet. What am I doing wrong? I looked at similar recent threads and I understand that logic of kill switch has changed, but it looks it got broken for me even in 386.1.x and it's not as described in current 386.3.2.

(my Asus IP is 192.168.50.1)
Code:
admin@RT-AC68U-C2E8:/tmp/home/root# ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
admin@RT-AC68U-C2E8:/tmp/home/root# ip route
216.25.247.161 dev vlan2  proto kernel  scope link
216.25.247.160/27 dev vlan2  proto kernel  scope link  src 216.25.247.174
192.168.50.0/24 dev br0  proto kernel  scope link  src 192.168.50.1
127.0.0.0/8 dev lo  scope link
default via 216.25.247.161 dev vlan2
 
When you say you "Other OpenVPN settings are incorrect", what specifically did you purposely set incorrectly?

What I'm noticing is that w/ certain errors, particularly those so egregious that the OpenVPN process dies almost immediately (e.g., a missing CA.crt (Certificate Authority)), the kill switch can NOT be maintained. Initially the ip rules will be established, and the routing table (ovpnc1 in this case) will have a single 'prohibit default' route. But once the OpenVPN client dies, these are removed and the WAN is wide open.

One way to observe this behavior is to reboot and use ssh to run the following command to monitor the relevant data structures.

Code:
watch 'ip route show table ovpnc1; echo; ip rule'

You have to get into the router pretty quickly, before the OpenVPN process dies. And if you do, you'll see the kill switch is briefly active, but quickly dies.

Frankly, I don't know if this is the way it's supposed to work (@RMerlin would have to address that question). I suppose the argument could be made that egregious errors that would never allow the OpenVPN client to get past the basic error-checking stage, can't expect protection (presumably because the OpenVPN process is exiting normally). In the prior firmware, it seemed to work a bit differently, and the kill switch (iirc) was truly persistent, to the point it even worked when the OpenVPN client was OFF.
 
Last edited:
I left VPN client setting default, to simulate "any error that could occur during connecting". All I changed from default was: Automatic start at boot time = YES, Redirect Internet traffic through tunnel = VPN Director, Killswitch - Block routed clients if tunnel goes down = YES.

Is there any way with current FW to achieve killswitch / configuration that would prevent certain client(s) to have access to Internet unless specific VPN client/interface is up?
 
Understand, I didn't create the current or prior kill switch behavior. I'm only reporting what I'm seeing.

With the old kill switch, iirc, it would block the WAN even if misconfigured. The OpenVPN client didn't even need to be ON! But that caused issues for some users. So it was changed to its current behavior. With the new kill switch, I don't think the intent is to protect you from a *misconfigured* OpenVPN client. And I consider just accepting the defaults to be misconfigured. NOT unless it actually works, which seems extremely unlikely; the lack of a CA.crt is enough to make that impossible. IOW, the OpenVPN client *has* to be capable of getting connected. Then if at some point down the road it fails to connect, or does connect but the running connection fails for some reason, the kill switch will be activated.

Just based on observation, that's what I'm seeing. Again, @RMerlin would have to speak to the specifics regarding when and if the kill switch should be activated given a certain set of conditions.

Regardless, as I've told others, you could always create your own kill switch that behaves like the old firmware.


Frankly, imo, it makes more sense to manage the kill switch independently of the OpenVPN client anyway. You just configure firewall rules to block the WAN that matches your policy rules. I could probably even write a script for those purposes.
 
Thank you for your advice and explanations. So I understood the issue correctly. Killswithc in current implementation can't protect client from being exposed, unless VPN is in working condition, however fails (but not every failure counts). IMO it's a huge flaw in logic.
I'm also not that advanced user to be comfortable with custom scripts and FW commands. I saw your posts you're reffering. So I guess I'll have to roll several releases back. However it's strange that on 383.1.x I had the same issue....
 
This is just my opinion, so take it for what it's worth.

Personally I'm not a fan of how the router implements the kill switch, either now or before. I prefer to use firewall rules that are managed independently of the OpenVPN client(s), making the kill switch *static* and always active.

In contrast, the router's kill switch is an integral part of the OpenVPN client(s), to the point that blocking access to the WAN depends on a) the router detecting a failure, b) the router deciding what actually constitutes a failure, and c) that failure leading to a *dynamic* change in the routing table (specially the addition of a 'prohibit default' route at the time of failure).

For my purposes, I just don't like depending on a change in the state of the OpenVPN client and hoping the kill switch will be activated. I prefer to establish the denial to the WAN as a fixed, permanent requirement.

Why does the router work the way it does? Presumably because it's just easier to implement. It doesn't have to deal w/ blocking access on a rule by rule basis. Instead, if anything is bound to the OpenVPN client and the kill switch is enabled, denial to the WAN is a function of how the routing table is configured, which as I said, only requires the 'prohibit default' route be added. BUT w/ that ease of implementation comes all the caveats I mentioned previously.

FWIW, I'm working on a script to see if I can provide a kill switch based on the firewall, either as a replacement or supplement to the router's kill switch. What it will do is read the VPN Director rules from JFFS and use iptables to block the WAN accordingly. But it can still get tricky when you're dealing w/ multiple, concurrent OpenVPN clients, esp. when the rules vary one to the other, or even overlap. And if the VPN Director rules are changed/updated, it will probably require a reboot to force the firewall to be reinitialized and trigger the script again for reevaluation. IOW, I can't guarantee success, esp. for multiple, concurrent OpenVPN clients w/ overlapping rules. We'll see what happens.

In the meantime, it really isn't all that hard to manually create the rules, esp. for simple cases (the simplest being no VPN Director rules at all; you just unconditionally block access to the WAN from the private network (br0)).
 
There are many reasons why the current implementation is done the way it is.

The killswitch is implemented at the routing table level because that's where routing should be handled, not at the firewall level. It's also a much simpler, more static environment to work with than iptables, where rules are constantly changed or moved around based on service restarts, reconfiguration, or upstream changes from Asus. Manipulating firewall rules at the same time you restart the firewall is easy, but making any dynamic change to it based on events (such as a client going down) is next to impossible to accomplish in a reliable manner. Routing tables can easily be manipulated on-the-fly without any disrupting event such as firewall restarts.

Iptables has no notion of priority. Every rule is evaluated in a sequential order, and the first matching rule will stop processing. it makes any dynamic management unreliable, as you cannot predict at which location you are supposed to insert a rule if you need to dynamically change the firewall configuration without triggering a complete firewall restart. Any script that decides to insert its own ACCEPT or DROP rule ahead of your killswitch would completely bypass it.

A firewall restart event has no way of knowing for sure whether a client is currently down and should trigger the killswitch. This was an issue with the previous implementation where people complained that the killswitch would always be active even if they had chosen to manually stop a VPN client, and it's not down because of a connection failure. The VPN Director implementation was done the way it is to address this particular complain, as it handles the entire route management for every VPN client, independent of the firewall.

Also, lack of priority means you can't easily implement complicated multi-tunnel setups like some people seem so found of implementing with their VPN tunnels (and then come here trying to figure out why their 3 tunnel setups is having issues, as they have overlapping routes and what not). Using the routing tables means that killswitch are directly tied to each relevant OpenVPN client.

The recent change to only activate the killswitch if a client is in an error state is because with the previous implementation, a few users complained that stopping their client killed their entire Internet connection. Whichever way I decide to implement it, someone somewhere will complain that they want it working the other way around. So, I made a design decision to implement it the way it currently is, because this is what I felt is the most logical behaviour.

By all means, if someone is unhappy with how I designed the current implementation, feel free to disable it, and re-implement whichever different behaviour you wish to implement. That's why I implement so many hooks within the system to allow users to completely customize the firewall or the routing tables based on various events, be it firewall restarts or OpenVPN events. But the current implementation is done the way it is because I feel this is the most reliable, and cleanest way to implement it, and which will work for the largest majority of users, as it's the most flexible in some convoluted multi-tunnel setups where people have multiple VPN Director rules to decide what is tied to the tunnel and what isn't.

I'm just tired of getting people complain no matter how I decide to implement it, as every time something changes to satisfy a group of user, another group of users start complaining. So, the current implementation is the way it is, and I have no intention of making any change to this global implementation in the near future.
 
Frankly, I don't know if this is the way it's supposed to work (@RMerlin would have to address that question).

It should trigger the killswitch, provided that the OpenVPN failure properly sets the error state at boot time. This would have to be explicitely tested, I'll take a look once I resume development.
 
@RMerlin. Fir of all thank you for your efforts, I had been enjoying your work for years.
As for kill switch - I understand that there were reasons behind this implementation, however I would like to point that effectively current implementation does not work. Logic is "if VPN client tried to connect and failed or was connected and failed then kill switch is engaged. This is to keep kill switch off when VPN client is turned off manually". The there are many parameters of VPN client and in real life any of them could become outdated and incorrect, so VPN client can fail any moment for many reasons. And as my tests show - auto start of VPN client with wrong parameters does not trigger kill switch on. So IMO original logic is not implemented.
This is common real life scenario - certain network boxes suppose to use VPN or have no access to Internet at all. And saying "you have to have VPN client configured properly in order to have kill switch engaged when VPN client finally fails with some (which ones) errors" does not provide solution. See what I mean?
 
@RMerlin. Fir of all thank you for your efforts, I had been enjoying your work for years.
As for kill switch - I understand that there were reasons behind this implementation, however I would like to point that effectively current implementation does not work. Logic is "if VPN client tried to connect and failed or was connected and failed then kill switch is engaged. This is to keep kill switch off when VPN client is turned off manually". The there are many parameters of VPN client and in real life any of them could become outdated and incorrect, so VPN client can fail any moment for many reasons. And as my tests show - auto start of VPN client with wrong parameters does not trigger kill switch on. So IMO original logic is not implemented.
This is common real life scenario - certain network boxes suppose to use VPN or have no access to Internet at all. And saying "you have to have VPN client configured properly in order to have kill switch engaged when VPN client finally fails with some (which ones) errors" does not provide solution. See what I mean?
Please see post #8.
 
@RMerlinAnd as my tests show - auto start of VPN client with wrong parameters does not trigger kill switch on. So IMO original logic is not implemented.

Just to be precise (since it may help find the problem and resolve it), when *I* tested w/ nothing more than enabling autostart, the kill switch, and one rule (no other changes), hit apply, and rebooted, I *did* see the ip rules and 'prohibit default' in the corresponding routing table (e.g., ovpncX) for a brief period. But those data structures would quickly disappear, as if the router decided the OpenVPN client didn't need to block the WAN anymore. But you have to be quick in getting into the router after a reboot to see this happen. So I don't think the issue is the router not adding the protection, as much as explaining why it eventually (and rather quickly) removes it. That does seem to be a bug of some sort. And if corrected, would probably alleviate much of the OP's concerns.
 
Last edited:
As promised, I've created a script to implement a kill switch based on the firewall, rather than as the router does, based on the routing tables.


Basically what it does is process the VPN Director rules and create firewall rules to block the WAN for the same local and/or remote ip/network.

1. By default, it only considers OpenVPN clients that have the "Automatic start at boot time" setting enabled. But there's an option to enable/disable that behavior as you see fit.

2. If *any* OpenVPN client is using "Redirect Internet traffic through tunnel" w/ a setting of "Yes (all)", then all VPN Director policy rules are ignored and *all* LAN clients are denied access to the WAN. There's just no practical means to programmatically resolve issues where some of the OpenVPN clients have specific rules, and others route everything over the VPN. In general, I recommend you *always* use the "VPN Director (policy rules)" option whenever you have multiple, concurrent OpenVPN clients.

3. You have the option to specify whether the firewall rules do or don't use state. The script fully documents the differences, and why you might choose one over the other. So no need to repeat it here.

4. Nothing prevents using this script at the same time as the router's built-in kill switch, since they operate on completely different principles. But as a practical matter, if the firewall rules work for you, they are probably sufficient, and the router's built-in kill switch is superfluous (and if the router's kill switch eventually proves more to your liking, vice-versa).

5. Realize that any changes to the vpn policy rules w/ the VPN Director will NOT be recognized by the script until you reboot. And that's because (as I said before) the VPN Director doesn't use the firewall. It only changes the routing system (specifically the ip rules) to implement those policies. I suppose you could *force* a reinitialization of the firewall (which will also rerun the script), but I don't generally recommend it since I don't know the full consequences of such an action. Better to play it safe and reboot. But that's your call.

Code:
service restart_firewall

6. To install, use the curl command below, then reboot. It installs as a firewall-start script and will NOT overwrite an existing firewall-start script (including itself). You must also have "JFFS custom scripts and configs" enabled under Administration->System.

Code:
curl -kLs bit.ly/merlin-installer|tr -d '\r'|sh -s F2GmyrCC

If necessary, you can edit the options using the nano editor.

Code:
nano /jffs/scripts/merlin-ovpn-client-killswitch.sh

It's certainly my hope (and preference) that the router's kill switch works to most ppl's satisfaction. I suspect it only needs some tweaking. As the developer has stated, the router's kill switch has more to offer in terms of flexibility and dynamic behavior than the firewall can ever offer. This is only my attempt to provide an alternative for those who find it absolutely necessary. Esp. for those w/o much experience w/ iptables.
 
Last edited:
I left VPN client setting default, to simulate "any error that could occur during connecting". All I changed from default was: Automatic start at boot time = YES, Redirect Internet traffic through tunnel = VPN Director, Killswitch - Block routed clients if tunnel goes down = YES.

Is there any way with current FW to achieve killswitch / configuration that would prevent certain client(s) to have access to Internet unless specific VPN client/interface is up?

BTW, one thing to note here. Under this exact scenario, you can't expect the router to block access to the WAN since you haven't defined any policies rules. Read the option carefully, "Block routed clients if tunnel goes down". Well without any policy rules, there are no routed clients to that VPN! Assuming no other configured and active OpenVPN clients, all your LAN clients are being passed through to the main routing table, which means the WAN.

That's not to say there isn't a problem here based on your opening post, where you indicated you did specify some policy rules. But I just to be clear about this subsequent scenario you described and why it's NOT going to block the WAN.
 
BTW, one thing to note here. Under this exact scenario, you can't expect the router to block access to the WAN since you haven't defined any policies rules. Read the option carefully, "Block routed clients if tunnel goes down". Well without any policy rules, there are no routed clients to that VPN! Assuming no other configured and active OpenVPN clients, all your LAN clients are being passed through to the main routing table, which means the WAN.
At the time of test director had two rules - to route the LAN client and my laptop only via VPN.
And thank you for script and explanations. I'm going to try it now.
 
Ok, I had couple of hiccups on the way, but made it work. Thank you very much for your script, it's a saver.

1. There's a bug in the script, it won't read Director rule if it has description. At least description "eGreat VPN only" prevents script from reading IP address and adding it to firewall chain ovpn_block_wan.
2. I think I found nasty bug in FW that caused me all this headache in the first place. I had playing and rebooting my router maybe 10 times during today's test and after one reboot. Two VPN client settings were reverted! Service state became OFF and Automatic start at boot time = OFF. This is very strange, because every single other VPN client setting was still there... I think this bug killed my VPN connection after restart and my client became exposed.
So I commented "VPN_AUTOSTART_ONLY" in the script and it's now bulletproof. Even if VPN autostart setting are reverted somehow, my LAN boxes will be blocked from using public VPN.
3. How do I remove script if I need to?
 
1. There's a bug in the script, it won't read Director rule if it has description. At least description "eGreat VPN only" prevents script from reading IP address and adding it to firewall chain ovpn_block_wan.

I didn't have any problems w/ having a description. It might be something specific to your list of policies. It would help if you could post the contents of the entire variable so I can just test it exactly as you have/had it defined.

Code:
cat /jffs/openvpn/vpndirector_rulelist

3. How do I remove script if I need to?

Just delete it and reboot.

Code:
rm /jffs/scripts/firewall-start
 
Last edited:
1. There's a bug in the script, it won't read Director rule if it has description. At least description "eGreat VPN only" prevents script from reading IP address and adding it to firewall chain ovpn_block_wan.

Ok, found the problem. I wasn't handling embedded spaces correctly. I updated the script (v1.0.1).
 
There are many reasons why the current implementation is done the way it is.

The killswitch is implemented at the routing table level because that's where routing should be handled, not at the firewall level. It's also a much simpler, more static environment to work with than iptables, where rules are constantly changed or moved around based on service restarts, reconfiguration, or upstream changes from Asus. Manipulating firewall rules at the same time you restart the firewall is easy, but making any dynamic change to it based on events (such as a client going down) is next to impossible to accomplish in a reliable manner. Routing tables can easily be manipulated on-the-fly without any disrupting event such as firewall restarts.

Iptables has no notion of priority. Every rule is evaluated in a sequential order, and the first matching rule will stop processing. it makes any dynamic management unreliable, as you cannot predict at which location you are supposed to insert a rule if you need to dynamically change the firewall configuration without triggering a complete firewall restart. Any script that decides to insert its own ACCEPT or DROP rule ahead of your killswitch would completely bypass it.

A firewall restart event has no way of knowing for sure whether a client is currently down and should trigger the killswitch. This was an issue with the previous implementation where people complained that the killswitch would always be active even if they had chosen to manually stop a VPN client, and it's not down because of a connection failure. The VPN Director implementation was done the way it is to address this particular complain, as it handles the entire route management for every VPN client, independent of the firewall.

Also, lack of priority means you can't easily implement complicated multi-tunnel setups like some people seem so found of implementing with their VPN tunnels (and then come here trying to figure out why their 3 tunnel setups is having issues, as they have overlapping routes and what not). Using the routing tables means that killswitch are directly tied to each relevant OpenVPN client.

The recent change to only activate the killswitch if a client is in an error state is because with the previous implementation, a few users complained that stopping their client killed their entire Internet connection. Whichever way I decide to implement it, someone somewhere will complain that they want it working the other way around. So, I made a design decision to implement it the way it currently is, because this is what I felt is the most logical behaviour.

By all means, if someone is unhappy with how I designed the current implementation, feel free to disable it, and re-implement whichever different behaviour you wish to implement. That's why I implement so many hooks within the system to allow users to completely customize the firewall or the routing tables based on various events, be it firewall restarts or OpenVPN events. But the current implementation is done the way it is because I feel this is the most reliable, and cleanest way to implement it, and which will work for the largest majority of users, as it's the most flexible in some convoluted multi-tunnel setups where people have multiple VPN Director rules to decide what is tied to the tunnel and what isn't.

I'm just tired of getting people complain no matter how I decide to implement it, as every time something changes to satisfy a group of user, another group of users start complaining. So, the current implementation is the way it is, and I have no intention of making any change to this global implementation in the near future.
Hi RMerlin,

First of all .. Thank You for maintaining the Merlin firmware. Maybe that is just not said often enough!

I also made the mistake of trusting the VPN Client implementation stays the same over firmware versions.
Until I noticed indeed that my WAN connection came back once I disabled the VPN.

Unfortunate I am not that much of a wizz to implement firewall rules (although maybe if I tried really hard?) ...
For me (and please believe me I think many people) it would be fine it the full connection to the VPN Redirector set IP addresses went down.

Is it possible to add one more option in the VPN Client section? Kill WAN connection if VPN is disabled: yes/no?

Please. And many thanks for considering if possible.

Kind regards,
Pat.
 
As promised, I've created a script to implement a kill switch based on the firewall, rather than as the router does, based on the routing tables.


Understand, this is just a first attempt (this stuff can get complicated to implement), so I can't guarantee it to be error free. I've been tweaking it for a while, but at some point you just have to let it go and see what you've got.

Basically what it does is process the VPN Director rules and create firewall rules to block the WAN for the same local and/or remote ip/network.

1. By default, it only considers OpenVPN clients that have the "Automatic start at boot time" setting enabled. But there's an option to enable/disable that behavior as you see fit.

2. If *any* OpenVPN client is using "Redirect Internet traffic through tunnel" w/ a setting of "Yes (all)", then all VPN Director policy rules are ignored and *all* lan clients are denied access to the WAN. There's just no practical means to programmatically resolve issues where some of the OpenVPN clients have specific rules, and others route everything over the VPN. In general, I recommend you *always* use the "VPN Director (policy rules)" option whenever you have multiple, concurrent OpenVPN clients.

3. You have the option to specify whether the firewall rules do or don't use state. The script fully documents the differences, and why you might choose one over the other. So no need to repeat it here.

4. Nothing prevents using this script at the same time as the router's built-in kill switch, since they operate on completely different principles. But as a practical matter, if the firewall rules work for you, they are probably sufficient, and the router's built-in kill switch is superfluous (and if the router's kill switch eventually proves more to your liking, vice-versa).

5. Realize that any changes to the vpn policy rules w/ the VPN Director will NOT be recognized by the script until you reboot. And that's because (as I said before) the VPN Director doesn't use the firewall. It only changes the routing system (specifically the ip rules) to implement those policies. I suppose you could *force* a reinitialization of the firewall (which will also rerun the script), but I don't generally recommend it since I don't know the full consequences of such an action. Better to play it safe and reboot. But that's your call.

Code:
service restart_firewall

6. Installation only requires that you copy/paste the script into the terminal window of an ssh session on the router (or you can use curl, see below), then reboot. It installs as a firewall-start script and will NOT overwrite an existing firewall-start script (including itself). You must also have "JFFS custom scripts and configs" enabled under Administration->System.

Code:
curl -kLs pastebin.com/raw/F2GmyrCC | tr -d '\r' | sh

If necessary, you can edit the options using the nano editor.

Code:
nano /jffs/scripts/firewall-start

It's certainly my hope (and preference) that the router's kill switch works to most ppl's satisfaction. I suspect it only needs some tweaking. As the developer has stated, the router's kill switch has more to offer in terms of flexibility and dynamic behavior than the firewall can ever offer. This is only my attempt to provide an alternative for those who find it absolutely necessary. Esp. for those w/o much experience w/ iptables.

THANKS!!! Seems to be working great; disable VPN .. all routing blocked. (although I did not try it extensively.
 

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