How to set up a firewall with a vpn (i.e. protonvpn)
SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How to set up a firewall with a vpn (i.e. protonvpn)
I'm running -current64 fully updated and I use network-manager to establish my initial network connection and that works fine. For some time now I have been using ProtonVPN and after booting and logging in I issue the "protonvpn c" command to select a server to connect to. It is usually CH-DE1 Secure-Core server and that works fine. Now to my firewall question. I have a very basic understanding of firewalls. What my question is is how to configure the firewall to handle the fact that my ProtonVPN connection uses variable IP addresses presumably to handle load balancing. That is although I always use the CH-DE1 Secure-Core connection that can actually make a connection to a number of different servers and my visible IP address will vary.
bash-5.2# protonvpn s
ProtonVPN now offers an official Linux app which includes a graphical user interface.
Visit https://protonvpn.com/support/official-linux-client to upgrade.
Status: Connected
Time: 0:04:25
IP: 194.126.177.71
Server: CH-DE#1
Features: Secure-Core
Protocol: UDP
Kill Switch: Enabled
Country: Germany
City: None
Load: 58%
Received: 78.44 KB
Sent: 22.42 KB
So I am at a loss as to how to figure out how to set up a firewall to handle protecting eth0 given the variable IP addresses. I have read a number of articles trying to get to grips with this but have no answers. Most say that a reputable VPN service will have a suitable firewall in place. Some have said that although the VPN may provide suitable firewall protection your eth0 interface is still exposed.
My head is spinning. Can someone please point me to a solution. Many thanks in advance
Distribution: VM Host: Slackware-current, VM Guests: Artix, Venom, antiX, Gentoo, FreeBSD, OpenBSD, OpenIndiana
Posts: 1,011
Rep:
Assuming that protonvpn uses standard openvpn protocol, make sure that your firewall lets tun0 traffic through. That is all. Or all proton0 (I assume that this is "proprietary" virtual device corresponding to tun0 handling vpn traffic) traffic. Nothing else is needed.
I am sure yours will be different but I use Torguard and the VPN interface on my machine is tun0. This is what my iptables entries look like on my firewall, this is not my entire firewall, but this is the relevant sections and it should give you an idea. I am no network or iptables firewall guru so I an not 100% sure this is the best way to do it, but it does work.
Code:
###############################################################################
#
# INPUT Chain
#
# Allow OpenVPN Connection
$IPT -A INPUT -i $INET_IFACE -m state --state NEW -p udp --dport 1194 -j ACCEPT
$IPT -A INPUT -i $TUN_IFACE -j ACCEPT
$IPT -A FORWARD -i $TUN_IFACE -j ACCEPT
$IPT -A FORWARD -i $TUN_IFACE -o $INET_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $INET_IFACE -o $TUN_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -t nat -A POSTROUTING -s 10.35.0.0/24 -o $INET_IFACE -j MASQUERADE
###############################################################################
#
# OUTPUT Chain
#
# Allow Output Through OpenVPN
$IPT -A OUTPUT -o $TUN_IFACE -j ACCEPT
$TUN_IFACE variable being "tun0"
$INET_IFACE variable being "eth0"
Perhaps something in what I've adopted will be of assistance. (not guaranteed to be correct...)
Code:
root:~# cat rc.openvpn
#!/bin/bash
#
# Start/Stop/Restart the OpenVPN connection
# Also update the IPTables to contain a killswitch for the VPN
# OpenVPN configuration file directory to utilize random server
dOVPN="/etc/openvpn/NORDVPN/ovpn_udp"
# OpenVPN login info to pass with the config file
pOVPN="/etc/openvpn/NORDVPN/login.info"
# OpenVPN PID Directory
dPID="/var/run/openvpn"
# WAN IP address file for status checking
fWANIP="$dPID/WAN.ip"
# IPTables variables -- adjust if needed
IPT="/usr/sbin/iptables"
INET="eth0"
IVPN="tun0"
root_check() {
# Check that we are running this script as the root user
if [[ $EUID != 0 ]]; then
echo "[ ABORT ]: This script must be ran as root!"
echo ""
exit 1
fi
return 0
}
dPID_check() {
# Make sure we have a PID directory, if not create one.
if [ ! -d $dPID ]; then
echo "Creating missing PID storage directory: [ $dPID ]"
echo ""
/usr/bin/mkdir -p $dPID > /dev/null 2>&1
/usr/bin/chown root:root $dPID
/usr/bin/chmod 755 $dPID
fi
return 0
}
iptables_flush() {
echo "Flushing IPTables firewall rules..."
echo ""
# Reset default policies to ACCEPT
$IPT -P INPUT ACCEPT
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -t nat -P PREROUTING ACCEPT
$IPT -t nat -P POSTROUTING ACCEPT
$IPT -t nat -P OUTPUT ACCEPT
$IPT -t mangle -P PREROUTING ACCEPT
$IPT -t mangle -P OUTPUT ACCEPT
# Flush all rules
$IPT -F
$IPT -t nat -F
$IPT -t mangle -F
# Erase all non-default chains
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
# Zero our counters
$IPT -Z
return 0
}
iptables_load() {
# Set IPTables rules to enable protection
echo "Creating IPTables firewall rules..."
# First set the policies to DROP everything
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP
# Allow loopback communication
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Allow local network connections
$IPT -A INPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT
$IPT -A OUTPUT -s 192.168.0.0/16 -d 192.168.0.0/16 -j ACCEPT
# Allow connections to VPN server
$IPT -A INPUT -i eth0 -s $VPNIP/8 -j ACCEPT
$IPT -A OUTPUT -o eth0 -d $VPNIP/8 -j ACCEPT
# Allow all connections on the vpn tunnel interface
$IPT -A INPUT -i tun0 -j ACCEPT
$IPT -A OUTPUT -o tun0 -j ACCEPT
# Drop anything that was not explicitly allowed above
$IPT -A INPUT -j DROP
$IPT -A OUTPUT -j DROP
$IPT -A FORWARD -j DROP
# Zero our counters
$IPT -Z
return 0
}
openvpn_start() {
# First flush our existing firewall rules
iptables_flush
# Return our external IP address and store it for later status checks
echo "Fetching the external WAN IP address..."
echo ""
WANIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
echo $WANIP > $fWANIP
echo "Local IP:" $WANIP
# Grab a random *ovpn file from our directory
rOVPN=`shuf -n1 -e $dOVPN/*`
# Start the OpenVPN with listed configuration file
echo "Starting the OpenVPN tunnel [ $rOVPN ]"
echo ""
# Start the OpenVPN tunnel
# /usr/sbin/openvpn --writepid $dPID/PIA.pid --config "$rOVPN" --auth-user-pass $pOVPN
/usr/sbin/openvpn --writepid $dPID/PIA.pid --daemon --config "$rOVPN" --auth-user-pass $pOVPN
# Pause to wait for the OpenVPN to come up completely
sleep 10
# Return our new external IP address to make sure the VPN started
VPNIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
echo "VPN IP: " $VPNIP
if [ $WANIP != $VPNIP ]; then
echo "VPN tunnel is established."
echo ""
# Set the IPTables rules
iptables_load
fi
return 0
}
openvpn_stop() {
# Stop the OpenVPN connection
echo "Stopping the OpenVPN Tunnels."
echo ""
/usr/bin/killall -9 openvpn > /dev/null 2>&1
rm $dPID/*.pid
rm $fWANIP
# Flush the IPTables rules
iptables_flush
return 0
}
main () {
case "$1" in
'start')
openvpn_start
;;
'stop')
openvpn_stop
;;
'restart')
openvpn_stop
openvpn_start
;;
'status')
openvpn_status
;;
*)
echo "usage $0 start|stop|restart|status"
esac
}
root_check "$@"
dPID_check "$@"
main "$@"
Daedra and BrianW thak you both for your examples. Those look like they will get me up an running as soon as I figure out how to implement them. What I had done up to this point was to generate a firewall using alienBOB's Easy Firewall Generator (thank you Eric) and pasted that into /etc/rc.d/rc.firewall. I'll now have a look at that and try to figure out how to add the bits that also open proton0 to traffic.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.