ARR 在客户端用户之间混合 HTTP 服务器变量

ARR 在客户端用户之间混合 HTTP 服务器变量

我正在尝试做什么?

我正在设置蓝绿部署以实现零停机部署。

执行情况如何?

  1. 我有一台服务器。
  2. 我创建了一个网络农场。
  3. 我在不同的端口设置了 3 个网站,分别为蓝色、绿色和主网站。主网站处理来自客户端的所有请求,并将请求重写到 Web Farm。
  4. Web 场通过 ARR(应用程序请求路由)将请求路由到活动网站(蓝色或绿色)
  5. 由于蓝/绿网站接收来自 Web Farm/ARR 的请求,REMOTE_ADDR(客户端 IP 地址)显示 127.0.0.1。
  6. 尽管这是预期的,但我并不想要它,我已经创建了一个 URL 重写规则,该规则在主网站上使用 REMOTE_ADDR 设置 HTTP_X_FORWARDED_FOR_INTERNAL 服务器变量。
  7. 我在蓝/绿网站上创建了另一条规则,该规则使用来自主网站的 HTTP_X_FORWARDED_FOR_INTERNAL 设置 REMOTE_ADDR 服务器变量。
  8. 结果,我得到了 REMOTE_ADDR 作为真实客户端 IP 地址。太棒了!
  9. 对于单个客户端用户来说,一切都运行良好。

什么没有按预期进行?

当我从不同的 IP 地址连接到网站时(尤其是静态内容),蓝/绿应用程序会接收其他客户端拥有的错误 IP 地址(REMOTE_ADDR)。

例子:

  1. A和B是不同的IP地址。
  2. A 连接到 foo.com/somestaticfile.css。
  3. B 连接到 foo.com/somestaticfile.css。

当我检查 IIS 应用程序日志时,来自 B 的请求日志显示 IP 地址为“A”,尽管它应该是 B!

我还可以根据 cookie 确认请求来自 B,我们在 cookie 中保存了 ip 地址,并且根据 IIS 应用程序日志,cookie 中的 ip 地址不等于 REMOTE_ADDR。

编辑:我发现了另一个问题,“有时”一些 javascript 响应的 mime 类型在响应中变成“text/html”,因为我们实现了 X-Content-Type-Options=nosniff,所以这些脚本不会被浏览器加载。

Refused to execute script from 'https://foo.com/bundles/scripts/common?v=Pc3UWD-GF8GEIazC15mnIr_UYtcH3cQPlDPwAf2cXtU1' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.

编辑2:我发现了一些有用的东西。当我访问一些返回 40x 状态代码的链接时。错误与每次重现的 IP 地址有关。这是我未经身份验证后被重定向的 URL。

https://foo.com/account/signin?sessionExpired=true&returnUrl=%2ferror%2fnotfound%2f%3f404%3bhttps%3a%2f%2ffoo.com%3a10003%2ferror%2fnotfound

returnUrl解码后的值为:“/error/notfound/?404;https://foo.com:10003/error/notfound

诡异的?

我已尝试过什么方法来解决此情况?

我以为这是某种缓存问题,然后我禁用了我知道的所有缓存机制;

  1. 从全局设置禁用 IIS 缓存。
  2. 通过创建缓存控制规则禁用 ARR 缓存。
  3. 已禁用 Web Farm 缓存。

但它没有起作用。

我已经清除了所有配置并使用ARR 助手它是为在此类配置中将 IP 地址转发到最后面的 Web 应用程序而开发的,我遇到了相同的问题。

您可能需要的配置文件

在主 Web 应用程序中设置 HTTP_X_FORWARDED_FOR_INTERNAL 的规则。

<rule name="Set HTTP_X_FORWARDED_FOR_INTERNAL">
                <match url="(.*)" />
                <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                <serverVariables>
                    <set name="HTTP_X_FORWARDED_FOR_INTERNAL" value="{REMOTE_ADDR}" />
                </serverVariables>
                <action type="None" />
            </rule>

在蓝/绿应用程序中设置 REMOTE_ADDR 的规则。

<rule name="Set REMOTE_ADDR">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_X_FORWARDED_FOR_INTERNAL}" pattern="^$" negate="true" />
      </conditions>
      <serverVariables>
        <set name="REMOTE_ADDR" value="{HTTP_X_FORWARDED_FOR_INTERNAL}" />
        <set name="REMOTE_HOST" value="{HTTP_X_FORWARDED_FOR_INTERNAL}" />
      </serverVariables>
      <action type="None" />
    </rule>

在全局级别禁用 ARR 缓存的规则。

 <rewrite>
        <globalRules>
            <rule name="ARR_CacheControl_9dc69ea7-26f6-4654-af58-2e289d681463" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
                <match url="*" />
                <serverVariables>
                    <set name="ARR_CACHE_CONTROL_OVERRIDE" value="1,no-cache" />
                </serverVariables>
                <action type="None" />
            </rule>
        </globalRules>
    </rewrite>

整个 Web 场配置

<webFarms>
    <webFarm name="iissucks" enabled="true">
        <server address="bluecloud" enabled="true">
            <applicationRequestRouting httpPort="880" httpsPort="8443" />
        </server>
        <server address="greencloud" enabled="true">
            <applicationRequestRouting httpPort="980" httpsPort="9443" />
        </server>
        <applicationRequestRouting>
            <healthCheck url="https://iissucks/account/signin" interval="00:00:01" statusCodeMatch="200-599" responseMatch="I_am_healthy." />
            <protocol xForwardedForHeaderName="X-Forwarded-For-Farm" includePortInXForwardedFor="false">
                <cache enabled="false" queryStringHandling="NoCaching" validationInterval="00:00:00" />
            </protocol>
        </applicationRequestRouting>
    </webFarm>
    <applicationRequestRouting>
        <hostAffinityProviderList>
            <add name="Microsoft.Web.Arr.HostNameRoundRobin" />
        </hostAffinityProviderList>
    </applicationRequestRouting>
</webFarms>

答案1

我远非 IIS 专家,但我发现您的问题很有趣。我看到您的全局缓存禁用规则stopProcessing="true"中有一个参数设置。也许在缓存禁用规则停止处理任何其他规则后,您的变量设置规则没有被执行。

相关内容