Zum Inhalt springen
Avanet

Sophos Firewall per Central API exportieren und importieren

Seit Sophos Central Firewall Management 2026.29 lassen sich Konfigurationen von Firewalls mit SFOS 22.0 MR2 oder neuer per REST API exportieren und importieren. Der Ablauf besteht aus wenigen Schritten: API-Zugang authentifizieren, Firewall-ID ermitteln, Export oder Upload starten und die zurückgegebene Transaktion bis zum Abschluss prüfen.

Ein Import verändert die Ziel-Firewall und ist kein Restore-Backup. Vorher ein aktuelles Firewall-Backup erstellen, den Ablauf zuerst mit einer Testfirewall durchführen und die Wirkung danach lokal abnehmen.

Voraussetzungen und API-Variablen vorbereiten

Benötigt werden:

  • eine mit Sophos Central verbundene und verwaltete Firewall ab SFOS 22.0 MR2;
  • eine aktive bezahlte Firewall-Subscription ausserhalb der Base License oder einen aktiven Supportvertrag;
  • ein eigenes API-Credential mit den benötigten Rechten;
  • curl, jq und für einen Import md5 oder md5sum;
  • Tenant-ID, regionaler API-Host und die Firewall-ID;
  • ein Wartungsfenster und ein getesteter Rückweg für Importe.

API-Zugangsdaten werden in Sophos Central unter Global Settings > Access Control > API Credentials erstellt. Für einen Tenant empfiehlt Sophos die Rolle Service Principal Firewall. Im Partner Dashboard liegt die Funktion unter Global Settings > APIs & Integrations > API Credentials Management; dort stehen andere Rollen zur Auswahl und es gilt die kleinste Rolle mit Zugriff auf den Ziel-Tenant. Client Secret, JWT, Secure Storage Master Key und später ausgegebene Download- oder Upload-URLs gehören nicht in Tickets, Chats oder Screenshots.

Die Beispiele laufen in Bash und setzen ein Tenant-Credential voraus. Partner- und Enterprise-Credentials müssen zuerst den Ziel-Tenant samt regionalem API-Host auflösen. Diesen Unterschied erklärt Sophos unter How Our APIs Work.

Client ID und Client Secret eingeben, ohne das Secret in die Shell-History zu schreiben:

read -r -p "Client ID: " CLIENT_ID
read -r -s -p "Client Secret: " CLIENT_SECRET
printf '\n'

Danach ein zeitlich begrenztes JWT anfordern:

JWT=$(
  printf '%s' "$CLIENT_SECRET" |
    curl --fail-with-body --silent --show-error \
      --request POST \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'grant_type=client_credentials' \
      --data-urlencode "client_id=$CLIENT_ID" \
      --data-urlencode 'client_secret@-' \
      --data-urlencode 'scope=token' \
      https://id.sophos.com/api/v2/oauth2/token |
    jq -er '.access_token'
)
unset CLIENT_SECRET

Die einfachen curl-Beispiele übergeben das kurzlebige JWT als Header-Argument. Sie gehören deshalb auf eine vertrauenswürdige Admin-Workstation, auf der keine fremden Benutzer lokale Prozessargumente mitlesen können.

whoami liefert bei einem Tenant-Credential die Tenant-ID und den regionalen API-Host:

WHOAMI=$(
  curl --fail-with-body --silent --show-error \
    --header "Authorization: Bearer $JWT" \
    https://api.central.sophos.com/whoami/v1
)

TENANT_ID=$(jq -er 'select(.idType == "tenant") | .id' <<<"$WHOAMI")
API_HOST=$(jq -er '.apiHosts.dataRegion' <<<"$WHOAMI")
printf 'Tenant: %s\nAPI host: %s\n' "$TENANT_ID" "$API_HOST"

Bricht jq hier ab, ist das Credential wahrscheinlich einem Partner oder einer Enterprise-Organisation zugeordnet. Dann nicht mit deren ID als X-Tenant-ID weiterarbeiten, sondern den verwalteten Tenant und dessen apiHost ermitteln.

Firewall-ID ermitteln

