ProtonVPN, without using protonvpn app. (Qubes OS 4.2.0)

Original forum link
https://forum.qubes-os.org/t/22606
Original poster
renehoj
Created at
2023-12-06 19:12:02
Posts count
7
Likes count
6
Tags
networking, openvpn, vpn

The ProntonVPN openvpn services can be used without using the protonvpn app, by using shell scripts and Network Manager to configure the VPN connection.

I’m going to base this guide on Debian 12, but most of the steps should be identical for Fedora, minimal templates might require extra packages to be installed.

Network Manager The package network-manager-openvpn-gnome needs to be installed, it allows you to use openvpn with network manager. apt install network-manager-openvpn-gnome

Sys-vpn Create a new qube called sys-vpn with the option “provides networking” enabled, after it’s created go to the services tab and add the service network-manager.

The following steps are done in sys-vpn.

Download the openvpn config files Log into your ProtonVPN account, and download the standard and secure openvpn files for all servers. Unpack the standard config files into /home/user/proton/ovpn, and the secure core files into /home/user/proton/ovpn-secure.

VPN password and username While logged into your ProtonVPN account copy your vpn username and password, it’s on the same page as the config files.

ProtonVPN DIY client Create the file /home/user/proton/protonvpn.sh

protonvpn.sh content
#!/bin/bash

username=YOURUSERNAME

enableVPN() {
    nmcli con import type openvpn file $1
    id=${1#*/}
    id=${id%.*}
    nmcli con modify $id +vpn.data "username=$username"
    nmcli con up $id passwd-file pass.txt
}

cleanConnections() {
    for conn in $(nmcli conn show | grep vpn)
    do
        if [[ $conn == *"protonvpn"* ]]; then 
            nmcli conn delete $conn
        fi
    done
}

loadRandom() {
    echo "load random"
    file=$(find ovpn/ -type f | shuf -n 1)

    cleanConnections
    enableVPN $file
}

loadCountry() {
    echo "load country"
    IFS=':' read -r -a ccs <<< "$1"
    cc=${ccs[ $RANDOM % ${#ccs[@]} ]}
    file=$(find ovpn/node-$cc* -type f | shuf -n1)

    cleanConnections
    enableVPN $file
}

if [ -z "$1" ]
then
    loadRandom
    echo "load random"
else
    loadCountry $1
fi

Create the file /home/user/proton/protonvpn-secure.sh

protonvpn-secure.sh content
#!/bin/bash

username=YOURUSERNAME

enableVPN() {
    nmcli con import type openvpn file $1
    id=${1#*/}
    id=${id%.*}
    nmcli con modify $id +vpn.data "username=$username"
    nmcli con up $id passwd-file pass.txt
}

cleanConnections() {
    for conn in $(nmcli conn show | grep vpn)
    do
        if [[ $conn == *"protonvpn"* ]]; then 
            nmcli conn delete $conn
        fi
    done
}

loadSecurecore() {
    echo "load securecore"
    file=$(find ovpn-secure/ -type f | shuf -n 1)

    cleanConnections
    enableVPN $file
}

loadSecureCore

In both files add your username to the username line at the top of the file.

Create the file /home/user/proton/pass.txt and add the line: vpn.secret.password:YOUR-VPN-PASSWORD

You should now be able to connect the VPN using the shell script, the network manager icon will show the swirl animation while connecting, and the lock when the connection is established.

./protonvpn.sh will connect you to a random server. ./protonvpn.sh cc will connect you to a random server in that country. ./protonvpn.sh cc1:cc2:cc3 will connect to a random server in any of the countries. ./protonvpn-secure.sh will connect you to a random secure core server.

Rerunning the script will disconnect you from your current server, and reconnect you to a new random server.

Firewall (optional) If you only want hosts using sys-vpn to be able to connect to the internet though the vpn, you can add the following rules to /rw/config/qubes-firewall-user-script in sys-vpn. nft 'insert rule ip qubes custom-forward iifname "eth0" counter drop' nft 'insert rule ip qubes custom-forward oifname "eth0" counter drop'

Autostart (optional) Create the file /home/user/.config/autostart/protonvpn-autostart.desktop

protonvpn-autostart.desktop content
[Desktop Entry]
Type=Application
Name=ProtonVPN Autostart
Exec="/home/user/proton/protonvpn-connect.desktop.sh"
X-GNOME-Autostart-enable=true

Start menu (optional) In /home/user/.local/share/applications create the files: protonvpn-connect.desktop protonvpn-disconnect.desktop protonvpn-securecore.desktop

.dekstop file content
[Desktop Entry]
Name=
Exec=
Terminal=false
Type=Application
Icon=protonvpn-logo
Comment=ProtonVPN script
Categories=Network;
Keywords=vpn;

In protonvpn-connect.desktop use the lines

Name=Proton VPN: Connect VPN
Exec=/home/user/proton/protonvpn-connect.desktop.sh

In protonvpn-disconnect.desktop use the lines

Name=Proton VPN: Disconnect VPN
Exec=/home/user/proton/protonvpn-disconnect.desktop.sh

In protonvpn-securecore.desktop use the lines

Name=Proton VPN: Connect Secure core VPN
Exec=/home/user/proton/protonvpn-secure.desktop.sh

Create the file /home/user/proton/protonvpn-connect.desktop.sh

protonvpn-connect.desktop.sh content
#!/bin/bash

cd /home/user/proton
./protonvpn.sh

Create the file /home/user/proton/protonvpn-disconnect.desktop.sh

protonvpn-disconnect.desktop.sh content
#!/bin/bash

for conn in $(nmcli conn show | grep vpn)
do
    if [[ $conn == *"protonvpn"* ]]; then 
        nmcli conn delete $conn
    fi
done

Create the file /home/user/proton/protonvpn-securecore.desktop.sh

protonvpn-securecore.desktop.sh content
#!/bin/bash

cd /home/user/proton
./protonvpn-secure.sh

The menu buttons will connect and disconnect the VPN, edit the protonvpn-connect.desktop.sh script if you want country code connect when you use the start menu