Sophos Firewall per Central API exportieren und importieren
Mit SFOS 22.0 MR2 oder neuer lassen sich Firewall-Konfigurationen über die Sophos Central REST API in Sophos Fusion (ehemals Sophos Central) 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.
Für direkten Zugriff auf die Firewall beschreibt lokale REST API und API-Schlüssel in SFOS 23.0 einen anderen Weg. Diese lokalen Administrator-Schlüssel ersetzen weder den Cloud-Service-Principal noch Token, Tenant oder regionalen API-Host dieses Artikels.
Für einen einzelnen manuellen Change direkt im lokalen WebAdmin passt stattdessen Konfiguration selektiv exportieren und importieren. Der Artikel erklärt zusätzlich Entities.xml, SSMK, Objektabhängigkeiten und die Merge-Wirkung des Imports.
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 Fusion 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,jqund für einen Importmd5odermd5sum;- Tenant-ID, regionaler API-Host und die Firewall-ID;
- ein Wartungsfenster und ein getesteter Rückweg für Importe.
Credential-Erstellung, Rollen, Token- und whoami-Vertrag, Regionsermittlung, Secret-Schutz, Validierung und gemeinsame Fehlerdiagnose stehen zentral unter Sophos Central API-Zugangsdaten sicher verwalten. Den Ablauf dort vollständig ausführen; dieser Artikel übernimmt anschliessend SOPHOS_ACCESS_TOKEN, SOPHOS_TENANT_ID und SOPHOS_API_HOST.
API-Zugangsdaten werden in Sophos Fusion 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. Für alle tenantbezogenen Aufrufe ist anschliessend der von whoami für diesen Tenant zurückgegebene regionale apiHost zu verwenden.
Die drei vom Owner-Ablauf validierten Werte auf die Variablennamen dieses Artikels abbilden:
JWT="$SOPHOS_ACCESS_TOKEN"
TENANT_ID="$SOPHOS_TENANT_ID"
API_HOST="$SOPHOS_API_HOST"
Das JWT wird nicht erneut angefordert; JWT ist der oben übernommene, kurzlebige Access-Token.
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.
Tenant-ID und Regionalhost stammen ebenfalls aus dem Owner-Ablauf:
TENANT_ID und API_HOST sind bereits validiert. Bei Partner- oder Enterprise-Credentials müssen sie aus der vollständig paginierten Tenantliste des Owner-Ablaufs stammen.
Firewall-ID ermitteln
Die Firewall-Liste zeigt Name, Hostname, Seriennummer, Firmware und UUID:
FIREWALLS_FILE=$(mktemp); printf '[]\n' >"$FIREWALLS_FILE"
page=1; max_pages=1000; expected_pages=
while (( page <= max_pages )); do
PAGE_RESPONSE=$(curl --fail-with-body --silent --show-error --get \
--header "Authorization: Bearer $JWT" --header "X-Tenant-ID: $TENANT_ID" \
--data-urlencode "page=${page}" --data-urlencode 'pageSize=100' \
--data-urlencode 'pageTotal=true' "$API_HOST/firewall/v1/firewalls")
page_total=$(jq -er 'select((.items|type)=="array")|.pages.total|select(type=="number" and floor==. and .>=1 and .<=1000)' <<<"$PAGE_RESPONSE")
if [[ -z "$expected_pages" ]]; then expected_pages=$page_total; fi
[[ "$page_total" == "$expected_pages" ]] || exit 1
jq -e --argjson page "$PAGE_RESPONSE" '.+$page.items' "$FIREWALLS_FILE" >"${FIREWALLS_FILE}.new"; mv "${FIREWALLS_FILE}.new" "$FIREWALLS_FILE"
(( page >= expected_pages )) && break; ((page++))
done
(( page == expected_pages )) || exit 1
jq -r '.[]|[.name,.hostname,.serialNumber,.firmwareVersion,.id]|@tsv' "$FIREWALLS_FILE"
Die UUID der richtigen Firewall übernehmen und nicht allein nach einem ähnlichen Anzeigenamen auswählen:
read -r -p 'Firewall-UUID aus dem freigegebenen Inventar: ' REQUESTED_FIREWALL_ID
UUID_RE='^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'
FIREWALL_ID=$(jq -er --arg id "$REQUESTED_FIREWALL_ID" --arg re "$UUID_RE" '[.[]|select((.id|type)=="string" and (.id|test($re)) and (.id|ascii_downcase)==($id|ascii_downcase))]|select(length==1)|.[0].id' "$FIREWALLS_FILE")
rm -f "$FIREWALLS_FILE"; unset PAGE_RESPONSE REQUESTED_FIREWALL_ID page page_total expected_pages max_pages
Fehlt die Firewall, zuerst Tenant, Region, Sophos-Fusion-Verbindung und Management-Freigabe prüfen. Die Registrierung erklärt Sophos Firewall mit Sophos Fusion 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 Entity-Namen sind exakt und case-sensitive; für das gezeigte Beispiel lauten sie FirewallRule und NATRule. includeDependency ist bei einem selektiven Export standardmässig false; die Option bewusst setzen und das resultierende Paket trotzdem prüfen.
Umfang und Grenzen des Pakets
Vor einem API-Import sind auch diese für die TAR-Datei geltenden SFOS-Regeln wichtig:
- Der Import aktualisiert vorhandene Einstellungen. Fehlt eine Einstellung im Paket, bleibt sie auf dem Ziel bestehen; ist sie in beiden Konfigurationen vorhanden, gilt der Wert aus dem Import.
- Bei externer Authentifizierung enthält der Export nur lokal manuell angelegte Benutzer. Bei
OTPTokenswerden nur ausgegebene Tokens dieser manuell angelegten Benutzer exportiert. REDDevicezieht den benötigten DHCP-Server auch mitincludeDependencynicht automatisch mit. Dafür zusätzlichDHCPServerexportieren oder den DHCP-Server nach dem Import neu erstellen.- Eine importierte URL-Liste darf höchstens 128 Domains enthalten.
- Für XGS 88w, 108w, 118w und 128w gelten zusätzliche Bedingungen für Wireless-Konfigurationen, unter anderem für Frequenzbänder, Security Mode, Encryption, Bridges und die Anzahl eindeutiger SSIDs.
Eine fehlerfrei lesbare TAR-Inhaltsliste beweist daher nur, dass das Archiv technisch geöffnet werden kann. Sie bestätigt weder, dass alle fachlich benötigten Objekte enthalten sind, noch dass sie auf der Zielhardware wirksam werden.
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:
- Sind genau die erwarteten Regeln, Objekte und Einstellungen vorhanden?
- Fehlen Benutzer, Passwörter, Zertifikate oder abhängige Objekte wegen eines fehlenden oder falschen SSMK?
- Passen Interfaces, Zonen, Gateways, Firmware, Pattern-Version und Hardwaremodell zum Paket?
- Funktionieren Routing, NAT, VPN, Authentifizierung und Managementzugriff mit definierten Testfällen?
- Zeigen Audit Trail und Konfigurationslogs unerwartete Änderungen?
- 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.
Rollback nach einem fehlerhaften Import
Schlägt die lokale Abnahme fehl, den Rollout stoppen, die Transaction-Antwort sichern und nicht mit weiteren Importen überdecken. Für den Rückweg im lokalen WebAdmin zu Backup and firmware > Backup and restore gehen. Unter Restore configuration mit Choose file das vorher erstellte Backup wählen, dessen Encryption password eingeben und Upload and restore starten.
Der Restore ersetzt die aktuelle Konfiguration, löscht das auf der Firewall gespeicherte Backup und startet die Firewall neu. Danach ist die WebAdmin-IP aus der wiederhergestellten Konfiguration aktiv. Der Zugriff auf diese IP und das Verschlüsselungspasswort müssen deshalb vor dem Import bereitstehen. Nach dem Neustart dieselben Funktionstests wiederholen und mit einem erneuten Export prüfen; Änderungen nach dem Backup gehen beim Restore verloren.
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 Sophos-Fusion-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 Sophos-Fusion-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.
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