Die Firewall-Liste zeigt Name, Hostname, Seriennummer, Firmware und UUID:

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer $JWT" \
  --header "X-Tenant-ID: $TENANT_ID" \
  "$API_HOST/firewall/v1/firewalls?pageSize=1000" |
  jq -r '.items[] |
    [.name, .hostname, .serialNumber, .firmwareVersion, .id] |
    @tsv'

Die UUID der richtigen Firewall übernehmen und nicht allein nach einem ähnlichen Anzeigenamen auswählen:

FIREWALL_ID="<firewall-uuid>"

Fehlt die Firewall, zuerst Tenant, Region, Central-Verbindung und Management-Freigabe prüfen. Die Registrierung erklärt Sophos Firewall mit Sophos Central verbinden.

Konfiguration exportieren

Vollständigen Export starten

Der Export läuft asynchron. Der erste Aufruf liefert deshalb nur eine Transaction-ID:

EXPORT_RESPONSE=$(
  curl --fail-with-body --silent --show-error \
    --request POST \
    --header "Authorization: Bearer $JWT" \
    --header "X-Tenant-ID: $TENANT_ID" \
    --header 'Content-Type: application/json' \
    --data '{"fullExport":true}' \
    "$API_HOST/firewall/v1/firewall-config/firewalls/$FIREWALL_ID/export"
)

EXPORT_TX=$(jq -er '.transactionId' <<<"$EXPORT_RESPONSE")
printf 'Export transaction: %s\n' "$EXPORT_TX"

Den Status nach einigen Sekunden erneut abrufen:

EXPORT_STATUS=$(
  curl --fail-with-body --silent --show-error \
    --header "Authorization: Bearer $JWT" \
    --header "X-Tenant-ID: $TENANT_ID" \
    "$API_HOST/firewall/v1/firewall-config/firewalls/transactions/$EXPORT_TX"
)

jq '{status, result, createdAt, finishedAt, expiryAt, response}' \
  <<<"$EXPORT_STATUS"

Den Request ungefähr alle zehn Sekunden wiederholen, bis status den Endzustand finished erreicht. pending und started sind noch keine Fehler.

Erst bei status: "finished" und result: "success" enthält response.url die zeitlich begrenzte Download-URL:

DOWNLOAD_URL=$(
  jq -er '
    select(.status == "finished" and .result == "success") |
    .response.url
  ' <<<"$EXPORT_STATUS"
)

OUTPUT="sophos-firewall-config-$(date +%F).tar"
curl --fail-with-body --location --output "$OUTPUT" "$DOWNLOAD_URL"
tar -tf "$OUTPUT"
unset DOWNLOAD_URL

Die TAR-Datei kann sensible Netz-, Benutzer-, VPN- und Policy-Daten enthalten. Die Datei geschützt ablegen oder nach der Auswertung löschen. Für einen lesbaren Report oder Vorher-Nachher-Vergleich kann die enthaltene Entities.xml in Sophos Firewall Config Studio verwendet werden.

Nur ausgewählte Konfigurationen exportieren

Für einen selektiven Export sind die Entity-Namen exakt und mit korrekter Gross-/Kleinschreibung anzugeben. Dieses Beispiel exportiert Firewall- und NAT-Regeln mit abhängigen Objekten:

curl --fail-with-body --silent --show-error \
  --request POST \
  --header "Authorization: Bearer $JWT" \
  --header "X-Tenant-ID: $TENANT_ID" \
  --header 'Content-Type: application/json' \
  --data '{
    "fullExport": false,
    "includeDependency": true,
    "exportEntities": ["FirewallRule", "NATRule"]
  }' \
  "$API_HOST/firewall/v1/firewall-config/firewalls/$FIREWALL_ID/export"

Die gültigen Entity-Namen stehen im aktuellen Export-Endpunkt der Sophos Firewall API. includeDependency ist bei einem selektiven Export standardmässig false; die Option bewusst setzen und das resultierende Paket trotzdem prüfen.

Konfiguration importieren

