在Nginx反向代理中实现基于关键词和黑名单的访问控制(ACL)可以有效过滤恶意请求、限制特定内容访问或实现安全策略。以下是几种实现方式:
server {
listen 80;
server_name example.com;
location / {
if ($request_uri ~* (malicious|blocked|spam)) {
return 403;
# 或者重定向到其他页面
# return 301 http://example.com/blocked.html;
}
proxy_pass http://backend;
}
}
map $request_uri $is_blocked {
default 0;
~*(malicious|blocked|spam|hack) 1;
}
server {
listen 80;
server_name example.com;
location / {
if ($is_blocked) {
return 403;
}
proxy_pass http://backend;
}
}
geo $blocked_ip {
default 0;
192.168.1.100 1;
10.0.0.0/8 1;
# 可以从文件加载
include /etc/nginx/conf.d/ip-blacklist.conf;
}
server {
listen 80;
server_name example.com;
location / {
if ($blocked_ip) {
return 403;
}
proxy_pass http://backend;
}
}
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default yes;
CN no; # 阻止中国IP
RU no; # 阻止俄罗斯IP
}
server {
listen 80;
server_name example.com;
location / {
if ($allowed_country = no) {
return 403;
}
proxy_pass http://backend;
}
}
}
map $http_user_agent $bad_agent {
default 0;
~*(wget|curl|scan|bot|spider) 1;
}
server {
listen 80;
server_name example.com;
location / {
if ($bad_agent) {
return 403;
}
proxy_pass http://backend;
}
}
# 定义黑名单变量
map $remote_addr $ip_blacklist {
default 0;
include /etc/nginx/conf.d/ip-blacklist.map;
}
map $http_user_agent $bad_agent {
default 0;
include /etc/nginx/conf.d/ua-blacklist.map;
}
map $request_uri $bad_keywords {
default 0;
include /etc/nginx/conf.d/keyword-blacklist.map;
}
server {
listen 80;
server_name example.com;
# 统一访问控制
if ($ip_blacklist) {
return 403;
}
if ($bad_agent) {
return 403;
}
if ($bad_keywords) {
return 403;
}
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 记录被阻止的请求
location = /log_blocked {
internal;
access_log /var/log/nginx/blocked.log combined;
return 204;
}
}
http {
lua_shared_dict ip_blacklist 10m;
init_by_lua_block {
-- 初始化时加载黑名单
local blacklist = {
"192.168.1.100",
"10.0.0.0/8"
}
local dict = ngx.shared.ip_blacklist
for _, ip in ipairs(blacklist) do
dict:set(ip, true)
end
}
server {
listen 80;
server_name example.com;
access_by_lua_block {
local ip = ngx.var.remote_addr
local dict = ngx.shared.ip_blacklist
if dict:get(ip) then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
location / {
proxy_pass http://backend;
}
}
}
性能考虑:频繁的正则表达式匹配会影响性能,尽量使用map指令预编译规则
维护性:将黑名单规则放在单独的文件中,便于管理更新
include /etc/nginx/conf.d/blacklist/*.conf;
日志记录:记录被阻止的请求以便分析
log_format blocked '$remote_addr - $remote_user [$time_local] '
'"$request" $status "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/blocked.log blocked;
动态更新:考虑使用API或定时任务更新黑名单,避免频繁重载Nginx
分层防护:结合防火墙、WAF等多层防护机制
以上配置可以根据实际需求组合使用,构建适合您业务场景的访问控制策略。