Restarting a VPN client on pfSense through the CLI (SSH)

I recently had some issues with a flaky VPN service. I wanted to make a little script I could run on a different machine that would restart the VPN connection, should it break. This particular VPN connection included a DNS service for the remote .local-domain, which I decided to use for testing, but you could in theory use any valid connection test.

Either way, pulling the correct function names and options from /usr/local/www/status_services.php – following the reference to /etc/inc/service-utils.inc – I came up with this script:

#!/usr/bin/env bash
if ! nslookup -timeout=2 remote.server.local >/dev/null 2>&1; then
    echo "VPN not OK - restarting"
    ssh my.pfsense.ip /usr/local/bin/php -q <<-EOF
        <?php
            include('service-utils.inc');
            service_control_restart("openvpn", array('vpnmode' => 'client', 'id' => '3'));
        ?>
    EOF
fi

This will connect to my pfSense box using keyless login from a trusted machine, and restart the VPN connection.

The client ID was obtained from the restart link in the pfSense web interface:

vpnid

UPDATE

I ended up finding the browser VPN ID too hackish, and made a script that looks up the ID in the pfSense config instead. Might also be useful for adapting to future issues. Here: http://www.dhampir.no/stuff/bash/pfsense-vpnreset

17 Comments

  • Muhammad says:

    i was workingon this all day. pfsense channel on freenode was useless. thanks!

  • sorin says:

    Sadly this doesn’t work with pfsense 2.4.1 because the password file is overridden by pfsense on connect.

    You can find more information on https://redmine.pfsense.org/issues/8122 — maybe you found another workaround for this. I am really interested about finding a way to automate the connection.

    • bolt says:

      I don’t use one-time passwords with OpenVPN on pfSense, sorry. But I currently have 4 VPN clients running with usernames, passwords and client certificates, and those still work fine in 2.4.1 🙂

  • EDER MASCULINO GOMES says:

    ola

  • stefano says:

    Thanks a lot for your solution.
    I’m noob and i don’t know how to use and put this script… can you help me?
    I have a big problem that sometimes my VPN Gateway going offline and my connection drops… then i wont tu run a script every x minutes to ping and host and check if connection works or restart OpenVPN service that solve the problem.
    For run periodically i think that cron can solve the problem. but i don’t know how to begin.
    regards

    • bolt says:

      What you’d need is a simple crontab line to run a script:
      */5 * * * * /root/bin/my_vpn_ping_test

      Containing something like:
      #!/bin/bash
      ip="1.2.3.4" # your test IP here
      pfsense="10.0.0.1"
      vpnname="Work-VPN"
      if ! ping -c 1 -w 10 "$ip"; then
      /root/bin/pfsense-vpnreset "$pfsense" "$vpnname"
      fi

      Extend as required.

      • STefano says:

        Thanks a lot for your reply, in pfsense variable what ip i need to put? is there also a way to check if cron run my script like a log?

        • bolt says:

          The pfsense variable is the IP or hostname of your pfSense machine, to which you’ve hopefully already set up automatic login. I.e. you should be able to do ssh root@pfsenseip without specifying a password. This is done via the .ssh/authorized_keys file as on any Linux-style system.

          If you want to log your output, simply modify your crontab line to do so:
          */5 * * * * /root/bin/my_vpn_ping_test >>/var/log/vpn_test.log 2>&1

          ..or similar. Or have the script do it internally. And add any additional debug information or timestamps as desired. Or pipe output to the “logger” command to use your system’s built-in logging capabilities. Your options are limitless 🙂

          • Stefano says:

            Bolt really thanks a lot for all your essential help!!! 😀
            If is possible i want to use cron installed in my pfsense to do this.
            if is possibile i want to do this:
            Use cron installed inside pfsense and print to log if vpn is working or not inside the log of pfsense itself.

          • Stefano says:

            I think that i have solved part of my problem, using this:
            >>/var/log/vpn_test.log 2>&1

            now i have the log so i know that cron work properly, there i a way to print time and day?

            If i run the script inside pfsense i need to do this?
            The pfsense variable is the IP or hostname of your pfSense machine, to which you’ve hopefully already set up automatic login. I.e. you should be able to do ssh root@pfsenseip without specifying a password. This is done via the .ssh/authorized_keys file as on any Linux-style system.

          • bolt says:

            If you run the script inside of pfSense, you don’t need any SSH stuff. Also, pfSense does not come with Bash by default. You can install it though.
            Without the SSH part, you can shorten the script down to just the PHP section. Perhaps like this: https://blog.dhampir.no/wp-content/uploads/2019/01/stefano-vpnreset.sh
            I added simple date printing in the PHP 🙂

          • Stefano says:

            Really thanks a lot!!
            Where i can put this file? and how i can use the file? is there also a way to send an email if the vpn is offline?

          • bolt says:

            You put it on your pfSense machine. Using curl to download it or scp or something to transfer it over.
            Then you make it executable (chmod +x filename) and get your crontab to run it.
            As for the email and using pfSense’s internal logging capabilities, this is something I have not investigated, as I run my script on a machine where all those features are available through different means. Perhaps try the pfSense forums?

          • Stefano says:

            Sorry what kind of command i need to put inside the Cron?

          • bolt says:

            Put whatever you use to run it. The crontab manpage is useful to figure out the numbers. The last script I linked you to is PHP. To run that every 5 minutes, do something like:
            */5 * * * * /usr/local/bin/php -q /root/script/path/here >/root/vpnscript.log 2>&1

      • Stefano says:

        Thanks a lot!! Tomorrow I will try!! I really appreciate you awesome support!!
        I have also try to send some messages in PFSens forum but no one help me.. 🙁
        Regards
        Stefano

        • Stefano says:

          Bolt really thanks a lot!!
          Now i’M out of home but when I come back I will try!! 🙂

Leave a Reply to EDER MASCULINO GOMES Cancel reply

Your email address will not be published. Required fields are marked *