jotyGill / openpyn-nordvpn

Easily connect to and switch between, OpenVPN servers hosted by NordVPN on Linux (+patch leakes)
GNU General Public License v3.0
628 stars 114 forks source link

[Firewall] Don't delete user defined firewall rules #202

Open ISO-morphism opened 6 years ago

ISO-morphism commented 6 years ago

Right now openpyn flushes the filter table's INPUT and OUTPUT chains before applying rules to ensure traffic doesn't get in/out except through the VPN tunnel. It would be nice to allow rules that a user previously defined to survive an openpyn -f.

iptables allows us to define custom chains in addition to the builtin ones. Openpyn's rules could be applied to a custom chain, and that chain could be inserted at the front of the INPUT and OUTPUT chains, then removed with openpyn --kill-flush.

Starting firewall:

# Create new custom chains
iptables --new-chain OPENPYN_INPUT
iptables --new-chain OPENPYN_OUTPUT

# Apply all of the rules openpyn currently applies to the custom chains
# instead of the builtin chains
# -- other rules here --
iptables -A OPENPYN_INPUT -j DROP
iptables -A OPENPYN_OUTPUT -j DROP

# Insert our custom chains at the beginning of the builtin INPUT/OUTPUT chains
iptables -I INPUT -j OPENPYN_INPUT
iptables -I OUTPUT -j OPENPYN_OUTPUT

# Now INPUT and OUTPUT jump straight to custom chains that have a DROP target at
# the end of them, so traffic will never make it out of them and back into INPUT/OUTPUT.

Then to remove the firewall, we simply remove the custom chains and the user's previously defined rules come back into effect.

# References to the custom chains must be removed before the chains
# can be deleted
iptables -D INPUT -j OPENPYN_INPUT
iptables -D OUTPUT -j OPENPYN_OUTPUT

# Chains must be empty in order to be deleted
iptables -F OPENPYN_INPUT
iptables -F OPENPYN_OUTPUT

# Delete the chains
iptables -X OPENPYN_INPUT
iptables -X OPENPYN_OUTPUT

I'd be happy to take on implementing this as a PR if you think it's worthwhile. Admittedly I only really cracked open the iptables manual/wikipedia page a couple of hours ago, so I may be missing something or have some syntax wrong as I haven't tested yet.