有时候需要在nginx配置一些禁止访问的IP,或者只配置一些可以访问的IP,下面的一些nginx里面配置的方法。
①直接写deny,去禁止某些IP地址,在指定的IP里面访问者会收到403返回。
server { location / { # 拒绝一个IP范围 deny 192.168.1.0/24; # 拒绝特定的IP地址 deny 192.168.2.1; deny 192.168.2.2; # 允许其他所有IP地址 allow all; } }
②如果要开放某些IP访问,其他的禁用,刚好相反设置:
location / { allow 192.168.1.0/24;# 允许特定的IP地址范围 deny all;# 禁止其他所有IP地址 }
③动态黑名单
根据某些条件动态拦截IP,可以结合使用Nginx和外部脚本。
创建一个黑名单文件,例如
/var/nginx/blacklist.txt
。在Nginx配置中使用
http_access_module
来引用这个文件。
http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr -$remote_user [$time_local] "$request" ' '$status$body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; # Include the blacklist include /etc/nginx/blacklist.conf; }
在/etc/nginx/blacklist.conf
文件中:
geo $block { default 0; include /var/nginx/blacklist.txt;#加载名单 } map $block$limit { 1 ""; 0 $binary_remote_addr; } limit_req_zone $limit zone=one:10m rate=1r/s;
map
指令用于根据变量$block
的值设置另一个变量$limit
的值。1 "";
表示如果$block
的值是1(即在黑名单中),则$limit
被设置为空字符串(这将阻止请求)。0 $binary_remote_addr;
表示如果$block
的值是0(即不在黑名单中),则$limit
被设置为客户端的IP地址的二进制表示(这允许请求通过)。limit_req_zone
指令定义了一个共享内存区域zone
,用于存储IP地址的请求频率信息。$limit
是根据前面map
指令设置的变量。zone=one:10m
定义了区域名称one
和分配给它的内存大小(10MB)。rate=1r/s
设置了每个IP地址每秒允许的最大请求数量。在这个例子中,每个IP地址每秒最多只能有一个请求。
然后在的location块中使用limit_req
指令:
location / { limit_req zone=one burst=5; # 其他配置... }
然后需要一个脚本来更新blacklist.txt
文件,这可以通过分析访问日志、监控系统活动等方式实现。
/var/nginx/blacklist.txt
文件是Nginx geo
指令用来定义IP地址黑名单的文件。该文件的格式相对简单,每行包含一个IP地址或一个IP地址范围,后面跟着一个空格和一个值,通常这个值是1,表示该IP地址或范围应该被阻止。以下是该文件可能包含的内容的示例:
192.168.1.1 1 192.168.1.2 1 192.168.1.3 1 192.168.1.0/24 1
④高级点的哈,有点小开销哦——使用Lua脚本和Redis模块
1. 使用Lua脚本和Redis模块
Nginx可以通过Lua模块(ngx_lua
)来执行Lua脚本,并且可以使用Lua库如resty.redis
与Redis进行交互。以下是一个基本的示例,展示如何在Nginx中使用Lua来检查Redis中的黑名单:
首先,确保你的Nginx安装了ngx_lua
模块和resty.redis
库。
http { # 设置Lua包路径 lua_package_path '/path/to/lua-resty-redis/lib/?.lua;;'; server { listen 80; server_name localhost; location / { access_by_lua_block { local redis = require "resty.redis" local red = redis:new() red:set_timeout(1000) -- 1 second local ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.log(ngx.ERR, "failed to connect to redis: ", err) return ngx.exit(500) end local ip = ngx.var.binary_remote_addr local is_blocked = red:sismember("ip_blacklist", ip) if is_blocked then ngx.log(ngx.ERR, "IP ", ip, " is blocked") return ngx.exit(403) end } # 其他location配置... } } }
在这个配置中:
access_by_lua_block
是在请求被处理之前执行的Lua代码块。使用
resty.redis
库连接到Redis服务器,并检查当前请求的IP是否在名为ip_blacklist
的Redis集合中。
使用Lua脚本和Redis模块会引入额外的性能开销。
补充,有时候会限制IP每秒的请求次数:
http { limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; server { location / { limit_req zone=mylimit burst=5 nodelay; ... } } }
它限制了每个客户端IP每秒钟只能发起10个请求。在这个配置中,$binary_remote_addr
变量用于获取客户端IP地址,zone=mylimit:10m
定义了一个名为mylimit
的共享内存区域,大小为10MB,用于存储每个IP的请求状态。rate=10r/s
设置了每秒允许的最大请求数。burst=5
表示允许短时间内超过限制的请求数量,nodelay
表示不对超出限制的请求进行延迟处理。