linux-cli-community icon indicating copy to clipboard operation
linux-cli-community copied to clipboard

[Enhancement] Background daemon for connection monitoring

Open Rafficer opened this issue 4 years ago • 17 comments

Is your feature request related to a problem? Please describe. Currently, when a connection goes down the CLI has no way of re-establishing the connection in the event it cuts, as it doesn't run a background service. This also makes it impossible for the CLI to automatically connect on boot or notify the user in such case

Describe the solution you'd like A background daemon constantly checking the VPN connection and re-establishing it in the event it goes down.

Rafficer avatar Nov 19 '19 06:11 Rafficer

This would then also solve #26 and #23.

Rafficer avatar Nov 19 '19 06:11 Rafficer

I'm wondering if we can make things like systemctl enable [background_daemon_name] where the daemon will ping protonvpn's server every x seconds/minutes.

vinliao avatar Dec 24 '19 09:12 vinliao

Yes, that's the plan.

Rafficer avatar Dec 24 '19 09:12 Rafficer

I created a stupid simple bash script to automatically reconnect to a random vpn server every time it fails to ping google. It works fine when I run sudo ./pvpn-connect.sh but it fails to work when I run sudo nohup ./pvpn-connect.sh &. I also tried creating a service with that script, but it also doesn't reconnect.

Do you know the reason why the script doesn't work properly on background?

vinliao avatar Dec 24 '19 11:12 vinliao

Yes please! I'd like to have my VPN automatically reconnect when I wake my laptop from sleep. I have already made a systemd service to connect upon boot but it seems to be impossible (for me) to have a systemd system-sleep service to reconnect!

bryanpaget avatar Dec 30 '19 15:12 bryanpaget

Might want to take a look at what Mullvad does. I believe they have a background daemon and it works very smoothly.

cwmke avatar Jan 28 '20 18:01 cwmke

Thanks @vinliao for original script.
I wanted to make sure ping is going through protonvpn.

#!/bin/bash

while true;
do
  status=`protonvpn status|grep -c -oh Disconnected`
  # if disconnected
  if [ $status -ne 0 ]
  then
    retry=0
    protonvpn c -r
    # if first connect isn't succesful
    # then connect again
    while [ $? -ne 0 ];
    do
        retry=$((retry+1))
        echo "retry $retry"
        protonvpn c -r
    done
  fi
  sleep 60
done

ddonindia avatar Apr 04 '20 11:04 ddonindia

Apology first- I'm no expert programmer! I had an Idea/ question. Is there a process that runs @ waking that you can add protovpn r or possibly use as a trigger for a small script? My 2 Mint boxes disconnect 100% of the time when they sleep so I wouldn't imagine a great need to monitor..?

TheWindedScriber avatar May 27 '20 20:05 TheWindedScriber

@TheWindedScriber My first thought would be to enable a service at boot with a dependency on a network connection with systemd:

Something like:

sudo systemctl enable protonvpnd.service

But it must require a network connection first in order to work correctly (I think). I'm still a systemd novice :slightly_smiling_face:

Something like this could also be more easily packaged downstream into Linux distributions too, if it were committed to this git repo

jwflory avatar May 27 '20 21:05 jwflory

I found an example script for a service that runs on wake- not exactly sure how to configure this, but would this template work for example, just to run pvpn r?

`[Unit] Description=some description Before=sleep.target StopWhenUnneeded=yes

[Service] Type=pvpn r RemainAfterExit=yes ExecStop=-/path/to/your/script.sh

[Install] WantedBy=sleep.target`

TheWindedScriber avatar Jun 22 '20 04:06 TheWindedScriber

Anybody know where we are with this? I'm encountering this issue as well. I mean, it's not the end of the world that I have to run protonvpn c --sc again after resume but it is a little inconvenient.

m1k3s0 avatar Sep 16 '20 15:09 m1k3s0

It has been a while since I looked, but I can't remember if the process gives an error code if the connection breaks. If it did, it would be easier to write a systemd unit file that monitors the process and restarts automatically if the connection breaks. It could be closed by stopping the service.

