Sophos UTM Remote Access: SSL-VPN Profile mittels der RESTful-API steuern

Wer kennt es nicht, hin und wieder müssen externe Dienstleister Systeme innerhalb der eigenen Infrastruktur aktualisieren oder warten. Diesen Unternehmen stellt man nun einen Wartungszugang über SSL-VPN zur Verfügung, möchte aber nicht, dass dieser permanent verfügbar ist. Um dieses Ziel zu erreichen gibt es auf der Sophos UTM mehrere Möglichkeiten. Ich stelle hier vor, wie man Script-gesteuert dedizierte SSL-VPN-Profile ein- bzw. ausschaltet.

Vorbereitungen

Für diesen Blogbeitrag gehen wir davon aus, dass die RESTful-API der Sophos UTM erreichbar ist und ein Token für die Nutzung dieser erstellt wurde. Siehe hierzu unseren Blogbeitrag Sophos UTM – Konfiguration mit RESTful API.

Des Weiteren benötigen wir das zu steuernde SSL-VPN Profil.

Sophos REST API VPN Profil

Für die korrekte Funktionsweise wird noch eine Firewall-Regel benötigt. Da diese für dieses Script aber nicht relevant ist, führen wir sie hier nicht gesondert auf.

Da wir dieses Mal ein bereits erstelltes Objekt der UTM ändern wollen, benötigen wir die Referenz zu diesem Objekt, um dies ansprechen zu können.

Diese erhalten wir, wie beim letzten Mal, über eine SSH-Sitzung (root-Rechte sind hier nötig) und der Nutzung des Befehls config-watch.plx -v. Nachdem wir den Befehl abgesetzt haben, schalten wir über den WebAdmin das SSL-VPN Profil aus und sehen dadurch folgende Ausgabe in der SSH-Sitzung:

192:/root # confd-watch.plx -v
   watching the Confd storage on ASG 9.701006
s  1  caught USR1 signal(s)
vc 101 102  data version change detected at Tue Feb 11 13:20:05 2020
oc REF_SslRemFirma1wart ssl_vpn remote_access_profile status  changed
   status = 0
ec tcp Node:ssl_vpn->port []
s  1  caught USR1 signal(s)
vc 102 103  data version change detected at Tue Feb 11 13:20:05 2020
nc ssl_vpn->interface

Nun suchen wir in der Ausgabe nach der Zeile, in der ein Objekt geändert wurde:

oc REF_SslRemFirma1wart ssl_vpn remote_access_profile status  changed

Hier können wir die Referenz der zu schaltenden SSL-VPN Profil entnehmen REF_SslRemFirma1wart und auch die nötigen Informationen, um im WebGUI der RESTful-API die korrekte URL für den API call entnehmen zu können.

Sophos RESTful API RAP Remote Access Profile

Mittels der markierten GET-Methode und der uns bekannten Referenz (REF_SslRemFirma1wart) können wir uns den aktuellen Status des SSL-VPN Profils Objektes anzeigen lassen, was wir auch tun.

Die nun im WebGUI sichtbare request URL sieht wie folgt aus:

https://192.168.2.4:4444/api/objects/ssl_vpn/remote_access_profile/REF_SslRemFirma1wart

Jetzt haben wir alle für das Script nötigen Informationen gesammelt:

  • URL des WebAdmin
  • Token des API-Nutzers
  • die Referenz des SSL-VPN Profils
  • die request URL zum Aufruf des Objekts vom SSL-VPN Profil

Die request URL wird fest im Script in der dafür nötigen Funktion hinterlegt. Die restlichen Informationen werden für den Aufruf des Scripts benötigt.

Das Script

Param (

    [Parameter(Mandatory = $true, HelpMessage="Unter welcher IP und Port ist der WebAdmin erreichbar. Beispiel 192.168.2.4:4444")]
    [ValidateNotNullOrEmpty()]
    [String] $UTM,
    [Parameter(Mandatory = $true, HelpMessage="Angabe der Referenz des SSLVPN Objekts für Remote Access. Beispiel REF_SslRemTest")]
    [ValidateNotNullOrEmpty()]
    [String] $SSLVPN_ref,
    [Parameter(Mandatory = $true, HelpMessage="Angabe des API Tokens.")]
    [ValidateNotNullOrEmpty()]
    $token
)

