wknapik / vpnfailsafe

IP leak prevention for OpenVPN

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Connection tracking?

ch9PcB opened this issue · comments

Hi @wknapik

I wish to know if vpnfailsafe.sh is able to do the following:

iptables -A INPUT -p tcp -m tcp -m conntrack -s 1.2.3.4 -i eth0 --sport 1194 -j ACCEPT  --ctstate ESTABLISHED

If the current version of vpnfailsafe does not have it, would it be possible for you to incorporate it?

Thanks.

Hi @ch9PcB. vpnfailsafe was designed to work alongside an existing firewall, without interfering beyond its intended function. The idea is that the user defines their firewall rules, saves them (using iptables-save, or some init script that calls it) and then uses vpnfailsafe, which adds three chains with its own rules.

I don't have access to any device other than a phone at the moment to test it, but you should be able to just add that rule and have it work as intended. If it doesn't, I'll be able to help you in a few days.

Or is your point, that rules are added only for the configured protocols, which might exclude TCP ?

I am sorry if you do not have access to internet. I do not need an immediate answer to my question. Please reply to my post at a time most convenient to you.

I understand when you wrote: "vpnfailsafe was designed to work alongside an existing firewall, without interfering beyond its intended function." I shall include some conntrack rules in my iptables.

I don't understand what you wrote: " that rules are added only for the configured protocols, which might exclude TCP ?"

Hi @ch9PcB. What I meant in my second comment was that the rule you mentioned looks a lot like it's meant to allow traffic from a vpn server over tcp. If that was the idea, than vpnfailsafe should take care of adding such a rule for every remote in your client config. For instance if your config contains lines like

remote foo.example.com 1194 udp
remote bar.example.com 443 tcp

then vpnfailsafe will add rules allowing traffic in both directions between the client and the foo and bar servers over their respective protocols and ports. So this is something you don't need to worry about.

If the rule you wanted to add is not related to the current vpn connection though, you can simply add it to your regular firewall and it should work just fine. Just make sure to save those firewall rules before vpnfailsafe is active, so you don't end up saving the vpnfailsafe-specific rules, which are meant to be added "on demand" rather than permanently.

If adding the rule solved the problem for you, please let me know and we can close this issue. If not, please describe the problem you're having.

Hi @wknapik

Let me illustrate my question with an example.

Before I came to know about vpnfailsafe, I used to use a set of iptables firewall rules to ensure that when the VPN connection was terminated abruptly, no internet traffic would go out of my laptop PC. (These rules were offered to me by a kind user on an online forum.)

Furthermore I was told that the iptables rules include connection tracking, which is better than most "vanilla" iptables rules that one gets from some how-to guides.

Below is a sample of the iptables rules that the kind user gave me:

#!/bin/bash

echo "Please wait a moment......"
echo "Saving original iptables....and....applying new iptables rules"

iptables-save > /home/user/iptables.save

iptables -A INPUT -m conntrack -j DROP --ctstate INVALID
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -p tcp -m tcp -m conntrack -s 111.222.333.444 -i eth0 --sport 443 -j ACCEPT  --ctstate ESTABLISHED #TCP
iptables -A OUTPUT -p tcp -m tcp -m conntrack -d 111.222.333.444 -o eth0 --dport 443 -j ACCEPT --ctstate NEW,ESTABLISHED
iptables -A INPUT -p udp -m udp -m conntrack -s 555.666.777.888 -i eth0 --sport 1195 -j ACCEPT  --ctstate ESTABLISHED #UDP
iptables -A OUTPUT -p udp -m udp -m conntrack -d 555.666.777.888 -o eth0 --dport 1195 -j ACCEPT --ctstate NEW,ESTABLISHED
iptables -A INPUT -i eth0 -j DROP
iptables -A OUTPUT -o eth0 -j REJECT
iptables -A OUTPUT -p tcp -m tcp -m conntrack -o tun0 --dport 80 -j ACCEPT  --ctstate NEW,ESTABLISHED
iptables -A OUTPUT -p tcp -m tcp -m conntrack -o tun0 --dport 443 -j ACCEPT  --ctstate NEW,ESTABLISHED
iptables -A OUTPUT -p udp -m udp -m conntrack -o tun0 --dport 53 -j ACCEPT  --ctstate NEW,ESTABLISHED
iptables -A OUTPUT -p tcp -m tcp -m conntrack -o tun0 --dport 53 -j ACCEPT  --ctstate NEW,ESTABLISHED
iptables -A INPUT -p tcp -m tcp -m conntrack -i tun0 --sport 80 -j ACCEPT  --ctstate ESTABLISHED
iptables -A INPUT -p tcp -m tcp -m conntrack -i tun0 --sport 443 -j ACCEPT  --ctstate ESTABLISHED
iptables -A INPUT -p udp -m udp -m conntrack -i tun0 --sport 53 -j ACCEPT  --ctstate ESTABLISHED
iptables -A INPUT -p tcp -m tcp -m conntrack -i tun0 --sport 53 -j ACCEPT  --ctstate ESTABLISHED
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
iptables -A FORWARD -j DROP

Question: If I use vpnfailsafe, can I do away the above iptables rules? (This is what I really wish to know.)

P.S.: As I have provided the iptables rules above, could you comment on them please? Are they in need of improvements? Thanks in advance.

Question: If I use vpnfailsafe, can I do away the above iptables rules?

It depends.

vpnfailsafe was not meant to set up a complete firewall for the user. Only prevent IP leaks. Other safety measures are left to the user's pre-existing firewall rules.

So the rules you have that are only meant to prevent IP leaks can be removed without loss, but the ones meant to further limit the traffic allowed to/from your machine could be left in.

