有时候需要在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表示不对超出限制的请求进行延迟处理。