Nginx 实现屏蔽境外IP访问
方式一 指定IP
- 在nginx目录下创建blockips.conf 并添加
deny 42.200.167.4;
- 其中 42.200.167.4为屏蔽的ip地址
- 在nginx.conf中任何server{ ... }前 添加 include /etc/nginx/blockips.conf;
- 刷新配置 systemctl reload nginx
方式二 通过GeoIP禁止国外IP访问
- 检查一下nginx是否编译了GeoIP模块
nginx -V
-
出现 --with-http_geoip_module 说明nginx已经编译了GeoIP模块
-
没有GeoIP 模块 手动添加
# ./configure --prefix=/usr/local/webserver/nginx-1.6.2 --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/pcre-4-27/pcre-8.35 --with-http_geoip_module
# make
# make install
- /usr/local/webserver/nginx-1.6.2 为nginx目录
接下来我们安装GeoIP数据库
- 乌班图安装办法
apt-get install geoip-database libgeoip1
- CentOS安装办法
yum -y install geoip-devel
-
安装完成之后,GeoIP数据库会被安装在 /usr/share/GeoIP/GeoIP.dat。
-
这个GeoIP.dat是GeoIP数据库文件,使用apt-get命令安装的话这个文件不是最新的,我们可以从 http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz 这里下载最新的GeoIP数据库文件。
mv /usr/share/GeoIP/GeoIP.dat /usr/share/GeoIP/GeoIP.dat_bak
cd /usr/share/GeoIP/
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gunzip GeoIP.dat.gz
- 配置nginx.conf文件
vi /etc/nginx/nginx.conf
- 将下面的内容添加进 http {} 区域,并且要放在任何 include 语句之前。
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default yes;
FK no;
FM no;
EH no;
}
- 上面这些语句是除了 FK,FM,EH这三个地区的用户允许其它地区的用户访问。
- 也可以只允许部分地区用户访问,如下:
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
FK yes;
FM yes;
EH yes;
}
- 上面这些语句是除了 FK,FM,EH这三个地区的用户其它地区的用户都不允许访问。
- 上面的语句只是设置了一个 $allowed_country 变量,要最终实现禁止设置的地区用户访问,我们要对 $allowed_country 变量进行判断处理。
- 在 server {} (网站代理的server)区域里添加以下内容:
if ($allowed_country = no) {
return 403;
}
// 或者
if ($geoip_country_code != "CN") { // 只允许中国IP访问
return 500 "error";
}
- 也可以针对某个特定url进行限制:
location /special {
if ($allowd_country = no) {
return 403;
}
}
- 关于我个人的nginx配置是
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
CN yes;
}
- 网站里面配置(网站代理的server)的是
if ($allowed_country = no) {
return 402;
}
- 除了中国以外的IP ,访问都会返回 402
这个模块需要geo数据库和读取数据库的库文件。
Get the free database of geo_city
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
Get the free database of geo_coundty
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
Get the libgeoip. In debian you can do like this:
sudo apt-get install libgeoip-dev
In other systems, you can download the source and compile it youself.
wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz
实战
http {
log_format geoip_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" '
'Country: $geoip_country_code '
'CountryName: $geoip_country_name';
# 使用 geoip 地址库,需要下载geoip.dat 地址库并且nginx已安装--with-http_geoip_module模块
geoip_country /usr/local/nginx/geoip.dat;
map $geoip_country_code $allowed_access {
default 0;
CN 1;
}
#方式二 使用 geo 指定白名单;
geo $allowlist {
default 0;
include /usr/local/nginx/allowlist.conf;
}
# allowlist.conf 白名单格式如下
# 1.0.1.0/24 1;
# 1.0.2.0/23 1;
# 1.0.8.0/21 1;
# 42.50.0.0/16 1;
server {
listen 443 ssl http2;
server_name xxxx.com;
ssl_certificate /home/ssl/xxx.com.pem;
ssl_certificate_key /home/ssl/xxx.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# 测试日志,会记录$geoip_country_code,如果是中国区域访问,日志中会记录 Country: CN
access_log /home/.nginx/logs/access_geoip.log geoip_log;
# 指定只允许中国IP能访问,这个判断必须放在 server 里
if ($geoip_country_code != "CN") {
return 500 "error";
}
# 或者,如果不在白名单IP中直接返回444,这个判断必须放在 server 里
#if ( $allowlist = 0 ) {
# return 444;
#}
# 测试访问
location /debug {
add_header Content-Type text/plain;
return 200 "Country: $geoip_country_code";
}
}
}
TCP geoip方式
- 如果需要
--with-stream_geoip_module模块可以添加到上面的编译脚本中,此模块可用于TCP协议转发区域IP限制,如下
stream {
geoip_country /usr/local/nginx/geoip.dat;
server {
listen 3306;
if ($geoip_country_code != "CN") {
return "";
}
proxy_pass 192.168.1.100:3306;
}
}
TCP 白名单方式
// 需要跟 http {} 同级,而不是配置 http {}里面
stream {
log_format simple '$remote_addr:$remote_port '
'[$time_iso8601] '
'$protocol $status ';
# 导入包含中国 IP 列表
#include /usr/local/nginx/china_ips_dynamic.conf;
# 这里只是验证,所有只指定一个IP段,生产环境可以使用include方式导入多个
allow 119.41.0.0/16;
deny all;
upstream iot_demo {
server 127.0.0.1:8882;
}
server {
listen 8881;
proxy_pass iot_demo;
proxy_timeout 3s;
proxy_responses 1;
access_log /home/.nginx/logs/tcp_access.log simple;
}
}
获取中国白名单脚本
#!/bin/bash
# 从网上获取中国 IP 列表并生成 nginx 配置
# 下载最新的中国 IP 列表
curl -s https://www.ipdeny.com/ipblocks/data/countries/cn.zone | \
awk '{print "allow " $1 ";"}' > ./china_ips_dynamic.conf
# 添加 deny all
echo "deny all;" >> ./china_ips_dynamic.conf

浙公网安备 33010602011771号