侧边栏壁纸
博主头像
Awesome Devin 博主等级

行动起来,活在当下

  • 累计撰写 345 篇文章
  • 累计创建 26 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

Nginx 实现屏蔽境外IP访问

Administrator
2025-12-22 / 0 评论 / 0 点赞 / 4 阅读 / 0 字

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.29.4 --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.29.4 为nginx目录

接下来我们安装GeoIP数据库

Ubuntu安装办法:

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;
}

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 yourself.

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

实战

使用ip+自定义页面,阻止非中国ip访问

  • 配合白名单ip使用

nginx配置

	#引用允许中国ip段规则,注释后配置的反向代理将无效
	include /www/server/ip/*.conf;
	
	error_page 403 /banip.html;
	location = /banip.html {
            root /www/server/nginx/html/;
            internal;
            allow all;  # 关键!必须添加
        }
	deny all;

使用自定义403页面banip.html

<html>
<head>
  <title>Access Restricted</title>
  <meta charset="UTF-8">
</head>
<body>
  <center>
    <h1>Access Restricted</h1>
    <p>We're sorry, but this website is only available to users within China. Access from international IP addresses has been restricted.</p>
  </center>
  <hr>
  <center>awesome server</center>
</body>
</html>

参考链接:
https://www.cnblogs.com/osinn/p/18816323

0
博主关闭了所有页面的评论