Support-Portal

Sophos SG: Einpflegen von Microsoft Office 365-Netzwerken mittels Powershell

Der folgende Artikel beschreibt, wie sie mit Hilfe der in der Sophos SG integrierten API-Schnittstelle und Powershell automatisiert Microsoft Office 365-Netzwerke in eine Netzwerkgruppe einfügen.

Der mit der Sophos UTM verwendete Nutzer muss mindestens die Rechte „Network Protection Manager“ besitzen.

Schritt 1: Aktivieren der API-Schnittstelle

  1. Öffnen sie den Webadmin.
  2. Navigieren sie zu Verwaltung –> WebAdmin-Einstellungen –> RESTful API
  3. Aktivieren sie den Schalter, um die API einzuschalten.
  4. Klicken sie auf „Neues API-Token…“
  5. Wählen sie einen Benutzer, der Mindestens die Rechte „Network Protection Manager“ besitzt, aus und klicken sie auf Speichern.
  6. Notieren sie das Token des Benutzers.

 

Schritt 2: Vorbereiten der Netzwerkgruppe und REF-ID der Netzwerkgruppe finden

  1. Navigieren sie zu Verwaltung –> Systemeinstellungen –> Shell-Zugriff
  2. Aktivieren sie den Shell-Zugriff, vergeben sie Passwörter für loginuser und root und klicken sie auf „Festgelegte Passwörter übernehmen“.
  3. Verbinden sie sich per SSH, zum Beispiel mit putty, mit der Konsole der Sophos UTM. Loggen sie sich mit loginuser ein und wechseln sie mit dem Befehl su auf den root-User.
  4. Setzen sie folgenden Befehl ab:
    confd-watch.plx -v
  5. Wechseln sie zurück zum Webadmin.
  6. Navigieren sie zu Definitionen & Benutzer –> Netzwerkdefinitionen
  7. Klicken sie auf „Neue Netzwerkdefinition“
  8. Vergeben sie einen Namen für die Gruppe. Für diese Anleitung verwenden wir „O365_networks“. Ändern sie den Typ auf Netzwerkgruppe und speichern sie.
  9. Auf der Konsole sollte nun eine Ausgabe zu sehen sein:
    1  caught USR1 signal(s)
    
    vc 69 70  data version change detected at Thu Sep 17 16:06:13 2020
    
    o+ REF_NetGroO365networ network group  created
  10. Notieren sie die REF-ID, in diesem Beispiel „REF_NetGroO365networ“

