Esportare e importare Sophos Firewall tramite Central API
Da Sophos Central Firewall Management 2026.29 è possibile esportare e importare tramite REST API le configurazioni dei firewall con SFOS 22.0 MR2 o versione successiva. La procedura prevede pochi passaggi: autenticare l’accesso API, individuare l’ID del firewall, avviare l’esportazione o l’upload e verificare fino al completamento la transazione restituita.
Un’importazione modifica il firewall di destinazione e non equivale al ripristino di un backup. Prima creare un backup del firewall aggiornato, provare la procedura su un firewall di test e collaudare poi localmente il risultato.
Preparare i requisiti e le variabili API
Sono necessari:
- un firewall con SFOS 22.0 MR2 o versione successiva, connesso e gestito tramite Sophos Central;
- una sottoscrizione firewall a pagamento attiva diversa dalla Base License oppure un contratto di supporto attivo;
- credenziali API dedicate con le autorizzazioni necessarie;
curl,jqe, per un’importazione,md5omd5sum;- ID tenant, host API regionale e ID del firewall;
- una finestra di manutenzione e una procedura di ritorno testata per le importazioni.
Le credenziali API vengono create in Sophos Central in Global Settings > Access Control > API Credentials. Per un tenant, Sophos consiglia il ruolo Service Principal Firewall. Nel Partner Dashboard la funzione si trova in Global Settings > APIs & Integrations > API Credentials Management; qui sono disponibili altri ruoli e va scelto quello con i privilegi minimi che consenta di accedere al tenant di destinazione. Client Secret, JWT, Secure Storage Master Key e gli URL di download o upload generati successivamente non devono essere inseriti in ticket, chat o screenshot.
Gli esempi vengono eseguiti in Bash e presuppongono credenziali tenant. Con credenziali partner o enterprise è necessario prima individuare il tenant di destinazione e il relativo host API regionale. Sophos spiega questa differenza in How Our APIs Work.
Inserire Client ID e Client Secret senza scrivere il secret nella cronologia della shell:
read -r -p "Client ID: " CLIENT_ID
read -r -s -p "Client Secret: " CLIENT_SECRET
printf '\n'
Richiedere quindi un JWT con validità limitata:
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
I semplici esempi con curl passano il JWT di breve durata come argomento dell’header. Devono quindi essere eseguiti su una workstation amministrativa affidabile, sulla quale altri utenti non possano leggere gli argomenti dei processi locali.
Con credenziali tenant, whoami restituisce l’ID tenant e l’host API regionale:
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"
Se jq si interrompe in questo punto, le credenziali sono probabilmente associate a un partner o a un’organizzazione enterprise. Non continuare usando il relativo ID come X-Tenant-ID, ma individuare il tenant gestito e il suo apiHost.
Individuare l’ID del firewall
L’elenco dei firewall mostra nome, hostname, numero di serie, firmware e 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'
Usare l’UUID del firewall corretto e non basarsi soltanto su un nome visualizzato simile:
FIREWALL_ID="<firewall-uuid>"
Se il firewall non compare, verificare prima tenant, regione, connessione a Central e autorizzazione alla gestione. La registrazione è descritta in Connettere Sophos Firewall a Sophos Central.
Esportare la configurazione
Avviare un’esportazione completa
L’esportazione viene eseguita in modo asincrono. La prima chiamata restituisce quindi soltanto un ID transazione:
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"
Richiedere nuovamente lo stato dopo alcuni secondi:
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"
Ripetere la richiesta circa ogni dieci secondi finché status raggiunge lo stato finale finished. pending e started non sono ancora errori.
Solo con status: "finished" e result: "success", response.url contiene l’URL di download con validità limitata:
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
Il file TAR può contenere dati sensibili relativi a reti, utenti, VPN e policy. Conservarlo in modo protetto oppure eliminarlo dopo l’analisi. Per ottenere un report leggibile o un confronto prima/dopo, è possibile usare il file Entities.xml contenuto nel pacchetto in Sophos Firewall Config Studio.
Esportare soltanto configurazioni selezionate
Per un’esportazione selettiva, i nomi delle entità devono essere specificati esattamente e rispettando maiuscole e minuscole. Questo esempio esporta le regole firewall e NAT insieme agli oggetti dipendenti:
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"
I nomi validi delle entità sono elencati nell’attuale endpoint di esportazione della Sophos Firewall API. Per un’esportazione selettiva, il valore predefinito di includeDependency è false; impostare consapevolmente l’opzione e verificare comunque il pacchetto risultante.
Importare la configurazione
L’importazione prevede la richiesta di un URL di upload, il caricamento del file TAR, la conferma dei dati del file e la verifica della transazione. L’esempio usa un solo firewall di test e imposta deliberatamente performPartialImport su false. Il valore predefinito dell’API è true e consente un’importazione parziale per ogni firewall.
Verificare prima la compatibilità: il firewall di destinazione deve avere almeno la stessa versione del firmware e dei pattern. Sophos supporta le importazioni selettive tra modelli diversi soltanto da un modello inferiore a uno superiore; l’hardware di destinazione deve avere almeno lo stesso numero di porte Ethernet. Se i nomi delle porte sono diversi, Entities.xml deve essere adattato prima dell’upload.
Preparare il file di importazione e il checksum
Preparare il file di destinazione, il checksum e la dimensione del file:
FILE="sophos-firewall-config-2026-08-03.tar"
FILE_SIZE=$(wc -c <"$FILE" | tr -d ' ')
Su macOS:
CHECKSUM_MD5=$(md5 -q "$FILE")
Su Linux:
CHECKSUM_MD5=$(md5sum "$FILE" | awk '{print $1}')
Richiedere una sessione di upload e caricare il file
Richiedere una sessione di upload e visualizzare soltanto i campi non segreti:
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"
Prima della scadenza dell’URL prefirmato, caricare il file usando il metodo PUT restituito. Non inviare header JWT o tenant a questo URL:
curl --fail-with-body --silent --show-error \
--request PUT \
--upload-file "$FILE" \
"$UPLOAD_URL"
unset UPLOAD_URL
Completare l’importazione e verificarne lo stato
Se il pacchetto contiene informazioni sensibili e viene importato in un firewall diverso o reinstallato, è necessario il Secure Storage Master Key corrispondente. Senza questa chiave, SFOS non importa le informazioni sensibili e le configurazioni che ne dipendono. Il prompt seguente non mostra il secret; premendo Invio viene omesso:
read -r -s -p "Secure Storage Master Key, altrimenti Invio: " SSMK
printf '\n'
Completare l’upload e assegnare il pacchetto al firewall di destinazione:
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"
Una richiesta accetta da 1 a 25 ID firewall univoci. Per ulteriori firewall, il pacchetto deve essere caricato di nuovo; non riutilizzare lo stesso URL prefirmato o lo stesso ID transazione.
Verificare lo stato dell’importazione tramite lo stesso endpoint delle transazioni:
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"
Ripetere anche questa richiesta circa ogni dieci secondi finché non compare status: "finished". Solo allora valutare result e, in presenza di più destinazioni, ogni elemento in response.items.
success conferma l’elaborazione da parte dell’API, non l’effetto funzionale.
Collaudare localmente l’importazione
Dopo finished, verificare su ogni firewall di destinazione:
- Sono presenti esattamente le regole, gli oggetti e le impostazioni previsti?
- Mancano utenti, password, certificati o oggetti dipendenti a causa di un SSMK assente o errato?
- Interfacce, zone, gateway, firmware, versione dei pattern e modello hardware corrispondono al pacchetto?
- Routing, NAT, VPN, autenticazione e accesso amministrativo funzionano con casi di test definiti?
- Audit Trail e log di configurazione mostrano modifiche inattese?
- Una nuova esportazione o un confronto in Config Studio mostra soltanto le differenze pianificate?
L’importazione/esportazione aggiorna la configurazione esistente e non rimuove automaticamente tutto ciò che manca nel pacchetto. Il file TAR non rappresenta quindi uno stato desiderato completo e non sostituisce backup, rollback e test funzionali.
Risoluzione dei problemi
L’esportazione non restituisce un URL di download
L’URL compare soltanto dopo status: "finished" e result: "success". In caso di error o partialSuccess, verificare i campi in response e non continuare con un URL vuoto o scaduto.
HTTP 401 o 403
Con 401, in genere il JWT è scaduto o non valido. Ripetere l’autenticazione. Con 403, verificare il ruolo Central, il contesto tenant, X-Tenant-ID e l’host API regionale. L’autorizzazione dell’API XML locale in /webconsole/APIController non è responsabile di questa funzione; viene trattata separatamente in Proteggere l’accesso all’API XML di Sophos Firewall.
Upload-complete restituisce 400 o 409
Verificare ID transazione, scadenza dell’URL di upload, dimensione effettiva del file, checksum MD5 esadecimale e ID firewall univoci. Non modificare il file dopo l’upload. Per un nuovo tentativo, usare una nuova sessione di upload.
L’importazione termina con error o partialSuccess
Conservare response e, in presenza di più firewall di destinazione, response.items. Se una chiamata API restituisce una risposta di errore 4xx o 5xx separata, documentare inoltre error, message, code, correlationId e requestId. Verificare quindi localmente versione di destinazione, stato dei pattern, modello, porte, dipendenze e SSMK. Se la risposta di Central non è sufficiente, controllare fwcm-api-executor.log sul firewall come descritto in Servizi e file di log di Sophos Firewall.
L’endpoint delle transazioni è determinante per lo stato API; non presupporre che l’operazione compaia nella Task Queue di Central Firewall.
Un’importazione molto grande si interrompe
Sophos elenca il Known Issue NR-19066: un’importazione con un numero molto elevato di oggetti può superare il limite di elaborazione di due ore. Invece di ripetere senza modifiche l’importazione completa, creare pacchetti selettivi più piccoli, importarli singolarmente e collaudare ogni passaggio.
Al termine della sessione, eliminare le variabili sensibili:
unset JWT CLIENT_ID TENANT_ID API_HOST FIREWALL_ID TARGET_FIREWALL_ID
unset EXPORT_TX IMPORT_TX CHECKSUM_MD5 FILE_SIZE