function UTM-API-Call {
    Param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String] $Path,
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [String] $Ref = $null,
        [Parameter(Mandatory = $false)]
        [AllowNull()]
        [Object] $Body = $null,
        [Parameter(Mandatory = $true)]
        [ValidateSet('GET', 'POST', 'PATCH', 'DELETE')]
        [String] $Method = 'GET'
    )

    $token = [Convert]::ToBase64String([System.Text.Encoding]::Default.GetBytes("token:{0}" -f $token))
    $headers = @{}
    $headers.add("Authorization",'Basic ' + $token)
    $headers.add("Content-Type", "application/json")
    $headers.add("Accept", "application/json")
    if ($method -eq 'DELETE') {
        $headers.add("X-Restd-Err-Ack", "all")
    }
    [String] $api_base_url = "https://{0}" -f $UTM
    [String] $api_url = "{0}/api/{1}" -f ($api_base_url, $Path)
    if ($Ref) { $api_url = "{0}{1}" -f ($api_url, $Ref); }
    $kwargs = @{
        Headers = $headers
        Method = $Method
        Uri = $api_url
    }
    if ($Body) {$kwargs["Body"] = $Body; }
    return (Invoke-RestMethod @kwargs)
}
function Change-SSLVPN-Status{
    $status = UTM-API-Call -Method 'GET' -Path "objects/ssl_vpn/remote_access_profile/" -Ref $SSLVPN_ref
    $path = "objects/ssl_vpn/remote_access_profile/"
    if ($status.status -eq $false){
        $body = '{"status":true}'
        UTM-API-Call -Method 'PATCH' -Path $path -Ref $SSLVPN_ref -Body $body | out-null

        $result = "Der Status des SSLVPN-Profils: " + $status.name + " wurde in ""Eingeschaltet"" geändert"

        write-host -ForegroundColor Green $result
    }
    else{
        $body = '{"status":false}'
        UTM-API-Call -Method 'PATCH' -Path $path -Ref $SSLVPN_ref -Body $body | out-null
        $result = "Der Status des SSLVPN-Profils: " + $status.name + " wurde in ""Ausgeschaltet"" geändert"
        write-host -ForegroundColor Red $result
    }
}

#Anpassen des SSL Verhaltens der Powershell

Add-Type @"

    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
             ServicePoint srvPoint, X509Certificate certificate,
             WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

Change-SSLVPN-Status

Die Nutzung des Scripts

Für den Aufruf des Scripts sind diesmal mehr Parameter erforderlich:

  • UTM
  • SSLVPN_ref
  • Token

In den folgenden Beispielen sieht man beide Möglichkeiten, wie die Parameter an das Script übermittelt werden können.

Beispiel 1:

Sophos REST API Windows Powershell

Beispiel 2:

Sophos REST API Windows Powershell 2

Das Script schaltet nach dem Aufruf das angegebene SSL-VPN Profil in den jeweils anderen Status und zeigt dies mit einer grünen „Eingeschaltet“ oder roten „Ausgeschaltet“ Ausgabe innerhalb der PowerShell an.

Weitere Script-Anwendungen

Dieses Script kann man nun sehr einfach um alle Objekte, die in einer Sophos UTM „schaltbar“ sind, erweitern, wie z.B.:

  • Firewall-Regeln
  • Die diversen NAT-Regeln
  • Web Proxy Regeln / Ausnahmen
  • Interfaces

Dazu werden passende Funktionen hinzugefügt oder der Pfad in der existierenden Funktion wird umgeschrieben.

Mithilfe dieser Anleitung können auch Sie nun in Ihrer Sophos UTM SSL-VPN Profile mit der RESTful-API steuern.

Wenn ich eine weitere Hilfestellung oder zumindest eine Anregung zur Verwendung der Sophos UTM RESTful API geben konnte, freut es mich.
Eventuell schreibe ich einen weiteren Artikel zur API oder Sophos UTM generell.
Schreiben Sie mir im Kommentar (oder persönlich) welcher Anwendungsfall und welche Themen Sie interessieren.

2 Kommentare

  1. Vielen Dank erstmal für die geniale Idee und die super dokumentierte Umsetzung. Ich habe das mal ausprobiert und kann den Aufruf nicht durchführen:

    Invoke-RestMethod : [
    {
    „name“: „SSL-VPN Fernzugriff-Profil-Objekt kann nicht gelesen werden: Zugriff verweigert.“,
    „rights“: „ANONYMOUS“,
    „attrs“: [],
    „Oattrs“: [
    „class“,
    „type“
    ],

    1. Hallo Arne,

      auf den ersten Blick schaut es so aus das etwas mit der Rechtezuweisung nicht korrekt konfiguriert ist.

      „name“: „SSL-VPN Fernzugriff-Profil-Objekt kann nicht gelesen werden: Zugriff verweigert.“,
      „rights“: „ANONYMOUS“,

      Hat der Nutzer dem das API Token zugewiesen wurde die nötigen Rechte um mit dem SSLVPN Objekt zu interagieren zu können?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

CAPTCHA *