But in order for that to work, the protonvpn-cli needs to emit an error code that the operating system can catch and react to.

jwflory avatar Sep 16 '20 20:09 jwflory

Simple workaround works pretty well for me (alias watchvpn): alias vpnstatus='$VPNPYTHON -m protonvpn_cli status' alias vpnconnect='sudo $VPNPYTHON -m protonvpn_cli connect --fastest && vpnstatus' alias vpnrandomconnect='sudo $VPNPYTHON -m protonvpn_cli connect --random && vpnstatus' alias vpndisconnect='sudo $VPNPYTHON -m protonvpn_cli disconnect && vpnstatus' alias watchvpn='watch -n5 $VPNPYTHON -m protonvpn_cli status'

delminskii avatar Oct 11 '20 16:10 delminskii

A small modification to the recommanded systemd auto start service and a new service to handle the sleep state resolve the problem quite cleanly.

First let's improve the autostart service to cleanly handle its stop :

sudo nano /etc/systemd/system/protonvpn-autoconnect.service

Here is the new content (only the ExecStop= line has been added) :

[Unit]
Description=ProtonVPN-CLI auto-connect
Wants=network-online.target

[Service]
Type=forking
ExecStart=/usr/local/bin/protonvpn connect -f
ExecStop=/usr/local/protonvpn disconnect
Environment=PVPN_WAIT=300
Environment=PVPN_DEBUG=1
Environment=SUDO_USER=user

[Install]
WantedBy=multi-user.target

(of course we have to replace the path to the protonvpn executable in the ExecStop= line with the output of sudo which protonvpn as in the original service)

Next you need to create a dedicated service to stop the first one before sleeping and start it when geting out of sleep :

sudo nano /etc/systemd/system/protonvpn-suspendresume.service

Add the following contents to this file:

[Unit]
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/bin/systemctl stop protonvpn-autoconnect
ExecStop=-/usr/bin/systemctl start protonvpn-autoconnect
[Install]
WantedBy=sleep.target

(this time you need to replace the path to the systemctl executable in the ExecStart= and ExecStop= lines with the output of which systemctl)

After that you just need to reload the services:

sudo systemctl daemon-reload

And enable them:

sudo systemctl enable protonvpn-autoconnect protonvpn-suspendresume

And now your connection will be cleanly disconnected when suspending and will reconnect when resuming.

This is inspired heavily by this stackexchange very good answer.

If this seems like an acceptable solution I can provide a PR (just to update the doc with a new paragraph to the Enhancements part.

pymaldebaran avatar Nov 27 '20 10:11 pymaldebaran

I have done exactly what @pymaldebaran suggested in the previous post, however, to accomplish the same goal I needed to do a small change in the protonvpn-autoconnect.service:

[Unit]
Description=ProtonVPN-CLI auto-connect
Wants=network-online.target

[Service]
Type=forking
ExecStartPre=/usr/local/bin/protonvpn disconnect
ExecStart=/usr/local/bin/protonvpn connect -f
ExecStop=/usr/local/bin/protonvpn disconnect
Environment=PVPN_WAIT=60
Environment=PVPN_DEBUG=1
Environment=SUDO_USER=user

[Install]
WantedBy=multi-user.target

Without the ExecStartPre= line, the service would wait out and throw an exit error.

I do think this would be a nice addition to the Enhancements section of the usage guide.

dfhssilva avatar Sep 03 '21 19:09 dfhssilva

@dfhssilva With your version do you need the second service that I used to handle the sleeping case ? If not not then it's an impressive improvement over my proposition and indead your suggestion should really be added to the doc.

pymaldebaran avatar Sep 04 '21 06:09 pymaldebaran

@pymaldebaran yes, I still need to do everything as you did, including adding the protonvpn-suspendresume.service. I still think it would be a good addition to the documentation. If needed I can volunteer to do a PR.

dfhssilva avatar Sep 04 '21 08:09 dfhssilva