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

Oğu*_*pçu 5 iis load-balancing web-farm arr

我正在尝试做什么?

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

执行情况如何?

  1. 我有一台服务器。
  2. 我创建了一个网络农场。
  3. 我在不同的端口设置了蓝色、绿色、主要的 3 个网站。Main 处理来自客户端的所有请求并将请求重写到 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.
Run Code Online (Sandbox Code Playgroud)

编辑 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 Helper,它是为在这样的配置中将 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>
Run Code Online (Sandbox Code Playgroud)

在蓝/绿应用中设置 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>
Run Code Online (Sandbox Code Playgroud)

在全局级别禁用 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>
Run Code Online (Sandbox Code Playgroud)

整个网络场配置

<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>
Run Code Online (Sandbox Code Playgroud)

小智 0

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