You are not logged in.
Pages: 1
Topic closed
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
Looks reasonable, from a glance.
However, you are inviting connection problems if you disable ICMP.
Offline
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.
Are you familiar with our Forum Rules, and How To Ask Questions The Smart Way?
BlueHackers // fscanary // resticctl
Offline
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.
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
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
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
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
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 So there are at least 3 interfaces involved:
* lo (trusted, easy)
* tunnel for VPN
* Internet-facing (your 192.168.0.0/24)
Offline
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
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
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
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
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
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
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
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
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
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
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
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
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
Pages: 1
Topic closed