Matthew Evans

Infrastructure and Security Ninja. I know DevOps-fu.

ProtonVPN-CLI as systemd service

02 Dec 2018 » protonvpn, security

Pre-requisites needed:

  1. Active ProtonVPN Account
  2. Your ProtonVPN OpenVPN Credentials - find them here.


The purpose of this article:

  1. To maintain an always-on connection to ProtonVPN that starts automatically at boot and will restart if terminated abnormally.


Phase 1 - Install and configure protonvpn-cli as root:

  1. Make sure you are logged into your Linux machine as root.
    • Executing as sudo will not work!
  2. Install the protonvpn-cli package:

    [[email protected] ~]# bash -c "git clone && ./protonvpn-cli/ --install"
    Cloning into 'protonvpn-cli'...
    remote: Enumerating objects: 19, done.
    remote: Counting objects: 100% (19/19), done.
    remote: Compressing objects: 100% (10/10), done.
    remote: Total 487 (delta 10), reused 17 (delta 9), pack-reused 468
    Receiving objects: 100% (487/487), 119.21 KiB | 3.41 MiB/s, done.
    Resolving deltas: 100% (295/295), done.
    [*] Done.
    [[email protected] ~]#
  3. Initialize protonvpn-cli as root:

    [[email protected] ~]# /usr/bin/protonvpn-cli --init
    Enter OpenVPN username: <your OpenVPN/IKEv2 username>
    Enter OpenVPN password: <your OpenVPN/IKEv2 password>
    [.] ProtonVPN Plans:
    1) Free
    2) Basic
    3) Plus
    4) Visionary
    Enter Your ProtonVPN plan ID: <choose your subscribed plan>
    [.] Would you like to use a custom DNS server? (Warning: This would make your VPN connection vulnerable to DNS leaks. Only use it when you know what you\'re doing) [y/N]:
    [.] [Security] Decrease OpenVPN privileges? [Y/n]: 
    [.] Enable Killswitch? [Y/n]: 
    [*] Done.
    [[email protected] ~]#
  4. Run protonvpn-cli and choose your preferred connection:

    [[email protected] ~]# /usr/bin/protonvpn-cli --connect ch-cz#1 udp
    Fetching ProtonVPN servers...
    [$] Connected!
    [#] New IP:
    [[email protected] ~]# /usr/bin/protonvpn-cli --disconnect
    [#] Disconnected.
    [#] Current IP:
    [[email protected] ~]#
    • Note:
      • You can execute /usr/bin/protonvpn-cli --menu to find the servername and protocol, udp or tcp.
        • Make sure to cancel out or run /usr/bin/protonvpn --disconnect before proceeding.
      • I chose secure core Switzerland to Czechia, servername ch-cz#1, in the example above.


Phase 2 - Configuring the systemd .service file:

  1. Open your favoite text editor and paste the following contents:

    Description=ProtonVPN CLI Auto-Start
    ExecStart=/usr/bin/protonvpn-cli --last-connect
    ExecReload=/usr/bin/protonvpn-cli --disconnect && /usr/bin/protonvpn-cli --last-connect
    ExecStop=/usr/bin/protonvpn-cli --disconnect
  2. Save the file to /etc/systemd/system/protonvpn-cli.service.
  3. Execute systemctl daemon-reload so systemd picks up the new file.
  4. Execute systemctl enable protonvpn-cli.service && systemctl start protonvpn-cli.service.
  5. Execute systemctl status protonvpn-cli.service and look for Connected!
    • Here is a sample output:
       [[email protected] ~]# systemctl start protonvpn-cli.service
       [[email protected] ~]# systemctl status protonvpn-cli.service
       ● protonvpn-cli.service - ProtonVPN CLI Service
       Loaded: loaded (/etc/systemd/system/protonvpn-cli.service; enabled; vendor preset: disabled)
       Active: active (running) since Sun 2018-12-02 17:10:54 EST; 14s ago
       Process: 4576 ExecStart=/usr/bin/protonvpn-cli --last-connect (code=exited, status=0/SUCCESS)
       Main PID: 4734 (openvpn)
       Tasks: 1 (limit: 9507)
       Memory: 3.0M
       CGroup: /system.slice/protonvpn-cli.service
               └─4734 openvpn --daemon --config /root/.protonvpn-cli/protonvpn_openvpn_config.conf
       Dec 02 17:10:45 torbox.anonymous systemd[1]: Starting ProtonVPN CLI Service...
       Dec 02 17:10:47 torbox.anonymous protonvpn-cli[4576]: Connecting...
       Dec 02 17:10:54 torbox.anonymous protonvpn-cli[4576]: [$] Connected!
       Dec 02 17:10:54 torbox.anonymous protonvpn-cli[4576]: [#] New IP:
       Dec 02 17:10:54 torbox.anonymous systemd[1]: Started ProtonVPN CLI Service.
    • You can also verify you are connected by executing /usr/bin/protonvpn-cli --status:

       [[email protected] ~]# protonvpn-cli --status
       [OpenVPN Status]: Running
       [ProtonVPN Status]: Running
       [Internet Status]: Online
       [Public IP Address]:
       [ProtonVPN] [Server Name]: CH-CZ#1
       [ProtonVPN] [OpenVPN Protocol]: UDP
       [ProtonVPN] [Exit Country]: CZ
       [ProtonVPN] [Tier]: 2
       [ProtonVPN] [Server Features]: SECURE_CORE,Plus
       [ProtonVPN] [Server Load]: 37


Miscellaneous information:

  1. Since our systemd file uses the protonvpn-cli --last-connect switch, it simply connects to the last server you have instructed the client to connect to. Therefore, if you want to change the server you are connecting to, simply execute the following commands:
    • systemctl stop protonvpn-cli.service
    • /usr/bin/protonvpn-cli --connect servername protocol
    • /usr/bin/protonvpn-cli --disconnect
    • systemctl start protonvpn-cli.service
  2. By adding Restart=always to the systemd file, in addition to the ProtonVPN kill-switch protection, systemd will monitor the service itself and if the protonvpn-cli or openvpn process terminates, crashes, or is killed abnormally, it will be restarted automatically. This offers an additional layer of protection that compliments the kill-switch nicely.