Sophos UTM: Exporting the WAF certificate using PowerShell

Sophos UTM can now automatically request and renew certificates from Let's Encrypt. This function is particularly useful for web server protection (WAF). The certificate for the various WAF services is thus managed by the UTM and renewed accordingly before it expires.

I have already received several requests from people who would like to use the WAF certificate for other internal services. Most of the requests are of course related to Exchange servers. The Exchange URLs were configured with the same host name, so the WAF certificate would also be valid on the internal Exchange server. Here is an example of the Exchange configuration:

Exchange configuration

In this case, UTM Webserver Protection is also configured to the host name "mail.frankysweb.de":

image

Connections from the Internet are routed to the Exchange server using Sophos UTM WAF. Internally, the IP of the Exchange server is resolved directly using DNS Split Brain. In this case, it is also possible to use the Sophos WAF certificate for Exchange (or other services).

In order for the Let's Encrypt certificate of the UTM to be used for other services, it must first be exported from the UTM. This can be done manually via the GUI:

Manual export of the WAF certificate

However, Let's Encrypt certificates are only valid for 90 days, so manual export from the UTM and import to the respective internal target systems is usually not a practical option. However, this process can be automated using the Sophos REST API and a small script.

Here is a small example of a PowerShell script that retrieves a certificate via Sophos REST API and converts it into a PFX file (see explanation of the script below):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
param (
     [ Parameters ( Position =0, Mandatory = $true )]
         $UTMAddress = "utm.domain.local" ,
     [ Parameters ( Position =1, Mandatory = $true )]
         [string] $UTMApiToken = "xxXXxxxxXXXXXXXXXX" ,
     [ Parameters ( Position =2, Mandatory = $true )]
         [string] $CertREF = "REF_0815abcd" ,
     [ Parameters ( Position =3, Mandatory = $false )]
         [string] $OpenSSLPath = "C:\Program Files (x86)\OpenSSL\bin\openssl.exe" ,
     [ Parameters ( Position =4, Mandatory = $false )]
         [string] $PFXFilePath = $PSScriptRoot
     )
#Set TLS Settings (Only TSLv1.1 and TLSv1.2)
[System.Net.ServicePointManager] ::SecurityProtocol = @( "Tls12" , "Tls11" , "Tls" )
#Build Credentials
$securePassword = ConvertTo-SecureString $UTMApiToken -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential( "token" , $securePassword )
#UTM API Call to get certificate and private key
$UTMAPICall = "https://$UTMAddress" + ":4444/api/objects/ca/host_key_cert/$CertREF"
try
     {
         $UTMCertResponse = Invoke-RestMethod -Method GET -Uri $UTMAPICall -Credential $credential
     }
catch
     {
         write-error "Error getting certificate from UTM"
         exit
     }
#Write private key and certificate to temp files
try
     {
         $TempCertFile = "$env:temp\" + $CertREF + ".cer"
         $TempKeyFile = "$env:temp\" $CertREF + ".key"
         $UTMCertResponse .certificate | set-content $TempCertFile
         $UTMCertResponse .key | set-content $TempKeyFile
     }
catch
     {
         write-error "Error writing temp files"
         exit
     }
    
#Build PFX File from certificate and key
try
     {
         $PFXFileNameAndPath = "$PFXFilePath" + "\" + "$CertREF" + ".pfx"
         . $OpenSSLPath pkcs12 -export -in $TempCertFile -inkey $TempKeyFile -out $PFXFileNameAndPath -password pass: $UTMApiToken
         remove-item $TempCertFile -force
         remove-item $TempKeyFile -force
     }
catch
     {
         write-error "Error building PFX File"
     }

The script requires a few parameters to work. The parameter "UTMAddress" should be clear. The connection to the REST Api works via API token (UTMApiToken), the token can be created in the WebAdmin of the UTM:

Sophos API Token

The REF ID of the certificate is required so that the corresponding certificate can be retrieved by the UTM. The REF ID can be found in the "Let's Encrypt" live log, for example:

