Proteja um Endpoint Web com AWS WAF

AWSBeginner
Pratique Agora

Introdução

Uma aplicação web deve bloquear um caminho interno de exportação, mantendo a saúde disponível. Você anexará uma regra de caminho, testará se as solicitações chegam ao backend e atualizará a regra antes da limpeza.

Conclua primeiro Get Started with AWS on LabEx e Conceda Privilégios Mínimos a um Leitor de Relatórios. Esta VM nova fornece uma aplicação e um estágio REST API independente; recursos anteriores de API ou rede não são necessários.

Relação com as certificações

Este laboratório oferece prática nos seguintes tópicos de exame.

Crie uma Web ACL Regional

Nesta etapa, você definirá uma regra de solicitação do AWS WAF dentro de uma lista de controle de acesso web (Web ACL). O WAF inspeciona solicitações antes que cheguem à aplicação. A REST API fornecida tem um estágio nomeado que pode ser associado a uma Web ACL Regional; esta entrada difere da HTTP API usada no curso de API/Cognito.

Abra AWS View ao lado do Terminal para comparar regras, a associação de estágio e se cada solicitação chega ao backend. Preserve a Web ACL e o estágio de referência não relacionados.

Uma regra combina uma condição de correspondência com uma ação. Uma ação padrão se aplica quando nenhuma regra corresponde. Bloquearemos /internal/ e permitiremos outros caminhos.

Entre no diretório do projeto e confirme a identidade do operador preparado. O stage-arn.txt fornecido contém o ARN do estágio da aplicação, não uma credencial. A substituição de comando armazena esse valor para a associação posterior.

cd /home/labex/project
aws sts get-caller-identity --query Arn --output text
STAGE_ARN=$(cat stage-arn.txt)

Espere labex-sec05-operator. Antes de qualquer Web ACL ser associada, a exportação interna sintética chega ao backend. curl faz uma solicitação HTTP real; -sS remove a saída de progresso, mantendo erros de conexão, e -w imprime o status da resposta.

curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export

Espere HTTP 200 e uma resposta sintética do backend. Grave um arquivo de regra com um heredoc entre aspas: as linhas entre <<'EOF' e EOF tornam-se o arquivo JSON exatamente como escritas. UriPath seleciona o caminho, STARTS_WITH corresponde ao prefixo e NONE evita transformá-lo. Prioridades numéricas menores são executadas primeiro; esta ACL tem uma regra na prioridade zero. As configurações de visibilidade desabilitam amostras e métricas opcionais para este exercício focado. Salve as mesmas configurações em visibility.json para a própria ACL e sua atualização posterior.

cat > rules-internal.json <<'EOF'
[{
  "Name": "block-private-export",
  "Priority": 0,
  "Action": {"Block": {}},
  "Statement": {"ByteMatchStatement": {
    "SearchString": "/internal/",
    "FieldToMatch": {"UriPath": {}},
    "PositionalConstraint": "STARTS_WITH",
    "TextTransformations": [{"Priority": 0, "Type": "NONE"}]
  }},
  "VisibilityConfig": {"SampledRequestsEnabled": false, "CloudWatchMetricsEnabled": false, "MetricName": "labex-sec05-owned-export"}
}]
EOF

Crie a ACL Regional com Allow padrão. --cli-binary-format raw-in-base64-out instrui a AWS CLI v2 a interpretar SearchString como bytes literais de entrada, em vez de esperar uma string base64. file:// carrega o documento de regra; --query seleciona apenas o ID resultante da ACL.

cat > visibility.json <<'EOF'
{
  "SampledRequestsEnabled": false,
  "CloudWatchMetricsEnabled": false,
  "MetricName": "labex-sec05-owned-export"
}
EOF

ACL_ID=$(aws wafv2 create-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --default-action Allow={} \
  --visibility-config file://visibility.json \
  --rules file://rules-internal.json \
  --cli-binary-format raw-in-base64-out \
  --query Summary.Id \
  --output text)
ACL_ARN=$(aws wafv2 get-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --query WebACL.ARN \
  --output text)
aws wafv2 get-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --query 'WebACL.{Name:Name,Default:DefaultAction,Rules:Rules[].Name}'

Espere a ACL do laboratório, Allow padrão e block-private-export. Criar uma política não a anexa a um endpoint. O AWS View ainda deve mostrar nenhuma associação de destino.

Associe a ACL e Teste Solicitações Reais

Nesta etapa, você conectará sua política ao estágio REST API fornecido e comparará uma solicitação pública com uma solicitação de exportação correspondente. Um estágio identifica um ambiente de API implantado; a associação aplica a ACL às solicitações desse estágio.

WAF antes do backend

A Web ACL associada rejeita o caminho interno antes que ele chegue ao backend.

Associe apenas sua ACL ao ARN de destino fornecido. O estágio de referência não relacionado já tem sua própria ACL de referência; não a substitua.

