You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Nginx+Varnish栈的CMS时间与地理访问限制实现咨询

实现基于时间+地理位置的URL访问限制方案

嘿,针对你的CMS架构(Nginx→Varnish→Apache/PHP/MySQL)和访问限制需求,我推荐在Nginx层做处理——毕竟它是流量的第一道关卡,在这里拦截能最大程度减轻后端Varnish和Apache的压力,效率最高。下面是一步步的实现方案:

1. 配置Nginx的GeoIP2模块(识别地理位置)

首先需要让Nginx能识别请求的国家,推荐用GeoIP2模块(比旧版GeoIP更准确):

第一步:安装GeoIP2模块

如果你的Nginx是编译安装的,需要重新编译并加入--with-http_geoip2_module参数;如果是包管理器安装(比如Debian/Ubuntu的nginx-extras),直接安装对应的包即可。

第二步:配置GeoIP2数据库

下载MaxMind的GeoLite2-Country免费数据库(需要注册MaxMind账号获取),然后在Nginx的http块中配置:

http {
    # 加载GeoIP2模块(编译安装时如果已经加入,这行可以省略)
    load_module modules/ngx_http_geoip2_module.so;

    # 指定GeoIP2国家数据库路径
    geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        $geoip2_country_code country iso_code; # 得到两位国家代码,比如CN=中国,US=美国
    }
}

2. 定义需要限制的时间段

Nginx默认使用UTC时间,所以先把你要限制的本地时间段转换成UTC,然后用map指令匹配时间:
比如你要禁止北京时间10:00-18:00(对应UTC时间2:00-10:00),配置如下:

http {
    map $time_iso8601 $block_time {
        default 0; # 默认不限制
        # 匹配UTC时间的2:00到10:59:59
        ~^[0-9]{4}-[0-9]{2}-[0-9]{2}T(0[2-9]|10):[0-9]{2}:[0-9]{2}Z$ 1;
    }
}

3. 在Server块中配置URL级别的访问限制

针对你要保护的指定URL/分类(比如/restricted-category/开头的路径),在Nginx的server块中添加规则:

server {
    listen 443 ssl;
    server_name your-domain.com;

    # 你的SSL证书配置省略...

    # 匹配需要限制的URL/分类
    location ~ ^/restricted-category/ {
        # 规则:如果是目标国家(比如CN)+ 在禁止时间段内,返回403
        if ($geoip2_country_code = CN) {
            if ($block_time = 1) {
                return 403; # 或者跳转到提示页面,比如 return 302 /blocked-notice.html;
            }
        }

        # 其他情况,正常转发到Varnish(端口80)
        proxy_pass http://127.0.0.1:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 其他URL的正常转发配置
    location / {
        proxy_pass http://127.0.0.1:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

关键注意事项

  • 时区转换:一定要确认Nginx的时间是UTC,把你的本地时间段转换成UTC后再写正则。如果必须用本地时区,需要编译Nginx时加入Perl模块,用Perl脚本处理,但复杂度会提升,推荐优先用UTC转换。
  • 数据库更新:GeoLite2数据库需要定期更新(每月一次),可以写个定时任务脚本自动下载更新,保证国家识别的准确性。
  • 测试方法:用curl模拟目标国家的IP请求测试:
    # 模拟中国IP,在禁止时间段内请求限制URL
    curl -H "X-Forwarded-For: 114.114.114.114" https://your-domain.com/restricted-category/
    
  • 缓存影响:因为Nginx在入口就拦截了不符合规则的请求,这些请求根本不会到达Varnish,所以不会影响Varnish的正常缓存逻辑。

内容的提问来源于stack exchange,提问作者Imad Sani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:24:30