How to block internet connection when VPN fails?

If none of the more specific forums is the right place to ask

How to block internet connection when VPN fails?

Postby Danielorum » 2013-10-21 18:02

Hello everybody. So glad i found this forum, full of experts!

I am running Debian on my server (OpenMediaVault) and i am connected to a VPN service, using openvpn. BUT! How do i make sure that the internet connection, stays through my VPN service, or gets blocked, if the connection through the VPN tunnel fails? Jeah, yeah call me paranoid.. :)

I have read this:
viewtopic.php?f=10&t=80287&p=437205&hilit=VPN+Fails+Stop+Traffic#p437205

This guy had the same idea, but i dont know how i use the source code. Is there a script somewhere i can just download? And i don't want the LAN connection to be blocked.. only outgoing traffic!!

Cross my fingers, for expert advice!

Thanks.
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby Cramer » 2013-10-23 12:07

Hi,

I use this VPN for free and when internet is blocked, then connection with VPN is stopped. :D

Cramer
Cramer
 
Posts: 1
Joined: 2013-10-23 12:01

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-10-23 16:40

Hi Cramer:

Thanks for the reply, but i am running a debian server, and that site you suggested, does not support that:

A: It is possible to set up a VPN connection manually with any device and on any operating system. Our VPN software is currently available only on Windows; with iOS, Mac and Android coming soon.
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby koanhead » 2013-10-24 19:37

Danielorum wrote:Hello everybody. So glad i found this forum, full of experts!
...

I have read this:
viewtopic.php?f=10&t=80287&p=437205&hilit=VPN+Fails+Stop+Traffic#p437205

This guy had the same idea, but i dont know how i use the source code. Is there a script somewhere i can just download? And i don't want the LAN connection to be blocked.. only outgoing traffic!!

Thanks.


You can run that code by putting it in a file (called $FILENAME or whatever you choose) and typing
Code: Select all
python $FILENAME

in a terminal.

A more graceful way to do it would be to copy $FILENAME into
Code: Select all
/etc/network/if-up.d
where it will run automagically when the network interface comes up.
User avatar
koanhead
 
Posts: 110
Joined: 2013-06-20 16:54

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-10-27 10:18

Thanks for your reply.

But i found out that this script, brings down the ethernet adapter, and not just blocks the internet traffic. So i cant use this. I cant believe that noone has a solution for this..
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-01 13:55

