Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Application Gateway permite-lhe reescrever conteúdos selecionados em pedidos e respostas. Com esta funcionalidade, pode traduzir URLs, parâmetros de string de consulta e modificar cabeçalhos de pedidos e respostas. Também pode adicionar condições para garantir que o URL ou os cabeçalhos especificados só sejam reescritos quando certas condições forem cumpridas. Estas condições baseiam-se nas informações do pedido e da resposta.
Os recursos de cabeçalho HTTP e reconfiguração de URL só estão disponíveis para o Application Gateway v2 SKU.
Cabeçalhos de solicitação e resposta
O Application Gateway permite adicionar, remover ou atualizar cabeçalhos de solicitação e resposta HTTP enquanto os pacotes de solicitação e resposta se movem entre os pools de cliente e back-end. Os cabeçalhos HTTP permitem que um cliente e servidor passem informação extra com um pedido ou resposta. Ao reescrever estes cabeçalhos, pode realizar tarefas importantes, incluindo:
- Adicionar campos de cabeçalho relacionados com segurança como HSTS e X-XSS-Protection
- Remoção de campos de cabeçalho de resposta que possam revelar informações sensíveis
- Remoção de informação de porta dos cabeçalhos X-Forwarded-For
Pode reescrever todos os cabeçalhos em requisições e respostas, exceto os Connection e Upgrade cabeçalhos. Você também pode usar o gateway de aplicativo para criar cabeçalhos personalizados e adicioná-los às solicitações e respostas que estão sendo roteadas por meio dele. Para aprender a reescrever cabeçalhos de pedidos e respostas com o Application Gateway usando o portal Azure, veja aqui.
Caminho da URL e cadeia de caracteres de consulta
Com o recurso de regravação de URL no Application Gateway, você pode:
Reescreva o nome do host, o caminho e a cadeia de consulta da URL do pedido
Escolha reescrever a URL de todas as solicitações em um ouvinte ou somente as solicitações que correspondem a uma ou mais das condições definidas. Essas condições são baseadas nas propriedades da solicitação (cabeçalho da solicitação e variáveis de servidor).
Escolha rotear a solicitação (selecione o pool de back-end) com base na URL original ou na URL reescrita
Para aprender a reescrever URL com o Application Gateway usando o portal Azure, veja aqui.
Compreender as regras de reescrita no Application Gateway
Um conjunto de reescrita é uma coleção de uma regra de roteamento, condição e ação.
Associação de regras de roteamento de pedidos: A configuração de reescrita associa-se a um listener de origem através da sua regra de roteamento. Quando se usa uma regra de encaminhamento do tipo Basic, a configuração de reescrita associa-se ao seu listener e funciona como uma reescrita global. Quando usas uma regra de roteamento baseada em caminhos, defines a configuração de reescrita de acordo com o mapa de caminho da URL. Neste último caso, aplica-se apenas a uma área de caminho específica de um sítio. Pode aplicar um conjunto de regravação a várias regras de roteamento, mas uma regra de roteamento só pode ter uma regra de regravação associada.
Condição de Reescrita: Esta configuração é opcional. Com base nas condições que definir, o Application Gateway avalia o conteúdo dos pedidos e respostas HTTP(S). A subsequente "ação de reescrita" ocorre se o pedido ou resposta HTTP(S) corresponder a esta condição. Se você associar mais de uma condição a uma ação, a ação ocorrerá somente quando todas as condições forem atendidas. Ou seja, é uma operação lógica de AND. Você pode usar condições de regravação para avaliar o conteúdo de solicitações e respostas HTTP(S). Essa configuração opcional permite que você execute uma regravação somente quando uma ou mais condições forem atendidas. O gateway de aplicativo usa esses tipos de variáveis para avaliar o conteúdo de solicitações e respostas:
Você pode escolher os seguintes tipos para procurar uma condição:
Uma condição permite-lhe avaliar se existe um cabeçalho ou variável especificado, ao corresponder os respetivos valores através de texto ou um padrão Regex. Para configurações avançadas de reescrita, você também pode capturar o valor da variável de cabeçalho ou servidor para uso posterior em Ação de regravação. Saiba mais sobre padrões e captura.
Ação de Reescrita: O conjunto de ações de reescrita permite-lhe reescrever cabeçalhos (pedido ou resposta) ou os componentes de URL.
Uma ação pode ter os seguintes tipos de valor ou suas combinações:
- Texto.
- Valor do cabeçalho do pedido - Para usar o valor do cabeçalho de um pedido capturado, especifique a sintaxe como
{http_req_headerName}. - Valor do cabeçalho de resposta - Para usar o valor de um cabeçalho de resposta capturado da condição anterior, especifique a sintaxe como
{http_resp_headerName}. O bloco Ação de reescrita também suporta o campo "Header Value Matcher" para o cabeçalho Set-Cookie. Este campo opcional permite-lhe comparar e capturar o valor de um cabeçalho específico quando existem múltiplos cabeçalhos de Set-Cookie com o mesmo nome. Para manipular o valor capturado desse cookie específico, você pode usar{capt_header_value_matcher}o . Saiba mais sobre captura em Definição de Ações. - Variável de servidor - Para usar uma variável de servidor, especifique a sintaxe como
{var_serverVariable}. Lista de variáveis de servidor suportadas.
Nota
O uso do campo Header Value Matcher {capt_header_value_matcher} não é atualmente suportado através do portal. Por isso, precisa de usar um método não-portal para quaisquer operações PUT se usar este campo.
Quando usa uma ação para reescrever uma URL, são suportadas as seguintes operações:
- Caminho URL: O novo valor a definir como caminho.
- Cadeia de Caracteres de Consulta de URL: O novo valor para o qual a cadeia de caracteres de consulta deve ser reescrita.
- Reavaliar mapa de caminho: especifique se o mapa de caminho de URL deve ser reavaliado após a regravação. Se não selecionares esta opção, o caminho da URL original é usado para coincidir com o padrão de caminho no mapa de caminho de URL. Se definires esta opção como verdadeira, o mapa do caminho URL é reavaliado para verificar a correspondência com o caminho reescrito. Habilitar essa opção ajuda a rotear a solicitação para um pool de back-end diferente após a regravação.
Correspondência e captura de padrões
O Application Gateway suporta correspondência e captura de padrões sob Condição e Ação. Em Ação, suporta correspondência de padrões e captura apenas para um cabeçalho específico.
Correspondência de padrões
O Application Gateway usa expressões regulares para correspondência de padrões. Use expressões compatíveis com Regular Expression 2 (RE2) ao escrever a sua sintaxe de correspondência de padrões.
Você pode usar a correspondência de padrões em Condição e Ação.
- Condição: Use esta definição para corresponder aos valores de um Cabeçalho ou Variável do Servidor. Para corresponder a um padrão nos "Condições", use a propriedade "padrão".
-
Ação: A correspondência de padrões em Action Set está disponível apenas para o cabeçalho
Set-Cookiede resposta. Para corresponder a um padrão deSet-Cookieem uma ação, utilize a propriedadeHeaderValueMatcher. Se capturado, o seu valor pode ser usado como{capt_header_value_matcher}. Como pode haver múltiplosSet-Cookiecabeçalhos, a correspondência de padrões aqui permite-lhe procurar um cookie específico. Por exemplo, para uma certa versão do user-agent, deves reescrever oset-cookiecabeçalho de resposta paracookie2commax-age=3600(uma hora). Neste caso, pode utilizar- Condição - Tipo: Cabeçalho da solicitação, Nome do cabeçalho: user-agent, Padrão a corresponder: *2.0
- Ação - Tipo de reescrita: Cabeçalho de resposta, Tipo de ação: Set, Nome do cabeçalho: Set-Cookie, Matcher de Valor do Cabeçalho:
cookie2=(.*), Valor do cabeçalho:cookie2={capt_header_value_matcher_1};Max-Age=3600
Nota
Se estiver a executar um Firewall de Aplicações Web Gateway (WAF) com Core Rule Set 3.1 ou anterior, pode ter problemas ao usar Expressões Regulares Compatíveis com Perl (PCRE) ao fazer asserções lookahead e lookbehind (negativas ou positivas).
Sintaxe para captura
Podes usar padrões para capturar uma substring para uso posterior. Coloque parênteses em torno de um subpadrão na definição de regex. O primeiro par de parênteses armazena sua substring em 1, o segundo par em 2 e assim por diante. Podes usar quantos parênteses quiseres. O Perl define mais variáveis numeradas para representar estas cadeias capturadas. Pode encontrar alguns exemplos nesta orientação de programação Perl.
- (\d)(\d) # Corresponder dois dígitos, capturando-os nos grupos 1 e 2
- (\d+) # Corresponder um ou mais dígitos, capturando-os todos no grupo 1
- (\d)+ # Corresponder um dígito uma ou mais vezes, capturando o último no grupo 1
Uma vez capturados, você pode usá-los no valor do Conjunto de Ações usando o seguinte formato:
- Para uma captura de cabeçalho de solicitação, você deve usar {http_req_headerName_groupNumber}. Por exemplo, {http_req_User-Agent_1} ou {http_req_User-Agent_2}
- Para uma captura de cabeçalho de resposta, você deve usar {http_resp_headerName_groupNumber}. Por exemplo, {http_resp_Location_1} ou {http_resp_Location_2}. Enquanto para um cabeçalho de resposta Set-Cookie capturado através da propriedade "HeaderValueMatcher", você deve usar {capt_header_value_matcher_groupNumber}. Por exemplo, {capt_header_value_matcher_1} ou {capt_header_value_matcher_2}.
- Para uma variável de servidor, você deve usar {var_serverVariableName_groupNumber}. Por exemplo, {var_uri_path_1} ou {var_uri_path_2}
Nota
- O uso de / para prefixar e sufixar o padrão não deve ser especificado no padrão para corresponder ao valor. Por exemplo, (\d)(\d) corresponderá a dois dígitos. /(\d)(\d)/ não corresponde a dois dígitos.
- O caso da variável de condição precisa corresponder ao caso da variável de captura. Por exemplo, se a minha variável de condição for User-Agent, a minha variável de captura deverá corresponder a User-Agent (isto é, {http_req_User-Agent_2}). Se a minha variável de condição estiver definida como user-agent, a minha variável de captura deve ser para user-agent (ou seja, {http_req_user-agent_2}).
- Se quiseres usar o valor total, não deves mencionar o número. Basta usar o formato {http_req_headerName}, etc. sem o groupNumber.
Variáveis de servidor
O Application Gateway usa variáveis de servidor para armazenar informações úteis sobre o servidor, a conexão com o cliente e a solicitação atual na conexão. Exemplos de informações armazenadas incluem o endereço IP do cliente e o tipo de navegador da web. As variáveis de servidor mudam dinamicamente, por exemplo, quando uma nova página é carregada ou quando um formulário é postado. Você pode usar essas variáveis para avaliar condições de regravação e reescrever cabeçalhos. Para usar o valor das variáveis de servidor para reescrever cabeçalhos, você precisa especificar essas variáveis na sintaxe {var_serverVariableName}
O gateway de aplicativo suporta as seguintes variáveis de servidor:
| Nome da variável | Descrição |
|---|---|
| add_x_forwarded_for_proxy | O campo de cabeçalho de solicitação do cliente X-Forwarded-For com a variável (veja a client_ip explicação mais adiante nesta tabela) anexada a ele no formato IP1, IP2, IP3 e assim por diante. Se o campo X-Forwarded-For não estiver no cabeçalho da solicitação do cliente, a add_x_forwarded_for_proxy variável será igual à $client_ip variável. Essa variável é útil quando você deseja reescrever o cabeçalho X-Forwarded-For definido pelo Application Gateway para que o cabeçalho contenha apenas o endereço IP sem as informações da porta. |
| cifras_suportadas | Uma lista das cifras suportadas pelo cliente. |
| algoritmos_de_cifra_utilizados | A cadeia de caracteres de cifras usada para uma conexão TLS estabelecida. |
| client_ip | O endereço IP do cliente do qual o gateway de aplicativo recebeu a solicitação. Se houver um proxy reverso antes do gateway de aplicativo e do cliente de origem, client_ip retornará o endereço IP do proxy reverso. |
| client_port | A porta do cliente. |
| client_tcp_rtt | Informações sobre a conexão TCP do cliente. Disponível em sistemas que suportam a opção de soquete TCP_INFO. |
| client_user | Quando a autenticação HTTP é usada, o nome de usuário fornecido para autenticação. |
| alojar | Nesta ordem de precedência: o nome do host da linha de solicitação, o nome do host do campo Cabeçalho da solicitação do host ou o nome do servidor correspondente a uma solicitação. Exemplo: Na solicitação http://contoso.com:8080/article.aspx?id=123&title=fabrikam, o valor do host é contoso.com |
| cookie_nome | O cookie de nome . |
| método_http | O método usado para fazer a solicitação de URL. Por exemplo, GET ou POST. |
| http_status | O status da sessão. Por exemplo, 200, 400 ou 403. |
| http_version | O protocolo de solicitação. Normalmente, HTTP/1.0, HTTP/1.1 ou HTTP/2.0. |
| query_string | A lista de pares variável/valor que segue o ? na URL solicitada. Exemplo: Na solicitação http://contoso.com:8080/article.aspx?id=123&title=fabrikam, query_string valor é id=123&title=fabrikam |
| bytes_recebidos | O comprimento da solicitação (incluindo a linha da solicitação, o cabeçalho e o corpo da solicitação). |
| request_query | Os argumentos na linha de solicitação. |
| Esquema_de_solicitação | O esquema de solicitação: http ou https. |
| request_uri | O URI de solicitação original completo (com argumentos). Exemplo: na solicitação http://contoso.com:8080/article.aspx?id=123&title=fabrikam*, request_uri valor é /article.aspx?id=123&title=fabrikam |
| bytes_enviados | O número de bytes enviados para um cliente. |
| porta_do_servidor | A porta do servidor que aceitou uma solicitação. |
| protocolo_de_conexão_SSL | O protocolo de uma conexão TLS estabelecida. |
| ssl_ativado | "Ligado" se a conexão operar no modo TLS. Caso contrário, uma cadeia de caracteres vazia. |
| uri_path | Identifica o recurso específico no host que o cliente da Web deseja acessar. A variável refere-se ao caminho da URL original antes de qualquer manipulação. Esta é a parte do URI de solicitação sem os argumentos. Por exemplo, na solicitação http://contoso.com:8080/article.aspx?id=123&title=fabrikam, o valor uri_path é /article.aspx. |
Variáveis do servidor de autenticação mútua
O Application Gateway oferece suporte às seguintes variáveis de servidor para cenários de autenticação mútua. Usa estas variáveis de servidor como farias com outras variáveis de servidor.
| Nome da variável | Descrição |
|---|---|
| certificado_do_cliente | O certificado do cliente no formato PEM para uma conexão SSL estabelecida. |
| data_fim_certificado_cliente | A data final do certificado do cliente. |
| impressão_digital_do_certificado_de_cliente | A impressão digital SHA1 do certificado do cliente para uma conexão SSL estabelecida. |
| emissor_de_certificado_do_cliente | A cadeia de caracteres "DN do emissor" do certificado do cliente para uma conexão SSL estabelecida. |
| número_serial_certificado_cliente | O número de série do certificado do cliente para uma conexão SSL estabelecida. |
| data_de_início_do_certificado_do_cliente | A data de início do certificado do cliente. |
| sujeito_do_certificado_do_cliente | A cadeia de caracteres "DN do assunto" do certificado do cliente para uma conexão SSL estabelecida. |
| Verificação de certificado de cliente | O resultado da verificação do certificado do cliente: SUCESSO, FALHADO:<razão>, ou NENHUM se não houver certificado presente. |
Cenários comuns para reescrita de cabeçalho
Remover informações de porta do cabeçalho X-Forwarded-For
O Application Gateway insere um cabeçalho X-Forwarded-For em todas as solicitações antes de encaminhar as solicitações para o back-end. Este cabeçalho é uma lista separada por vírgulas de portas IP. Pode haver cenários em que os servidores back-end só precisam dos cabeçalhos para conter endereços IP. Você pode usar a regravação de cabeçalho para remover as informações da porta do cabeçalho X-Forwarded-For. Uma maneira de fazer isso é definir o cabeçalho para a variável de servidor add_x_forwarded_for_proxy. Como alternativa, você também pode usar a variável client_ip:
Modificar um URL de redirecionamento
Modificar um URL de redirecionamento pode ser útil em certas circunstâncias. Por exemplo, pode inicialmente redirecionar clientes para um caminho como "/blog", mas agora querer enviá-los para "/updates" devido a uma alteração na estrutura do conteúdo.
Aviso
Pode ser necessário modificar uma URL de redirecionamento ao configurar o Application Gateway para substituir o nome do host ao encaminhar para o backend. Nesta configuração, o backend vê um nome de host diferente do do navegador. O redirecionamento não usa o nome de host correto. Esta configuração não é recomendada.
Para mais informações sobre as limitações e implicações de tal configuração, veja Preservar o nome original do host HTTP entre um proxy reverso e a sua aplicação web backend. Para a configuração recomendada do App Service, consulte "Custom Domain (recomendado)" em Configurar App Service com Application Gateway. Reescrever o cabeçalho de localização na resposta, conforme descrito no exemplo seguinte, deve ser considerado uma solução alternativa e não resolve a causa raiz.
Quando o serviço de aplicativo envia uma resposta de redirecionamento, ele usa o mesmo nome de host no cabeçalho do local de sua resposta que o da solicitação que recebe do gateway de aplicativo. Assim, o cliente faz a solicitação diretamente em contoso.azurewebsites.net/path2 vez de passar pelo gateway de aplicativo (contoso.com/path2). Ignorar o gateway de aplicativo não é desejável.
Você pode resolver esse problema definindo o nome do host no cabeçalho do local para o nome de domínio do gateway de aplicativo.
Aqui estão as etapas para substituir o nome do host:
Crie uma regra de reescrita com uma condição que verifique se o cabeçalho de localização na resposta contém azurewebsites.net. Insira o padrão '(https?)://. azurewebsites.net(.).
Execute uma ação para reescrever o cabeçalho do local para que ele tenha o nome de host do gateway de aplicativo. Introduza
{http_resp_Location_1}://contoso.com{http_resp_Location_2}como valor do cabeçalho. Como alternativa, você também pode usar a variávelhostde servidor para definir o nome do host para corresponder à solicitação original.
Implementar cabeçalhos HTTP de segurança para evitar vulnerabilidades
Você pode corrigir várias vulnerabilidades de segurança implementando os cabeçalhos necessários na resposta do aplicativo. Esses cabeçalhos de segurança incluem X-XSS-Protection, Strict-Transport-Security e Content-Security-Policy. Você pode usar o Application Gateway para definir esses cabeçalhos para todas as respostas.
Excluir cabeçalhos indesejados
Talvez você queira remover cabeçalhos que revelam informações confidenciais de uma resposta HTTP. Por exemplo, talvez você queira remover informações como o nome do servidor back-end, o sistema operacional ou os detalhes da biblioteca. Você pode usar o gateway de aplicativo para remover esses cabeçalhos:
Não podes criar uma regra de reescrita para eliminar o cabeçalho do host. Se você tentar criar uma regra de reescrita com o tipo de ação definido para excluir e o cabeçalho definido como host, isso resultará em um erro.
Verificar a presença de um cabeçalho
Você pode avaliar uma solicitação HTTP ou cabeçalho de resposta para a presença de um cabeçalho ou variável de servidor. Essa avaliação é útil quando você deseja executar uma reescrita de cabeçalho somente quando um determinado cabeçalho está presente.
Cenários comuns para reconfiguração de URL
Seleção de caminho baseada em parâmetros
Para realizar situações em que deseja escolher o grupo de servidores backend com base no valor de um cabeçalho, parte da URL ou string de consulta no pedido, use uma combinação da funcionalidade de reescrita de URL e roteamento baseado em caminhos.
Crie um conjunto de reescrita com uma condição que verifique um parâmetro específico (cadeia de consulta, cabeçalho, etc.) e depois execute uma ação onde altera o caminho da URL (garantir que o mapa do caminho Reevaluate está ativado). Associe o conjunto de reescrita a uma regra baseada em caminhos. A regra baseada em caminho deve conter os mesmos caminhos de URL especificados no conjunto de regravação e seu pool de back-end correspondente.
Assim, o conjunto de reescrita permite-te verificar um parâmetro específico e atribuir-lhe um novo caminho, e a regra baseada em caminhos permite-te atribuir pools de backend a esses caminhos. Desde que a opção "Reavaliar mapa de caminho" esteja ativada, as rotas de tráfego baseiam-se no caminho especificado no conjunto de reescrita.
Para obter um exemplo de caso de uso usando cadeias de caracteres de consulta, consulte Rotear o tráfego usando a seleção de caminho baseada em parâmetros no portal.
Reescrever parâmetros de cadeia de caracteres de consulta com base na URL
Considere o cenário de um site de compras onde o link visível para o utilizador é simples e legível, mas o servidor backend precisa dos parâmetros da string de consulta para mostrar o conteúdo correto.
Nesse caso, o Application Gateway pode capturar parâmetros da URL e adicionar pares chave-valor da string de consulta a partir desses parâmetros na URL. Por exemplo, se o utilizador quiser reescrever https://www.contoso.com/fashion/shirts para https://www.contoso.com/buy.aspx?category=fashion&product=shirts, pode alcançar este objetivo através da seguinte configuração de reescrita de URL.
Condição - Se a variável do servidor uri_path for igual ao padrão /(.+)/(.+)
Ação - Defina o caminho da URL e a buy.aspx cadeia de caracteres de consulta como category={var_uri_path_1}&product={var_uri_path_2}
Para um guia passo a passo para alcançar o cenário descrito anteriormente, consulte Rewrite URL com Application Gateway usando o portal Azure.
Reescrever armadilhas comuns de configuração
Não podes ativar o 'Reavaliar mapa de caminho' para regras básicas de encaminhamento de pedidos. Esta restrição impede um ciclo de avaliação infinito para uma regra básica de encaminhamento.
Para regras de encaminhamento baseadas em caminhos, precisa de pelo menos uma regra de reescrita condicional ou uma regra de reescrita sem ativar o 'Reavaliar o mapa de caminhos'. Este requisito impede um ciclo de avaliação infinito para uma regra de encaminhamento baseada em caminhos.
Se um ciclo for criado dinamicamente com base nas entradas do cliente, os pedidos recebidos terminam com um código de erro 500. O Application Gateway continua a servir outros pedidos sem qualquer degradação neste cenário.
Usando a regravação de URL ou a regravação de cabeçalho de host com o Web Application Firewall (WAF_v2 SKU)
Quando você configura a regravação de URL ou a regravação de cabeçalho de host, a avaliação do WAF acontece após a modificação do cabeçalho da solicitação ou dos parâmetros de URL (pós-regravação). Quando remove a configuração de reescrita de URL ou reescrita do cabeçalho do host no seu Application Gateway, a avaliação do WAF ocorre antes da reescrita do cabeçalho (pré-reescrita). Esta ordem garante que as regras WAF se aplicam ao pedido final que o seu backend pool recebe.
Por exemplo, suponha que tem a seguinte regra de reescrita de cabeçalho para o cabeçalho "Accept" : "text/html" - se o valor do cabeçalho "Accept" for igual a "text/html", então reescreva o valor para "image/png".
Com apenas a reescrita do cabeçalho configurada, a avaliação do WAF ocorre em "Accept" : "text/html". Mas quando configura a reescrita de URL ou a reescrita do cabeçalho do host, a avaliação WAF ocorre em "Accept" : "image/png".
Reescrita de URL vs redirecionamento de URL
Para uma reescrita de URL, o Application Gateway reescreve o URL antes de enviar o pedido para o backend. Esta ação não altera o que os utilizadores veem no navegador porque as alterações estão ocultas ao utilizador.
Para um redirecionamento de URL, o Application Gateway envia uma resposta de redirecionamento para o cliente com a nova URL. Essa resposta exige que o cliente reenvie o seu pedido para a nova URL fornecida no redirecionamento. O URL que o usuário vê no navegador atualiza para o novo URL.
Limitações
- Não há suporte para regravações quando o gateway de aplicativo é configurado para redirecionar as solicitações ou mostrar uma página de erro personalizada.
- Os nomes dos cabeçalhos de solicitação podem conter caracteres alfanuméricos e hífenes. Os nomes de cabeçalhos que contêm outros caracteres são descartados quando um pedido é enviado para o destino backend.
- Os nomes dos cabeçalhos de resposta podem conter caracteres alfanuméricos e símbolos específicos, conforme definido na RFC 7230.
- Não podes reescrever
X-Original-Host,Connection, eupgradecabeçalhos. - As reescritas não são suportadas para respostas 4xx e 5xx geradas diretamente pelo Application Gateway.