You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM配置IP阻止策略无效,如何拦截恶意扫描请求?

排查Azure APIM拦截恶意扫描请求的策略失效问题

问题描述

我需要拦截针对网站的扫描请求(比如路径以/.env结尾的请求),请求流转路径为:Azure FD → Node.js服务器 → APIM → 后端服务器。我在Azure API管理(APIM)的产品级别配置了策略,意图缓存恶意扫描IP并阻止其访问,但策略未生效,/.env这类请求仍能正常通过。已确认产品级别的速率限制策略可以生效,但恶意请求拦截逻辑无效,请帮忙排查配置错误并提供可行方案。

当前策略代码

<policies>
    <inbound>
        <base />
        <!-- Check if this IP is blocked -->
        <cache-lookup-value key="@("blocked-ip-" + context.Request.IpAddress)" variable-name="isBlocked" />
        <choose>
            <when condition="@(context.Variables.ContainsKey("isBlocked"))">
                <return-response>
                    <set-status code="403" reason="Forbidden" />
                    <set-body>Access denied.</set-body>
                </return-response>
            </when>
        </choose>
        <!-- Detect /.env probe and block the IP -->
        <choose>
            <when condition="@(context.Request.Url.Path.EndsWith("/.env") || context.Request.Url.Path.EndsWith("/.env."))">
                <cache-store-value key="@("blocked-ip-" + context.Request.IpAddress)" value="true" duration="300" />
                <return-response>
                    <set-status code="403" reason="Forbidden" />
                    <set-body>Access denied.</set-body>
                </return-response>
            </when>
        </choose>
        
        <!-- This is just a test policy to see it's being reached. It IS being reached. -->
        <rate-limit-by-key calls="1" renewal-period="6" counter-key="@(context.Request.IpAddress)" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

问题根源排查

  1. 真实客户端IP获取错误
    请求经过Azure FD和Node.js转发后,context.Request.IpAddress获取的是Node.js服务器的IP,而非攻击者的真实IP。APIM默认取直接连接的客户端IP,导致你封禁的是中间转发服务器,而非真正的扫描来源。

  2. 路径匹配逻辑局限性
    EndsWith判断仅能匹配严格以/.env或/.env.结尾的路径,但恶意扫描可能携带参数(如/.env?test=1)、URL编码(如/.env%20)或多余斜杠(如/.env/),此时匹配逻辑会失效。

  3. 缓存读取/存储的一致性风险
    若APIM缓存配置未正确启用,或产品级策略使用的缓存空间与预期不符,可能导致封禁记录无法正常读取,无法触发拦截。

修复后的策略方案

首先确保Node.js服务器转发请求时添加X-Forwarded-For头传递真实客户端IP,然后修改APIM策略如下:

<policies>
    <inbound>
        <!-- 获取真实客户端IP:优先读取X-Forwarded-For的第一个IP -->
        <set-variable name="clientIp" value="@(context.Request.Headers.ContainsKey("X-Forwarded-For") ? context.Request.Headers["X-Forwarded-For"][0].Split(',')[0].Trim() : context.Request.IpAddress)" />
        
        <!-- 检查IP是否已被封禁 -->
        <cache-lookup-value key="@("blocked-ip-" + context.Variables["clientIp"])" variable-name="isBlocked" />
        <choose>
            <when condition="@(context.Variables.ContainsKey("isBlocked"))">
                <return-response>
                    <set-status code="403" reason="Forbidden" />
                    <set-body>Access denied.</set-body>
                </return-response>
            </when>
        </choose>
        
        <!-- 扩展路径匹配:检测任何包含/.env的路径(忽略大小写) -->
        <choose>
            <when condition="@(context.Request.Url.Path.ToLower().Contains("/.env") || context.Request.Url.RawPath.ToLower().Contains("/.env"))">
                <cache-store-value key="@("blocked-ip-" + context.Variables["clientIp"])" value="true" duration="300" />
                <return-response>
                    <set-status code="403" reason="Forbidden" />
                    <set-body>Access denied.</set-body>
                </return-response>
            </when>
        </choose>
        
        <!-- 测试用速率限制(已适配真实客户端IP) -->
        <rate-limit-by-key calls="1" renewal-period="6" counter-key="@(context.Variables["clientIp"])" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

额外优化建议

  • 前端拦截前置:直接在Azure Front Door配置规则,拦截包含/.env、/admin等恶意路径的请求,减少后续节点的压力。
  • 正则匹配增强:使用正则表达式覆盖更多扫描场景,比如:
    @(Regex.IsMatch(context.Request.Url.Path, @"\.env(\.|$|\?)", RegexOptions.IgnoreCase))
    
  • IP列表补充防护:将频繁扫描的IP直接添加到APIM的IP拒绝列表,配合缓存封禁实现多层防护。
  • 日志验证:启用APIM请求日志,查看clientIp、Request.Url.Path等变量的实际值,确认匹配逻辑是否触发。

内容的提问来源于stack exchange,提问作者PythonForEver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 19:33:09