重写应用程序网关的 HTTP 标头Rewrite HTTP headers with Application Gateway

备注

本文进行了更新,以便使用新的 Azure PowerShell Az 模块。This article has been updated to use the new Azure PowerShell Az module. 你仍然可以使用 AzureRM 模块,至少在 2020 年 12 月之前,它将继续接收 bug 修补程序。You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. 若要详细了解新的 Az 模块和 AzureRM 兼容性,请参阅新 Azure Powershell Az 模块简介To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. 有关 Az 模块安装说明,请参阅安装 Azure PowerShellFor Az module installation instructions, see Install Azure PowerShell.

HTTP 标头可让客户端和服务器连同请求或响应一起传递附加的信息。HTTP headers allow a client and server to pass additional information with a request or response. 重写这些标头可以完成重要的任务,例如,添加安全相关的标头字段(如 HSTS/ X-XSS-Protection)、删除可能透露敏感信息的响应标头字段,以及从 X-Forwarded-For 标头中删除端口信息。By rewriting these headers, you can accomplish important tasks, such as adding security-related header fields like HSTS/ X-XSS-Protection, removing response header fields that might reveal sensitive information, and removing port information from X-Forwarded-For headers.

当请求和响应数据包在客户端与后端池之间移动时,可以通过应用程序网关添加、删除或更新 HTTP 请求和响应标头。Application Gateway allows you to add, remove, or update HTTP request and response headers while the request and response packets move between the client and back-end pools. 还可以通过它来添加条件,确保只有在满足特定条件的情况下才能重写指定标头。And it allows you to add conditions to ensure that the specified headers are rewritten only when certain conditions are met.

应用程序网关还支持多个服务器变量,这些变量可帮助你存储有关请求和响应的附加信息。Application Gateway also supports several server variables that help you store additional information about requests and responses. 这样,你就可以更轻松地创建强大的重写规则。This makes it easier for you to create powerful rewrite rules.

备注

HTTP 标头重写支持仅适用于 Standard_V2 和 WAF_v2 SKUThe HTTP header rewrite support is only available for the Standard_V2 and WAF_v2 SKU.

重写标头

支持的标头Supported headers

可以重写请求和响应中的所有标头,但 Host、Connection 和 Upgrade 标头除外。You can rewrite all headers in requests and responses, except for the Host, Connection, and Upgrade headers. 还可以使用应用程序网关创建自定义标头,并将其添加到通过该网关路由的请求和响应。You can also use the application gateway to create custom headers and add them to the requests and responses being routed through it.

重写条件Rewrite conditions

可以使用重写条件来评估 HTTP(S) 请求和响应的内容,仅当满足其中一个或多个条件时,才执行标头重写。You can use rewrite conditions to evaluate the content of HTTP(S) requests and responses and perform a header rewrite only when one or more conditions are met. 应用程序网关使用以下类型的变量来评估 HTTP(S) 请求和响应的内容:The application gateway uses these types of variables to evaluate the content of HTTP(S) requests and responses:

  • 请求中的 HTTP 标头。HTTP headers in the request.
  • 响应中的 HTTP 标头。HTTP headers in the response.
  • 应用程序网关服务器变量。Application Gateway server variables.

可以使用条件来评估指定的变量是否存在、指定的变量是否与特定的值匹配,或指定的变量是否与特定的模式匹配。You can use a condition to evaluate whether a specified variable is present, whether a specified variable matches a specific value, or whether a specified variable matches a specific pattern. 使用 Perl 兼容的正则表达式 (PCRE) 库来设置条件中的正则表达式模式匹配。You use the Perl Compatible Regular Expressions (PCRE) library to set up regular expression pattern matching in the conditions. 若要了解正则表达式语法,请参阅 Perl 正则表达式主页To learn about regular expression syntax, see the Perl regular expressions main page.

重写操作Rewrite actions

使用重写操作指定要重写的请求和响应标头,以及标头的新值。You use rewrite actions to specify the request and response headers that you want to rewrite and the new value for the headers. 可以创建新标头、修改现有标头的值,或删除现有标头。You can either create a new header, modify the value of an existing header, or delete an existing header. 新标头或现有标头的值可设置为以下类型的值:The value of a new header or an existing header can be set to these types of values:

  • 文本。Text.
  • 请求标头。Request header. 若要指定请求标头,需使用语法 {http_req_headerName}。To specify a request header, you need to use the syntax {http_req_headerName}.
  • 响应标头。Response header. 若要指定响应标头,需使用语法 {http_resp_headerName}。To specify a response header, you need to use the syntax {http_resp_headerName}.
  • 服务器变量。Server variable. 若要指定服务器变量,需使用语法 {var_serverVariable}。To specify a server variable, you need to use the syntax {var_serverVariable}.
  • 文本、请求标头、响应标头和服务器变量的组合。A combination of text, a request header, a response header, and a server variable.

