Saltar para o conteudo
Avanet

Exportar e importar Sophos Firewall através da API do Central

Com SFOS 22.0 MR2 ou posterior, é possível exportar e importar configurações de firewall através da REST API do Sophos Central no Sophos Fusion (anteriormente Sophos Central). O processo inclui apenas alguns passos: autenticar o acesso à API, determinar o ID da firewall, iniciar a exportação ou o upload e verificar a transação devolvida até à conclusão.

Para acesso direto ao firewall, REST API local e chaves API no SFOS 23.0 descreve outro percurso. Estas chaves administrativas locais não substituem service principal cloud, token, tenant ou host API regional deste artigo.

Para uma única alteração manual diretamente no WebAdmin local, usar antes Exportar e importar seletivamente a configuração. O artigo também explica Entities.xml, SSMK, dependências dos objetos e o efeito de merge do import.

Uma importação altera a firewall de destino e não equivale ao restauro de um backup. Antes, deve ser criado um backup atual da firewall, o processo deve ser executado primeiro numa firewall de teste e o resultado deve ser validado localmente.

Preparar os requisitos e as variáveis da API

São necessários:

  • uma firewall com SFOS 22.0 MR2 ou posterior, ligada e gerida através do Sophos Fusion;
  • uma subscrição paga da firewall ativa para além da Base License ou um contrato de suporte ativo;
  • credenciais de API próprias com as permissões necessárias;
  • curl, jq e, para uma importação, md5 ou md5sum;
  • ID do tenant, host regional da API e ID da firewall;
  • uma janela de manutenção e um caminho de retorno testado para importações.

Criação de Credentials, funções, contratos Token e whoami, região, proteção de secrets, validação e diagnóstico comum estão centralizados em Gerir as credenciais da API Sophos Central em segurança. Concluir primeiro esse processo; este artigo reutiliza depois SOPHOS_ACCESS_TOKEN, SOPHOS_TENANT_ID e SOPHOS_API_HOST.

As credenciais da API são criadas no Sophos Fusion em Global Settings > Access Control > API Credentials. Para um tenant, a Sophos recomenda a função Service Principal Firewall. No Partner Dashboard, a função encontra-se em Global Settings > APIs & Integrations > API Credentials Management; estão disponíveis outras funções e deve ser usada a de menor privilégio com acesso ao tenant de destino. O Client Secret, o JWT, o Secure Storage Master Key e os URL de download ou upload emitidos posteriormente não devem ser incluídos em pedidos de suporte, chats ou capturas de ecrã.

Os exemplos são executados em Bash e pressupõem credenciais de um tenant. As credenciais de partner e enterprise têm primeiro de determinar o tenant de destino e o respetivo host regional da API. Para pedidos específicos do tenant, utilizar o host regional validado no procedimento de credenciais: obtido de whoami para credenciais de tenant, ou da entrada do tenant de destino na lista totalmente paginada para credenciais Partner ou Enterprise.

Associar os três valores validados pelo processo Owner às variáveis utilizadas aqui:

JWT="$SOPHOS_ACCESS_TOKEN"
TENANT_ID="$SOPHOS_TENANT_ID"
API_HOST="$SOPHOS_API_HOST"

Não pedir novamente o JWT: JWT é o Access Token temporário reutilizado acima.

Os exemplos simples de curl passam o JWT de curta duração como argumento do header. Por isso, devem ser executados numa estação de trabalho administrativa fidedigna, onde outros utilizadores não possam ler os argumentos dos processos locais.

O Tenant ID e o host regional também provêm do processo Owner:

TENANT_ID e API_HOST já estão validados. Para Credentials Partner ou Enterprise, devem vir da lista de tenants totalmente paginada do processo Owner.

Determinar o ID da firewall

A lista de firewalls mostra o nome, hostname, número de série, firmware e 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"

Usar o UUID da firewall correta e não selecionar apenas com base num nome de apresentação semelhante:

read -r -p 'UUID da firewall do inventário aprovado: ' 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

Se a firewall não aparecer, verificar primeiro o tenant, a região, a ligação ao Sophos Fusion e a autorização de gestão. O registo é explicado em Ligar o Sophos Firewall ao Sophos Fusion.

