9人参与 • 2025-03-05 • https
在如何用nginx代理mysql连接,并限制可访问ip一文中,我们实现了通过nginx代理mysql连接,并限制了指定ip才能通过nginx进行连接,以提高数据安全性。
该场景适用于根据具体的ip地址来进行访问限制,假如我们要上线一个新的功能,但是只想在某些地区进行小规模的测试,就无能为力了。
我们可以通过添加第三方模块ngx_http_geoip2_module
来实现,其实nginx也提供了ngx_http_geoip_module
,至于我们为什么不使用它,我们后续揭晓。
我们先来回顾一下,如何通过指定ip来进行访问限制。
nginx提供了ngx_http_access_module
和ngx_stream_access_module
模块,前者针对http请求,后者针对stream连接,它们的指令非常简单,仅包含allow
和deny
指令,唯一区别就是作用域不同。
我们这里就以ngx_http_access_module
模块为例。
该指令设置指定的ip允许访问。可以和deny
指令配合使用
作用域:http, server, location, limit_except
语法:allow address | cidr | unix: | all;
示例:
# 允许192.168.110.1访问 allow 192.168.110.1; # 允许192.168.110.1到192.168.255.254 allow 192.168.110.0/16; # 允许192.168.110.1到192.168.110.254 allow 192.168.110.0/24; # 允许所有的ip访问 allow all;
该指令设置指定的ip禁止访问。可以和allow
指令配合使用。
作用域:http, server, location, limit_except
语法:deny address | cidr | unix: | all;
# 禁止192.168.110.1访问 deny 192.168.110.1; # 禁止192.168.110.1到192.168.255.254 deny 192.168.110.0/16; # 禁止192.168.110.1到192.168.110.254 deny 192.168.110.0/24; # 禁止所有的ip访问 deny all;
禁止所有的ip访问,192.168.110.100
除外。
http { server { listen 80; server_name localhost; allow 192.168.110.100; deny all; } }
tips:如果指定了allow,需要配合deny使用,否则就是允许所有的ip地址访问。
前面我们提到了nginx也提供了ngx_http_geoip_module
来实现根据国家/城市进行访问限制。
官当文档:https://nginx.org/en/docs/http/ngx_http_geoip_module.html
从上图可以得知该模块需要maxmind的数据库,并且格式为.dat
,那好,我们来看看maxmind提供的数据,如下图:
其格式为.mmdb
,与该模块的数据格式不匹配,因此我们使用第三方模块ngx_http_geoip2_module
。
下载地址:https://github.com/leev/ngx_http_geoip2_module/archive/refs/heads/master.zip
首先,我们需要安装用于读取.mmdb的文件的依赖。
apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
对于添加第三方模块,我们需要在configure时使用--add-module
来实现。
例如:
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-stream --add-module=/home/stone/nginx-1.22.1/module/ngx_http_geoip2_module
其余步骤,可参照【nginx基本命令&不停机版本升级】一文进行,这里不再赘述。
下载地址(需注册账号):https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
国家库:
城市库:
通过解压缩得到geolite2-country.mmdb
和geolite2-city.mmdb
数据库文件。
在进行配置之前,我们先通过第一步安装的依赖库来体验一下。
mmdblookup --file /usr/local/nginx/geolite2-city.mmdb --ip 183.195.99.161
可以看到,其识别出这是一个来自上海的ip地址。
接下来,我们开始配置。
http { include mime.types; default_type application/octet-stream; # 自定义日志格式 log_format geoip '$http_x_forwarded_for_temp - $remote_user [$time_local] - $request - $status - $geoip2_country_name_en - $geoip2_city_name_en'; geoip2 /usr/local/nginx/geolite2-country.mmdb { auto_reload 5m; $geoip2_metadata_country_build metadata build_epoch; $geoip2_country_code source=$http_x_forwarded_for_temp country iso_code; $geoip2_country_name_en source=$http_x_forwarded_for_temp country names en; $geoip2_country_name_zh source=$http_x_forwarded_for_temp country names zh-cn; } geoip2 /usr/local/nginx/geolite2-city.mmdb { auto_reload 5m; $geoip2_city_name_en source=$http_x_forwarded_for_temp city names en; $geoip2_city_name_zh source=$http_x_forwarded_for_temp city names zh-cn; } server { listen 80; server_name localhost; access_log logs/geoip.log geoip; default_type text/html; # 正则匹配取反 if ($geoip2_city_name_en !~ 'shanghai'){ return 403 "<h1>forbidden!</h1><p>you don't have permission to access the url on this server.</p>"; } location / { return 200 '<p>real ip: $http_x_forwarded_for_temp</p><p>country: $geoip2_country_name_en</p><p>city: $geoip2_city_name_en</p>'; } } }
tips:由于我们这里没有外网环境,因此使用$http_x_forwarded_for_temp
变量来模拟,只需在请求头中加入x-forwarded-for-temp
字段即可。实际环境还是使用$http_x_forwarded_for
变量用来获取请求的真实ip。
1)发起请求,x-forwarded-for-temp=183.195.99.161,上海ip,响应码200。
2)发起请求,x-forwarded-for-temp=221.192.127.124,唐山ip,响应码403。
3)日志记录:
以上就是nginx限制可访问ip的全部内容,nginx是多模块化的,还有很多高级功能,我们后面继续探索。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论