服务器变量Server variables

应用程序网关使用服务器变量来存储有关服务器、与客户端建立的连接以及对连接的当前请求的有用信息。Application Gateway uses server variables to store useful information about the server, the connection with the client, and the current request on the connection. 例如,存储的信息包括客户端的 IP 地址和 Web 浏览器类型。Examples of information stored include the client’s IP address and the web browser type. 服务器变量会动态更改,例如,加载新页或发布表单时就会更改。Server variables change dynamically, for example, when a new page loads or when a form is posted. 可以使用这些变量来评估重写条件和重写标头。You can use these variables to evaluate rewrite conditions and rewrite headers. 若要使用服务器变量的值重写标头,需要在语法 {var_serverVariable} 中指定这些变量In order to use the value of server variables to rewrite headers, you will need to specify these variables in the syntax {var_serverVariable}

应用程序网关支持以下服务器变量:Application gateway supports these server variables:

变量名称Variable name 说明Description
add_x_forwarded_for_proxyadd_x_forwarded_for_proxy X-Forwarded-For 客户端请求标头字段,其中追加了 IP1、IP2、IP3 等格式的 client_ip 变量(请参阅此表后面的解释)。The X-Forwarded-For client request header field with the client_ip variable (see explanation later in this table) appended to it in the format IP1, IP2, IP3, and so on. 如果 X-Forwarded-For 字段不在客户端请求标头中,则 add_x_forwarded_for_proxy 变量等于 $client_ip 变量。If the X-Forwarded-For field isn't in the client request header, the add_x_forwarded_for_proxy variable is equal to the $client_ip variable. 若要重写应用程序网关设置的 X-Forwarded-For 标头,使该标头仅包含 IP 地址而不包含端口信息,则此变量特别有用。This variable is particularly useful when you want to rewrite the X-Forwarded-For header set by Application Gateway so that the header contains only the IP address without the port information.
ciphers_supportedciphers_supported 客户端支持的加密法列表。A list of the ciphers supported by the client.
ciphers_usedciphers_used 用于已建立 TLS 连接的加密法字符串。The string of ciphers used for an established TLS connection.
client_ipclient_ip 客户端的 IP 地址,应用程序网关从中接收请求。The IP address of the client from which the application gateway received the request. 如果应用程序网关和发起方客户端的前面有反向代理,则 client_ip 将返回该反向代理的 IP 地址。If there's a reverse proxy before the application gateway and the originating client, client_ip will return the IP address of the reverse proxy.
client_portclient_port 客户端端口。The client port.
client_tcp_rttclient_tcp_rtt 有关客户端 TCP 连接的信息。Information about the client TCP connection. 在支持 TCP_INFO 套接字选项的系统上可用。Available on systems that support the TCP_INFO socket option.
client_userclient_user 使用 HTTP 身份验证时提供用于身份验证的用户名。When HTTP authentication is used, the user name supplied for authentication.
hosthost 按此优先顺序排列:请求行中的主机名、Host 请求标头字段中的主机名,或与请求匹配的服务器名称。In this order of precedence: the host name from the request line, the host name from the Host request header field, or the server name matching a request. 示例:在请求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,主机值将为 contoso.com Example: in the request http://contoso.com:8080/article.aspx?id=123&title=fabrikam, host value will be is contoso.com
cookie_namecookie_name name Cookie。The name cookie.
http_methodhttp_method 用于发出 URL 请求的方法。The method used to make the URL request. 例如 GET 或 POST。For example, GET or POST.
http_statushttp_status 会话状态。The session status. 例如 200、400 或 403。For example, 200, 400, or 403.
http_versionhttp_version 请求协议。The request protocol. 通常为 HTTP/1.0、HTTP/1.1 或 HTTP/2.0。Usually HTTP/1.0, HTTP/1.1, or HTTP/2.0.
query_stringquery_string 请求的 URL 中“?”后面的变量/值对列表。The list of variable/value pairs that follows the "?" in the requested URL. 示例:在请求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,query_string 值将为 id=123&title=fabrikam Example: in the request http://contoso.com:8080/article.aspx?id=123&title=fabrikam, query_string value will be id=123&title=fabrikam
received_bytesreceived_bytes 请求的长度(包括请求行、标头和请求正文)。The length of the request (including the request line, header, and request body).
request_queryrequest_query 请求行中的参数。The arguments in the request line.
request_schemerequest_scheme 请求方案:http 或 https。The request scheme: http or https.
request_urirequest_uri 完整的原始请求 URI(带参数)。The full original request URI (with arguments). 示例:在请求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,request_uri 值将为 /article.aspx?id=123&title=fabrikam Example: in the request http://contoso.com:8080/article.aspx?id=123&title=fabrikam, request_uri value will be /article.aspx?id=123&title=fabrikam
sent_bytessent_bytes 发送到客户端的字节数。The number of bytes sent to a client.
server_portserver_port 接受请求的服务器端口。The port of the server that accepted a request.
ssl_connection_protocolssl_connection_protocol 已建立的 TLS 连接的协议。The protocol of an established TLS connection.
ssl_enabledssl_enabled 如果连接在 TLS 模式下建立,则为“On”。“On” if the connection operates in TLS mode. 否则为空字符串。Otherwise, an empty string.
uri_pathuri_path 标识 Web 客户端要访问的主机中的特定资源。Identifies the specific resource in the host that the web client wants to access. 这是请求 URI 中没有参数的部分。This is the part of the request URI without the arguments. 示例:在请求 http://contoso.com:8080/article.aspx?id=123&title=fabrikam 中,uri_path 值将为 /article.aspx Example: in the request http://contoso.com:8080/article.aspx?id=123&title=fabrikam, uri_path value will be /article.aspx