Sophos Let's Encrypt Live Log

The following entry from the live log shows a renewal process and the corresponding REF ID of the certificate (blue box):

Sophos REF ID

The Sophos REST API provides the private key and the certificate. This example script generates a PFX file so that Windows systems can do something with it. The conversion to the PKCS12 format (PFX file) is carried out using OpenSSL. OpenSSL must therefore be present on the computer and the corresponding path to the EXE must be passed (OpenSSLPath). OpenSSL for Windows can be downloaded here:

The PFX file can in turn be imported onto Windows target systems and used for Exchange and IIS Server, for example.

The PFXFilePath parameter can be used to specify the path for the exported certificate in PKCS12 format. The password for the PFX file corresponds to the UTMApiToken.

Here is an example of how to call the script:

image

Importing or assigning the certificate to the target system is not part of this script. However, with a little PowerShell know-how, the script is easy to extend.

If you are interested in an automated export and import for Exchange Server, please leave a short comment.

Note 15.07.19A version for export and import for WAF and Exchange Server can be found here:

Sophos UTM: Export WAF certificate using PowerShell (Exchange version)

24 thoughts on “Sophos UTM: Zertifikat der WAF mittels PowerShell exportieren”

  1. Hallo Frank,
    kann man hier statt der UTM auch die XG für dieses vorhaben verwenden?? Das Prinzip müsste das gleiche sein, oder?

    Viele Grüße
    Markus

    Reply
  2. Danke für das Skript, für jeden der sich die Frage stellt wie man per Domain Namen statt REF ID sucht, sollte man einfach so vorgehen dass man sich die passende ID über Domainname sucht bzw. über die Objeket die als Json reinkommen, und dann in den unter-namespace mit diesem passenden REF_ID geht um sich .cer + .key zu erstellen

    $CertREF= ($UTMCertResponse | Select-Object -Property _ref,certificate |
    Where-Object { $_.certificate -like „*$domainname*“ } |
    Select-Object „_ref“ -ExpandProperty „_ref“ -Unique )

    ##UND DANACH bin ich ähnlich wie oben vorgegangen
    $UTMAPICall = „https://$UTMAddress“ + „: $port/api/objects/ca/host_key_cert/$CertREF“
    $UTMCertResponse = Invoke-RestMethod -Method GET -Uri $UTMAPICall -Verbose -Credential $credential

    Reply
  3. Hallo zusammen,
    leider bekomme ich bei dem Script immer folgende Fehlermeldung:

    C:\Users\administrator\Desktop\Cert\Cert_Rest_Api.ps1 : Error getting certificate from UTM
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Cert_Rest_Api.ps1

    Das Script versuche ich auf einem Server 2019 auszuführen.

    Weiß jemand was ich dagegen tun kann?

    Reply
    • Also da die Exception von der Powershell kommt, würde ich sagen dass der Zielpfad nicht ordnung ist, oder vielleicht der Zugriff auf die openssl.exe? Shell als Admin gestartet? Skript freigeschaltet in den Dateieigenschaften?

      Reply
  4. Tach zusammen :) nun bin ich doch schon mal einen Schritt weitergekommen. Sobald man den richtigen „token“ nimmt klappt das allerdings nur begrenzt. Ein neuer Rechtefehler tritt nun auf:

    WARNUNG: Changing PowerShell TLS settings
    WARNUNG: Building UTM Rest API Creds
    WARNUNG: Getting Cert from UTM REST API
    WARNUNG: Writing cert TMP files
    WARNUNG: Convert UTM Cert and Key to PKCS12
    WARNUNG: UTM Cert Serial: 038003E9D7BC85A6F2A0C806CCD1485E7163
    WARNUNG: Get current Exchange Server Certificate
    C:\UTMCertificate\Get-SophosUTMCertificate.ps1 : Can’t find current Exchange certificate: Fehler bei Active Directory-Vorgang auf . Die angegebenen Anmeldeinformationen für ‚AD\xxx‘ sind ungültig. Error getting
    certificate from UTM: [
    {

    Kann mir jemand hierbei helfen oder zumindest mir einen neuen Ansatz geben wo nun die Fehlerquelle liegen kann.

    ==> Can’t find current Exchange certificate > Würde mich über echt jede Hilfestellung sehr freuen!!

    Gruß
    Philipp

    Reply
  5. Servus zusammen,

    ich scheine wohl einfach die einfachsten Dinge nicht hinbekommen.
    Mein Fehlerbild sieht wie folgt aus:

    „C:\UTMCertificate\Get-SophosUTMCertificate.ps1 : Error getting certificate from UTM: [
    {
    „name“: „X.509-Zertifikat-Objekt kann nicht gelesen werden: Zugriff verweigert.“,
    „rights“: „ANONYMOUS“,
    „attrs“: [],
    „Oattrs“: [
    „class“,
    „type“
    ],
    „objname“: „“,
    „del_object“: „“,
    „ref“: „REF_QVEFoUuMkNjE“,
    „msgtype“: „OBJECT_LOOKUP_DENY“,
    „format“: „%_O-Objekt kann nicht gelesen werden: Zugriff verweigert.“,
    „class“: „ca“,
    „type“: „host_key_cert“,
    „perms“: „MAILSEC,RASMAN,WEBSEC,WEBAUDITOR,MAILAUDITOR,READONLY,WEBAPPAUDITOR,WEBAPPSEC,NTTCUSTOMER,NTTOPERATOR,SUPERADMIN,RASAUDITOR,NTTCUSTOMER2“,
    „never_hide“: 0,
    „fatal“: 1
    }

    Es wäre wirklich super wenn mir jemand eine Hilfestellung geben könnte.

    Ein Ansatz wäre auch schon super… Denn wieso ich keine Rechte habe kann ich mir einfach nicht erklären.

    Danke und Gruß
    Philipp

    Reply
  6. Manchmal sind die Lösungen einfach, zu geringes Recht des auslesenden Benutzers. Somit läuft das Skript perfekt.
    Sorry, aber manchmal dauert’s halt etwas. Ist auch recht warm heut :-)

    Reply
  7. Der Vollständigkeit wegen, im temporären Pfad (Skript Zeile 32+33) wird eine cer Datei und eine key Datei erstellt. Die Key Datei ist bei mir jeweils 0 Byte groß, auch bei verschiedenen LE-Zertifikaten. Die cer-Datei rund 8KB und enthält auch das korrekte Zertifikat.

    Reply
  8. Hat jemand eine Idee warum ich folgenden Fehler erhalte?
    15876:error:0909006C:PEM routines:get_name:no start line:crypto\pem\pem_lib.c:745:Expecting: ANY PRIVATE KEY
    Beste Grüße
    Alex

    Reply
  9. ok, kann man vielleciht mit der Rest API der XG ein Zertifikat austauschen?
    Let’s Encrpyt läuft bei mir bereits auf IIS, es muss nur immer das Zertifikat in der XG geändert werden.

    Reply
  10. Vielen Dank Frank, wie immer tolle Arbeit.
    Der Import auf Exchange Seite wäre wohl das Sahnehäubchen.

    Reply
  11. Das sieht sehr spannend aus und würde die Kombination UTM und Exchange perfekt ergänzen.
    Mit automatischem Import in Exchange wäre es ziemlich klasse.

    Reply
  12. Super, darauf habe ich gewartet! :-)

    Da ich auch eine Sophos UTM habe, könnte ich mir mit automatisierten Let’s Encrypt Zertifikats-Export und Import mein Exchange-Kauf-Zertifikat sparen…

    Reply
  13. Großes Interesse!

    Vielen Dank schon mal für diesen Teil der Lösung, das ist grandios!

    Viele Grüße, Christoph.

    Reply

Leave a Comment