You are not logged in.

#1 2017-03-29 20:15:42

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

iptables "internet kill switch" when VPN is disconnected

I'm interested in making sure that only network traffic through my VPN is allowed on my laptop. That is, if my laptop (a VPN client) is disconnected from my VPN server (which I don't control), I don't want to send or receive any traffic on the client (unless it is to reestablish connection with my VPN). I have setup the following iptables rules on my laptop, and it seems to work. When I am connected to the VPN server I can access the internet, and when I am disconnected I cannot. I also want to allow LAN connections, which this does. The 209.xx... IP addresses are my VPN's DNS servers.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 192.168.0.0/24 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d 192.168.0.0/24 -j ACCEPT
-A OUTPUT -d 209.222.18.222/32 -j ACCEPT
-A OUTPUT -d 209.222.18.218/32 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 1197 -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
COMMIT

I see many examples of people explicitly listing out the IP addresses of their VPN servers, but listing port 1197 and the RELATED,ESTABLISHED rule as above seem to not make that necessary.

Again, this seems to work, but am I missing potentially missing something with these rules? Are there better ways to do this?

I did find this thread: https://bbs.archlinux.org/viewtopic.php?id=192218 However, it seems more complicated than necessary.

Offline

#2 2017-03-29 21:23:49

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: iptables "internet kill switch" when VPN is disconnected

Looks reasonable, from a glance.

However, you are inviting connection problems if you disable ICMP.

Offline

#3 2017-03-29 21:55:46

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,229
Website

Re: iptables "internet kill switch" when VPN is disconnected

rdeckard wrote:

I see many examples of people explicitly listing out the IP addresses of their VPN servers, but listing port 1197 and the RELATED,ESTABLISHED rule as above seem to not make that necessary.

Again, this seems to work, but am I missing potentially missing something with these rules? Are there better ways to do this?

What you've done is reasonable, just remember that UDP 1197 will be allowed *anywhere*, so any traffic on that port will be allowed, even if it's not actually VPN tunnel traffic.  I would categorize it as a very-low-risk hole (depending on your likely threat vectors), but if you want to close it up then you should limit it to your VPN providers IP addresses.

Offline

#4 2017-03-30 02:14:05

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: iptables "internet kill switch" when VPN is disconnected

fukawi2 wrote:

What you've done is reasonable, just remember that UDP 1197 will be allowed *anywhere*, so any traffic on that port will be allowed, even if it's not actually VPN tunnel traffic.  I would categorize it as a very-low-risk hole (depending on your likely threat vectors), but if you want to close it up then you should limit it to your VPN providers IP addresses.

Thanks for pointing out the potential hole. I chose not to list every IP address for my VPN, since there is no public listing. I was having to resolve the domain each time and getting a new address that needed to be whitelisted. It seems like allowing this hole is an acceptable compromise for me, since I just don't want to accidently browse the web, check email, etc without the VPN connection.

brebs wrote:

However, you are inviting connection problems if you disable ICMP.

Following Simple Stateful Firewall, I added a few ICMP rules.

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -s 192.168.0.0/24 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d 192.168.0.0/24 -j ACCEPT
-A OUTPUT -d 209.222.18.222/32 -j ACCEPT
-A OUTPUT -d 209.222.18.218/32 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 1197 -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
COMMIT

Offline

#5 2017-03-30 08:11:17

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: iptables "internet kill switch" when VPN is disconnected

You've got it the wrong way around - ICMP type 8 (echo request) is probably the *least* useful to you.

ICMP type 3 (destination unreachable) is probably the most useful, if you want reliable connections that can adjust to e.g. MTU differences.

Edit: Also, should enable ICMP on *each* interface.

Last edited by brebs (2017-03-30 10:01:11)

Offline

#6 2017-03-30 13:42:31

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: iptables "internet kill switch" when VPN is disconnected

brebs wrote:

You've got it the wrong way around - ICMP type 8 (echo request) is probably the *least* useful to you.

ICMP type 3 (destination unreachable) is probably the most useful, if you want reliable connections that can adjust to e.g. MTU differences.

Edit: Also, should enable ICMP on *each* interface.

