LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

Nginx进阶:使用GeoIP2模块构筑基于国家地理位置的安全访问策略

admin
2026年5月11日 10:25 本文热度 81

引  言
不论在自己公司还是客户那儿的搭建的 WEB服务器,一旦将其端口或IP映射到公网,基本每秒都在遭受全球范围内的自动化扫描与入侵尝试。其中,又以美国IP的异常请求尤为猖獗,成为国内服务器安全防护需要重点关注的对象。
为此,本文将以 Ubuntu 24.04 为操作环境,详细介绍如何在Nginx 1.24 中使用 GeoIP2 模块,过滤屏蔽特定国家/地区(以美国为例)的IP访问,希望可以帮助你上线的服务器,一定程度上减少被攻陷的机率。

1

安装Nginx服务与GeoIP2模块

# 安装装常用软件源的工具sudo apt updatesudo apt install -y software-properties-common unzip vim
# 安装Nginx及GeoIP2模块sudo apt install -y nginx libnginx-mod-http-geoip2
# 查看GeoIP2模块是否启用,有返回with-http_geoip结果即为正常root@P15:/# nginx -V 2>&1 | grep -o 'with-http_geoip'
# 创建存放GeoIP数据库文件的目录mkdir /usr/share/GeoIP

2

准备GeoIP2数据库文件

GeoLite2 数据库类型

数据库说明说明文件大小
GeoLite2-City城市级别地理位置数据~70MB
GeoLite2-Country国家级别地理位置数据~7MB
GeoLite2-ASNASN 网络运营商数据~9MB

免费获取数据库的方式



Maxminds


Maxminds 网站的数据最权威、更新最及时,但需要注册账户并获取许可证密钥才能实现数据库的自动更新

https://www.maxmind.com/en/geolite2/signup



DB-IP


DB-IP 提供了 MMDB 格式和 CSV 格式的完全免费、无需注册的数据库,访问地址如下:

https://db-ip.com/db/lite.php

可以通过下面的命令进行数据库更新,将文件放到 /usr/share/GeoIP 目录

# 从 db-ip 网站下载当月最新的 dbip-country-lite 文件到 /usr/share/GeoIP 目录cd /usr/share/GeoIP && wget https://download.db-ip.com/free/dbip-country-lite-$(date +%Y-%m).mmdb.gz# 解压mmdb.gz文件,有重名就覆盖gunzip -f dbip-country-lite-$(date +%Y-%m).mmdb.gz# 清理过时mmdb数据库压缩文件rm -rf /usr/share/GeoIP/*.mmdb.gz# 将 dbip-country-lite的mmdb文件重命名为GeoLite2-Country.mmdbmv -f dbip-country-lite-$(date +%Y-%m).mmdb GeoLite2-Country.mmdb


Free GeoIP Databases


用户 lwpk110 在 Github 上提供了 MaxMind GeoLite2、DB-IP 等数据库的自动化下载和发布服务。因下载的文件名包含年月日等信息,且不是每日更新,故无法使用常规命令行方式,实现数据库文件的自动更新。但是,它提供开箱即用的 GeoIP 查询 API 服务和 Web 界面,支持Docker轻量部署,一键启动。感兴趣的朋友可以访问下面的访问深入学习

https://github.com/lwpk110/free-geoip-databases

3

查询IP在数据库中的归属地

mmdblookup 是一个命令行工具,主要用途是查询和读取特定 IP 地址在数据库文件(后缀为 .mmdb)中的的地理位置信息

# 安装mmdblookup工具apt install mmdb-bin
# 基本语法:mmdblookup --file <数据库文件路径> --ip <要查询的IP地址> <查询路径>mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8
# 验证数据库并查询国家代码mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8 country iso_code

执行上面的命令后,会返回下面的结果:


{"continent":  {    "code":      "NA" <utf8_string>    "geoname_id":      6255149 <uint32>    "names":      {        "de":          "Nordamerika" <utf8_string>        "en":          "North America" <utf8_string>        "es":          "Norteamérica" <utf8_string>        "fa":          " امریکای شمالی" <utf8_string>        "fr":          "Amérique Du Nord" <utf8_string>        "ja":          "北アメリカ大陸" <utf8_string>        "ko":          "북아메리카" <utf8_string>        "pt-BR":          "América Do Norte" <utf8_string>        "ru":          "Северная Америка" <utf8_string>        "zh-CN":          "北美洲" <utf8_string>      }  }"country":  {    "geoname_id":      6252001 <uint32>    "is_in_european_union":      false <boolean>    "iso_code":      "US" <utf8_string>    "names":      {        "de":          "Vereinigte Staaten von Amerika" <utf8_string>        "en":          "United States" <utf8_string>        "es":          "Estados Unidos de América (los)" <utf8_string>        "fa":          "ایالات متحدهٔ امریکا" <utf8_string>        "fr":          "États-Unis" <utf8_string>        "ja":          "アメリカ合衆国" <utf8_string>        "ko":          "미국" <utf8_string>        "pt-BR":          "Estados Unidos" <utf8_string>        "ru":          "США" <utf8_string>        "zh-CN":          "美国" <utf8_string>      }  }}

4

配置Nginx

使用 vim 打开目标文件 /etc/nginx/nginx.conf,在http块中进行如下配置。以美国为例,禁止通过公网访问此服务器。

user www-data;worker_processes auto;pid /run/nginx.pid;error_log /var/log/nginx/error.log;include /etc/nginx/modules-enabled/*.conf;
events {        worker_connections 768;        # multi_accept on;}
http {        # 加载并使用数据库并定义变量        # 将查询到的国家ISO代码赋值给变量 $geoip2_country_code        geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {            $geoip2_country_code country iso_code;        }        # 定义访问控制映射        # 此 map 块创建一个新变量 $deny_country。        # 当 $geoip2_country_code 的值为 “US” 时,$deny_country 被设为 “yes”,否则为 “no”。        map $geoip2_country_code $deny_country {            default no;  # 默认允许访问            US      yes; # 如果国家代码是 US,则标记为拒绝            # 可以在此添加其他要屏蔽的国家代码,例如:            # RU      yes; # 俄罗斯            # CN      no;  # 中国允许(示例)        }
       ##        # Basic Settings        ##
       sendfile on;        tcp_nopush on;        types_hash_max_size 2048;        # server_tokens off;
       # server_names_hash_bucket_size 64;        # server_name_in_redirect off;
       include /etc/nginx/mime.types;        default_type application/octet-stream;
       ##        # SSL Settings        ##
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE        ssl_prefer_server_ciphers on;
       ##        # Logging Settings        ##
       access_log /var/log/nginx/access.log;
       ##        # Gzip Settings        ##
        gzip on;
       ##        # Virtual Host Configs        ##
       include /etc/nginx/conf.d/*.conf;        include /etc/nginx/sites-enabled/*;}

使用 vim 打开目标文件 /etc/nginx/sites-enabled/default,在server块中进行如下配置,应用禁止美国访问的规则。

server {        listen 80 default_server;        listen [::]:80 default_server;
        # 应用过滤屏蔽规则        if ($deny_country = yes) {            # 直接返回 403 禁止访问            return 403 "Access denied from your region.\n";            # 或者可以重定向到其他页面            # return 301 https://example.com/blocked.html;            # 或者记录日志后拒绝            # access_log /var/log/nginx/blocked.log;            # return 444; # 立即关闭连接        }
       root /var/www/html;
       # Add index.php to the list if you are using PHP        index index.html index.htm index.nginx-debian.html;
       server_name _;
       location / {                # First attempt to serve request as file, then                # as directory, then fall back to displaying a 404.                try_files $uri $uri/ =404;        }}

检查配置是否正确

sudo nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successful

重新加载 nginx 使配置生效

sudo nginx -s reload# 或者使用 sudo systemctl reload nginx

5

验证屏蔽过滤的效果

  • 从美国代理或使用美国IP访问测试:尝试访问您的网站,应收到 403 错误。

  • 命令行验证(在服务器上):使用 mmdblookup 工具确认IP地址的归属国家是否正确

sudo mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip <美国IP地址> country iso_code# 应返回:<utf8_string> US

  • 日志检查:被屏蔽的访问记录会保存在 Nginx 错误日志中。

6

定时更新数据库文件

执行下面的命令,生成 update_geoip.sh 的脚本用来实现数据库文件的更新

cat >> /usr/share/GeoIP/update_geoip.sh << 'EOF'#!/bin/bash## 进入目标目录cd /usr/share/GeoIP || exit 1
# 构建基于当前年月的文件名和URLCURRENT_DATE=$(date +%Y-%m)DBIP_FILE="dbip-country-lite-${CURRENT_DATE}"GZ_FILE="${DBIP_FILE}.mmdb.gz"DOWNLOAD_URL="https://download.db-ip.com/free/${GZ_FILE}"
# 从 db-ip 网站下载当月最新的 dbip-country-lite 文件wget -q -O "$GZ_FILE" "$DOWNLOAD_URL"
# 解压mmdb.gz文件,有重名就覆盖gunzip -f "$GZ_FILE"
# 清理mmdb数据库压缩文件rm -f ./*.mmdb.gz
# 将 dbip-country-lite的mmdb文件重命名为GeoLite2-Country.mmdbmv -f "${DBIP_FILE}.mmdb" "GeoLite2-Country.mmdb"EOF

为脚本添加可执行权限

chmod +x /usr/share/GeoIP/update_geoip.sh

将脚本添加到 crontab 的月度计划

# 编辑当前用户的crontab任务,每月20号凌晨3点执行(crontab -l 2>/dev/null; echo "0 3 20 * * /usr/share/GeoIP/update_geoip.sh") | crontab -

验证 crontab 配置

# 查看当前用户的cron任务crontab -l# 查看root用户的cron任务sudo crontab -l






  • nginx版本要求:为保证 geoip2 模块的正常使用,建议安装的 nginx 版本至少要需要满足 1.9.11 或 以上

  • 使用 map的优势:map 指令在 Nginx 启动时即完成映射表的构建,在请求处理阶段只需进行高效的哈希查找,性能远优于在多个 location 中使用 if 条件判断。

  • 处理代理和 CDN:如果你的 Nginx 前方有 CDN(如 Cloudflare)或负载均衡器(LSB),真实客户端 IP 地址可能存在于 X-Forwarded-For 等请求头中。这时你需要使用 geoip2_proxy 指令来指定可信的代理 IP 段,并告诉模块从正确的头部读取 IP。

http {    geoip2_proxy 10.0.0.0/8; # 您的内网或代理IP段    geoip2_proxy_recursive on; # 递归地从 X-Forwarded-For 中取最左侧的非代理IP    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {        $geoip2_country_code country iso_code;    }    # ... 省略后续配置}

  • 仅允许特定国家访问:只需将 map 逻辑反转即可

map $geoip2_country_code $allow_country {    default no;  # 默认禁止    CN      yes; # 仅允许中国    HK      yes; # 允许香港    # ... 省略后续配置}server {    if ($allow_country = no) {        return 403;    }    # ... 省略后续配置}

通过以上步骤,我们就可以构建一个基于国家地理位置的WEB访问控制策略,能够有效拦截源自特定国家(如美国)的流量,提升了上线服务器的带宽利用率和安全性。


该文章在 2026/5/11 10:25:29 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-9  粤公网安备44030602007207号