josh-ma
Goto Top

Sophos XGS Firewall: WAF-Zertifikate per API für mehrere Regeln auto. austauschen

Servus,

beim Wechsel eines Zertifikats auf einer Sophos steht man in Umgebungen mit mehreren WAF-Regeln vor einer mühsamen Aufgabe
Das Zertifikat muss manuell in jeder einzelnen WAF-Regel angepasst werden – ein Prozess, der je nach Anzahl der Regeln sehr zeitaufwendig sein kann.

Da Sophos aktuell keine zentrale Zertifikatsverwaltung für WAF-Regeln bietet, habe ich mir ein kleines Skript geschrieben, um den Vorgang vollständig über die API zu automatisieren.

Voraussetzungen:
  • Sophos XG/XGS Firewall mit aktivierter API (Admin > API → aktivieren + API-Nutzer konfigurieren)
  • API-Nutzer mit vollständigen Rechten (docs.sophos.com)
  • Zertifikate bereits auf der Firewall hochgeladen (unter Zertifikate)
  • Python 3 auf einem Client (z. B. Windows mit MobaXterm oder Linux)

Warum benutze ich Hosted Address als Filter?
Wir strukturieren unsere WAF-Regeln nach Ports bzw. Interfaces (z. B. #Port7, #Port2 usw.).
Die Hosted Address bietet eine gute Möglichkeit, Regeln logisch zu gruppieren.

Wichtig zu wissen (Thema Gruppenzuordnung):
Das einzige kleine Problem bei der API-Nutzung:
Sophos übergibt aktuell keine Gruppenzuordnung bei API-Änderungen. Bedeutet: Sobald du eine Regel via API änderst, fliegt sie aus der Gruppe raus.

Über die Weboberfläche können wir das fix beheben:

  • Gehe zu den WAF-Regeln
  • Markiere alle, die du geändert hast
  • Klicke oben rechts auf "Add to group"
  • Wähle die passende Gruppe aus
  • Fertig – alle markierten Regeln werden neu zugeordnet.

Sophos löscht Gruppen automatisch, wenn keine Regel mehr darin ist.
Heißt: Wenn du alle Regeln einer Gruppe per API änderst, ohne vorher mindestens eine manuell zu ändern, ist die Gruppe danach weg.
Also am besten vorher eine Regel manuell ändern – dann bleibt die Gruppe erhalten.

waf_group

Noch ein wichtiger Hinweis:
Auch wenn das Skript funktioniert, sollte man es idealerweise außerhalb der regulären Arbeitszeit laufen lassen.
Beim Aktualisieren der WAF-Regeln über die API kann es zu kurzen Unterbrechungen bei der Erreichbarkeit der betroffenen Dienste kommen – meistens nur für ein paar Sekunden, aber sicher ist sicher.

Und ganz klar:
Vorher ein Backup der Konfiguration machen!

Mein Python-Skript:
import requests
import urllib3
import xml.etree.ElementTree as ET
from xml.sax.saxutils import escape

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Zugangsdaten
firewall = "IP/DNS"  
user = "api-user"  
passwd = "PASSWORD"  

ziel_hosted_address = "#Port2"  
altes_zertifikat = "Wildcard_2024"  
neues_zertifikat = "Wildcard_2025"  

# XML-Request zum Abruf aller Regeln
xml_payload_get = f"""  
<Request>
  <Login>
    <Username>{escape(user)}</Username>
    <Password>{escape(passwd)}</Password>
  </Login>
  <Get>
    <FirewallRule/>
  </Get>
</Request>
"""  

url = f"https://{firewall}:4444/webconsole/APIController"  
headers = {'Content-Type': 'application/x-www-form-urlencoded'}  
data = {'reqxml': xml_payload_get}  

response = requests.post(url, headers=headers, data=data, verify=False)
root = ET.fromstring(response.text)

status = root.findtext(".//Login/status")  
if status and "Failure" in status:  
    print(f"Fehler beim Abrufen: {status}")  
    exit()

# Zähler für Änderungen
geaendert = 0

# Alle passenden Regeln durchgehen
for rule in root.findall(".//FirewallRule"):  
    policy_type = rule.findtext("PolicyType", default="")  
    if policy_type != "HTTPBased":  
        continue

    hosted_address = rule.findtext(".//HTTPBasedPolicy/HostedAddress", default="")  
    if hosted_address != ziel_hosted_address:
        continue

    name = rule.findtext("Name", default="(Unbenannt)")  

    cert_node = rule.find(".//HTTPBasedPolicy/Certificate")  
    if cert_node is None:
        print(f"Regel '{name}' hat kein Zertifikat gesetzt – wird übersprungen.")  
        continue

    if cert_node.text != altes_zertifikat:
        print(f"Regel '{name}' hat bereits ein anderes Zertifikat: {cert_node.text} – wird übersprungen.")  
        continue

    print(f"Regel '{name}' – Zertifikat wird ersetzt (Hosted Address: {hosted_address}).")  
    cert_node.text = neues_zertifikat

    # Neues XML für Set-Request erzeugen
    firewall_rule_xml = ET.tostring(rule, encoding="unicode")  

    xml_payload_set = f"""  
    <Request>
      <Login>
        <Username>{escape(user)}</Username>
        <Password>{escape(passwd)}</Password>
      </Login>
      <Set>
        {firewall_rule_xml}
      </Set>
    </Request>
    """  

    data_set = {'reqxml': xml_payload_set}  
    response_set = requests.post(url, headers=headers, data=data_set, verify=False)

    print("Antwort auf Set-Anfrage:")  
    print(response_set.text)
    print("--------------------------------------------------")  
    geaendert += 1

print(f"\nVorgang abgeschlossen – {geaendert} Regel(n) geändert.")  

Anbei die Dokumentation für die API: docs.sophos.com/nsg/sophos-firewall/19.5/API/index.html

Content-ID: 672290

Url: https://administrator.de/tutorial/sophos-xgs-firewall-waf-zertifikate-per-api-fuer-mehrere-regeln-auto-austauschen-672290.html

Ausgedruckt am: 03.04.2025 um 09:04 Uhr

user217
user217 03.04.2025 um 09:14:19 Uhr
Goto Top
Hallo,

ich dachte das macht die xgs jetzt automatisch per lets encrypt!?
LucarToni
LucarToni 03.04.2025 um 09:29:54 Uhr
Goto Top
Zitat von @user217:

Hallo,

ich dachte das macht die xgs jetzt automatisch per lets encrypt!?

Das stimmt auch, jedoch haben auch Kunden mehrere WAF Regeln und ein gekauftes Zertifikat. Dabei kann der Austausch doch etwas mühselig sein (50 Regeln und 50 mal klicken).
Kunden mit LE - Übernimmt dann die Firewall eigenständig.