查看: 21  |  回复: 0
  nginx 基于 IP 地址的地理位置判断
楼主
发表于 2026年1月14日 15:30

基于 IP 地址的地理位置判断,将中国 IP 段的请求转发到国内 DNS,美国 IP 段的请求转发到美国 DNS。

nginx.conf 中的部分代码:

# Nginx基于IP地理位置的DNS路由配置
# 根据客户端IP地址自动选择最优DNS服务器

stream {
    # ========================================================
    # 方法1:使用Nginx内置的geo模块(推荐)
    # ========================================================
    # geo模块专门用于基于IP地址的变量赋值
    geo $client_country {
        default global;  # 默认使用全球DNS
       
        # 中国IP地址段(部分示例)
        # APNIC分配给中国的主要IP段
        1.0.0.0/8        CN;
        2.0.0.0/8        CN;
        3.0.0.0/8        CN;
        4.0.0.0/8        CN;
        5.0.0.0/8        CN;
        6.0.0.0/8        CN;
        7.0.0.0/8        CN;
        8.0.0.0/8        CN;
        9.0.0.0/8        CN;
        10.0.0.0/8       CN;  # 私有地址,但通常在中国网络内
       
        # 中国电信IP段
        58.0.0.0/8       CN;
        59.0.0.0/8       CN;
        60.0.0.0/8       CN;
        113.0.0.0/8      CN;
        114.0.0.0/8      CN;
        115.0.0.0/8      CN;
        116.0.0.0/8      CN;
        117.0.0.0/8      CN;
        118.0.0.0/8      CN;
        119.0.0.0/8      CN;
        120.0.0.0/8      CN;
        121.0.0.0/8      CN;
        122.0.0.0/8      CN;
        123.0.0.0/8      CN;
       
        # 中国联通IP段
        101.0.0.0/8      CN;
        102.0.0.0/8      CN;
        103.0.0.0/8      CN;
        106.0.0.0/8      CN;
        107.0.0.0/8      CN;
        108.0.0.0/8      CN;
        109.0.0.0/8      CN;
        110.0.0.0/8      CN;
        111.0.0.0/8      CN;
        112.0.0.0/8      CN;
       
        # 中国移动IP段
        117.0.0.0/8      CN;  # 与电信重叠
        118.0.0.0/8      CN;  # 与电信重叠
        119.0.0.0/8      CN;  # 与电信重叠
        120.0.0.0/8      CN;  # 与电信重叠
        121.0.0.0/8      CN;  # 与电信重叠
        122.0.0.0/8      CN;  # 与电信重叠
        123.0.0.0/8      CN;  # 与电信重叠
        124.0.0.0/8      CN;
        125.0.0.0/8      CN;
        126.0.0.0/8      CN;
        134.0.0.0/8      CN;
        135.0.0.0/8      CN;
        136.0.0.0/8      CN;
        137.0.0.0/8      CN;
        138.0.0.0/8      CN;
        139.0.0.0/8      CN;
       
        # 美国IP地址段(部分示例)
        # ARIN分配给美国的主要IP段
        64.0.0.0/8       US;
        65.0.0.0/8       US;
        66.0.0.0/8       US;
        67.0.0.0/8       US;
        68.0.0.0/8       US;
        69.0.0.0/8       US;
        70.0.0.0/8       US;
        71.0.0.0/8       US;
        72.0.0.0/8       US;
        73.0.0.0/8       US;
        74.0.0.0/8       US;
        75.0.0.0/8       US;
        76.0.0.0/8       US;
        77.0.0.0/8       US;
        78.0.0.0/8       US;
        79.0.0.0/8       US;
        80.0.0.0/8       US;
        81.0.0.0/8       US;
        82.0.0.0/8       US;
        83.0.0.0/8       US;
        84.0.0.0/8       US;
        85.0.0.0/8       US;
        86.0.0.0/8       US;
        87.0.0.0/8       US;
        88.0.0.0/8       US;
        89.0.0.0/8       US;
        90.0.0.0/8       US;
        91.0.0.0/8       US;
        92.0.0.0/8       US;
        93.0.0.0/8       US;
        94.0.0.0/8       US;
        95.0.0.0/8       US;
        96.0.0.0/8       US;
        97.0.0.0/8       US;
        98.0.0.0/8       US;
        99.0.0.0/8       US;
        100.0.0.0/8      US;
        101.0.0.0/8      US;  # 与中国联通重叠
        102.0.0.0/8      US;  # 与中国联通重叠
       
        # 主要云服务商IP段
        172.16.0.0/12    US;  # AWS私有地址
        10.0.0.0/8       US;  # 私有地址,但常用于美国云服务
    }
   
    # 根据国家选择DNS服务器池
    map $client_country $dns_pool {
        CN      dns_cn;      # 中国IP使用国内DNS
        US      dns_us;      # 美国IP使用美国DNS
        default dns_global;  # 其他国家使用全球DNS
    }
   
    # ========================================================
    # 方法2:使用map模块的正则表达式匹配(备用方案)
    # ========================================================
    # 这种方法更灵活,但性能略低于geo模块
    map $remote_addr $dns_pool_regex {
        # 中国IP段正则匹配
        ~^1\.\d+\.\d+\.\d+$      dns_cn;  # 1.0.0.0/8
        ~^2\.\d+\.\d+\.\d+$      dns_cn;  # 2.0.0.0/8
        ~^3\.\d+\.\d+\.\d+$      dns_cn;  # 3.0.0.0/8
        ~^4\.\d+\.\d+\.\d+$      dns_cn;  # 4.0.0.0/8
        ~^5\.\d+\.\d+\.\d+$      dns_cn;  # 5.0.0.0/8
        ~^11[3-9]\.\d+\.\d+\.\d+$ dns_cn;  # 113.0.0.0/8 - 119.0.0.0/8
        ~^12[0-9]\.\d+\.\d+\.\d+$ dns_cn;  # 120.0.0.0/8 - 129.0.0.0/8
        ~^10[1-3]\.\d+\.\d+\.\d+$ dns_cn;  # 101.0.0.0/8 - 103.0.0.0/8
       
        # 美国IP段正则匹配
        ~^6[4-9]\.\d+\.\d+\.\d+$ dns_us;   # 64.0.0.0/8 - 69.0.0.0/8
        ~^7[0-9]\.\d+\.\d+\.\d+$ dns_us;   # 70.0.0.0/8 - 79.0.0.0/8
        ~^8[0-9]\.\d+\.\d+\.\d+$ dns_us;   # 80.0.0.0/8 - 89.0.0.0/8
        ~^9[0-9]\.\d+\.\d+\.\d+$ dns_us;   # 90.0.0.0/8 - 99.0.0.0/8
       
        # 默认使用全球DNS
        default dns_global;
    }
   
    # ========================================================
    # DNS服务器池定义
    # ========================================================
    # 国内DNS服务器池
    upstream dns_cn {
        least_conn;  # 使用最少连接负载均衡
       
        # 中国大陆DNS服务器
        server 223.5.5.5:53 max_fails=3 fail_timeout=30s;    # 阿里云DNS
        server 223.6.6.6:53 max_fails=3 fail_timeout=30s;    # 阿里云DNS备用
        server 119.29.29.29:53 max_fails=3 fail_timeout=30s; # 腾讯云DNS
        server 182.254.116.116:53 max_fails=3 fail_timeout=30s; # 腾讯云DNS备用
        server 180.76.76.76:53 max_fails=3 fail_timeout=30s; # 百度DNS
        server 114.114.114.114:53 max_fails=3 fail_timeout=30s; # 114DNS
        server 114.114.115.115:53 max_fails=3 fail_timeout=30s; # 114DNS备用
       
        # 备用服务器
        server 8.8.8.8:53 backup;  # 谷歌DNS作为备用
    }
   
    # 美国DNS服务器池
    upstream dns_us {
        least_conn;  # 使用最少连接负载均衡
       
        # 美国DNS服务器
        server 8.8.8.8:53 max_fails=3 fail_timeout=30s;      # 谷歌DNS
        server 8.8.4.4:53 max_fails=3 fail_timeout=30s;      # 谷歌DNS备用
        server 1.1.1.1:53 max_fails=3 fail_timeout=30s;      # Cloudflare DNS
        server 1.0.0.1:53 max_fails=3 fail_timeout=30s;      # Cloudflare DNS备用
        server 9.9.9.9:53 max_fails=3 fail_timeout=30s;      # Quad9 DNS
        server 149.112.112.112:53 max_fails=3 fail_timeout=30s; # Quad9 DNS备用
        server 208.67.222.222:53 max_fails=3 fail_timeout=30s; # OpenDNS
        server 208.67.220.220:53 max_fails=3 fail_timeout=30s; # OpenDNS备用
       
        # 备用服务器
        server 223.5.5.5:53 backup;  # 阿里云DNS作为备用
    }
   
    # 全球DNS服务器池(默认)
    upstream dns_global {
        least_conn;  # 使用最少连接负载均衡
       
        # 全球通用DNS服务器
        server 8.8.8.8:53 max_fails=3 fail_timeout=30s;      # 谷歌DNS
        server 1.1.1.1:53 max_fails=3 fail_timeout=30s;      # Cloudflare DNS
        server 9.9.9.9:53 max_fails=3 fail_timeout=30s;      # Quad9 DNS
        server 223.5.5.5:53 max_fails=3 fail_timeout=30s;    # 阿里云DNS
        server 119.29.29.29:53 max_fails=3 fail_timeout=30s; # 腾讯云DNS
    }
   
    # ========================================================
    # DNS代理服务器配置
    # ========================================================
    # DNS UDP代理(主要)
    server {
        listen 53 udp;
        proxy_pass $dns_pool;  # 使用geo模块的结果
        # proxy_pass $dns_pool_regex;  # 使用正则表达式的结果
       
        proxy_timeout 10s;
        proxy_responses 1;
        proxy_buffer_size 16k;
       
        # 故障转移配置
        proxy_next_upstream error timeout;
        proxy_next_upstream_tries 2;
       
        # 访问日志(记录国家信息便于调试)
        # access_log c:/nginx/logs/dns_udp_access.log '$remote_addr - $client_country - [$time_local] $protocol $status $bytes_sent $bytes_received';
        # error_log c:/nginx/logs/dns_udp_error.log info;
    }
   
    # DNS TCP代理(辅助)
    server {
        listen 53;
        proxy_pass $dns_pool;
        proxy_timeout 10s;
       
        # 故障转移配置
        proxy_next_upstream error timeout;
        proxy_next_upstream_tries 2;
       
        # access_log c:/nginx/logs/dns_tcp_access.log '$remote_addr - $client_country - [$time_local] $protocol $status $bytes_sent $bytes_received';
    }
   
    # ========================================================
    # 调试信息输出(可选)
    # ========================================================
    # 用于测试IP地理位置判断是否正确
    server {
        listen 8080;
       
        return 'Client IP: $remote_addr\nCountry: $client_country\nDNS Pool: $dns_pool\n';
    }
}