I'll admit this is a little confusing to me. I have been looking at the iptables manpage some as well as a few articles, but most don't address filtering the OUTPUT chain. Here's what I have now:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:ICMP - [0:0]
:TCPIN - [0:0]
:TCPOUT - [0:0]
:UDPIN - [0:0]
:UDPOUT - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDPIN
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCPIN
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p udp -m conntrack --ctstate NEW -j UDPOUT
-A OUTPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCPOUT
-A OUTPUT -j REJECT --reject-with icmp-net-unreachable
-A TCPIN -s 192.168.0.0/24 -j ACCEPT
-A TCPIN -i tun+ -j ACCEPT
-A TCPOUT -d 192.168.0.0/24 -j ACCEPT
-A TCPOUT -o tun+ -j ACCEPT
-A UDPIN -s 192.168.0.0/24 -j ACCEPT
-A UDPIN -i tun+ -j ACCEPT
-A UDPOUT -d 192.168.0.0/24 -j ACCEPT
-A UDPOUT -d 209.222.18.222/32 -j ACCEPT
-A UDPOUT -d 209.222.18.218/32 -j ACCEPT
-A UDPOUT -p udp -m udp --dport 1197 -j ACCEPT
-A UDPOUT -o tun+ -j ACCEPT
COMMIT

Adding the OUTPUT rule to jump to REJECT fixed a problem of my programs hanging, waiting for a connection when the VPN is down. Now they simply tell me the connection is refused (which is much more desirable).

Am I on the right track here? You mentioned implementing ICMP for each interface, but I only want traffic on the tun interface.

Edit: I changed one of the REJECT rules to "icmp-net-unreachable".

Edit2: Here's a simplified version:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 192.168.0.0/24 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d 192.168.0.0/24 -j ACCEPT
-A OUTPUT -d 209.222.18.222/32 -j ACCEPT
-A OUTPUT -d 209.222.18.218/32 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 1197 -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
-A OUTPUT -j REJECT --reject-with icmp-net-unreachable
COMMIT

Last edited by rdeckard (2017-03-30 14:02:39)

Offline

#7 2017-03-30 15:22:16

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: iptables "internet kill switch" when VPN is disconnected

I think I know what you're getting at now. To enable ICMP I could add the following in the appropriate places:

-A INPUT -p icmp -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -p icmp -j ACCEPT
-A OUTPUT -p icmp -m conntrack --ctstate NEW -j ACCEPT

Offline

#8 2017-03-30 16:01:39

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: iptables "internet kill switch" when VPN is disconnected

There is no need to involve connection-tracking, with ICMP. Just allow ICMP (unless you expect DDoS attacks).

Regarding "I only want traffic on the tun interface", don't forget that the tun traffic actually goes *through* your Internet-facing interface wink So there are at least 3 interfaces involved:

* lo (trusted, easy)
* tunnel for VPN
* Internet-facing (your 192.168.0.0/24)

Offline

#9 2017-03-30 16:24:31

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: iptables "internet kill switch" when VPN is disconnected

Gotcha. Here's what I ended up going with in the end, adding ICMPIN and ICMPOUT chains that accept icmp protocol on tun and 192.168.0.0/24. Thanks for all of the feedback.

:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:ICMPIN - [0:0]
:ICMPOUT - [0:0]
:TCPIN - [0:0]
:TCPOUT - [0:0]
:UDPIN - [0:0]
:UDPOUT - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -j ICMPIN
-A INPUT -p udp -m conntrack --ctstate NEW -j UDPIN
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCPIN
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -j ICMPOUT
-A OUTPUT -p udp -m conntrack --ctstate NEW -j UDPOUT
-A OUTPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCPOUT
-A OUTPUT -j REJECT --reject-with icmp-net-unreachable
-A ICMPIN -i tun+ -j ACCEPT
-A ICMPIN -s 192.168.0.0/24 -j ACCEPT
-A ICMPOUT -o tun+ -j ACCEPT
-A ICMPOUT -d 192.168.0.0/24 -j ACCEPT
-A TCPIN -i tun+ -j ACCEPT
-A TCPIN -s 192.168.0.0/24 -j ACCEPT
-A TCPOUT -d 192.168.0.0/24 -j ACCEPT
-A TCPOUT -o tun+ -j ACCEPT
-A UDPIN -s 192.168.0.0/24 -j ACCEPT
-A UDPIN -i tun+ -j ACCEPT
-A UDPOUT -d 192.168.0.0/24 -j ACCEPT
-A UDPOUT -d 209.222.18.222/32 -j ACCEPT
-A UDPOUT -d 209.222.18.218/32 -j ACCEPT
-A UDPOUT -p udp -m udp --dport 1197 -j ACCEPT
-A UDPOUT -o tun+ -j ACCEPT
COMMIT