重写配置Rewrite configuration

若要配置 HTTP 标头重写,需要完成以下步骤。To configure HTTP header rewrite, you need to complete these steps.

  1. 创建 HTTP 标头重写所需的对象:Create the objects that are required for HTTP header rewrite:

    • 重写操作:用于指定要重写的请求和请求标头字段,以及标头的新值。Rewrite action: Used to specify the request and request header fields that you want to rewrite and the new value for the headers. 可将一个或多个重写条件关联到一个重写操作。You can associate one or more rewrite conditions with a rewrite action.

    • 重写条件:一个可选配置。Rewrite condition: An optional configuration. 重写条件评估 HTTP(S) 请求和响应的内容。Rewrite conditions evaluate the content of the HTTP(S) requests and responses. 如果 HTTP(S) 请求或响应与重写条件匹配,则会发生重写操作。The rewrite action will occur if the HTTP(S) request or response matches the rewrite condition.

      如果将多个条件关联到一个操作,仅当满足所有条件时,才会发生该操作。If you associate more than one condition with an action, the action occurs only when all the conditions are met. 换言之,操作属于逻辑 AND 运算。In other words, the operation is a logical AND operation.

    • 重写规则:包含多个重写操作/重写条件的组合。Rewrite rule: Contains multiple rewrite action / rewrite condition combinations.

    • 规则顺序:帮助确定重写规则的执行顺序。Rule sequence: Helps determine the order in which the rewrite rules execute. 在一个重写集中使用多个重写规则时,此配置非常有用。This configuration is helpful when you have multiple rewrite rules in a rewrite set. 规则顺序值较小的重写规则最先运行。A rewrite rule that has a lower rule sequence value runs first. 如果为两个重写规则分配了相同的规则顺序,则执行顺序是不确定的。If you assign the same rule sequence to two rewrite rules, the order of execution is non-deterministic.

    • 重写集:包含要与请求路由规则关联的多个重写规则。Rewrite set: Contains multiple rewrite rules that will be associated with a request routing rule.

  2. 将重写集 (rewriteRuleSet) 附加到路由规则。Attach the rewrite set (rewriteRuleSet) to a routing rule. 重写配置将通过路由规则附加到源侦听器。The rewrite configuration is attached to the source listener via the routing rule. 使用基本路由规则时,标头重写配置与源侦听器相关联,并且是全局标头重写。When you use a basic routing rule, the header rewrite configuration is associated with a source listener and is a global header rewrite. 使用基于路径的路由规则时,将在 URL 路径映射中定义标头重写配置。When you use a path-based routing rule, the header rewrite configuration is defined on the URL path map. 在这种情况下,该规则只会应用到站点的特定路径区域。In that case, it applies only to the specific path area of a site.

    备注

    URL 重写会改变标头,而不会更改路径的 URL。URL Rewrite alter the headers; it does not change the URL for the path.