Exportar a configuração

Iniciar uma exportação completa

A exportação é executada de forma assíncrona. Por isso, o primeiro pedido devolve apenas um ID de transação:

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"

Voltar a obter o estado após alguns segundos:

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"

Repetir o pedido aproximadamente a cada dez segundos até status atingir o estado final finished. pending e started ainda não são erros.

Só quando status: "finished" e result: "success" é que response.url contém o URL de download de duração limitada:

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

O ficheiro TAR pode conter dados sensíveis de rede, utilizadores, VPN e políticas. Deve ser guardado de forma protegida ou eliminado depois da análise. Para obter um relatório legível ou uma comparação antes/depois, o ficheiro Entities.xml incluído pode ser utilizado no Sophos Firewall Config Studio.

Exportar apenas configurações selecionadas

Numa exportação seletiva, os nomes das entidades têm de ser indicados exatamente e com a utilização correta de maiúsculas e minúsculas. Este exemplo exporta regras de firewall e NAT com objetos dependentes:

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"

Os nomes das entidades são exatos e sensíveis a maiúsculas e minúsculas; o exemplo utiliza FirewallRule e NATRule. Numa exportação seletiva, includeDependency tem false como predefinição; definir esta opção conscientemente e verificar o pacote resultante mesmo assim.

Âmbito e limitações do pacote

Antes de uma importação através da API, também devem ser consideradas estas regras do SFOS aplicáveis ao ficheiro TAR:

  • A importação atualiza as definições existentes. Uma definição ausente do pacote permanece inalterada no destino; se existir nas duas configurações, prevalece o valor importado.
  • Com autenticação externa, a exportação contém apenas os utilizadores criados manualmente na firewall. OTPTokens inclui somente os tokens emitidos para esses utilizadores.
  • REDDevice não inclui automaticamente o servidor DHCP necessário, mesmo com includeDependency. Exportar também DHCPServer ou recriar o servidor DHCP após a importação.
  • Uma lista de URL importada pode conter, no máximo, 128 domínios.
  • Os modelos XGS 88w, 108w, 118w e 128w têm condições adicionais para configurações wireless, incluindo bandas de frequência, Security mode, Encryption, bridges e número de SSID exclusivos.

Uma listagem TAR sem erros prova apenas que o arquivo pode ser aberto. Não confirma que todos os objetos necessários estejam presentes nem que sejam aplicados no hardware de destino.

Importar a configuração

A importação consiste em solicitar um URL de upload, carregar o ficheiro TAR, confirmar os dados do ficheiro e verificar a transação. O exemplo utiliza apenas uma firewall de teste e define deliberadamente performPartialImport como false. O valor predefinido da API é true e permite uma importação parcial por firewall.

Verificar primeiro a compatibilidade: a firewall de destino necessita, no mínimo, da mesma versão de firmware e de patterns. A Sophos só suporta importações seletivas entre modelos diferentes de um modelo inferior para um superior. Este procedimento pressupõe hardware de destino com, no mínimo, o mesmo número de portas Ethernet; os nomes de portas diferentes são mapeados em Entities.xml antes do upload. A ajuda SFOS também descreve importações adaptadas quando existem menos portas; consulte Compatibilidade de importação/exportação. Isto não constitui uma autorização da API comprovada separadamente para todos esses mapeamentos: esclareça com a Sophos qualquer caso de destino diferente antes de executar a API.

Preparar o ficheiro de importação e o checksum

Preparar o ficheiro de destino, o checksum e o tamanho do ficheiro:

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

No macOS:

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

No Linux:

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

Solicitar uma sessão de upload e carregar o ficheiro

Solicitar uma sessão de upload e mostrar apenas os campos não secretos:

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"

Carregar o ficheiro antes da expiração do URL pre-signed com o método PUT devolvido. Não enviar headers JWT ou de tenant para este URL:

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

Concluir a importação e verificar o estado