Offline

#10 2017-03-30 16:53:02

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: iptables "internet kill switch" when VPN is disconnected

I would switch the order around, to accept ICMP (with some rate-limiting, to prevent DDoS) *before* dropping INVALIDs.That would be better than having the uncertainty of whether the INVALID DROPping could include useful ICMP packets.

*Dropping* all INVALIDs is rather... unfriendly. A REJECT (rate-limited, for bonus points) may be preferable.

Offline

#11 2017-04-29 19:48:19

chmercesmoreira
Member
From: Rio de Janeiro/Brazil
Registered: 2016-02-13
Posts: 13

Re: iptables "internet kill switch" when VPN is disconnected

Hey, I just found this Arch Wiki page: https://wiki.archlinux.org/index.php/Pr … net_Access
teaching how to enable "kill switch" feature using iptables.

I have one doubt: After adding these rules everything is working as expected, but if I restart my computer, after it turns on I'm not getting any internet connection, I need to remove these rules, connect, and after that re-add the rules. How do I avoid this problem?


Knowledge is Irresistible

Offline

#12 2017-04-29 20:29:29

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: iptables "internet kill switch" when VPN is disconnected

What exactly isn't working? The idea of those rules is that openvpn is using exactly the IP address that's allowed in the rules, so it's supposed to still be able to connect. Afterwards the tun interface shows up that all other programs will use for their network access.

Offline

#13 2017-04-29 20:42:35

chmercesmoreira
Member
From: Rio de Janeiro/Brazil
Registered: 2016-02-13
Posts: 13

Re: iptables "internet kill switch" when VPN is disconnected

In my case I'm using the systemd service openvpn to start the VPN connection:

openvpn-client@Brazil.service

The problem is that using these iptables rules the service doesn't work, I'm unable to connect to the VPN server. Only after removing these iptables rules I can connect to the VPN server.
These are informations of the VPN server I'm connecting (PIA VPN)

client
dev tun
proto udp
remote brazil.privateinternetaccess.com 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass /etc/private-internet-access/login.conf
comp-lzo
verb 1
reneg-sec 0
crl-verify /etc/openvpn/client/crl.rsa.2048.pem
ca /etc/openvpn/client/ca.rsa.2048.crt
disable-occ
auth-nocache
script-security 2
up /etc/openvpn/update-resolv-conf.sh
down /etc/openvpn/update-resolv-conf.sh

I already changed the port from 1197 to 1198 on this rule:

-A OUTPUT -p udp -m udp --dport 1198 -j ACCEPT

, so that is not the problem.
Actually if I apply these rules with the connection to the VPN already done I get the correct behavior of the rules, restricting traffic only through the VPN. The problem is when I start the system.


Knowledge is Irresistible

Offline

#14 2017-04-29 21:01:35

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: iptables "internet kill switch" when VPN is disconnected

Perhaps DNS doesn't work and openvpn can't turn that "brazil.privateinternetaccess.com" name into an IP address? If I understood things right, you are supposed to use DNS servers 209.222.18.222 and 209.222.18.218 as those have a special case in the rules.

There should be an error message about what's happening in "journalctl -b -u openvpn-client@Brazil".

Offline

#15 2017-04-29 21:12:12

chmercesmoreira
Member
From: Rio de Janeiro/Brazil
Registered: 2016-02-13
Posts: 13

Re: iptables "internet kill switch" when VPN is disconnected

I run this command and there are no log errors on journal.
I'm already using the DNS provided by them:

$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 209.222.18.222
nameserver 209.222.18.218

http://i.imgur.com/Zywwtpu.png

These are the iptables rules I'm using, file: /etc/iptables/iptables.rules:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:10]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d 209.222.18.222/32 -j ACCEPT
-A OUTPUT -d 209.222.18.218/32 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 1198 -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
-A OUTPUT -j REJECT --reject-with icmp-net-unreachable
COMMIT

Mod note: Please don't embed large images in your posts. See the CoC regarding acceptable image sizes. -- WorMzy

Last edited by WorMzy (2017-04-29 21:56:02)


Knowledge is Irresistible

Offline

#16 2017-04-29 21:45:42

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: iptables "internet kill switch" when VPN is disconnected

Are you showing your resolv.conf when you are connected to the VPN? What does it look like if you are not connected?

What's openvpn printing in the journal when it can't connect?