Der Import besteht aus Upload-URL anfordern, TAR hochladen, Dateidaten bestätigen und Transaktion prüfen. Das Beispiel verwendet nur eine Testfirewall und setzt performPartialImport bewusst auf false. Der API-Standardwert ist true und erlaubt pro Firewall einen Teilimport.

Vorher die Kompatibilität prüfen: Die Ziel-Firewall benötigt mindestens dieselbe Firmware- und Pattern-Version. Selektive Imports zwischen unterschiedlichen Modellen unterstützt Sophos nur von einem niedrigeren auf ein höheres Modell; die Zielhardware muss mindestens gleich viele Ethernet-Ports besitzen. Bei abweichenden Portnamen muss Entities.xml vor dem Upload passend angepasst werden.

Importdatei und Prüfsumme vorbereiten

Zieldatei, Prüfsumme und Dateigrösse vorbereiten:

FILE="sophos-firewall-config-2026-08-03.tar"
FILE_SIZE=$(wc -c <"$FILE" | tr -d ' ')

Auf macOS:

CHECKSUM_MD5=$(md5 -q "$FILE")

Auf Linux:

CHECKSUM_MD5=$(md5sum "$FILE" | awk '{print $1}')

Upload-Session anfordern und Datei hochladen

Upload-Session anfordern und nur die nicht geheimen Felder ausgeben:

IMPORT_SESSION=$(
  curl --fail-with-body --silent --show-error \
    --request POST \
    --header "Authorization: Bearer $JWT" \
    --header "X-Tenant-ID: $TENANT_ID" \
    "$API_HOST/firewall/v1/firewall-config/firewalls/import"
)

IMPORT_TX=$(jq -er '.transactionId' <<<"$IMPORT_SESSION")
UPLOAD_URL=$(jq -er '.url' <<<"$IMPORT_SESSION")
jq '{transactionId, method, expiresAt}' <<<"$IMPORT_SESSION"

Die Datei vor Ablauf der Pre-signed URL mit der zurückgegebenen Methode PUT hochladen. An diese URL keinen JWT- oder Tenant-Header senden:

curl --fail-with-body --silent --show-error \
  --request PUT \
  --upload-file "$FILE" \
  "$UPLOAD_URL"
unset UPLOAD_URL

Import abschliessen und Status prüfen

Wenn das Paket sensible Informationen enthält und auf eine andere oder neu aufgesetzte Firewall importiert wird, ist der passende Secure Storage Master Key nötig. Ohne ihn importiert SFOS sensible Informationen und davon abhängige Konfigurationen nicht. Der folgende Prompt zeigt das Secret nicht an; mit Enter bleibt es weg:

read -r -s -p "Secure Storage Master Key, sonst Enter: " SSMK
printf '\n'

Upload abschliessen und das Paket der Ziel-Firewall zuweisen:

TARGET_FIREWALL_ID="$FIREWALL_ID"

COMPLETE_RESPONSE=$(
  printf '%s' "$SSMK" |
    jq -Rsc \
      --arg firewall "$TARGET_FIREWALL_ID" \
      --arg checksum "$CHECKSUM_MD5" \
      --argjson size "$FILE_SIZE" '
        . as $ssmk |
        {
          firewallIds: [$firewall],
          checksumMd5: $checksum,
          fileSizeBytes: $size,
          performPartialImport: false
        }
        + if ($ssmk | length) > 0
          then {secureMasterKey: $ssmk}
          else {}
          end
      ' |
    curl --fail-with-body --silent --show-error \
      --request POST \
      --header "Authorization: Bearer $JWT" \
      --header "X-Tenant-ID: $TENANT_ID" \
      --header 'Content-Type: application/json' \
      --data-binary @- \
      "$API_HOST/firewall/v1/firewall-config/firewalls/import/$IMPORT_TX/upload-complete"
)
unset SSMK
jq '{id, status, result}' <<<"$COMPLETE_RESPONSE"

Ein Request akzeptiert 1 bis 25 eindeutige Firewall-IDs. Für weitere Firewalls muss das Paket erneut hochgeladen werden; dieselbe Pre-signed URL oder Transaction-ID nicht wiederverwenden.

Den Importstatus über denselben Transaction-Endpunkt prüfen:

