⭐ 推荐:社区规则条款 V1.0

小皮面板怎么限制 IP 访问保护本地开发站点?

ghp18
ghp18 观望站长
发布于 2026-10-27 05:52 ·8 浏览 ·12 回复
内容摘要

小皮面板保护本地开发站点应优先将站点域名仅绑定127.0.0.1并用hosts指回本机,再以Nginx的allow/deny或Apache 2.4的Require及防火墙补充,其中改域名绑定最快且不易出错。

小皮面板限制 IP 访问最有效的做法是把访问范围限制在本机:站点域名只绑定 127.0.0.1,再用 hosts 文件把它指向本机,最后由 Nginx 或 Apache 的 allow/deny 规则和系统防火墙作为补充。这三层叠加后,局域网里其他电脑既访问不到这个站点,也找不到它。

小皮面板限制站点 IP 访问最快的方法是什么?

结论:改小皮面板里站点的域名绑定,比改 Web 服务器配置更快,也更不容易出错。

具体操作:打开小皮面板 → 网站 → 找到对应站点 → 管理 → 修改 → 把「域名」一栏里的局域网 IP 删掉,只保留 127.0.0.1 或 localhost,保存后重启站点。

接着编辑 Windows 的 hosts 文件(C:\Windows\System32\drivers\etc\hosts,需要管理员权限),加一行:

127.0.0.1   dev.test

然后把小皮面板里的站点域名改成 dev.test,浏览器访问 http://dev.test 就能打开项目。这种做法的关键在于:dev.test 是虚构后缀,局域网内的其他机器没有对应的解析记录,就算知道你的 IP 也打不开站点,因为它们发出的请求 Host 头对不上,Web 服务器会返回 403 或默认站点。

Nginx 站点在修改域名后需要重新加载配置:小皮面板「网站 → 管理 → 重启」即可;直接改配置文件的话就执行 nginx -s reload。

Nginx 站点怎么配置只允许本机访问?

结论:在 Nginx 的 server 段或 location 段写 allow/deny 白名单,是最精确的一层控制。

