插件窝 干货文章 Nginx反向代理中基于GeoIP的ACL配置

Nginx反向代理中基于GeoIP的ACL配置

GeoIP country Nginx http 559    来源:    2025-04-20

Nginx反向代理中基于GeoIP的ACL配置

GeoIP模块允许Nginx根据客户端IP地址的地理位置信息进行访问控制(ACL)。以下是详细的配置指南:

1. 前提条件

  • 已安装Nginx并支持ngx_http_geoip_module
  • 已下载GeoIP数据库文件

2. 安装GeoIP模块

对于Debian/Ubuntu系统:

sudo apt-get install libgeoip1 nginx-module-geoip

对于CentOS/RHEL系统:

sudo yum install geoip geoip-devel

3. 配置GeoIP数据库

  1. 下载GeoIP数据库:
mkdir -p /usr/share/GeoIP
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoIP.dat.gz
gunzip GeoLiteCity.dat.gz
mv GeoIP.dat GeoLiteCity.dat /usr/share/GeoIP/
  1. 在nginx.conf中加载GeoIP模块:
load_module modules/ngx_http_geoip_module.so;

4. 基本GeoIP配置

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

    # 定义国家代码变量
    map $geoip_country_code $allowed_country {
        default no;
        US yes;
        CA yes;
        GB yes;
        DE yes;
        FR yes;
    }
}

5. 基于国家的访问控制

方法1:使用if条件

server {
    location / {
        if ($allowed_country = no) {
            return 403;
        }
        proxy_pass http://backend;
    }
}

方法2:使用map和变量

server {
    location / {
        set $deny_access off;

        if ($geoip_country_code = CN) {
            set $deny_access on;
        }

        if ($geoip_country_code = RU) {
            set $deny_access on;
        }

        if ($deny_access = on) {
            return 403;
        }

        proxy_pass http://backend;
    }
}

6. 基于城市或地区的访问控制

server {
    location / {
        # 拒绝特定城市的访问
        if ($geoip_city = "Beijing") {
            return 403;
        }

        # 允许特定地区的访问
        if ($geoip_region = "CA") {
            proxy_pass http://backend;
        }

        # 默认拒绝
        return 403;
    }
}

7. 高级GeoIP变量

Nginx GeoIP模块提供了许多有用的变量:

  • $geoip_country_code - 国家代码(如US, CN)
  • $geoip_country_name - 国家名称
  • $geoip_city - 城市名称
  • $geoip_region - 地区/州代码
  • $geoip_region_name - 地区/州名称
  • $geoip_latitude - 纬度
  • $geoip_longitude - 经度
  • $geoip_postal_code - 邮政编码

8. 性能优化建议

  1. 将GeoIP数据库加载到内存中:
geoip_country /usr/share/GeoIP/GeoIP.dat memory;
geoip_city /usr/share/GeoIP/GeoLiteCity.dat memory;
  1. 定期更新GeoIP数据库(建议每月更新)

  2. 对于高流量网站,考虑使用CDN的GeoIP功能替代

9. 完整示例配置

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

    map $geoip_country_code $allowed_country {
        default no;
        US yes;
        CA yes;
        GB yes;
        DE yes;
        FR yes;
        JP yes;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($allowed_country = no) {
                return 403 "Access denied for your country";
            }

            # 额外城市限制
            if ($geoip_city = "Moscow") {
                return 403 "Access denied for this city";
            }

            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

10. 测试与验证

  1. 使用不同地区的VPN或代理服务器测试访问
  2. 检查Nginx错误日志:tail -f /var/log/nginx/error.log
  3. 使用curl测试:
curl -I http://example.com

通过以上配置,您可以灵活地基于地理位置控制对反向代理后端的访问。