# ========================================================
# IP地址判断方法说明
# ========================================================
# 1. GEO模块方法(推荐)
#    - 性能最好,专为IP地址匹配设计
#    - 支持CIDR格式(如 1.0.0.0/8)
#    - 支持从文件加载IP段(geo $client_country { include /path/to/geo.conf; })
#
# 2. MAP模块正则表达式方法
#    - 更灵活,支持复杂的正则匹配
#    - 性能略低于geo模块
#    - 适合需要更复杂匹配规则的场景
#
# 3. 外部GeoIP数据库方法(企业级方案)
#    - 使用MaxMind GeoIP2数据库
#    - 需要编译Nginx时添加--with-http_geoip2_module
#    - 配置示例:
#      geoip2 /path/to/GeoLite2-Country.mmdb {
#          $geoip2_country_code country iso_code;
#      }
#      map $geoip2_country_code $dns_pool {
#          CN dns_cn;
#          US dns_us;
#          default dns_global;
#      }
# ========================================================

# ========================================================
# 维护和更新建议
# ========================================================
# 1. IP地址段会定期更新,建议定期检查和更新
# 2. 可以从APNIC、ARIN等RIR获取最新的IP分配信息
# 3. 对于生产环境,建议使用专业的GeoIP数据库服务
# 4. 定期测试不同地区的DNS解析效果
# 5. 监控各DNS服务器的响应时间和成功率
# ========================================================


您需要登录后才可以回帖 登录 | 立即注册
【本版规则】请勿发表违反国家法律的内容,否则会被冻结账号和删贴。
用户名: 立即注册
密码:
2020-2026 MaNongKu.com