插件窝 干货文章 Nginx反向代理中基于IP地址和地理位置的ACL配置

Nginx反向代理中基于IP地址和地理位置的ACL配置

country GeoIP http allowed 258    来源:    2025-04-20

Nginx反向代理中基于IP地址和地理位置的ACL配置

基于IP地址的ACL配置

1. 基本IP访问控制

http {
    # 定义允许访问的IP列表
    geo $allowed_ip {
        default 0;
        192.168.1.0/24 1;
        10.0.0.1 1;
    }

    server {
        listen 80;

        location / {
            if ($allowed_ip = 0) {
                return 403;
            }
            proxy_pass http://backend;
        }
    }
}

2. 使用allow/deny指令

location /admin {
    allow 192.168.1.100;
    allow 10.0.0.0/8;
    deny all;

    proxy_pass http://backend;
}

3. 使用map模块进行更复杂的IP匹配

http {
    map $remote_addr $ip_acl {
        default "deny";
        "192.168.1.1" "allow";
        "10.0.0.0/8" "allow";
    }

    server {
        listen 80;

        location / {
            if ($ip_acl = "deny") {
                return 403;
            }
            proxy_pass http://backend;
        }
    }
}

基于地理位置的ACL配置

1. 安装GeoIP模块

首先需要确保Nginx编译时包含了--with-http_geoip_module选项,并安装GeoIP数据库。

2. 基本地理位置配置

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

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

    server {
        listen 80;

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

3. 使用GeoIP2模块(更现代的方式)

  1. 安装libmaxminddb和ngx_http_geoip2_module
  2. 配置示例:
http {
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_data_country_code country iso_code;
    }

    map $geoip2_data_country_code $allowed_country {
        default no;
        US yes;
        CA yes;
        GB yes;
    }

    server {
        listen 80;

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

4. 更复杂的地理位置规则

http {
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_data_country_code country iso_code;
        $geoip2_data_continent_code continent code;
    }

    map "$geoip2_data_continent_code:$geoip2_data_country_code" $region_acl {
        default "deny";
        "EU:DE" "allow";
        "NA:US" "allow";
        "AS:JP" "allow";
    }

    server {
        listen 80;

        location / {
            if ($region_acl = "deny") {
                return 403 "Access denied for your region";
            }
            proxy_pass http://backend;
        }
    }
}

组合IP和地理位置ACL

http {
    # IP ACL
    geo $allowed_ip {
        default 0;
        192.168.1.0/24 1;
    }

    # GeoIP ACL
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_data_country_code country iso_code;
    }

    map $geoip2_data_country_code $allowed_country {
        default 0;
        US 1;
        CA 1;
    }

    server {
        listen 80;

        location / {
            # 允许内部IP或来自允许国家的访问
            if ($allowed_ip = 0) {
                if ($allowed_country = 0) {
                    return 403;
                }
            }
            proxy_pass http://backend;
        }
    }
}

最佳实践

  1. 性能考虑:将频繁访问的IP放在geo/map块的顶部
  2. 维护性:将大型ACL列表放在单独文件中,使用include指令引入
  3. 日志记录:记录被拒绝的请求以便分析
  4. 定期更新:特别是GeoIP数据库需要定期更新
  5. 测试:在应用前充分测试ACL规则

通过以上配置,您可以灵活地控制Nginx反向代理的访问权限,基于IP地址或地理位置来允许或拒绝请求。