What you pasted is not the complete picture, that iptables -S would give. For instance INPUT/OUTPUT/FORWARD policies are unknown, as well as any rules that existed before the script was run.

The most basic, but very effective firewall for use on a desktop could be set up with a script like this one:

#!/usr/bin/env bash

set -euo pipefail

iptables -F
iptables -X
for table in nat mangle raw security; do
    for opt in -F -X; do
        iptables -t "$table" "$opt"
    done
done

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
iptables -I INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

All it does is clear all the rules and say only accept input that was requested from that machine, accept all output and don't forward anything. That's what most people want (I would think).

This, combined with vpnfailsafe would be a pretty good firewall in my book, though I'm no authority on the matter.

So going back to your question - assuming that the INPUT/OUTPUT policies are DROP/REJECT in your case, the firewall rules you pasted would do pretty much what the script I pasted + vpnfailsafe would achieve, with the additional limit on what services can be accessed (only ports 80 (http), 443 (https) and 53 (dns)) in the case of your script.

There would be no harm in using your script as-is, but removing just the leak-prevention rules would make sense. Or you could just use the basic script I pasted in this response and simplify your rules further (also allowing outgoing traffic to other ports).

So the rules you have that are only meant to prevent IP leaks can be removed without loss, but the ones meant to further limit the traffic allowed to/from your machine could be left in.

Thanks for your clarification.

What you pasted is not the complete picture, that iptables -S would give. For instance INPUT/OUTPUT/FORWARD policies are unknown, as well as any rules that existed before the script was run.

As suggested by you, below is the output before I launch my iptables firewall rules:

user@computer:~$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
user@computer:~$

Below is the output after I launch my iptables firewall rules:

user@computer:~$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -s 111.222.333.444/32 -i eth0 -p udp -m udp --sport 1194 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -s 111.222.333.444/32 -i eth0 -p udp -m udp --sport 1194 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -j DROP
-A INPUT -i tun0 -p tcp -m tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i tun0 -p tcp -m tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i tun0 -p udp -m udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i tun0 -p tcp -m tcp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun0 -j ACCEPT
-A FORWARD -i tun0 -o eth0 -j ACCEPT
-A FORWARD -j DROP
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -d 111.222.333.444/32 -o eth0 -p udp -m udp --dport 1194 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -d 111.222.333.444/32 -o eth0 -p tcp -m udp --dport 1194 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -o eth0 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o tun0 -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -o tun0 -p tcp -m tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -o tun0 -p udp -m udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -o tun0 -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
user@computer:~$ 

The most basic, but very effective firewall for use on a desktop could be set up with a script like this one:

Thank you for your script. If you do not mind, I have a few questions about it:

set -euo pipefail

What does it do?

for table in nat mangle raw security; do
for opt in -F -X; do
iptables -t "$table" "$opt"
done

What does it do?

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Don't you have to insert the resolved IP addresses of the VPN servers into the above rule?

As suggested by you, below is the output before I launch my iptables firewall rules:

Since the script you pasted doesn't set any policies, this would mean, that the firewall rules only really prevent IP leaks and drop packets in invalid state. I guess the author of those rules assumed there would be a DROP, or REJECT policy on INPUT (iptables -P INPUT DROP instead of iptables -P INPUT ACCEPT). If you want to keep using those rules, you should probably set that policy for INPUT and possibly FORWARD.

set -euo pipefail

What does it do?

It sets a few options for bash, all documented in the bash man page. The gist of it is that the script should exit on errors instead of continuing. It's not very relevant here. I just stick it at the beginning of all my scripts (though I skip -u on a case-by-case basis).

[the loop]

What does it do?

It just clears the firewall rules, so we start in a clean, known state.

Don't you have to insert the resolved IP addresses of the VPN servers into the above rule?

This is a general rule, we're not limiting this to any specific IP. It just says we want to accept traffic we requested and the general INPUT policy of DROP will drop everything else.

Since the script you pasted doesn't set any policies, this would mean, that the firewall rules only really prevent IP leaks and drop packets in invalid state.

If you want to keep using those rules, you should probably set that policy for INPUT and possibly FORWARD.

The backstory is this: there are times when I do not use a VPN tunnel, meaning that I am not worried about IP and DNS leaks. During those times, I will use the default policies set by my Linux distro which are:

user@computer:~$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
user@computer:~$

Question: If I change the default policies set by my Linux distro to "input drop" or "input reject", "forward drop" or "forward reject", will I still be able to surf the internet or ping websites?

This is a general rule, we're not limiting this to any specific IP. It just says we want to accept traffic we requested and the general INPUT policy of DROP will drop everything else.

Thanks for your clarification. Am I correct to state that it is better to specify resolved IP addresses?

During those times, I will use the default policies set by my Linux distro

You could just run the script I pasted in those instances and it would clean up all existing rules (including those set by vpnfailsafe) and set the minimal rules that should give you pretty good protection.

Just clearing all rules and setting all policies to ACCEPT will cause all traffic to/from your machine to be accepted, which is probably not what you want.

Question: If I change the default policies set by my Linux distro to "input drop" or "input reject", "forward drop" or "forward reject", will I still be able to surf the internet or ping websites?

If you clear all rules and just set those policies, you will not be able to to do much, since all INPUT will be DROPped/REJECTed.

Am I correct to state that it is better to specify resolved IP addresses?

If your rule is meant to work for one host, then you specify the source/destination, otherwise you don't. If you use a domain name, that domain will be resolved and an appropriate number of rules will be added, to cover each IP.

Anyway, I think this issue can be closed, since there's no problem with vpnfailsafe, that's being addressed here.