必须解耦时间判断与访问控制:推荐 cron+标记文件(每分钟更新 /tmp/allow_admin)、openresty+lua(毫秒级实时判断)、或 auth_request 委托后端服务;需确保系统时间同步,避免滥用 if,测试用 curl -i 验证状态码。

不能靠 Nginx 原生配置直接写“9点到18点放行”,必须把时间判断和访问开关解耦——核心是让 Nginx 在运行时能感知当前是否处于允许时段,并据此决定是否拦截请求。
用 cron + 标记文件做轻量级开关
这是最稳定、无需额外模块、适合大多数生产环境的做法:
- 写一个 shell 脚本(如 /opt/nginx-time-switch.sh),根据当前时间判断是否在允许窗口(例如工作日 08:00–18:00),然后创建或删除 /tmp/allow_admin 文件
- 用 crontab 每分钟执行一次该脚本,确保状态实时更新
- 在 Nginx 配置中用 map + try_files 判断该文件是否存在:
map $uri $is_allowed {
default 0;
~^/admin/ 1;
}
map $is_allowed $allow_flag {
0 0;
1 "";
}
再在 location 中:
location /admin/ {
try_files /tmp/allow_admin @deny;
proxy_pass http://backend;
}
location @deny { return 403; }
用 OpenResty + Lua 解析真实时间
如果已部署 OpenResty,可直接在 access 阶段做毫秒级判断,逻辑更清晰、无文件 I/O 依赖:
- 在 location 中添加:
access_by_lua_block {
local now = os.date("*t")
if now.hour = 18 or now.wday == 1 or now.wday == 7 then
ngx.exit(403)
end
} - 支持精确到分钟、跳过节假日(需配合外部日历 API 或本地 JSON 文件)、自动适配系统时区
- 修改后无需 reload,Lua 代码热生效
用 auth_request 委托外部服务决策
适合权限规则复杂、需与业务系统联动的场景(如审批流、值班表、临时授权):
- 写一个内部 HTTP 接口(如 http://127.0.0.1:8000/time-check),接收请求路径、客户端 IP、当前时间等参数,返回 200(允许)或 403(拒绝)
- Nginx 配置中启用:
location /admin/ {
auth_request /_time_auth;
auth_request_set $auth_status $upstream_status;
proxy_pass http://backend;
}
location = /_time_auth {
proxy_pass http://127.0.0.1:8000/time-check;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
} - 所有时间策略集中在后端服务中维护,Nginx 只负责转发和拦截
注意事项
无论选哪种方式,都要注意:
- 确保服务器系统时间准确(建议开启 chronyd 或 ntpd 同步);当前是 2026年9月4日星期五,若配置按“工作日”判断,需确认周末逻辑是否覆盖周五晚与周一早的边界
- 避免在 location 中滥用 if(尤其搭配 return 或 rewrite),优先用 map、auth_request 或 Lua 替代
- 测试时用 curl -I 检查响应头中的 Status,不要仅凭页面是否打开判断,因为 403 和 404 表现可能相似