可以创建多个 HTTP 标头重写集,并将每个重写集应用到多个侦听器。You can create multiple HTTP header rewrite sets and apply each rewrite set to multiple listeners. 但是,对于一个特定的侦听器,只能应用一个重写集。But you can apply only one rewrite set to a specific listener.

常见方案Common scenarios

下面是标头重写的一些常见使用方案。Here are some common scenarios for using header rewrite.

从 X-Forwarded-For 标头中删除端口信息Remove port information from the X-Forwarded-For header

应用程序网关先在所有请求中插入 X-Forwarded-For 标头,然后将请求转发到后端。Application Gateway inserts an X-Forwarded-For header into all requests before it forwards the requests to the backend. 此标头是 IP 端口的逗号分隔列表。This header is a comma-separated list of IP ports. 在某些情况下,后端服务器只需在标头中包含 IP 地址。There might be scenarios in which the back-end servers only need the headers to contain IP addresses. 你可以使用标头重写从 X-Forwarded-For 标头中删除端口信息。You can use header rewrite to remove the port information from the X-Forwarded-For header. 为此,一种做法是将该标头设置为 add_x_forwarded_for_proxy 服务器变量:One way to do this is to set the header to the add_x_forwarded_for_proxy server variable:

删除端口

修改重定向 URLModify a redirection URL

当后端应用程序发送重定向响应时,你可能希望将客户端重定向到不同的 URL,而不是后端应用程序指定的 URL。When a back-end application sends a redirection response, you might want to redirect the client to a different URL than the one specified by the back-end application. 例如,当应用服务托管在应用程序网关后面,并要求客户端重定向到其相对路径时,你可能希望这样做。For example, you might want to do this when an app service is hosted behind an application gateway and requires the client to do a redirection to its relative path. (例如,从 contoso.chinacloudsites.cn/path1 重定向到 contoso.chinacloudsites.cn/path2。)(For example, a redirect from contoso.chinacloudsites.cn/path1 to contoso.chinacloudsites.cn/path2.)

由于应用服务是多租户服务,因此它会使用请求中的主机标头将请求路由到正确的终结点。Because App Service is a multitenant service, it uses the host header in the request to route the request to the correct endpoint. 应用服务具有一个默认域名 *.chinacloudsites.cn(例如 contoso.chinacloudsites.cn),该域名不同于应用程序网关的域名(例如 contoso.com)。App services have a default domain name of *.chinacloudsites.cn (say contoso.chinacloudsites.cn) that's different from the application gateway's domain name (say contoso.com). 由于来自客户端的原始请求使用应用程序网关的域名 (contoso.com) 作为主机名,因此,应用程序网关会将主机名更改为 contoso.chinacloudsites.cn。Because the original request from the client has the application gateway's domain name (contoso.com) as the hostname, the application gateway changes the hostname to contoso.chinacloudsites.cn. 做出此更改的目的是使应用服务能够将请求路由到正确的终结点。It makes this change so that the app service can route the request to the correct endpoint.

当应用服务发送重定向响应时,它会在其响应的位置标头中,使用它从应用程序网关收到的请求中的相同主机名。When the app service sends a redirection response, it uses the same hostname in the location header of its response as the one in the request it receives from the application gateway. 因此,客户端将直接向 contoso.chinacloudsites.cn/path2 发出请求,而不是通过应用程序网关 (contoso.com/path2) 发出请求。So the client will make the request directly to contoso.chinacloudsites.cn/path2 instead of going through the application gateway (contoso.com/path2). 不应该绕过应用程序网关。Bypassing the application gateway isn't desirable.

将 location 标头中的主机名设置为应用程序网关的域名即可解决此问题。You can resolve this issue by setting the hostname in the location header to the application gateway's domain name.

下面是替换主机名的步骤:Here are the steps for replacing the hostname:

  1. 创建一个重写规则,其中的某个条件可以评估响应中的 location 标头是否包含 chinacloudsites.cn。Create a rewrite rule with a condition that evaluates if the location header in the response contains chinacloudsites.cn. 输入模式 (https?):\/\/.*chinacloudsites\.cn(.*)$Enter the pattern (https?):\/\/.*chinacloudsites\.cn(.*)$.
  2. 执行相应的操作来重写 location 标头,使其包含应用程序网关的主机名。Perform an action to rewrite the location header so that it has the application gateway's hostname. 为此,请输入 {http_resp_Location_1}://contoso.com{http_resp_Location_2} 作为标头值。Do this by entering {http_resp_Location_1}://contoso.com{http_resp_Location_2} as the header value.