IMPORT_STATUS=$(
  curl --fail-with-body --silent --show-error \
    --header "Authorization: Bearer $JWT" \
    --header "X-Tenant-ID: $TENANT_ID" \
    "$API_HOST/firewall/v1/firewall-config/firewalls/transactions/$IMPORT_TX"
)

jq '{status, result, createdAt, finishedAt, response}' <<<"$IMPORT_STATUS"

Auch diese Abfrage ungefähr alle zehn Sekunden wiederholen, bis status: "finished" erscheint. Erst dann result und bei mehreren Zielen jedes Element in response.items auswerten.

success bestätigt die API-Verarbeitung, nicht die fachliche Wirkung.

Import lokal abnehmen

Nach finished auf jeder Ziel-Firewall kontrollieren:

  1. Sind genau die erwarteten Regeln, Objekte und Einstellungen vorhanden?
  2. Fehlen Benutzer, Passwörter, Zertifikate oder abhängige Objekte wegen eines fehlenden oder falschen SSMK?
  3. Passen Interfaces, Zonen, Gateways, Firmware, Pattern-Version und Hardwaremodell zum Paket?
  4. Funktionieren Routing, NAT, VPN, Authentifizierung und Managementzugriff mit definierten Testfällen?
  5. Zeigen Audit Trail und Konfigurationslogs unerwartete Änderungen?
  6. Liefert ein erneuter Export beziehungsweise Config-Studio-Vergleich nur die geplanten Unterschiede?

Import/Export aktualisiert vorhandene Konfiguration und entfernt nicht automatisch alles, was im Paket fehlt. Die TAR-Datei ist deshalb weder ein vollständiger Sollzustand noch ein Ersatz für Backup, Rollback und Funktionstest.

Troubleshooting

Export bleibt ohne Download-URL

Die URL erscheint erst nach status: "finished" und result: "success". Bei error oder partialSuccess die Felder in response prüfen und nicht mit einer leeren oder abgelaufenen URL weiterarbeiten.

HTTP 401 oder 403

Bei 401 ist das JWT meist abgelaufen oder ungültig. Neu authentifizieren. Bei 403 Central-Rolle, Tenant-Kontext, X-Tenant-ID und regionalen API-Host prüfen. Die lokale XML-API-Freigabe unter /webconsole/APIController ist dafür nicht zuständig; sie wird separat unter Sophos Firewall XML API Zugriff absichern behandelt.

Upload-complete liefert 400 oder 409

Transaction-ID, Ablaufzeit der Upload-URL, tatsächliche Dateigrösse, hexadezimale MD5-Prüfsumme und eindeutige Firewall-IDs prüfen. Die hochgeladene Datei danach nicht verändern. Für einen neuen Versuch eine neue Upload-Session verwenden.

Import endet mit error oder partialSuccess

response und bei mehreren Ziel-Firewalls response.items sichern. Liefert ein API-Aufruf eine separate 4xx- oder 5xx-Fehlerantwort, zusätzlich error, message, code, correlationId und requestId dokumentieren. Danach Zielversion, Patternstand, Modell, Ports, Abhängigkeiten und SSMK lokal prüfen. Reicht die Central-Antwort nicht aus, auf der Firewall fwcm-api-executor.log gemäss Sophos Firewall Service- und Logdateien kontrollieren.

Der Transaction-Endpunkt ist für den API-Status massgebend; nicht annehmen, dass der Auftrag in der Central Firewall Task Queue erscheint.

Sehr grosser Import bricht ab

Sophos führt den Known Issue NR-19066: Ein Import mit sehr vielen Objekten kann das zweistündige Verarbeitungslimit überschreiten. Statt den vollständigen Import unverändert zu wiederholen, kleinere selektive Pakete bilden, einzeln importieren und jeden Schritt abnehmen.

Am Ende der Session sensible Variablen entfernen:

unset JWT CLIENT_ID TENANT_ID API_HOST FIREWALL_ID TARGET_FIREWALL_ID
unset EXPORT_TX IMPORT_TX CHECKSUM_MD5 FILE_SIZE