插件窝 干货文章 Nginx反向代理中的域名检索黑白名单策略

Nginx反向代理中的域名检索黑白名单策略

Nginx host 名单 反向 199    来源:    2025-04-20

Nginx反向代理中的域名检索黑白名单策略

在Nginx反向代理配置中,实现域名检索的黑白名单策略是常见的安全需求。以下是几种实现方式:

1. 基于map模块的黑白名单

http {
    # 定义白名单
    map $host $allowed_host {
        default 0;
        ~^example\.com$ 1;
        ~^sub\.example\.com$ 1;
        ~^allowed\.domain\.com$ 1;
    }

    # 定义黑名单
    map $host $denied_host {
        default 0;
        ~^blocked\.domain\.com$ 1;
        ~^malicious\.site$ 1;
    }

    server {
        listen 80;

        if ($denied_host) {
            return 403;
        }

        if ($allowed_host = 0) {
            return 403;
        }

        # 其他反向代理配置
        location / {
            proxy_pass http://backend;
        }
    }
}

2. 基于geo模块的黑名单

http {
    geo $blacklist {
        default 0;
        192.168.1.0/24 1;
        10.0.0.0/8 1;
    }

    server {
        listen 80;

        if ($blacklist) {
            return 403;
        }

        # 其他反向代理配置
    }
}

3. 使用include文件维护名单

创建白名单文件 /etc/nginx/whitelist.conf:

# 白名单
server_name ~^(www\.)?example\.com$;
server_name ~^sub\.example\.com$;

创建黑名单文件 /etc/nginx/blacklist.conf:

# 黑名单
server_name ~^blocked\.domain\.com$;
server_name ~^malicious\.site$;

在Nginx配置中引用:

http {
    include /etc/nginx/whitelist.conf;
    include /etc/nginx/blacklist.conf;

    server {
        listen 80;

        if ($host ~* (blocked\.domain\.com|malicious\.site)) {
            return 403;
        }

        # 其他反向代理配置
    }
}

4. 动态更新策略

对于需要频繁更新的名单,可以结合Lua脚本或外部数据库:

http {
    lua_shared_dict blacklist 10m;

    server {
        listen 80;

        access_by_lua_block {
            local blacklist = ngx.shared.blacklist
            local host = ngx.var.host

            if blacklist:get(host) then
                ngx.exit(403)
            end
        }

        # 其他反向代理配置
    }
}

最佳实践建议

  1. 性能考虑:map和geo模块在Nginx启动时加载到内存,性能最好
  2. 维护性:对于大型名单,使用单独文件并通过include引入
  3. 安全性:黑名单应作为最后防线,优先使用白名单策略
  4. 日志记录:记录被拦截的请求以便审计
  5. 动态更新:对于高频率变更,考虑使用Lua或外部API

完整示例配置

http {
    # 白名单
    map $host $allowed_host {
        hostnames;
        default 0;

        # 允许的域名
        .example.com 1;
        .trusted.org 1;
        localhost 1;
    }

    # 黑名单
    map $host $denied_host {
        hostnames;
        default 0;

        # 拒绝的域名
        .malicious.com 1;
        .spam.net 1;
    }

    server {
        listen 80;
        server_name _;

        # 检查黑名单
        if ($denied_host) {
            access_log /var/log/nginx/blocked_access.log;
            return 403 "Access Denied";
        }

        # 检查白名单
        if ($allowed_host = 0) {
            access_log /var/log/nginx/blocked_access.log;
            return 403 "Access Denied";
        }

        # 反向代理配置
        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 用于动态更新黑名单的接口(需保护)
        location /update_blacklist {
            allow 127.0.0.1;
            deny all;

            content_by_lua_block {
                -- 实现动态更新逻辑
            }
        }
    }
}

以上配置可以根据实际需求进行调整,建议在生产环境使用前进行充分测试。