Skip to content

Automatic Tunnel Resetting

Purpose: Generally speaking, when you have site-to-site VPN tunnels, you have to ensure that the health of the tunnel is operating as-expected. Sometimes VPN tunnels will report that they are online and connected, but in reality, no traffic is flowing to the remote side of the tunnel. In these instances, we can create a script that pings a device on the remote end, and if it does not respond in a timely manner, the script restart the VPN tunnel automatically.

Assumptions

This document assumes that you will be running a powershell script on a Windows environment. The curl commands can be used interchangably in Linux, but the example script provided here will be using curl.exe within a powershell script, and instead of running on a schedule using crontab, it will be using Windows Task Scheduler.

I will attempt to provide Linux-equivalant commands where-possible.

Sophos Environment

Configure Sophos XGS Firewall ACLs

You need to configure a user account that will be specifically used for leveraging the API controls that allow resetting the VPN tunnel(s). At this stage, you need to log into your Sophos XGS Firewall. For this example, we will assume you can reach your firewall at https://172.16.16.16:4444 and log in as the administrator.

Create API Access Profile

You need to create a profile that the API User will leverage to issue commands to the firewall's VPN settings. Without this profile, the user may have either not enough, or too much access.

  • Navigate to System > Profiles > Device Access > "Add"
  • Profile Name: VPNTunnelAPI
  • Check the radio box column named "None" to Deny all permissions to all areas of the firewall
  • Expand the "VPN" section of the permission tree, and check the box for "Read-Write" next to "Connect Tunnel"
  • Click the "Save" button to save the access profile

Create API Access User

Now we need to make a user account that we will use inside the script to authenticate against the firewall using the previously-mentioned access profile

  • Navigate to Configure > Authentication > Users > "Add"
  • Username: TunnelCheckerAPIUser
  • Name: TunnelCheckerAPIUser
  • User Type: Administrator
  • Profile: VPNTunnelAPI
  • Password: 01_placeholder_PASSWORD_here_02
  • Group: Open Group
  • Click the "Save" button to save the API user account

Create Device Access ACL

Now we need to configure an ACL within the Firewall to allow API access from the specific server we will be using in the next section.

  • Navigate to Administration > Device Access > Local service ACL exception rule > "Add"
  • Rule Name: API Access (IPSec Tunnel Heartbeat Script)
  • Source Zone: `The Zone of the Server/Device that will be used to run the script, such as a server network.
  • Source Network/Host: <IP_HOST_OF_DEVICE_RUNNING_SCRIPT>
  • Destination Host: XGS Firewall (Local IP) (This is an IP host pointing to the internal IP of the Firewall)
  • Services: HTTPS
  • Action: Accept

Configure API Access via IP

Lastly, you need to configure the API access to allow communication from the IP of the device. I know this seems redundant to the previous "Device Access ACL" but its required for this to work, otherwise you will get an Sophos API Operations are not allowed from the requester IP address error when running the script.

  • Navigate to System > Backup & Firmware > API > API Configuration
  • Add the IP of the Server/Device
  • Click the "Apply button

Server Environment

Choose a Server

It is important to choose a server/device that is able to communicate with the devices on the remote end of the tunnel. If it cannot ping the remote device(s), it will assume that the tunnel is offline and do an infinite loop of restarting the VPN tunnel.

Prepare the Script Folder

You need a place to put the script (and if on Windows, curl.exe). Follow the instructions specific to your platform below:

Download curl.exe from this location: Download and place it somewhere on the operating system, such as C:\Scripts\VPN_Tunnel_Checker. Then copy this script into that same folder and call it Tunnel_Checker.ps1 with the content below:

Curl Files Extraction

You will want to extract all of the files included in the zip file's bin folder. Specifically, copy the following files into the C:\Scripts\VPN_Tunnel_Checker folder:

  • curl.exe
  • curl-ca-bundle
  • libcurl-x64.def
  • libcurl-x64.dll
function Reset-VPN-Tunnel {
Write-Host "VPN Tunnel Broken - Bringing VPN Tunnel Down..."
.\curl -k https://172.16.16.16:4444/webconsole/APIController?reqxml=<Request><Login><Username>TunnelCheckerAPIUser</Username><Password>01_placeholder_PASSWORD_here_02</Password></Login><Set><VPNIPSecConnection><DeActive><Name>VPN_TUNNEL_NAME</Name></DeActive></VPNIPSecConnection></Set></Request>

Start-Sleep -Seconds 5

Write-Host "Bringing VPN Tunnel Up..."
.\curl -k https://172.16.16.16:4444/webconsole/APIController?reqxml=<Request><Login><Username>TunnelCheckerAPIUser</Username><Password>01_placeholder_PASSWORD_here_02</Password></Login><Set><VPNIPSecConnection><Active><Name>VPN_TUNNEL_NAME</Name></Active></VPNIPSecConnection></Set></Request>
}

function Check-VPN-Tunnel {
# Server Connectivity Check
Write-Host "Checking Tunnel Connection to PLACEHOLDER..."
if (-not (Test-Connection '10.0.0.29' -Quiet)) {
        Reset-VPN-Tunnel
    }

# Server Connectivity Check
Write-Host "Checking Tunnel Connection to PLACEHOLDER..."
if (-not (Test-Connection '10.0.0.30' -Quiet)) {
        Reset-VPN-Tunnel
    }
}

function Trace-VPN-Tunnel {
    Write-Host "Tracing Path to PLACEHOLDER:"
    pathping -n -w 500 -p 100 10.0.0.29

    Write-Host "Tracing Path to PLACEHOLDER:"
    pathping -n -w 500 -p 100 10.0.0.30
}

CD "C:\Scripts\VPN_Tunnel_Checker"
Check-VPN-Tunnel

#Write-Host "Checking Tunnel Quality After Running Script..."
#Trace-VPN-Tunnel

Optional Reporting

You may find that you want some extra logging enabled so you can track the script doing its job to ensure its working. You can add the following to the script above to add that functionality.

Add the following to the bottom of each server in the Check-VPN-Tunnel function, directly below the Reset-VPN-Tunnel function.

Add-Content -Path "C:\Scripts\VPN_Tunnel_Checker\Tunnel.log" -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') PLACEHOLDER Connection Down"

Lastly, change the very end of the script under where the Check-IHS-Tunnel function is being called to look like this if you want to log heartbeats and not just when a VPN tunnel is down. The purpose of this is to show the script is actually running. I recommend only temporarily implementing it during initial deployment.

CD "C:\Scripts\VPN_Tunnel_Checker"
Check-VPN-Tunnel
Add-Content -Path "C:\Scripts\VPN_Tunnel_Checker\Tunnel.log" -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Heartbeat"
PLACEHOLDER

Create Scheduled Task

At this point, you need this script to run automatically on its own every 5 minutes or so, so you need to create a task in the Windows Task Scheduler in order to achieve this.

  • Open "Task Scheduler" on the device
  • Expand "Task Scheduler Library" in the tree on the left-hand side
  • Right-click anywhere in the task list and select "Create New Task..."
    • General:
      • Name: Check VPN Tunnel Every 5 Minutes
      • When running this task, use the following user account: SYSTEM
    • Triggers:
      • Click "New..."
      • Begin the Task: On a Schedule
      • Settings: Daily
      • Advanced Settings > Repeat Task Every: 5 Minutes > for a duration of 1 Day
    • Actions:
      • Click "New..."
      • Action: Start a Program
      • Program/Script: C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe
      • Add Arguments: -ExecutionPolicy Bypass -File "C:\Scripts\VPN_Tunnel_Checker\Tunnel_Checker.ps1"
  • Press the "OK" button to save the scheduled task, then wait for 5 minutes to ensure it triggers as-expected.
  • PLACEHOLDER
  • PLACEHOLDER