If you want to try a different way to block internet access without VPN, I use rules that make it so root is the only one who can freely use Internet through the ethernet interface. Users are only allowed to use the tun interface. Openvpn can connect because it's running as root, but Firefox, Bittorrent etc. are running as users and are blocked when the VPN is down. It allows to still do things like "sudo pacman -Syu" when the VPN is down. The rules look like this:

iptables.rules:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [527:66104]
-A INPUT -i lo -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s 192.168.1.0/24 -i en+ -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
-A OUTPUT -o en+ -m owner --uid-owner 0 -j ACCEPT
-A OUTPUT -o en+ -m owner --uid-owner dnsmasq -j ACCEPT
-A OUTPUT -d 192.168.1.0/24 -o en+ -j ACCEPT
COMMIT

ip6tables.rules:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s fe80::/10 -i en+ -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o tun+ -j ACCEPT
-A OUTPUT -o en+ -m owner --uid-owner 0 -j ACCEPT
-A OUTPUT -o en+ -m owner --uid-owner dnsmasq -j ACCEPT
-A OUTPUT -d fe80::/10 -o en+ -j ACCEPT
COMMIT

There's also a rule that the dnsmasq user can go out, and rules to allow using ethernet to local network for everyone.

Last edited by Ropid (2017-04-29 21:48:06)

Offline

#17 2017-04-29 22:06:14

chmercesmoreira
Member
From: Rio de Janeiro/Brazil
Registered: 2016-02-13
Posts: 13

Re: iptables "internet kill switch" when VPN is disconnected

Yes, this is my resolv.conf before I'm connected to the VPN server:

# Generated by resolvconf
search rjo.virtua.com.br
nameserver 201.17.1.82
nameserver 201.17.1.175

These DNS addresses are from my ISP.

There are no messages related to openvpn on my journal at startup (when I'm stuck without connection), I'm using this logging level (/etc/systemd/journald.conf):

MaxLevelStore=err
MaxLevelSyslog=warning
MaxLevelKMsg=warning
MaxLevelConsole=err

Last edited by chmercesmoreira (2017-04-29 22:08:37)


Knowledge is Irresistible

Offline

#18 2017-04-29 22:42:34

Ropid
Member
Registered: 2015-03-09
Posts: 1,069

Re: iptables "internet kill switch" when VPN is disconnected

I think with these rules here you are supposed to replace your ISPs nameserver with the ones from PIA or it won't work.

What does "systemctl status openvpn-client@Brazil" say after startup when your are stuck? Does it maybe not even start? It's supposed to start after "network-online.target" is hit, which should be the case if you've already got sent your IP and DNS servers from your ISP.

EDIT: I did not touch journald.conf, so use the defaults there, and openvpn writes a lot in the journal. You could perhaps stop its service and then start openvpn yourself from the command line to see what it prints. Something like this is how systemd starts it:

sudo bash -c "cd /etc/openvpn/client; /usr/bin/openvpn --nobind --config Brazil.conf"

Last edited by Ropid (2017-04-29 22:50:14)

Offline

#19 2017-04-29 23:16:46

chmercesmoreira
Member
From: Rio de Janeiro/Brazil
Registered: 2016-02-13
Posts: 13

Re: iptables "internet kill switch" when VPN is disconnected

I found a solution, you were right since the beginning of our discussion, the problem were the DNS server from my ISP that was unable to resolve the VPN hostname to the IP address.
To solve this problem I fixed the DNS from privateinternetaccess VPN on resolv.conf:

# Generated by resolvconf
nameserver 209.222.18.222
nameserver 209.222.18.218

And removed write access to this file to prevent other processes modifying it:

sudo chattr +i /etc/resolv.conf

Last edited by chmercesmoreira (2017-04-29 23:17:11)


Knowledge is Irresistible

Offline

#20 2018-06-05 14:14:29

hansolo325
Member
Registered: 2018-06-05
Posts: 1

Re: iptables "internet kill switch" when VPN is disconnected

For sure, but if you apply VPN redacted  on that, you will get different and way better results.

Last edited by ewaller (2018-06-05 17:42:06)

Offline

#21 2018-06-05 17:44:00

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,214

Re: iptables "internet kill switch" when VPN is disconnected

Read our Code of conduct:
https://wiki.archlinux.org/index.php/Co … bumping.22
and
https://wiki.archlinux.org/index.php/Co … licitation

Not a good first post.  Consider this a warning.


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

Board footer

Powered by FluxBB