Se o pacote contiver informações sensíveis e for importado para uma firewall diferente ou reinstalada, é necessário o Secure Storage Master Key correspondente. Sem esta chave, o SFOS não importa as informações sensíveis nem as configurações que delas dependem. O pedido seguinte não mostra o secret; ao premir Enter, este é omitido:

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

Concluir o upload e atribuir o pacote à firewall de destino:

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"

Um pedido aceita entre 1 e 25 IDs de firewall exclusivos. Para firewalls adicionais, o pacote tem de ser carregado novamente; não reutilizar o mesmo URL pre-signed ou ID de transação.

Verificar o estado da importação através do mesmo endpoint de transações:

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"

Repetir também este pedido aproximadamente a cada dez segundos até aparecer status: "finished". Só depois se deve avaliar result e, no caso de vários destinos, cada elemento em response.items.

success confirma o processamento pela API, não o efeito funcional.

Validar localmente a importação

Após finished, verificar em cada firewall de destino:

  1. Estão presentes exatamente as regras, os objetos e as definições esperados?
  2. Faltam utilizadores, palavras-passe, certificados ou objetos dependentes devido a um SSMK em falta ou incorreto?
  3. As interfaces, zonas, gateways, firmware, versão dos patterns e modelo de hardware correspondem ao pacote?
  4. O routing, NAT, VPN, autenticação e acesso de gestão funcionam com casos de teste definidos?
  5. O Audit Trail e os logs de configuração mostram alterações inesperadas?
  6. Uma nova exportação ou uma comparação no Config Studio mostra apenas as diferenças planeadas?

A importação/exportação atualiza a configuração existente e não remove automaticamente tudo o que está em falta no pacote. Por isso, o ficheiro TAR não representa um estado de destino completo nem substitui um backup, um rollback e um teste funcional.

Reverter uma importação incorreta

Se a validação local falhar, interromper a implementação, guardar a resposta da transação e não ocultar o resultado com novas importações. Para recuperar no WebAdmin local, aceder a Backup and firmware > Backup and restore. Em Restore configuration, usar Choose file para selecionar o backup criado anteriormente, introduzir a respetiva Encryption password e iniciar Upload and restore.

O restauro substitui a configuração atual, elimina o backup guardado na firewall e reinicia o dispositivo. Em seguida, fica ativo o endereço IP do WebAdmin existente na configuração restaurada. Esse endereço e a palavra-passe de encriptação devem estar disponíveis antes da importação. Após o reinício, repetir os mesmos testes funcionais e verificar com uma nova exportação; as alterações posteriores ao backup perdem-se durante o restauro.

Resolução de problemas

A exportação não apresenta um URL de download

O URL só aparece depois de status: "finished" e result: "success". Em caso de error ou partialSuccess, verificar os campos em response e não continuar com um URL vazio ou expirado.

HTTP 401 ou 403

Com 401, o JWT está geralmente expirado ou é inválido. Efetuar novamente a autenticação. Com 403, verificar a função do Sophos Fusion, o contexto do tenant, X-Tenant-ID e o host regional da API. A autorização da API XML local em /webconsole/APIController não é responsável por esta função; é abordada separadamente em Proteger o acesso à API XML do Sophos Firewall.

Upload-complete devolve 400 ou 409

Verificar o ID da transação, a data de expiração do URL de upload, o tamanho real do ficheiro, o checksum MD5 hexadecimal e os IDs de firewall exclusivos. Não alterar o ficheiro depois do upload. Para uma nova tentativa, utilizar uma nova sessão de upload.

A importação termina com error ou partialSuccess

Guardar response e, no caso de várias firewalls de destino, response.items. Se uma chamada à API devolver uma resposta de erro 4xx ou 5xx separada, documentar também error, message, code, correlationId e requestId. Em seguida, verificar localmente a versão de destino, o estado dos patterns, o modelo, as portas, as dependências e o SSMK. Se a resposta do Sophos Fusion não for suficiente, verificar fwcm-api-executor.log na firewall de acordo com Serviços e ficheiros de log do Sophos Firewall.

O endpoint de transações é determinante para o estado da API; não assumir que a tarefa aparece na Central Firewall Task Queue.

No fim da sessão, remover as variáveis sensíveis:

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