Schritt 3: Vorbereiten & Ausführen des Scripts

  1. Erstellen sie die Datei „utmliste.txt“
  2. Die erste Zeile der Textdatei ist folgende (ohne Leerzeichen): socket,group_ref,token
  3. Die zweite Zeile der Textdatei setzt sich zusammen aus (ohne Leerzeichen): IP der UTM:Port des Webadmins, REF_ID, API-Token
  4. Erstellen sie eine Datei „Script.ps1“ und kopieren sie folgendes Script, zum Beispiel mit Texteditor, hinein:
    [CmdletBinding(SupportsShouldProcess=$True)]
    Param (
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [String] $UTMFile = ".\utmliste.txt",
    
        [Parameter(Mandatory = $false)]
        [ValidateSet('Worldwide', 'Germany')]
        [String] $O365_Instance = "Worldwide",
    
        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [guid] $O365_ClientRequestId = (new-guid)
    )
    
    [String] $O365_BaseURL = "https://endpoints.office.com/endpoints"
    
    Class O365Network
    {
        [String]$ip
        [String]$name
        [String]$utm_ref
        O365Network (
            [String]$ip,
            [String]$name,
            [String]$utm_ref
        ) {
            $this.ip = $ip
            $this.name = $name
            $this.utm_ref = $utm_ref
        }
    }
    
    function Read-UTM-Hosts {
        return (Import-Csv -Path $UTMFile)
    }
    
    function Get-O365-URL {
        return (
            "{0}/{1}?noipv6&ClientRequestId={2}" -f ($O365_BaseURL,  $O365_Instance, $O365_ClientRequestId)
        )
    }
    
    function Get-O365-Data {
        [String] $url = Get-O365-URL
        try {
            $data = Invoke-RestMethod -Uri $url
            $iplist = $data.ips | sort -Unique
        }
        catch {
            $iplist = $null
        }
        return $iplist
    }
    
    function Get-O365-Networks {
        $iplist = Get-O365-Data
        if($iplist) {
            $netobjlist = (
                $iplist | % { [O365Network]::new($_, "O365_{0}" -f $_, $null); }
            )
        }
        else {
            $netobjlist = $iplist
        }
        return $netobjlist
    }
    
    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 $current_utm_host.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 $current_utm_host.socket
    
        # base_url + "/api/" + request path
        [String] $api_url = "{0}/api/{1}" -f ($api_base_url, $Path)
        # if a ref has been given, append it to the API url
        if ($Ref) { $api_url = "{0}{1}" -f ($api_url, $Ref); }
    
        # construct arguments for Invoke-RestMethod call
        $kwargs = @{
            Headers = $headers
            Method = $Method
            Uri = $api_url
        }
    
        if ($Body) {$kwargs["Body"] = $Body; }
        return (Invoke-RestMethod @kwargs)
    }
    
    
    function Get-UTM-Networks {
        $group = UTM-API-Call -Method 'GET' -Path "objects/network/group/" -Ref $current_utm_host.group_ref
    
        $networkUTMlist = @()
        foreach ($member_ref in $group.members){
            $network = UTM-API-Call -Method 'GET' -Path "objects/network/network/" -Ref $member_ref
            $networkUTMlist += [O365Network]::new($null, $network.name, $network._ref)
        }
        return $networkUTMlist
    }
    
    function Delete-UTM-Networks {
        Param (
            [Parameter(Mandatory = $true)]
            [Object] $NetworksDelete
        )
        foreach ($network in $NetworksDelete) {
            UTM-API-Call -Method 'DELETE' -Path "objects/network/network/" -Ref $network.utm_ref
        }
    }
    
    function Add-UTM-Networks {
        Param (
            [Parameter(Mandatory = $true)]
            [Object] $NetworksAdd
        )
    
        foreach ($network in $NetworksAdd.Values) {
            if (-not $network.utm_ref) {
                $net = $network.ip.split("/")
                $body = '{"name":"' + $network.name + '","address":"' + $net[0] + '","netmask":"' + $net[1] + '","resolved":true}'
                $result = UTM-API-Call -Method 'POST' -Path "objects/network/network/" -Body $body
                if ($result) {
                    $network.utm_ref = $result._ref
                }
            }
        }
    }
    
    function Update-UTM-Group {
        Param (
            [Parameter(Mandatory = $true)]
            [Object] $NetworksUpdate
        )
    
        $netref = (
            $NetworksUpdate.Values.utm_ref | Where-Object { $_; } | % { '"{0}"' -f $_; }
        ) -join ","
    
        $body = '{"members":[' + $netref + ']}'
        UTM-API-Call -Method 'PATCH' -Path "objects/network/group/" -Ref $current_utm_host.group_ref -Body $body | out-null
    }
    
    #Begin des Scripts
    $o365_networks = Get-O365-Networks
    
    #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
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    
    if ($o365_networks) {
        foreach ($current_utm_host in (Read-UTM-Hosts)) {
            write-host $current_utm_host.socket
            $utm_networks = Get-UTM-Networks
            $networks = @{}
            $networks_delete = @()
            foreach ($network in $o365_networks){
                # reset UTM_REF
                $network.utm_ref = $null
                $networks.add($network.name, $network)
            }
            foreach ($network in $utm_networks){
                if ($networks.ContainsKey($network.name)) {
                    $mod = $networks[$network.name]
                    $mod.utm_ref = $network.utm_ref
                }
                else {
    
                    $networks_delete += $network
                }
            }
            if ($networks_delete){
                Delete-UTM-Networks -NetworksDelete $networks_delete
            }
                Add-UTM-Networks -NetworksAdd $networks
                Update-UTM-Group -NetworksUpdate $networks
            }
        }
    else {
        write-host "Fehler im Abruf der O365-Referenz Datei."
        write-host "Prüfen sie die Internetverbindung für den Aufruf der Webseite https://endpoints.office.com/endpoints/worldwide?clientrequestid=insert your ID"
    
    }
  5. utmliste.txt und Script.ps1 müssen im selben Ordner liegen. Führen sie Script.ps1 mit Powershell aus.
Tags: Sophos UTM, WebAdmin, sophos, Sophos SG, Microsoft, Office 365, Powershell