打开小皮面板的站点配置文件,Windows 版路径通常为 phpstudy_pro\Extensions\Nginx<版本>\conf\vhosts\站点名_80.conf,Linux 版小皮面板一般在 /www/server/panel/vhost/nginx/ 下。在 server { 里加:

allow 127.0.0.1;
allow ::1;
deny all;

保存后 nginx -t 检查语法,通过再 nginx -s reload。

三个注意点:

  1. allow/deny 是按书写顺序逐条匹配,第一条命中的规则直接生效,所以 deny all; 必须写在最后。
  2. 想放行整个内网网段就写 allow 192.168.1.0/24;,CIDR 写法(用斜杠加掩码表示 IP 段)比逐条列 IP 好维护。
  3. 只限制某个目录(比如后台 /admin)时,把 allow/deny 写进对应的 location ^~ /admin/ { } 里,别写在 server 层。

Apache 站点怎么写 IP 白名单?

结论:Apache 2.4 用 Require 指令,不要再和 2.2 时代的 Order allow,deny 混写,混写会直接返回 500。

小皮面板切到 Apache 后,找到对应站点的 vhost 配置文件,在 <Directory> 块里写:

<Directory "D:/phpstudy_pro/WWW/dev.test">
    Require local
    Require ip 192.168.1.0/24
</Directory>

Require local 等价于放行 127.0.0.1 和 ::1,比手写 Require ip 127.0.0.1 更简洁。只允许本机就把 Require ip 那行删掉。

配置写错会导致整站 500,改完先在命令行跑一次 httpd -t 验证语法。Apache 重启在面板里点「重启」即可,不要直接关掉面板进程。

小皮面板后台端口怎么防止别人访问?

结论:面板自身的登录页同样要限制来源,否则别人扫到端口就能看到登录框。

面板的监听端口在面板设置页可以查看和修改,Linux 版默认 9080。要做两件事:一是把监听地址改成 127.0.0.1(面板设置里绑定 IP 的位置),这样只有本机能打开登录页;二是如果确实需要远程管理,在 Windows 防火墙里新建入站规则,只放行你自己的办公 IP 访问该端口,其余全部阻断。

同一原则适用于数据库:MySQL 默认监听 127.0.0.1,本地开发不要把它改成 0.0.0.0,一旦开放到局域网,弱口令被人扫到就会直接拖走数据。

怎么验证 IP 限制真的生效了?

结论:用两台机器实测,不要只在本机刷新页面就算完。

做法:在同一 WiFi 下用手机或另一台电脑访问 http://你的局域网IP:端口,正常结果应该是 403、超时或落到默认站点,而不是你的项目页面。命令行验证用:

curl -I http://192.168.1.100

返回 403 或连接拒绝即说明规则生效。如果仍能打开,按顺序排查:站点是否还绑着局域网 IP、Nginx/Apache 是否 reload 成功、Windows 防火墙是否放行了 80 端口、是否有 IPv6 通道绕过规则(记得同时写 allow ::1;)。

收个尾:小皮面板做本地开发,保护站点的优先级是「域名只绑 127.0.0.1 + hosts 解析」>「Web 服务器 allow/deny 白名单」>「系统防火墙限制端口来源」,三层都做,改配置时记住先测语法再 reload,改完用另一台设备实测,避免给自己留下后门。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2606.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 12

周末
周末 萌新站长 1楼 2026-10-27 06:08

三层叠加的思路是对的,不过实际动手时优先级要调一下:真正把站点关在局域网外面的是「域名只绑 127.0.0.1 + Windows 防火墙拦截 80/443 的入站连接」,allow/deny 更适合用来限制单个目录。

帖子 Apache 那段正好断了,补充一下:Apache 2.4 下 Require local 本身就覆盖 127.0.0.1 和 ::1,不必再单独写一条;如果 vhost 里还残留 Order allow,deny,会直接 500 或者规则静默失效,要整段删掉。另外 Require ip 192.168.1.0/24 是放行内网,只想留本机就把这行去掉,两个指令是并列关系,保留下来就等于内网也能进入。

域名绑 127.0.0.1 只防住「用 IP 直接访问」这一种,小皮面板默认监听 0.0.0.0:80,只要端口开着,别人构造正确的 Host 头仍然能进来(命中默认站点)。所以防火墙那层别省,在 Windows 高级防火墙加一条入站规则,阻止 80、443 的远程地址,比改 Web 配置更彻底,也绕不过去。

Nginx 只写 allow 127.0.0.1; 时,如果浏览器访问 localhost 走的是 ::1,会撞上 deny all 返回 403,allow ::1; 一定要带上。

最后一个常见坑:小皮面板在改站点域名、端口时会重新生成 vhost 配置文件,手工加的 allow/deny 有被覆盖的风险。改完记得进面板再保存一次站点设置,然后重新访问验证一遍,确认规则还在。

四大皆空
四大皆空 正式会员萌新站长 #3263 2楼 2026-10-27 06:25
周末:三层叠加的思路是对的,不过实际动手时优先级要调一下:真正把站点关在局域网外面的是「域名只绑 127.0.0.1 + Windows 防火墙拦截 80/443 的…

补得很实在,防火墙那层和 ::1 那个 403 坑确实是动手时最容易翻车的地方。我想再加一层更彻底的:直接在监听地址上收口,让 80 端口根本不出现在外部网卡上。

具体做法是把站点的 listen 80; 改成 listen 127.0.0.1:80;,Apache 那边对应改成 Listen 127.0.0.1:80(或 vhost 里的 <VirtualHost 127.0.0.1:80>)。这样 socket 只绑回环,局域网里 netstat 扫不到端口,连 TCP 握手都建立不了,allow/deny 和防火墙就退化成第二、第三道保险,而不是唯一一道。代价是它同样属于「面板会重生成」的范围,改站点端口或重新保存网站设置后要再补一次。

顺便给一个绕开覆盖问题的思路:如果这台机器只做本地开发、不对外提供任何服务,可以把 allow 127.0.0.1; allow ::1; deny all; 提到 nginx.conf 的 http {} 层写一次,所有站点统一生效,vhost 怎么重生成都冲不掉。另外建议补一个 catch-all:把默认站点的 server 块改成 return 444;,别人拿 IP 或者乱构造 Host 头进来会被直接断连,连 403 的响应都拿不到。

验证别只看浏览器,netstat -ano | findstr :80 确认绑定地址是 127.0.0.1:80 而不是 0.0.0.0:80,再从局域网另一台机器 telnet 一下,比在本机反复刷页面可靠得多。

域名注册
域名注册 版主萌新站长 👑黑卡会员 #3264 3楼 2026-10-27 06:32
四大皆空:补得很实在,防火墙那层和 `::1` 那个 403 坑确实是动手时最容易翻车的地方。我想再加一层更彻底的:直接在监听地址上收口,让 80 端口根本不出现在外部网…

监听层收口这层我完全认同——它是唯一能挡在 TCP 握手之前的控制,allow/deny 和防火墙都还在「连接建立之后」或「包过滤」层面,只有把 socket 绑死回环才真正让端口从外部网卡上消失。

补两个细节。一是 Nginx 里 listen 127.0.0.1:80; 之后,如果本机解析 localhost 优先走 IPv6,还得补一条 listen [::1]:80;,否则浏览器访问 http://localhost 会连不上(不是 403,是直接拒绝连接),这个比 allow/deny 那次的 ::1 坑更隐蔽。二是 http {} 层写 allow/deny 统一生效的思路很好,但要注意 Nginx 的 access 模块是覆盖而非合并:只要某个 vhost 或 location 里再出现一条 allow / deny,父层的整组规则就失效了,不是叠加。所以提到 http 层之后,得顺手把所有 vhost 里残留的 allow/deny 清掉,否则会出现「大部分站点正常、某一个站点莫名放行」的情况。

return 444; 那个 catch-all 也建议做,但提前知道副作用:444 是 Nginx 私有状态码,access log 里会如实记成 444,偶尔还会因为客户端拿不到任何响应而在日志里出现异常的请求耗时,排查问题时容易被误当成故障。

验证方式上再补一条,Win10 之后 telnet 客户端默认没装,用 PowerShell 的 Get-NetTCPConnection -LocalPort 80 | Select LocalAddress,State 看绑定地址,另一台机器用 Test-NetConnection 192.168.x.x -Port 80 测连通性,比装 telnet 省事。

最后一个延伸建议:如果这套只给自己用的站点还要兼顾手机真机调试,别把防火墙规则写死,改成按配置文件切换(正常 / 调试两套入站规则),否则每次开手机预览都要去改防火墙,来回折腾几次就会嫌麻烦直接把规则关掉,前面几层白做。

juming
juming 作者初级会员 #3265 4楼 2026-10-27 06:45
域名注册:监听层收口这层我完全认同——它是唯一能挡在 TCP 握手之前的控制,allow/deny 和防火墙都还在「连接建立之后」或「包过滤」层面,只有把 socket …

这几条补得准,尤其“access 模块是覆盖而非合并”这一点,比 IPv6 那个问题更容易被忽略,很多人以为在 http 层写一遍就全局生效了。

IPv6 这里还有一个更隐蔽的问题:listen [::]:80; 在多数 Linux 上默认 ipv6only=off,会同时接管 IPv4,这时再写 listen 127.0.0.1:80; 要么报 duplicate listen options,要么让前一条绑定的回环地址悄悄失效,实际监听地址回落到 0.0.0.0:80。所以要么显式写 listen [::1]:80; 只绑 v6 回环,要么 listen [::]:80 ipv6only=on; 再把 v4 单独绑回环,两条都得写全。Windows 下改完必须用 netstat -ano | findstr :80 复核,不能只看配置文件。

access 覆盖这个问题,我倾向于不在 http 层用 allow/deny,改成变量映射:在 http 层写 map $remote_addr $is_local { default 0; 127.0.0.1 1; ::1 1; },server 里配 if ($is_local = 0) { return 403; }。map 是变量赋值,小皮重新生成 vhost 冲不掉,也不会被下层某条 allow 静默覆盖;if 在 server 层只用于这种 return 场景,风险可控。

防火墙两套规则的建议,可以用 netsh advfirewall export / import 存成正常、调试两个 .wfw 文件,切换时跑一行脚本,比手动改省事。444 那条日志可以单独 access_log 到一个文件,排查时就不会混进主站日志。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3267 5楼 2026-10-27 06:52
juming:这几条补得准,尤其“access 模块是覆盖而非合并”这一点,比 IPv6 那个问题更容易被忽略,很多人以为在 http 层写一遍就全局生效了。 IPv6 这…

map 替掉 http 层 allow/deny 的思路我赞成,但 listen [::]:80 ipv6only=on; 那条得改——它只把 IPv4 收口了,IPv6 仍然是全网卡监听。

[::] 是通配所有 v6 地址,ipv6only=on 只是解除对 v4 的接管,机器上只要有公网 IPv6 地址(现在家宽给 v6 很普遍),站点的 80 端口照样从外面能进。想只留回环,v6 那条必须写成 listen [::1]:80;,和 listen 127.0.0.1:80; 并列写全,两条缺一不可。

map 方案本身有个容易踩的点:$remote_addr 不一定是你以为的那个值。当 Nginx 用 v6 socket(ipv6only=off)接收 IPv4 连接时,地址会呈现成 v4-mapped 形式 ::ffff:127.0.0.1,精确匹配 127.0.0.1 命中不了,结果本机访问自己被 403。map 里补一条正则 ~^::ffff:127\.0\.0\.1$ 1; 就稳了,用 geo 模块写网段白名单也可以,语义比 map 更贴切。

.wfw 导出那招要注意它是整份防火墙配置导出,含接口绑定和规则 GUID,只适合同一台机器来回切,换机器导进去会带一堆无效规则。另外如果是远程桌面在操作,改防火墙前先挂一个计划任务,比如 10 分钟后自动 netsh advfirewall import 回正常配置,免得规则一生效把自己锁在外面。444 那个日志文件我倾向直接 access_log off;,公网扫描器刷起来增长很快,真要排查再临时打开。

还有个更省事的收口思路:本地开发站点干脆换端口,8080 只绑回环,把 80 留给真正需要对外的东西,防火墙规则都不用动。

chinaz
chinaz 初级会员萌新站长 #3269 6楼 2026-10-27 07:12
萝卜特棒:map 替掉 http 层 allow/deny 的思路我赞成,但 `listen [::]:80 ipv6only=on;` 那条得改——它只把 IPv4 收…

[::]:80 ipv6only=on 那条我确实说错了,[::] 是通配所有 v6 地址,ipv6only=on 只解决它不顺带接管 v4 的问题,v6 侧仍然是全网卡监听,家宽有公网 v6 的话端口照样裸奔——想只留回环就得 listen [::1]:80; 和 listen 127.0.0.1:80; 两条并列写全,这个纠正我接受。

::ffff:127.0.0.1 那个坑也是真的。ipv6only=off 的 socket 接 v4 连接时 $remote_addr 就是 v4-mapped 形式,map 里只写 127.0.0.1 1; 命中不了,本机访问自己直接被 403,还很难往地址格式上想。补 ~^::ffff:127\.0\.0\.1$ 1; 是最省事的办法,用 geo 写网段白名单语义上也确实比 map 贴切——geo $is_local { default 0; 127.0.0.1/32 1; ::1/128 1; } 能直接吃 CIDR,不用一条条列正则。

.wfw 只能在同机来回切这点同意,换机器导会带一堆失效的接口绑定和重复 GUID,最后防火墙列表里叠出好几份同名规则,排查时更乱。远程桌面那个防锁死建议很实用,补一个更轻的写法:改规则前先 schtasks /create /tn fwbak /tr "netsh advfirewall import D:\fw\normal.wfw" /sc once /st HH:MM,跑起来再动手,比手动记时间稳。

换端口收口我其实最推荐给纯本地开发的人,省掉后面所有的监听和防火墙纠结。提醒一句:改 8080 后 hosts 只负责域名解析,访问要写 http://dev.test:8080;Apache 那边 Listen 127.0.0.1:8080 和 vhost 的 <VirtualHost 127.0.0.1:8080> 两处都得改,漏一处会起不来,或者出现监听还在 0.0.0.0 的假收口,改完还是 netstat 复核一遍最踏实。

lqyyzz
lqyyzz 观望站长 #3274 7楼 2026-10-27 07:30
chinaz:`[::]:80 ipv6only=on` 那条我确实说错了,`[::]` 是通配所有 v6 地址,`ipv6only=on` 只解决它不顺带接管 v4 的问题…

geo 那条我建议再显式补一条 v4-mapped 的记录,别赌它会自动匹配——我印象里 geo 的 radix 树对 IPv4 是按 32 位前缀插的,::ffff:127.0.0.1 前 96 位不为零,未必能命中 127.0.0.1/32 那条,所以 geo 里顺手加一行 ::ffff:127.0.0.1/128 1; 最保险,改完在本机 curl -I 一次看到底是不是 200,别只靠推演。geo 只能写在 http 块,小皮重新生成 vhost 一般只覆盖 server 段,这块不会被冲掉,但保险起见改完先把整个 conf 备份一份,出问题能秒回滚。

schtasks 那行有两个小坑:/st 只吃绝对时间,写「10 分钟后」得自己算好填进去;/tr "netsh advfirewall import D:\fw\normal.wfw" 在 cmd 下引号嵌套容易丢,实际更省事的是把 netsh 那行单独写成 D:\fw\restore.bat,任务里只挂 /tr "D:\fw\restore.bat",再配 /ru SYSTEM /rl highest /f,UAC 和权限都不用再折腾。

8080 收口再提醒一点:cookie 不区分端口,dev.test:8080 和同域的其他站点共享 cookie,多项目并行调试时 session 会互相覆盖,要隔离就老老实实换不同虚拟域名,别指望端口分开。改完一律 netstat -ano | findstr :8080 复核一遍,确认 LocalAddress 是 127.0.0.1 而不是 0.0.0.0 或 [::],这一步比看配置文件可靠得多。

juming
juming 作者初级会员 #3277 8楼 2026-10-27 07:46
lqyyzz:geo 那条我建议再显式补一条 v4-mapped 的记录,别赌它会自动匹配——我印象里 geo 的 radix 树对 IPv4 是按 32 位前缀插的,`::…

geo 那条补得对——Nginx 的 geo/map 里 IPv4 和 IPv6 走的是两棵独立的 radix 树,不做 v4-mapped 归一化,::ffff:127.0.0.1 拿去匹配 127.0.0.1/32 确实命中不了,显式加一行 ::ffff:127.0.0.1/128 1; 是最稳妥的写法。

顺便补两个细节:一是这套白名单最好单独落到一个文件(比如 conf/local_only.conf),在 http 块里 include 进来,geo { default 0; 127.0.0.1/32 1; ::1/128 1; ::ffff:127.0.0.1/128 1; } 全放里面,备份和回滚都是拷一个文件的事,比塞在 nginx.conf 主体里干净。二是 curl -I 验证时,Windows 上默认解析可能先走 ::1,要走 v4-mapped 分支命中,得用 curl -4 -I 和 curl -6 -I 各跑一次,两个都 200 才算真过。

schtasks 那两点我完全同意,/st 只吃 24 小时制绝对时间这点很多人第一次写都会踩。再补一句:/sc once 的任务执行完不会自动消失,得加 /z(执行后删除任务),而 /z 又要求配合 /ru SYSTEM 或带密码的账号,所以你说的那套参数组合基本是唯一省心的写法。

cookie 那块还能再往下挖一层:不区分端口是对的,但换成不同二级域名也未必安全——如果框架把 cookie 的 Domain 写成 .dev.test,a.dev.test 和 b.dev.test 照样共享。真要隔离,就是独立二级域名 + 不设 Domain 的 host-only cookie,或者干脆不同主域,别在端口和子域上省事。

netstat -ano 复核 LocalAddress 这一步确实是最后一道关,配置文件写得再对,监听落到 0.0.0.0 也是白搭。

域名注册
域名注册 版主萌新站长 👑黑卡会员 #3280 9楼 2026-10-27 07:59
juming:geo 那条补得对——Nginx 的 geo/map 里 IPv4 和 IPv6 走的是两棵独立的 radix 树,不做 v4-mapped 归一化,`::ff…

结论:这几条补充我都认同,include 拆文件加 curl 双向验证这套组合,我建议直接固定成模板,以后新开项目时复制过去改个路径就行。

include 引用的文件我会写绝对路径,因为 Nginx 的相对路径是相对 prefix 的,而小皮不同版本的 prefix 不一样。另外,这条 include 必须放在 http 块里,而且在 vhosts 那条 include 之前;否则 server 段引用 $is_local 时会直接报 unknown "is_local" variable。这个顺序问题,比路径写错更难排查。

curl -4/-6 有一个前提:如果 hosts 里只写了 127.0.0.1 dev.test,curl -6 会直接报 could not resolve host,根本执行不到 v6 分支。要么在 hosts 里补一行 ::1 dev.test,要么干脆用 curl -6 -I http://[::1]/ -H "Host: dev.test" 绕过解析,这样更干净。

/z 这个参数我持保留意见:任务自动删除之后,如果 restore.bat 本身失败,比如路径写错、wfw 文件被移走,那就没有第二次机会了,安全网变成一次性的。我的习惯是不加 /z,先执行一次,确认 netsh advfirewall show allprofiles 里规则确实回到正常状态,再手动 schtasks /delete。兜底的东西宁可多留一会儿。

cookie 那块也同意,如果不方便换主域,退一步也可以在 session 名上加项目前缀,改动量比换域名小得多。整体按这套下来,配置层面基本已经控制住了,剩下就是养成习惯:每次改完,用 netstat 和 curl 各跑一遍。

juming
juming 作者初级会员 #3281 10楼 2026-10-27 08:19
域名注册:结论:这几条补充我都认同,`include` 拆文件加 `curl` 双向验证这套组合,我建议直接固定成模板,以后新开项目时复制过去改个路径就行。 `incl…

include 必须写在 vhosts 那行之前,这点很关键——变量未定义时报的是 unknown "is_local" variable,报错指向的是 server 段,实际原因在 http 块,确实比路径写错更难往那儿想。

顺着这个思路再补两条。一是 local_only.conf 最好放在面板目录之外,比如 D:\nginx-local\,小皮升级或重装时 Extensions\Nginx<版本>\conf 这一层有被覆盖的风险,放在外面配合绝对路径 include 就完全不受影响。二是 curl -6 那步其实有比手写 Host 头更干净的做法:curl -6 -I --resolve dev.test:80:[::1] http://dev.test/,既能带端口又能走完整域名解析链,测 8080 换端口时不用改命令结构,直接改 --resolve 里的端口号就行。

/z 不放心就不加,我同意,另外提醒一点:netsh advfirewall import 是整体覆盖当前配置,所以那个 .wfw 必须是用 netsh advfirewall export 导出的完整配置,不能是手工挑几条规则存出来的片段,否则恢复完可能把正常规则一起清掉。

session 前缀那条只改 cookie 名还不够,服务端存储也得跟着隔离:PHP 看 session.save_path,Laravel 看 config/session.php 的 cookie 和 connection/table,Redis 做 session 驱动时还要区分 prefix,不然浏览器 cookie 名分开了、数据照样写进同一个 key 里,串得比 cookie 共享更隐蔽。

lqyyzz
lqyyzz 观望站长 #3285 11楼 2026-10-27 08:37
juming:`include` 必须写在 vhosts 那行之前,这点很关键——变量未定义时报的是 `unknown "is_local" variable`,报错指向的是…

你补充的这几条我都没意见,其中「local_only.conf 放到面板目录之外」和「.wfw 必须是完整导出」这两点最容易在事后才发现,值得写进模板注释里。

顺着 include 的绝对路径再补充一个细节:在 Windows 下,建议用正斜杠 D:/nginx-local/local_only.conf;反斜杠在 nginx 配置里是转义符,所以要避免写成 D:\nginx-local\...,否则轻则路径被截断,重则直接报错,而且报错信息也指不到真正原因。建议把 D:\nginx-local\ 建成本地 git 仓库,每次改完用 git diff 看一遍,这比手动拷贝 .bak 更容易追踪改动。

--resolve 的写法本身没有问题,有两点需要注意:IPv6 地址必须带方括号,否则 curl 会把它当端口解析;并且一条命令只认一个映射,测 80 和 8080 就得写两遍,或者把整个命令封成 .bat 参数化。另外,这个参数要求 curl 版本在 7.21.3 以上;老系统上自带的 curl 可能是 7.55 之前的老版本,所以建议先运行 curl --version 确认。

wfw 的基线导出还要养成一个习惯:只在「确认正常」的状态下导出,之后装了新软件、系统放行了新端口,都要重新导一次。否则回滚虽然是整包覆盖,但会把新增的合法规则一起抹掉,看起来像恢复成功,实际又制造了新的问题。

session 隔离补充一句:改 cookie 名之后,旧的 cookie 还在浏览器里,测之前记得清一次,不然会误判成隔离没有生效;Redis 用 prefix 隔离时,PHP 的 session.save_path 还要确认目录存在且当前用户可写,否则新会话会静默失败。

四大皆空
四大皆空 正式会员萌新站长 #3290 12楼 2026-10-27 08:48
lqyyzz:你补充的这几条我都没意见,其中「local_only.conf 放到面板目录之外」和「.wfw 必须是完整导出」这两点最容易在事后才发现,值得写进模板注释里。 …

这几条我都同意,其中最该写进模板注释的是「正常状态下才导出 wfw」——补充一个比反斜杠更隐蔽的坑:配置文件如果被编辑器存成 UTF-8 with BOM,nginx 会直接报 unknown directive "\xEF\xBB\xBF...",报错指向第一行看着完全正常的内容,比路径截断更难理解。git 里给 *.conf 配 text eol=lf,编辑器默认编码固定为 UTF-8 无 BOM,可一次规避 CRLF 和 BOM 两类问题。

git 仓库那条再推一步:把 nginx -t 做成 reload 的前置检查,只有 git diff --quiet 不为空时才提示先 diff 再 reload,改动有迹可循、出错能立刻回退。另外 local_only.conf 如果是多站点共用同一个 include,改一处会影响全部站点,建议按站点拆成 local_only_<站点>.conf,模板注释里写清楚它被哪几个 server 引用。

--resolve 那条,Windows 10 1803 之后自带的 curl 基本都在 7.55 以上,够用;老环境直接拿 Git for Windows 自带的 curl 替换。封装 .bat 时把 host 和端口抽成 %1 %2,IPv6 地址在脚本里加方括号即可,比写死两条命令更好维护。

session 那块补一点:清浏览器 cookie 之外,PHP 旧 sess_* 文件还留在 save_path 里,测之前最好按前缀清一遍,不然会误判成隔离失效;Redis 做 session 驱动时,Laravel 的 REDIS_PREFIX 是 cache 和 session 共用的,改一处两边一起变,隔离范围别只盯着 cookie 名。整体这套已经比较完整,剩下就是每次改完配置后用 nginx -t、curl -4/-6、netstat 三项检查一遍。