phpenv无内置域名黑名单功能,须在nginx.conf的http块中用map定义$bad_domain变量,再于各server块顶部用if($bad_domain){return 444;}实现拦截,注意正则转义、大小写忽略及配置位置。

直接说结论:phpEnv 没有内置“域名黑名单”功能,也不能像宝塔那样点选配置;必须手动编辑 Nginx 配置文件,在 http 块中用 map 定义变量,再在 server 块顶部用 if + return 444 实现稳定拦截 —— 其他写法(比如在 location 里用 if ($host ~ ...))大概率失效。
为什么不能在 server 块里直接 if 匹配 $host
phpEnv 的 Nginx 默认配置里,$host 在 server 上下文中行为不可靠:它可能被解析为 IP 直连时的空值、带端口(如 evil.com:443)、大小写混杂,甚至因请求头顺序问题根本没触发。更关键的是,phpEnv 不默认开启 underscores_in_headers on,攻击者发个带下划线的 Host: evil_com 就能绕过正则匹配。
常见错误现象:
- 浏览器访问显示正常,但用
curl -H "Host: evil.com" http://your-ip却能成功 - 规则加在
location /内,结果/static/logo.png能访问,但/api/test.php却没被拦截 - 配置保存后 Nginx 启动失败,报错
"if" directive is not allowed here(误把 map 写进了 server 块)
正确做法:http 块定义 map,server 块顶部 return
必须把 map 放到全局 http 块里(即 /phpenv/nginx/conf/nginx.conf 文件最外层的 http { ... } 内),不能塞进 server 或 location。匹配要覆盖常见变体:
- 用
~*忽略大小写 - 点号必须转义:
evil\.com,不是evil.com - 加上端口可选分组:
(:[0-9]+)? - 用
default 0保证未匹配域名不触发拦截
示例(加在 nginx.conf 的 http 块末尾):
map $host $bad_domain {
default 0;
~* ^evil\.com(:[0-9]+)?$ 1;
~* ^malware\-site\.org$ 1;
}
然后在你要保护的每个 server 块最开头(root、location 之前)插入:
if ($bad_domain) {
return 444;
}
phpEnv 下修改配置的实际路径和验证要点
phpEnv 的 Nginx 配置主文件固定在:/phpenv/nginx/conf/nginx.conf。注意:
- 不要改
/phpenv/nginx/vhosts/下的站点配置 —— 那些是自动生成的,重启 phpEnv 会覆盖 - 改完必须执行:
/phpenv/nginx/sbin/nginx -t校验语法,再/phpenv/nginx/sbin/nginx -s reload - 验证别只用浏览器:用
curl -I -H "Host: evil.com" http://127.0.0.1看响应头是否为HTTP/1.1 444 - 如果用了反向代理(如前端套了另一层 Nginx),需确认
$host是真实传入的,否则得依赖$http_host并确保上游透传
真正容易被忽略的点是:phpEnv 的 Nginx 编译默认不启用 geo 或 realip 模块,所以没法用 geo 做 IP 分组;所有域名级拦截只能靠 map + $host 这一套,且必须写对位置、转义和正则边界。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











