

Contents
- 1 Introduction
- 2 Benefits
- 3 Preparation
- 4 Installing and configuring OpenVPN with ProtonVPN
- 4.1 Step-1: Install OpenVPN
- 4.2 Step-2: Install resolvconf
- 4.3 Step-3: Install /etc/openvpn/update-resolv-conf script
- 4.4 Step-4: Set permissions on /etc/openvpn/update-resolv-conf
- 4.5 Step-5: Register for free ProtonVPN account
- 4.6 Step-6: Login to ProtonVPN account
- 4.7 Step-7: Select and download ProtonVPN configuration file(s)
- 4.8 Step-8: Find your ProtonVPN credentials to use with OpenVPN
- 5 Starting a ProtonVPN connection using OpenVPN
- 6 Adding VPN network interface tun0 to firewall configuration
- 7 Verifying ProtonVPN connection is up
- 8 Stopping openvpn connection
- 9 DNS resolution
- 10 Appendicies
Introduction
This document shows how to configure OpenVPN [1] on Mageia Linux to use the ProtonVPN [2] service.
Benefits
This method shown here enables connecting to ProtonVPN via OpenVPN without using the ProtonVPN "app" which, is only available for certain Linux distributions and not available for Mageia Linux.
A VPN (virtual private network) connection has several security benefits:
- Hides the source IP address (eg your ISP router's external Internet facing address) which is replaced by the external VPN endpoint IP address.
- Encrypts all your network traffic (both upload and download) between your computer/mobile/tablet and the external VPN endpoint IP address.
ProtonVPN offers both a free and paid VPN services. To use these it is necessary to register for a free account at: ProtonVPN
A ProtonVPN account can also be used to access the (free or paid for) ProtonMail service.
Preparation
The guidance given here is based on: How to manually configure OpenVPN for ProtonVPN in Linux which is written for Debian (and similar). The steps shown here have been tested on Mageia 8 and 9.
Preparation-1: sudo
Check that sudo is installed and configured as described here: Configuring_sudo
Preparation-2: tcptraceroute
The tcptraceroute command will show the network route to connect to systems and is useful to help understand how your connections reach their destination.
tcptraceroute is not installed by default in Mageia. Install with:
/bin/sudo urpmi tcptraceroute |
^ Installing tcptraceroute |
Preparation-3: create directories
Several downloads will be needed. Create directories ready for downloads and easy reference.
mkdir -p ~/Downloads/ProtonVPN/configs/ |
^ Creating two directories for PronVPN downloads |
# | directory | comment |
---|---|---|
1 | ~/Downloads/ProtonVPN/ | for downloads of scripts, zip archives, etc |
2 | ~/Downloads/ProtonVPN/configs/ | for downloads of openvpn configuration files |
Preparation-4: Make some notes on the configuration before running openvpn connection
It will be useful to make notes about the network configuration before starting openvpn connections.
Check these again after the VPN is established and observe the differences.
Four things will change when the VPN is active:
- Network interface tun0 will appear
- IP address of default gateway
- IP address of nameserver
- External connection IP address
By making a note of these it will help to understand what changes openvpn makes when it establishes a VPN connection.
tun0 network interface
ifconfig tun0 # show if network interface tun0 is active |
routing table, default gateway, and routing
netstat -rn # show the routing table |
netstat -rn | grep ^0.0.0.0 | head -1 # show the IP address of the default gateway |
/bin/sudo tcptraceroute google.com # show the network route to external site |
nameserver in /etc/resolv.conf
grep nameserver /etc/resolv.conf # show the IP address(es) of any nameservers defined in /etc/resolv.conf |
external IP address
dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}' # what is my external IP address? |
Installing and configuring OpenVPN with ProtonVPN
Step-1: Install OpenVPN
/bin/sudo urpmi openvpn |
^ Installing openVPN |
Example:
[user@localhost ~]$ /bin/sudo urpmi openvpn distrib-coffee.ipsl.jussieu.fr::mageia/distrib/8/x86_64/media/core/updates/openvpn-2.5.0-2.1.mga8.x86_64.rpm installing openvpn-2.5.0-2.1.mga8.x86_64.rpm from /var/cache/urpmi/rpms Preparing... ############################################################################### 1/1: openvpn ############################################################################### |
^ Example of installing openVPN |
Step-2: Install resolvconf
If not already installed, install resolvconf:
/bin/sudo urpmi resolvconf |
^ Installing resolvconf |
Example:
[user@localhost ~]$ /bin/sudo urpmi resolvconf [sudo] password for user: Package resolvconf-1.79-5.mga8.noarch is already installed |
^ Example of installing resolvconf Here we see that resolvconf is already installed |
Step-3: Install /etc/openvpn/update-resolv-conf script
This script [5] was posted on a Mageia Linux forum [3] .
Example of /etc/openvpn/update-resolv-conf follows:
#!/bin/bash # # Parses DHCP options from openvpn to update resolv.conf # To use set as 'up' and 'down' script in your openvpn *.conf: # up /etc/openvpn/update-resolv-conf # down /etc/openvpn/update-resolv-conf # # Used snippets of resolvconf script by Thomas Hood <jdthood@yahoo.co.uk> # and Chris Hanson # Licensed under the GNU GPL. See /usr/share/common-licenses/GPL. # # 05/2006 chlauber@bnc.ch # # Example envs set from openvpn: # foreign_option_1='dhcp-option DNS 193.43.27.132' # foreign_option_2='dhcp-option DNS 193.43.27.133' # foreign_option_3='dhcp-option DOMAIN be.bnc.ch' [ -x /sbin/resolvconf ] || exit 0 case $script_type in up) for optionname in ${!foreign_option_*} ; do option="${!optionname}" echo $option part1=$(echo "$option" | cut -d " " -f 1) if [ "$part1" == "dhcp-option" ] ; then part2=$(echo "$option" | cut -d " " -f 2) part3=$(echo "$option" | cut -d " " -f 3) if [ "$part2" == "DNS" ] ; then IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3" fi if [ "$part2" == "DOMAIN" ] ; then IF_DNS_SEARCH="$part3" fi fi done R="" if [ "$IF_DNS_SEARCH" ] ; then R="${R}search $IF_DNS_SEARCH " fi for NS in $IF_DNS_NAMESERVERS ; do R="${R}nameserver $NS " done /bin/echo -n "$R" | /sbin/resolvconf -a "${dev}.inet" ;; down) /sbin/resolvconf -d "${dev}.inet" ;; esac |
^ Copy this (above) to /etc/openvpn/update-resolv-conf. See also: [5] |
Step-4: Set permissions on /etc/openvpn/update-resolv-conf
Make /etc/openvpn/update-resolv-conf executable:
# chmod 755 /etc/openvpn/update-resolv-conf |
^ Set 755 permissions on /etc/openvpn/update-resolv-conf |
Step-5: Register for free ProtonVPN account
In order to use the ProtonVPN service whether free or paid a registered login account is needed. Sign up here: register for ProtonVPN account.
Note that the registered account can also be used for the Free (and paid for) ProtonMail service.
Step-6: Login to ProtonVPN account
For this you will need to login to https://protonvpn.com using your (free) registered ProtonVPN account.
Login here: https://account.protonvpn.com/login
Step-7: Select and download ProtonVPN configuration file(s)
When logged in to ProtonVPN, click on Downloads in the left margin then select OpenVPN configuration files.
Make your selections to choose what you need to match your system.
You can either download individual .opvn configuration files or a zip archive of all.
It can save time to download one of the "all configs" zip files.
Then the choice of which .opvn connection file to use can be made when running the openvpn command.
Download single .opvn configuration files to: ~/Downloads/ProtonVPN/configs/.
Download zip collections to: ~/Downloads/ProtonVPN/ then:
cd ~/Downloads/ProtonVPN/configs/ unzip ../<zip-collection-filename> |
^ unzip in the ~/Downloads/ProtonVPN/configs/ directory |
Please see "2. Get the ProtonVPN config files" on this page: https://protonvpn.com/support/linux-openvpn/
Step-8: Find your ProtonVPN credentials to use with OpenVPN
When logged in to ProtonVPN, click on Dashboard. (at left margin) then click on Account.
Find your OpenVPN / IKEv2 username and OpenVPN / IKEv2 password
See also: "3. Find your ProtonVPN credentials (needed to login via OpenVPN to the ProtonVPN service) " on this page: https://protonvpn.com/support/linux-openvpn/
Starting a ProtonVPN connection using OpenVPN
/bin/sudo openvpn --config <path-to-ProtonVPN-configuration-file-opvn> |
^ starting a ProtonVPN connection using openvpn |
Example:
[user@localhost ~]$ /bin/sudo openvpn --config ~/Downloads/ProtonVPN/configs/37.120.198.178.udp.ovpn 2022-04-11 14:25:44 DEPRECATED OPTION: --cipher set to 'AES-256-CBC' but missing in --data-ciphers (AES-256-GCM:AES-128-GCM). Future OpenVPN version will ignore --cipher for cipher negotiations. Add 'AES-256-CBC' to --data-ciphers or change --cipher 'AES-256-CBC' to --data-ciphers-fallback 'AES-256-CBC' to silence this warning. 2022-04-11 14:25:44 OpenVPN 2.5.0 x86_64-mageia-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Mar 18 2022 2022-04-11 14:25:44 library versions: OpenSSL 1.1.1n 15 Mar 2022, LZO 2.10 🔐 Enter Auth Username: ***REDACTED***REDACTED*** 🔐 Enter Auth Password: ************************* 2022-04-11 14:26:09 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts 2022-04-11 14:26:09 Outgoing Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication 2022-04-11 14:26:09 Incoming Control Channel Authentication: Using 512 bit message hash 'SHA512' for HMAC authentication [ Text deleted for brevity ] 2022-04-11 14:26:10 net_route_v4_add: 0.0.0.0/1 via 10.27.0.1 dev [NULL] table 0 metric -1 2022-04-11 14:26:10 net_route_v4_add: 128.0.0.0/1 via 10.27.0.1 dev [NULL] table 0 metric -1 2022-04-11 14:26:10 Initialization Sequence Completed |
^ Example showing starting a ProtonVPN connection using openvpn Note: when prompted "Enter Auth Username" respond with OpenVPN / IKEv2 username and for "Enter Auth Password" use OpenVPN / IKEv2 password NB The VPN connection remains up as long as the openvpn process is running. The shell prompt does not appear until the openvpn command completes. To close the VPN type CONTROL-C to interrupt the openvpn command |
Adding VPN network interface tun0 to firewall configuration
The first time openvpn makes a connection it will add a new network interface tun0.
This can be seen using the /usr/sbin/ifconfig command.
tun0 needs to be added to the Mageia firewall configuration otherwise no network traffic will pass over tun0.
To add tun0: first start openvpn and (in a second shell) simply run the Mageia firewall configuration command: drakfirewall.
Go through each step accepting the settings already there. When you get to the list of network interfaces you should see tun0. Complete the settings and exit drakfirewall.
Now, the firewall will allow traffic over tun0.
This step only needs to be done once when the new tun0 network interface is added by running the openvpn command.
Verifying ProtonVPN connection is up
When the ProtonVPN connection has been established with the openvpn command, a new network interface tun0 will be active.
You can manually check (as shown below) or download and run vpn_status [4] script.
Check status with:
/usr/sbin/ifconfig tun0 2>&1 >/dev/null && echo "VPN tun0 is active" || echo "VPN tun0 is not active" |
^ Checking if network interface tun0 is active |
Example-1: VPN not active
[user@localhost ~]$ ifconfig tun0 2>&1 >/dev/null && echo "VPN tun0 is active" || echo "VPN tun0 is not active" tun0: error fetching interface information: Device not found VPN tun0 is not active |
^ Example: checking if network interface tun0 is active. Here is not active. |
Example-2: VPN active
[user@localhost ~]$ ifconfig tun0 2>&1 >/dev/null && echo "VPN tun0 is active" || echo "VPN tun0 is not active" VPN tun0 is active |
^ Example: checking if network interface tun0 is active. Here is active. |
Also, if the VPN is active then a new nameserver will be defined in /etc/resolv.conf.
The ProtonVPN nameserver will be at the IP address of the VPN endpoint.
Examine /etc/resolv.conf to find the IP address of the ProtonVPN nameserver and confirm it responds to ICMP echo requests (ping):
for ns in $(grep nameserver /etc/resolv.conf | sed -e "s/.* //" ); do echo echo "ping -c2 ${ns}" ping -c2 ${ns} if [ $? = 0 ]; then echo "connection to nameserver ${ns} is up" else echo "connection to nameserver ${ns} is down" fi done |
^ Example showing testing network connectivity to each nameserver in /etc/resolv.conf |
If all the ping commands in above script get a response then the VPN is likely to be up.
Check using https://ipleak.net/ in your web browser.
This will show the external IP address of the ProtonVPN endpoint.
This should correspond with whatever was selected with the --config option when the connection was started using openvpn.
Another check for the external IP address of the ProtonVPN endpoint:
dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}' |
^ Display the external IP address |
Check the routing table to see the default gateway IP address is set to the IP address of the ProtonVPN endpoint:
netstat -rn |
^ Display the routing table |
Example:
[user@localhost ~]$ netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.28.0.1 128.0.0.0 UG 0 0 0 tun0 0.0.0.0 192.168.141.2 0.0.0.0 UG 0 0 0 enp0s25 10.28.0.0 0.0.0.0 255.255.0.0 U 0 0 0 tun0 128.0.0.0 10.28.0.1 128.0.0.0 UG 0 0 0 tun0 169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 enp0s25 185.159.157.18 192.168.141.2 255.255.255.255 UGH 0 0 0 enp0s25 192.168.141.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s25 |
^ Example displaying routing table with netstat -rn command Here the default gateway (for destination 0.0.0.0) is 10.28.0.1 on interface tun0 which is the ProtonVPN endpoint IP address |
Using vpn_status script
Download:
wget -O - https://raw.githubusercontent.com/wikigazer/vpn_status/main/vpn_status > ~/bin/vpn_status chmod 755 ~/bin/vpn_status |
^ Downloading vpn_status script and making it executable |
Example: vpn_status when VPN is not active
[user@localhost ~]$ vpn_status Checking for network interface tun0 ifconfig tun0 tun0: error fetching interface information: Device not found +-----------------------------------------------------+ | Network interface tun0 not found: VPN is not active | +-----------------------------------------------------+ |
^ Example: vpn_status showing VPN is not active |
Example: vpn_status when VPN is active
[user@localhost ~]$ vpn_status Checking for network interface tun0 ifconfig tun0 tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500 inet 10.27.0.15 netmask 255.255.0.0 destination 10.27.0.15 inet6 fe80::a20c:3b42:d5b3:9f40 prefixlen 64 scopeid 0x20<link> unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC) RX packets 12520 bytes 6494566 (6.1 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 11744 bytes 1836708 (1.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 VPN active on network interface: tun0 Checking default gateway address netstat -rn | grep ^0.0.0.0 | head -1 | awk '{print }' 10.27.0.1 Checking network connectivity to default gateway: 10.27.0.1 ping -c2 10.27.0.1 PING 10.27.0.1 (10.27.0.1) 56(84) bytes of data. 64 bytes from 10.27.0.1: icmp_seq=1 ttl=64 time=7.20 ms 64 bytes from 10.27.0.1: icmp_seq=2 ttl=64 time=7.31 ms --- 10.27.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 7.201/7.257/7.313/0.056 ms connection to default gateway 10.27.0.1 is up Checking for nameserver IP address grep nameserver /etc/resolv.conf nameserver 10.27.0.1 Checking network connectivity to nameserver(s) ping -c2 10.27.0.1 PING 10.27.0.1 (10.27.0.1) 56(84) bytes of data. 64 bytes from 10.27.0.1: icmp_seq=1 ttl=64 time=7.55 ms 64 bytes from 10.27.0.1: icmp_seq=2 ttl=64 time=7.81 ms --- 10.27.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 7.551/7.680/7.809/0.129 ms connection to nameserver 10.27.0.1 is up Checking external IP address dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F\" '{ print $2}' 37.120.198.182 Checking network connectivity to well known external IP address ping -c2 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=8.43 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=13.2 ms --- 8.8.8.8 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 8.433/10.794/13.155/2.361 ms connection to external IP address 8.8.8.8 is up Checking network route to well know external website /bin/sudo tcptraceroute google.com tcptraceroute: Symbol `pcap_version' has different size in shared object, consider re-linking Selected device tun0, address 10.27.0.15, port 36981 for outgoing packets Tracing the path to google.com (216.58.212.238) on TCP port 80 (http), 30 hops max 1 lhr25s28-in-f14.1e100.net (216.58.212.238) [open] 7.592 ms 8.006 ms 7.443 ms connection to google.com is up completed +-------------------------------------+ | Good news: VPN is up and functional | +-------------------------------------+ |
^ Example: vpn_status showing VPN is active |
openvpn connection status from SIGUSR2 signal
Openvpn status can be found by sending a SIGUSR2 signal to the openvpn process.
Authenticated root, send SIGUSR2 signal to the openvpn process:
kill --signal SIGUSR2 $(ps -ef | grep -v grep | grep " openvpn " | head -1 | awk '{print $2}') |
^ sending a SIGUSR2 signal to the openvpn process ID causes status data to be displayed |
Example:
[user@localhost ~]$ /bin/sudo kill --signal SIGUSR2 $(ps -ef | grep -v grep | grep " openvpn " | head -1 | awk '{print $2}') [sudo] password for user: |
^ Example: sending a SIGUSR2 signal to the openvpn process |
2022-04-11 15:01:33 event_wait : Interrupted system call (code=4) 2022-04-11 15:01:33 OpenVPN STATISTICS 2022-04-11 15:01:33 Updated,2022-04-11 15:01:33 2022-04-11 15:01:33 TUN/TAP read bytes,2397708 2022-04-11 15:01:33 TUN/TAP write bytes,7180483 2022-04-11 15:01:33 TCP/UDP read bytes,7569872 2022-04-11 15:01:33 TCP/UDP write bytes,2764405 2022-04-11 15:01:33 Auth read bytes,7180483 2022-04-11 15:01:33 pre-compress bytes,0 2022-04-11 15:01:33 post-compress bytes,0 2022-04-11 15:01:33 pre-decompress bytes,0 2022-04-11 15:01:33 post-decompress bytes,0 2022-04-11 15:01:33 END |
^ Example: status data displayed by openvpn process on receipt of SIGUSR2 signal |
Stopping openvpn connection
To stop the openvpn connection: type CONTROL-C in the shell where the openvpn connection was started.
(see also above: starting openvpn connection).
This will close the ProtonVPN connection and restore /etc/resolv.conf to what it was before. So DNS resolution will go back to how it was before the VPN was established.
Example:
^C2022-04-08 00:19:33 event_wait : Interrupted system call (code=4) 2022-04-08 00:19:33 SIGTERM received, sending exit notification to peer 2022-04-08 00:19:34 net_route_v4_del: 185.159.157.89/32 via 192.168.141.2 dev [NULL] table 0 metric -1 2022-04-08 00:19:34 net_route_v4_del: 0.0.0.0/1 via 10.22.0.1 dev [NULL] table 0 metric -1 2022-04-08 00:19:34 net_route_v4_del: 128.0.0.0/1 via 10.22.0.1 dev [NULL] table 0 metric -1 2022-04-08 00:19:34 Closing TUN/TAP interface 2022-04-08 00:19:34 net_addr_v4_del: 10.22.0.2 dev tun0 2022-04-08 00:19:34 /etc/openvpn/update-resolv-conf tun0 1500 1584 10.22.0.2 255.255.0.0 init 2022-04-08 00:19:34 SIGTERM[soft,exit-with-notification] received, process exiting |
^ Example: hitting CTRL-C on the openvpn command closes down the VPN connection |
DNS resolution
Note that when the ProtonVPN connection is established with the openvpn command DNS resolution will be processed by the ProtonVPN nameserver not whatever nameservers you may have already defined in /etc/resolv.conf.
If you normally use an internal DNS nameserver for your own local network that local DNS namespace will not be served by the ProtonVPN nameserver.
Appendicies
Appendix-1: References
ref# | title | link |
---|---|---|
[1] | OpenVPN | https://openvpn.net/ |
[2] | ProtonVPN | https://protonvpn.com/ |
[3] | "Configuring Shorewall Firewall to Allow OpenVPN Con" | https://forums.mageia.org/en/viewtopic.php?f=25&t=12635 |
[4] | vpn_status script | https://raw.githubusercontent.com/wikigazer/vpn_status/main/vpn_status |
[5] | /etc/openvpn/update-resolv-conf script | https://forums.mageia.org/en/download/file.php?id=1798&sid=b56c294144b2b4c0838930327d6a52f7 |
Appendix-2: Checklist
# | ✔️ | item | link | comment |
---|---|---|---|---|
1 | sudo | Configuring_sudo | Needed for configuring and running openvpn | |
2 | tcptraceroute | install tcptraceroute | Shows network route for connections | |
3 | directories | Make directories | Make local directories for ProtonVPN downloads: ~/Downloads/ProtonVPN/configs/ | |
4 | network interface | tun0 | Status of network interface before VPN connection | |
5 | routing pre-VPN | routing table, default gateway, external IP | Status of routing table, default gateway, external IP address before VPN connection | |
6 | openvpn | install openvpn | ||
7 | resolvconf | install resolvconf | ||
8 | /etc/openvpn/update-resolv-conf | Install update-resolv-conf | Needed by openvpn command | |
9 | /etc/openvpn/update-resolv-conf | set permissions on update-resolv-conf | chmod 755 /etc/openvpn/update-resolv-conf | |
10 | Register free ProtonVPN account | Register | ||
11 | Login ProtonVPN | Login | ||
12 | Download ProtonVPN config files | Download | Single .opvn configuration files to: ~/Downloads/ProtonVPN/configs/<config_file_name.opvn> Zip collections to: ~/Downloads/ProtonVPN then cd ~/Downloads/ProtonVPN; unzip ../<zip-file-name> | |
13 | ProtonVPN credentials | find credentials | Find your OpenVPN / IKEv2 username and OpenVPN / IKEv2 password on your ProtonVPN account. | |
14 | Start openvpn | open connection | start ProtonVPN connection using openvpn with one of the .opvn files in ~/Downloads/ProtonVPN/configs/ | |
15 | Verify VPN is functional | verify VPN running | Check manually or run the vpn_status script to confirm VPN is working | |
16 | close VPN | stopping VPN | <ctrl>-C on openvpn command | |
17 | Verify VPN is non-functional | verify VPN not running | Check manually or run the vpn_status script to confirm VPN is not working | |
18 | Confirm pre-VPN DNS configuration | Closing the VPN should have returned DNS configuration to the state pre-VPN: cat /etc/resolv.conf |