aws wafv2 associate-web-acl --web-acl-arn "$ACL_ARN" --resource-arn "$STAGE_ARN"
aws wafv2 get-web-acl-for-resource \
  --resource-arn "$STAGE_ARN" \
  --query WebACL.Name \
  --output text

Espere labex-sec05-owned-export. Teste o caminho público de saúde, que não corresponde a /internal/, e depois o caminho interno de exportação.

curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/health
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export

Espere HTTP 200 para saúde e HTTP 403 com block-private-export para a exportação. Uma decisão Block retorna antes de o backend executar. O AWS View deve mostrar Executed para a solicitação de saúde e Not reached para a solicitação bloqueada. Uma associação nativa sozinha é insuficiente; esses resultados HTTP reais comprovam a aplicação da regra.

Exemplo do AWS View: a saúde chega ao backend, enquanto a exportação interna é bloqueada antes da execução.

Atualize a Regra e Observe o Comportamento em Execução

Nesta etapa, você moverá a proteção para o prefixo admin e mostrará o comportamento alterado sem reiniciar a aplicação. Uma atualização de Web ACL substitui a lista de regras. Seu token de bloqueio (lock token) protege contra sobrescrever uma alteração simultânea; obtenha-o da configuração nativa atual logo antes de atualizar e mantenha-o em uma variável.

Crie o novo documento de regra substituindo o prefixo URI no arquivo anterior. sed transforma o texto, e > grava o novo arquivo, preservando o documento original de regra.

sed 's|/internal/|/admin/|' rules-internal.json > rules-admin.json
LOCK_TOKEN=$(aws wafv2 get-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --query LockToken \
  --output text)
aws wafv2 update-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --lock-token "$LOCK_TOKEN" \
  --default-action Allow={} \
  --visibility-config file://visibility.json \
  --rules file://rules-admin.json \
  --cli-binary-format raw-in-base64-out \
  --query NextLockToken \
  --output text

O token de bloqueio retornado identifica a nova revisão da ACL; ele não é uma credencial de autenticação. Agora o antigo prefixo interno deve passar pela ação Allow padrão, enquanto a exportação admin deve ser bloqueada.

curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/internal/export
curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/admin/export

Espere HTTP 200 seguido de HTTP 403. O AWS View deve mostrar o novo prefixo /admin/, a solicitação interna bloqueada anterior e o par atual de solicitação interna permitida/admin bloqueada. As solicitações usam a regra nativa atual; reiniciar a VM ou a aplicação é desnecessário. Tipos de política não suportados negam acesso por padrão neste ambiente focado, portanto use apenas a declaração ensinada aqui.

Exemplo do AWS View após a atualização do prefixo em execução: a exportação interna é permitida e a exportação admin é bloqueada.

Desassocie e Exclua Apenas a ACL do Laboratório

Nesta etapa, você removerá sua política e confirmará que o roteamento comum da aplicação retorna. Conclua primeiro as verificações funcionais anteriores. A desassociação remove a aplicação da regra deste estágio; excluir a ACL depois remove o recurso de política do laboratório.

Desassocie sua Web ACL do estágio de destino e inspecione a associação com uma consulta nativa bem-sucedida. Espere uma associação vazia, em vez de tratar um erro de autenticação como evidência de exclusão.

aws wafv2 disassociate-web-acl --resource-arn "$STAGE_ARN"
aws wafv2 get-web-acl-for-resource --resource-arn "$STAGE_ARN" --query WebACL

A exportação admin anteriormente bloqueada agora deve chegar novamente ao backend fornecido.

curl -sS -w '\nHTTP %{http_code}\n' http://127.0.0.1:8090/admin/export

Espere HTTP 200. Obtenha um token de bloqueio atual, exclua apenas a ACL do laboratório e liste com sucesso as ACLs restantes. O nome do laboratório deve estar ausente, e labex-sec05-reference deve permanecer.

LOCK_TOKEN=$(aws wafv2 get-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --query LockToken \
  --output text)
aws wafv2 delete-web-acl \
  --name labex-sec05-owned-export \
  --scope REGIONAL \
  --id "$ACL_ID" \
  --lock-token "$LOCK_TOKEN"
aws wafv2 list-web-acls --scope REGIONAL --query 'WebACLs[].Name'

Mantenha ambos os estágios de API fornecidos e a ACL de referência intactos. Remova os documentos locais de regra e visibilidade e execute a verificação desta etapa antes de remover o profile temporário da CLI.

rm -f rules-internal.json rules-admin.json visibility.json
rm -f /home/labex/.aws/credentials /home/labex/.aws/config
unset STAGE_ARN ACL_ID ACL_ARN LOCK_TOKEN

Resumo

Você criou uma Web ACL Regional, a associou a um estágio REST API e testou o comportamento real de permitir/bloquear HTTP. Uma solicitação correspondente parou antes do backend, enquanto solicitações de saúde continuaram. Atualizar o prefixo URI alterou o roteamento em execução; a desassociação restaurou o endpoint. Você excluiu apenas a ACL do laboratório e preservou os estágios fornecidos e a política de referência.