What vpn client are you using? (Edit: Ignore that. I re-read your original post and see that you are using openvpn. Somehow I missed that the first time through. I will be able to post the details of my script later today...sorry I don't have access to it at the moment.)

I have a solution for Debian with openvpn and multiple ovpn files. I use a script to automatically restrict network traffic to the vpn and inbound ssh from the lan only, but it could be tweaked to allow other protocols.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-02 12:43

Here's my script, modified to allow all incoming traffic on eth0 from the local lan. It assumes you have no other iptables rules in place (that is the default with Debian, but may not be for other distros). If, after running it and connecting to your vpn you can no longer resolve hostnames, it's likely because your system isn't using the DNS servers provided by the vpn and is instead using your ISP or local router assigned servers (DNS leak! Bad!) To fix this, make sure the resolvconf package is installed and you run /etc/openvpn/update-resolv-conf on connecting/disconnecting from the vpn. The --up and --down command line parameters can be used for this like so: openvpn --script-security 2 --up /etc/openvpn/update-resolv-conf --down /etc/openvpn/update-resolv-conf

#!/bin/sh
/sbin/iptables -P INPUT DROP
/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT
/sbin/iptables -A OUTPUT -o eth0 -d 192.168.1.0/24 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A OUTPUT -p udp --sport 67 -j ACCEPT
/bin/grep -h '^remote ' /etc/openvpn/*.ovpn | /usr/bin/cut -d ' ' -f 2 | /usr/bin/sort -du | /usr/bin/xargs -I @ /sbin/iptables -A OUTPUT -d @ -j ACCEPT
/sbin/iptables -A OUTPUT -o eth0 -j REJECT


What it does (line by line):
1) Set policy to reject all incoming traffic other than what we specifically allow.
2) Allow incoming loopback traffic.
3) Allow incoming traffic already associated with a connection.
4) Allow incoming traffic on eth0 from the local lan.
5) Allow outbound traffic on eth0 to the local lan if it is already associated with a connection.
6) Allow outbound traffic on udp port 67 to allow the machine to get an IP address via DHCP (you can remove this if you use manually assigned addresses).
7) Parse the ovpn files found in /etc/openvpn and allow outbound traffic to any servers listed.
8) Reject all other outbound traffic on eth0. It is important to specify eth0 here, otherwise we'd block outbound traffic on the vpn itself.

Note: This will block normal web browsing and other such activity even when the vpn is disconnected (I simply never do anything on the net from this machine without the vpn). To enable normal communications, just run iptables -F to flush the rules. You can even use the --up and --down parameters of openvpn to do this as well. EDIT: That last sentence should be ignored for a secure setup. While it might be convenient to automatically disable the rules, it defeats the original purpose of preventing communication when the vpn fails unexpectedly.
Last edited by M51 on 2013-11-06 20:33, edited 1 time in total.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-11-04 20:24

This is perfect..really nice..

But i have some questions.

Why does it not say tun0 anywhere?

And how do i run these commands? Put them in a *.py file and execute it?
I must confess, i dont really understand everything you are explaining with the script. Stuff like loopback traffic and why (in rule 8) you would reject all other traffic in eth0. How can this script determin the eth0 traffic through the vpn, from traffic only locally?

Sorry for the dumb questions, but i really want to understand what im doing, before i do it..

Again, thanks for this.. i really hope i can use it!!
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-04 21:46

This is a bash script, so just put the contents in a file (give it a .sh extension if you like, but it isn't required). Let's say you decide to call it myscript.sh. Now run the command "chmod +x myscript.sh" to mark the file as executable.

Now you can run it from the directory you placed it in like so: ./myscript.sh
However, it must be run as root because it uses iptables (either use su or sudo to run it).
You can also run it automatically at boot up by placing it as an init script. That can get a bit involved so I won't go into it unless you ask.

To answer your questions:
We don't mention tun0 because we're not interested in restricting traffic on the vpn, only traffic outside the vpn.
Loopback is just basic networking stuff. Essentially it means allowing the machine to talk to itself, which is required for normal functioning.
The last rule blocks all traffic going out of eth0 that wasn't already allowed by an earlier rule. All vpn traffic will go to one of your vpn servers and will be allowed by one of the dynamically created rules in line 7.

The output rules written in english might look like this:
5) Allow the machine to send data to the local lan over eth0 IF AND ONLY IF the communication was initiated by another machine (one of your clients).
6) Allow the machine to ask for an ip address from your dhcp server.
7) Allow the machine to talk to vpn servers mentioned in /etc/openvpn/*.ovpn files.
8) Don't talk to anything else on eth0.

How about an example to help clarify? Say you want to go to a website over the vpn. The flow is something like this:
1) Your browser sends data to port 80 on some remote ip via tun0 (No output rule restricts this, so it is allowed. Note: the data hasn't left our machine yet.)
2) Data going out of tun0 (a virtual adapter) get encrypted by the vpn and wrapped into packets destined for the vpn server.
3) Encrypted packets are sent to the vpn server via eth0 (this is allowed by line 7 of our script - not counting the #!/bin/sh header).
4) The response is allowed because the connection was initiated by our machine (line 3 of the script).

Now we look at the flow if the vpn fails:
1) Your browser sends data to port 80 on some remote ip via eth0 (tun0 doesn't exist) and it is rejected. (Why it is rejected: Line 5 does not apply because no other machine on the lan initiated this connection. Line 6 does not apply because we are not currently getting an address via dhcp. Line 7 does not apply unless the website you are trying to hit happens to also be one of your vpn servers. Line 8 applies because the data is going out via eth0, so it is rejected.

This also prevents dns leaks even when the vpn is running:
1) Your browser (or torrent software or whatever) tries to resolve a host name.
2) The machine initiates a dns request using the dns servers in /etc/resolv.conf
3) Worst case scenario happens and the vpn provided dns servers don't respond in a timely fashion.
4) Your machine may try use the locally provided dns servers if they are still listed in /etc/resolv.conf, which generally they are.
5) If the dns servers are not on your local lan, the request will by blocked by line 8, however let's assume that you (like most people) knowingly or unknowingly use your router as a dns proxy, meaning the ip listed in /etc/resolv.conf is likely 192.168.1.1 (if you use 192.168.1.0 as your local network). That's a local lan address, but thankfully it will not match line 5 because no other machine on the lan initiated the communication and it is again blocked by line 8.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-11-06 22:33

Wow that is really well explained. I Just wanted to let you know that i have read your post. But due to a busy schedule, i cant try this out right now. But i will as soon as possible. I just have to read your post a couple of times to really understand the process.

Are you familar with UFW? I like this program because its so simple and seems stable. And again its something i can understand. The only reason why i am apprehensive about installing ufw and gufw is because the version that is released for my system (openmediavault - debian squeeze) is deprecated, and it takes alot of energy, setting up ubuntu server, and with alot of stuff done from the commandline...:(

Now, your script seems to make a great deal of sense to me...and i could avoid going the ubuntu route.. So i hope if its okay that i have some follow up questions later on?

There wouldent be any problems runming this script with mu distro, will there?
And what is my guarantee that these rules will be active, and not fail while the server is running? Perhaps its just me that dont understand how software operates.. A log file or something that can give me a piece of mind, that im protected.. ( my isp dosent like torrent traffic) :)

Again, thanks for this well explained post.
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-07 03:44

I've not used UFW. I prefer to just use iptables directly. It's really not that difficult once you get used to it.

You can use 'iptables -L' to list all the current rules for the iptables filter table. Do this before you try running the script to see if your distro uses any rules by default. If you have any existing rules, post them and I will tell you how you can combine these rules with yours.

With regard to your question about reliability: This script simply configures Linux's built in firewall capability, which is reliable enough it is used as the basis of commercial firewalls. Yes, you can log everything if you like, using optional arguments on each rule. You can also use 'iptables -L' at any time to reassure yourself the rules are in effect. I actually use 'iptables -L -n' because it is faster as it does not try to display hostnames for each rule in place of ip addresses (saves the time of doing a reverse dns lookup on each rule).

Understanding iptables in a nutshell:
Iptables has several tables of rules used for different purposes, each broken into 'chains'. The only table we use in the script is the 'filter' table, which is the default (which is why you don't see it mentioned on any of the command lines). The filter table is generally used to block or allow traffic and is divided into three chains called INPUT, FORWARD, and OUTPUT. Although it is possible to create custom chains, we don't need to do that. The forward chain is used for routing traffic from one adapter to another, so we don't care about that either, leaving just the input and output chains which correspond to incoming and outgoing traffic respectively. Each chain has a default policy which applies to any traffic which matches no rules. The default policy in Debian is ACCEPT, which means any traffic which matches no rule is allowed by default. With the rules defined by my script, we change the input chain to a default policy of DROP, which means to drop the packet immediately (like it never existed) if it matches no rules. The rest of the script lines append rules to the input and output chains to match packets of certain criteria. Rules are processed in order when a packet is sent/received.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-07 14:34

Just thought I'd add that UFW is a frontend for iptables...meaning it is no different in terms of reliability, just in ease of use.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-11-11 12:20

Hi again.

It took some days to setup my new system, but now i have re-read a bunch of times, and tried out the script. And it seems to be working very well!!

I have installed Ubuntu Server instead of Debian.. But it seems to be working without any problems.

I have a couple of questions thou:

I just copied the script as you wrote it, without changing anything. My router is on: 192.168.1.1 so i figured that i didn't have to change anything.

When i do:

"ip-trables -L -n" i get:

Code: Select all
root@ubuntu:~# iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  192.168.1.0/24       0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            192.168.1.0/24       state RELATED,ESTABLISHED
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp spt:67
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
ACCEPT     all  --  0.0.0.0/0            xx.xx.xx.xx
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable


Does the rules look like they are working as they should? Is there a way i can double check that everything is as it should be? the "xx.xx.xx.xx" As you probably have figured out, are the IP's for my VPN provider.

I have installed openVNP by:

sudo apt-get install openvpn resolvconf

So i guess, as you wrote in your post, that i would avoid DNS leaks, because the DNS is recieved from my VPN service?
I am not able to do: curl ifconfig.me
in order to find my external IP. But i guess this is what you ment, when you said:

Note: This will block normal web browsing and other such activity even when the vpn is disconnected (I simply never do anything on the net from this machine without the vpn).


Can i get my external IP without flushing the rules?
But it dosen't matter that much, actually it just proofs that the ip-tables are working.

And last, but not least, yes please tell me how i add this to init.d and make it start up as the first rule.

Besides that, thanks a million for your support! :)
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Re: How to block internet connection when VPN fails?

Postby M51 » 2013-11-11 16:30

You can do a verbose listing: 'iptables -L -n -v' to get a more detailed rule listing that includes adapter information.

I assume you are trying to get your external IP address when the vpn is down? If so you can either flush the rules before attempting, or add an exception for that particular site.

To add an exception, add the following line just before the last line that rejects all outbound traffic on eth0:
iptables -A OUTPUT -p tcp --dest ifconfig.me --dport 80 -j ACCEPT

Keep in mind, that the actual rule that gets added will contain the IP address, not the hostname. The name is resolved at the time the rule is added. If the address changes later, the rule will need to be updated. The simplest way would be to flush the rules and re-run the script. A more secure method would be to surgically remove and re-add just that single rule using iptables -D and -I to delete and insert a single rule (iptables man page is a big help here). Keep in mind that if you decide to change just that one rule while the others are still in effect, the vpn would have to be up for the name to be resolved successfully, as no outbound DNS queries are allowed when the vpn is down.

The easiest way to make everything come up automatically is to install the iptables-persistent package. It installs an init script which saves your iptables rules on shutdown and restores them on startup. That means you'd only have to run your script once to set the rules. After that they'd be restored automatically on every boot. If your *.ovpn files change, you can flush the rules and re-run your script to update them.
M51
 
Posts: 397
Joined: 2013-05-13 01:38

Re: How to block internet connection when VPN fails?

Postby Danielorum » 2013-11-13 15:26

Forgive me, for not being specific enough, but i was wondering if i could output my external IP, when i was connected to the VPN? But if it is too difficult, it dosen't matter.. it could just be nice if it was possible..

Besides that...I'm really amazed how well this works!
Danielorum
 
Posts: 32
Joined: 2013-10-21 17:47

Next

Return to General Questions

Who is online

Users browsing this forum: No registered users and 17 guests

fashionable