修改 location 标头

实现安全 HTTP 标头以防止漏洞Implement security HTTP headers to prevent vulnerabilities

在应用程序响应中实现必要的标头可以修复多个安全漏洞。You can fix several security vulnerabilities by implementing necessary headers in the application response. 这些安全标头包括 X-XSS-Protection、Strict-Transport-Security 和 Content-Security-Policy。These security headers include X-XSS-Protection, Strict-Transport-Security, and Content-Security-Policy. 可以使用应用程序网关为所有响应设置这些标头。You can use Application Gateway to set these headers for all responses.

安全标头

删除不需要的标头Delete unwanted headers

你可能想要从 HTTP 响应中删除透露敏感信息的标头。You might want to remove headers that reveal sensitive information from an HTTP response. 例如,你可能想要删除后端服务器名称、操作系统或库详细信息等信息。For example, you might want to remove information like the back-end server name, operating system, or library details. 可以使用应用程序网关删除以下标头:You can use the application gateway to remove these headers:

删除标头

检查某个标头是否存在Check for the presence of a header

可以在 HTTP 请求或响应标头中评估某个标头或服务器变量是否存在。You can evaluate an HTTP request or response header for the presence of a header or server variable. 如果你希望只有存在特定的标头时执行标头重写,则此评估非常有用。This evaluation is useful when you want to perform a header rewrite only when a certain header is present.

检查某个标头是否存在

限制Limitations

  • 如果响应中包含多个同名的标头,则重写其中某个标头的值会导致删除该响应中的其他标头。If a response has more than one header with the same name, then rewriting the value of one of those headers will result in dropping the other headers in the response. 这种情况往往出现于 Set-Cookie 标头,因为在一个响应中可以包含多个 Set-Cookie 标头。This can usually happen with Set-Cookie header since you can have more than one Set-Cookie header in a response. 例如,如果将应用服务与应用程序网关一起使用,并在应用程序网关上配置了基于 Cookie 的会话关联,则就会出现此类情况。One such scenario is when you are using an app service with an application gateway and have configured cookie-based session affinity on the application gateway. 在这种情况下,响应将包含两个 Set-Cookie 标头:一个用于应用服务(例如 Set-Cookie: ARRAffinity=ba127f1caf6ac822b2347cc18bba0364d699ca1ad44d20e0ec01ea80cda2a735;Path=/;HttpOnly;Domain=sitename.chinacloudsites.cn),另一个用于应用程序网关关联(例如 Set-Cookie: ApplicationGatewayAffinity=c1a2bd51lfd396387f96bl9cc3d2c516; Path=/)。In this case the response will contain two Set-Cookie headers: one used by the app service, for example: Set-Cookie: ARRAffinity=ba127f1caf6ac822b2347cc18bba0364d699ca1ad44d20e0ec01ea80cda2a735;Path=/;HttpOnly;Domain=sitename.chinacloudsites.cn and another for application gateway affinity, for example, Set-Cookie: ApplicationGatewayAffinity=c1a2bd51lfd396387f96bl9cc3d2c516; Path=/. 在此情况下重写其中一个 Set-Cookie 标头可能会导致从响应中删除另一个 Set-Cookie 标头。Rewriting one of the Set-Cookie headers in this scenario can result in removing the other Set-Cookie header from the response.

  • 当应用程序网关配置为重定向请求或显示自定义错误页时,不支持重写。Rewrites are not supported when the application gateway is configured to redirect the requests or to show a custom error page.

  • 目前不支持重写 Connection、Upgrade 和 Host 标头。Rewriting the Connection, Upgrade, and Host headers isn't currently supported.

  • 标头名称可以包含任何字母数字字符和 RFC 7230 中定义的特定符号。Header names can contain any alphanumeric characters and specific symbols as defined in RFC 7230. 目前不支持在标头名称中包含下划线 (_) 特殊字符。We don't currently support the underscore (_) special character in Header names.

后续步骤Next steps

若要了解如何重写 HTTP 标头,请参阅:To learn how to rewrite HTTP headers, see: