lua_shared_dict blacklist 20m; 
server {
    ...
    access_by_lua_block {
        local ip = ngx.var.remote_addr
        local uri = string.lower(ngx.unescape_uri(ngx.var.request_uri))
        local dict = ngx.shared.blacklist
        -- 特殊放行规则:证书验证路径
        if uri:find("^/%.well%-known") then
            return
        end
        -- 使用 table 匹配更多信任 IP
        local trusted_ips = {
          ["127.0.0.1"] = true,
          ["::1"] = true,
            -- ["其他信任内网IP"] = true 
        }
        if trusted_ips[ip] then
            return
        end   
        -- 已封禁直接丢弃
        if dict:get(ip) then
            return ngx.exit(444)
        end
        --  深度检测敏感词
        local forbidden_keywords = {
            -- 【PHP 特征】
            "%.php", "wp%-", "xmlrpc", "phpmyadmin", "pma", "thinkphp", "magento", "composer%.",
            -- 【Python 特征】
            "/flask/", "/django/", "/python/", "%.py", "wsgi",
            -- 【Node.js 特征】
            "node_modules", "package%.json", "package%-lock", "%.js.map", "pm2",
            -- 【ASP.NET/C# 特征】
            "%.aspx", "%.asp", "%.ashx", "%.asmx", "web%.config", "bin/",      
            -- 敏感文件与备份
            "%.env", "%.bak", "%.sql", "%.old", "%.save", "%.swp", "%.git", "%.svn",
            -- 框架指纹 (WordPress, Laravel, SpringBoot, ThinkPHP等)
            "wp%-", "xmlrpc", "actuator", "swagger", "api%-docs", "_profiler", "think",
            -- 常见扫描目标
            "phpinfo", "phpmyadmin", "composer%.", "package%.json",
            "magento", "solr", "nacos", "web%-inf",
            "/flask/", "/django/", "/python/", "node_modules"
        }
        for _, keyword in ipairs(forbidden_keywords) do
            if uri:match(keyword) then
                dict:set(ip, true, 3600) -- 封1小时
                ngx.log(ngx.WARN, "[SECURITY] 拦截到深度扫描: ", uri, " 来自: ", ip)
                return ngx.exit(444)
            end
        end
    }
    #########################################
    # 用法 
    #   域名访问(需要配置allow x.x.x.x)  
    #     curl "https://portal.valuetodays.xyz/manage_blacklist?action=list&token=TOKEN"
    #     curl "https://portal.valuetodays.xyz/manage_blacklist?action=flush&token=TOKEN"
    #   本机访问
    #     curl -k -H "Host: portal.valuetodays.xyz" "https://127.0.0.1/manage_blacklist?action=list&token=TOKEN"
    #     curl -k -H "Host: portal.valuetodays.xyz" "https://127.0.0.1/manage_blacklist?action=flush&token=TOKEN"
    #  
    ###########################
    # 1. 黑名单管理接口 (带 Token 保护)
    location ^~ /manage_blacklist {
        # Nginx 指令写在外面
        default_type text/plain; 
        # 如果需要 IP 限制,在这里放开
        allow 127.0.0.1; 
        allow 115.190.13.122; # 机器所在公网ip
        deny all; 
        content_by_lua_block {
        -- 获取参数
        local args = ngx.req.get_uri_args()
        local token = args["token"]
        local action = args["action"]
        local ip = args["ip"]
        -- 1. 安全校验:验证 Token
        -- 这里的 token 值请确保与你 curl 时一致
        if token ~= "111111" then
            ngx.status = 403
            ngx.say("Detected Your IP: ", ngx.var.remote_addr)
            ngx.say("Forbidden: Invalid Token")
            return ngx.exit(403)
        end
        local dict = ngx.shared.blacklist
        -- 2. 逻辑分发
        if action == "list" then
            local keys = dict:get_keys(20)
            ngx.say("Detected Your IP: " .. ngx.var.remote_addr)
            ngx.say("--- Blacklisted IPs (First 20) ---")
            for _, k in ipairs(keys) do
                ngx.say(k)
            end
        elseif action == "delete" and ip then
            dict:delete(ip)
            ngx.say("Success: IP " .. tostring(ip) .. " removed.")
        elseif action == "flush" then
            dict:flush_all()
            ngx.say("Success: Blacklist cleared.")
        else
            ngx.say("Detected Your IP: ", ngx.var.remote_addr)
            ngx.say("Usage: ?action=list&token=YOUR_TOKEN")
        end
        }
    }
    ...
}
作者:张三  创建时间:2026-08-26 17:54
最后编辑:张三  更新时间:2026-08-26 17:56
上一篇:
下一篇: