Rules Engine para Firewall
Consulte cada variável de critério, operador e comportamento que uma regra de firewall pode usar, e os campos de uma regra no Azion Console e na API.
Uma regra no Rules Engine para Firewall combina critérios, que decidem se uma requisição corresponde, com comportamentos, que agem sobre cada requisição que corresponde. Uma regra cujos critérios não correspondem não aplica nada. Para acompanhar uma requisição pelas regras de um firewall, consulte Como Firewall funciona.
Uma regra de firewall decide se uma requisição chega ou não à aplicação, porque o firewall recebe cada requisição antes da aplicação. Uma regra que escolhe como a aplicação serve uma requisição permitida, como o connector ou o cache setting dela, pertence ao Rules Engine para Applications.
Campos da regra
Cada firewall tem a sua própria lista de regras. Azion Console as mostra na aba Rules Engine do firewall, onde Rule abre o drawer Create Rule. A API as disponibiliza em /v4/workspace/firewalls/<firewall-id>/request_rules. Uma regra carrega dez campos: cinco que uma requisição define e cinco que a plataforma define e retorna.
| Campo | Tipo | Obrigatório | Padrão | Descrição |
|---|---|---|---|---|
id | integer | Somente leitura | — | O identificador que toda chamada posterior sobre a regra usa |
name | string, de 1 a 250 caracteres | Sim | — | O nome da regra. Azion Console o mostra como o campo Name e pede um nome único e descritivo |
description | string, até 1.000 caracteres | Não | "" | Um comentário sobre a regra, mostrado na coluna Description da lista de regras. Com mais de 1.000 caracteres, Azion Console mostra Description should not exceed 1000 characters |
active | boolean | Não | true | Se a regra está ativa. Azion Console o mostra como o switch Active na seção Status, e a lista de regras mostra Active ou Inactive |
criteria | array de 1 a 5 blocos, cada um sendo um array de 1 a 10 critérios | Sim | — | As condições que uma requisição precisa atender. Cada valor está listado em Critérios |
behaviors | array de objetos de comportamento, no mínimo 1 | Sim | — | O que a regra faz com uma requisição que corresponde. Cada valor está listado em Comportamentos |
order | integer | Somente leitura | Atribuído na criação | A posição da regra na lista de regras do firewall |
last_editor | string | Somente leitura | — | A conta que alterou a regra pela última vez, mostrada na coluna Last Editor |
last_modified | date-time | Somente leitura | — | Quando a regra foi alterada pela última vez, mostrado na coluna Last Modified |
created_at | date-time | Somente leitura | — | Quando a regra foi criada |
A plataforma atribui order na ordem de criação: a primeira regra de um firewall carrega 0, e a décima primeira carrega 10. A lista de regras do Azion Console permite reordenar as regras.
Critérios
Os critérios decidem sobre quais requisições uma regra age. Cada critério nomeia uma variável, um operador de comparação e, para a maioria dos operadores, um argumento com o qual a variável é comparada. O drawer Create Rule abre com um critério já definido como Request Uri e starts with, e ${request_uri} starts_with / corresponde a toda requisição que o workload recebe.
A tabela lista as variáveis na ordem do Azion Console. Nove delas exigem Web Application Firewall (WAF) habilitado no firewall, Network exige Network Shield e as outras cinco não exigem nenhum produto.
| Variável | Variável na API | Requer | O que contém | Exemplo |
|---|---|---|---|---|
| Header Accept | ${header_accept} | WAF | Os media types que o cliente aceita na resposta | application/json |
| Header Accept Encoding | ${header_accept_encoding} | WAF | As codificações de conteúdo, em geral algoritmos de compressão, que o cliente aceita na resposta | gzip |
| Header Accept Language | ${header_accept_language} | WAF | O idioma que o cliente espera | en-US |
| Header Cookie | ${header_cookie} | WAF | Os cookies que o cliente envia com a requisição | session_id=abc123 |
| Header Origin | ${header_origin} | WAF | A origem de uma requisição cross-site ou de uma requisição preflight: uma URI que nomeia o servidor, sem caminho | https://example.com |
| Header Referer | ${header_referer} | WAF | O endereço do documento, ou do elemento nele, de onde a URI da requisição foi obtida | https://example.com/landing-page |
| Header User Agent | ${header_user_agent} | WAF | A string que identifica a aplicação cliente, o sistema operacional, o fornecedor ou a versão | Mozilla/5.0 |
| Host | ${host} | Nenhum | Em ordem de precedência: o hostname na linha da requisição, o valor do header Host ou o nome do servidor que atende a requisição | api.example.com |
| Network | ${network} | Network Shield | O endereço IP do cliente, comparado com os endereços IP e intervalos CIDR, os ASNs ou os países de uma network list | 2 |
| Request Args | ${request_args} | WAF | Os argumentos na query string da requisição | page=1 |
| Request Method | ${request_method} | WAF | O método HTTP da requisição | POST |
| Request Uri | ${request_uri} | Nenhum | A URI da requisição | /api/v1/ |
| Scheme | ${scheme} | Nenhum | O esquema da requisição, HTTP ou HTTPS | https |
| Ssl Verification Status | ${ssl_verification_status} | Nenhum | O resultado da validação do certificado do cliente | CERTIFICATE_VERIFICATION_ERROR |
| Client Certificate Validation | ${client_certificate_validation} | Nenhum | O processo do servidor que autentica o certificado digital do cliente | true |
Quando o firewall não tem o produto que uma variável exige, Azion Console ainda lista a variável, mas não permite selecioná-la. O rótulo então carrega um sufixo, como Header Accept - required WAF ou Network - required Network Shield. A API recusa uma regra que usa ${network} em um firewall sem Network Shield, com 400 e o código 25047.
Network compara o endereço IP do cliente com uma network list. No Azion Console, o argumento passa a ser a lista Select a Network, que mostra todas as network lists da conta e termina com Create Network List. Na API, o argumento é o ID da lista, enviado como um inteiro JSON. Por exemplo, 2 é a lista de exit nodes do Tor que a Azion fornece, e qualquer regra pode referenciá-la. O mesmo ID enviado como string é recusado com 400 e o código 25042.
Depois que uma regra do firewall usa ${network}, Network Shield não pode ser desativado nesse firewall. A API responde 400 com o código 24005 e nomeia as regras que o mantêm.
Request Args não contém nada quando a requisição não tem query string, e uma variável vazia não corresponde. Por exemplo, uma regra com ${request_args} matches .* ignora todo POST que carrega o payload no corpo e nada na query string.
Ssl Verification Status recebe um de três valores, que Azion Console oferece na lista Select an SSL Status:
| Valor | Argumento na API | Significado |
|---|---|---|
| Success | SUCCESS | O certificado do cliente passou na validação |
| Certificate Verification Error | CERTIFICATE_VERIFICATION_ERROR | O certificado do cliente não era válido |
| Missing Client Certificate | MISSING_CLIENT_CERTIFICATE | A requisição não carregava certificado de cliente |
Operadores
Um critério compara a sua variável com o seu argumento por meio de um operador. Azion Console rotula cada operador em letras minúsculas, e a API envia o valor da segunda coluna como operator.
| Operador | Valor na API | O critério corresponde quando | Argumento |
|---|---|---|---|
| is equal | is_equal | O valor é igual ao argumento, comparado caractere por caractere | String |
| is not equal | is_not_equal | O valor não é exatamente o argumento | String |
| starts with | starts_with | O valor começa com o argumento | String |
| does not start with | does_not_start_with | O valor não começa com o argumento | String |
| matches | matches | O valor corresponde à expressão regular do argumento | Expressão regular |
| does not match | does_not_match | O valor não corresponde à expressão regular do argumento | Expressão regular |
| exists | exists | A variável tem um valor. Request Args existe quando a query string carrega um argumento | Nenhum |
| does not exist | does_not_exist | A variável não tem valor. Request Args não existe quando a query string não carrega nenhum argumento | Nenhum |
Azion Console oculta o campo de argumento para exists e does not exist, e o substitui por uma lista para Network e Ssl Verification Status.
Network é a exceção à tabela. Os seus matches e does not match carregam os valores de API is_in_list e is_not_in_list, e os dois comparam o endereço IP do cliente com a network list que o argumento nomeia. A API recusa matches em ${network} com 400 e o código 25039.
Cada variável oferece apenas alguns dos operadores:
| Variável | Operadores |
|---|---|
| Header Accept, Header Accept Encoding, Header Accept Language, Header Cookie, Header Origin, Header Referer, Header User Agent | matches, does not match |
| Host | is equal, is not equal, matches, does not match |
| Network | matches (is_in_list), does not match (is_not_in_list) |
| Request Args | is equal, is not equal, matches, does not match, exists, does not exist |
| Request Method | is equal, is not equal |
| Request Uri | is equal, is not equal, starts with, does not start with, matches, does not match |
| Scheme, Ssl Verification Status, Client Certificate Validation | is equal, is not equal |
Condicionais
Os critérios se combinam dentro de blocos, e uma regra tem de 1 a 5 blocos de 1 a 10 critérios cada. Dentro de um bloco, o primeiro critério carrega o condicional if, e cada critério seguinte carrega and ou or. Os blocos são unidos por And, que Azion Console exibe entre eles, então uma requisição corresponde à regra somente quando corresponde a todos os blocos.
No Azion Console, And e Or adicionam um critério a um bloco, e Add Criteria adiciona um bloco. Azion Console desabilita And e Or quando um bloco chega a 10 critérios, e Add Criteria quando a regra chega a 5 blocos. Os divisores entre critérios mostram o condicional como If, And ou Or.
Na API, criteria é uma lista de blocos, e cada bloco é uma lista de objetos de critério. A regra deste exemplo tem um bloco de dois critérios. Ela nega uma requisição somente quando o endereço IP do cliente está na network list e a URI começa com /ip-deny:
O placeholder <network-list-id> representa um inteiro, sem aspas ao redor.
Comportamentos
Os comportamentos são o que uma regra faz com uma requisição que corresponde aos seus critérios. Azion Console rotula a primeira linha de comportamento como Then e cada linha seguinte como And, e Add Behavior adiciona uma linha. Na API, cada comportamento é um objeto com um type, e os comportamentos que recebem configurações as carregam em attributes.
A coluna Requer nomeia o produto que o firewall precisa ter habilitado para que Azion Console ofereça o comportamento. Quando ele está desativado, Azion Console mostra Set WAF - required WAF ou Run Function - required Functions e não permite selecioná-lo. Nenhum dos seis comportamentos exige Network Shield.
| Comportamento | type na API | Requer | Atributos | O que o cliente recebe |
|---|---|---|---|---|
| Deny (403 Forbidden) | deny | Nenhum | Nenhum | 403, com a página de erro padrão da Azion intitulada Forbidden |
| Drop (Close Without Response) | drop | Nenhum | Nenhum | Nenhuma resposta: nem linha de status nem corpo |
| Set Rate Limit | set_rate_limit | Nenhum | type, limit_by, average_rate_limit, maximum_burst_size | 429 para uma requisição que o limite não admite, com a página de erro padrão intitulada Too Many Requests |
| Set WAF | set_waf | WAF | waf_id, mode | 400 para uma requisição que o rule set bloqueia no modo blocking, com a página de erro padrão intitulada Bad Request |
| Run Function | run_function | Functions | value | O que o código da instância de função fizer com a requisição |
| Set Custom Response | set_custom_response | Nenhum | status_code, content_type, content_body | O status code, o Content-Type e o corpo que os atributos definem |
Azion Console também limita como os comportamentos se combinam. Somente Run Function e Set WAF podem ser seguidos por outro comportamento, e cada um aparece no máximo uma vez em uma regra. Escolher Deny (403 Forbidden), Drop (Close Without Response), Set Rate Limit ou Set Custom Response remove todas as linhas de comportamento depois dele.
Deny (403 Forbidden)
Deny (403 Forbidden) recusa a requisição com 403 e não recebe atributos. O corpo é a página de erro padrão da Azion intitulada Forbidden, com cerca de 10,6 KB de HTML, que mostra o endereço IP do cliente e o ID da requisição. Nenhum header de resposta nomeia o firewall ou a regra. Na API, o comportamento é { "type": "deny" }.
Drop (Close Without Response)
Drop (Close Without Response) encerra a requisição sem respondê-la e não recebe atributos. O cliente não recebe linha de status nem corpo, de imediato. Um script que lê o status code vê 000, e um navegador mostra um erro de conexão. Na API, o comportamento é { "type": "drop" }.
Em HTTP/2, o curl informa o reset do stream e sai com o código 92:
Em HTTP/1.1 e em HTTP simples, o curl sai com o código 52:
Set Rate Limit
Set Rate Limit limita a taxa das requisições a que a regra corresponde. Uma requisição que a taxa e o burst não admitem recebe 429, com a página de erro padrão intitulada Too Many Requests. Nenhuma resposta carrega um header de rate limit, como retry-after ou um header x-ratelimit-.
| Atributo | Campo no Console | Valores | Descrição |
|---|---|---|---|
type | Rate Limit Type | second (Req/s) ou minute (Req/min) | O período em que a taxa é contada. O padrão é second |
limit_by | Limit By | client_ip (Client IP address) ou global (Global) | Se a taxa é contada por endereço IP do cliente ou sobre todas as requisições. Obrigatório. Azion Console pré-seleciona Client IP address |
average_rate_limit | Average Rate Limit | Inteiro, no mínimo 1 | As requisições permitidas por segundo ou por minuto, conforme type define. Obrigatório |
maximum_burst_size | Maximum Burst Size | Inteiro, no mínimo 1 | As requisições extras toleradas em um pico curto. Vale apenas para second: Azion Console oculta o campo para Req/min e não o envia |
Um rate limit de 10 requisições por segundo por endereço IP do cliente, com burst de 10:
Para saber como a taxa e o burst admitem requisições, consulte Como Firewall funciona.
Set WAF
Set WAF aplica um rule set de WAF às requisições a que a regra corresponde, e exige WAF habilitado no firewall. Um rule set só é executado quando uma regra carrega esse comportamento, e uma regra carrega no máximo um. Os rule sets ficam no Azion Console em Edge Libraries > WAF Rules.
| Atributo | Controle no Console | Valores | Descrição |
|---|---|---|---|
waf_id | Select a WAF | Inteiro | O ID do rule set a aplicar. Obrigatório |
mode | Select a WAF mode | logging (Logging) ou blocking (Blocking) | Se WAF recusa as requisições que o rule set sinaliza. Obrigatório |
No modo blocking, uma requisição que o rule set bloqueia recebe 400 com a página de erro padrão intitulada Bad Request, e nenhum header de resposta nomeia WAF. No modo logging, WAF não recusa a requisição. A API recusa um comportamento set_waf sem mode e qualquer mode diferente de logging ou blocking, inclusive learning.
Um comportamento que aplica um rule set no modo blocking:
Run Function
Run Function executa uma instância de função do firewall nas requisições a que a regra corresponde, e exige Functions habilitado no firewall. Um firewall criado pela API, pela CLI ou pela página de criação do Azion Console tem Functions ativado, e o drawer de criação do Azion Console começa com ele desativado.
O atributo value contém o ID da instância de função, não o da função. As instâncias ficam na aba Functions Instances do firewall. No Azion Console, Select a Function lista as instâncias ativas deste firewall, e Create Function Instance cria uma a partir dessa lista. Uma regra carrega no máximo um comportamento Run Function. Para criar uma instância, consulte Instancie uma função em um firewall.
Um comportamento que executa uma instância de função:
Para o código que uma função de firewall executa, consulte Functions no Firewall.
Set Custom Response
Set Custom Response responde à requisição com o status code, o content type e o corpo que define, e não exige nenhum produto. As três configurações vão em attributes, como em todo comportamento que recebe configurações.
| Atributo | Campo no Console | Valores | Descrição |
|---|---|---|---|
status_code | Status code | Inteiro, de 200 a 499 | O status code da resposta. Obrigatório |
content_type | Content Type | String, até 255 caracteres | O valor do header Content-Type. O padrão é uma string vazia |
content_body | Content Body | String, até 500 caracteres | O corpo da resposta. O padrão é uma string vazia |
API
Toda operação de regra é autenticada e fica em https://api.azion.com/v4/workspace/firewalls/<firewall-id>/request_rules. Uma requisição carrega um personal token no header Authorization, com o esquema Token, e uma requisição com corpo também carrega Content-Type: application/json.
| Operação | Método e caminho |
|---|---|
| Criar uma regra | POST /request_rules |
| Listar as regras de um firewall | GET /request_rules |
| Consultar uma regra | GET /request_rules/{request_rule_id} |
| Atualizar parte de uma regra | PATCH /request_rules/{request_rule_id} |
| Excluir uma regra | DELETE /request_rules/{request_rule_id} |
Uma criação e uma exclusão respondem 202, e uma leitura responde 200.
Esta chamada cria uma regra que nega toda requisição cuja URI começa com /deny-test:
A resposta carrega 202 e um state igual a pending. Este trecho da resposta mantém os campos que a plataforma adicionou:
A plataforma adiciona description, uma string vazia quando a criação não envia nenhuma, e order, a posição da regra no firewall. O id em data é o identificador que toda chamada posterior sobre a regra usa.
CLI
Azion CLI gerencia regras com o substantivo firewall-rule. azion create firewall-rule recebe apenas --firewall-id e --file, então os critérios e os comportamentos de uma regra ficam no mesmo corpo JSON que a API recebe.
| Comando | O que faz |
|---|---|
azion create firewall-rule | Cria uma regra a partir de um arquivo JSON, com --firewall-id e --file |
azion list firewall-rule | Lista as regras de um firewall, com --firewall-id. --details adiciona as colunas LAST EDITOR e LAST MODIFIED |
azion describe firewall-rule | Retorna uma regra, com --firewall-id e --rule-id. --format json imprime o registro completo |
Este arquivo descreve uma regra que nega, em /cli-rule, as requisições dos países de uma network list:
Salve-o como rule.json, substitua <network-list-id> pelo ID da lista como inteiro e crie a regra:
Erros
Uma regra rejeitada retorna um array errors. Cada entrada carrega um code, um title, um detail, o status e um ponteiro source que nomeia o campo, e algumas entradas adicionam um objeto meta:
| Código | Título | Status | O que causa | O que fazer |
|---|---|---|---|---|
10039 | Invalid Choice | 400 | Um valor fora de um enum: uma variable como $(network), uma grafia que a especificação da API v4 lista, um conditional diferente de if, and ou or, ou um mode como learning. O detail diz "<value>" is not a valid choice. | Envie um valor listado. O ponteiro source nomeia o campo, como /data/criteria/0/0/conditional |
10059 | Required Field | 400 | Um campo obrigatório ausente, como um comportamento set_waf sem mode, em /data/behaviors/0/attributes/mode | Adicione o campo que o ponteiro source nomeia |
24005 | Cannot Disable Firewall Network Protection Module | 400 | Desativar Network Shield em um firewall cujas regras usam ${network} | Altere ou exclua as regras que o detail lista e, depois, desative Network Shield |
25030 | Entity Not Found | 400 | Um argumento de ${network} que nomeia uma network list inexistente. O detail diz Network List '<network-list-id>' not found. | Envie o ID de uma lista existente |
25031 | Entity Not Active | 400 | Um argumento de ${network} que nomeia uma network list inativa. O detail diz Network List '<network-list-id>' is not active. | Ative a lista e, depois, crie a regra |
25036 | Invalid Informed WAF | 400 | Um waf_id que não nomeia nenhum rule set. O detail diz The informed WAF (<waf-id>) is not valid., e meta.waf_id repete o valor | Envie o ID de um rule set existente |
25039 | Invalid Operator | 400 | ${network} com o operador matches. O detail diz The operator 'matches' is not valid for the '${network}' variable. | Envie is_in_list ou is_not_in_list |
25042 | Invalid Operator Argument Type | 400 | Um argumento de ${network} enviado como string, como "57102", o tipo que a especificação da API v4 dá a ele. O detail diz The argument type '<network-list-id>' is not valid for the operator 'is_in_list'. | Envie o ID da network list como inteiro JSON |
25047 | Missing Required Modules | 400 | Uma regra que usa ${network} em um firewall sem Network Shield | Habilite Network Shield no firewall, com modules.network_protection.enabled definido como true, e depois crie a regra |
Duas recusas da CLI não carregam código. Uma regra cujo comportamento run_function nomeia uma instância de função inexistente falha com Error: failed to create the Firewall Rule: ["Function Instance '99999999' not found."], com o ID que o arquivo enviou. Um comportamento escrito com name em vez de type falha com Error: Failed to decode the given 'json' file. Verify if the file format is JSON or fix its content according to the JSON format specification at https://www.json.org/json-en.html, embora o arquivo seja um JSON válido: a chave que a plataforma lê é type.