BLOG

Nginx站点配置中容易忽略的细节

Nginx 配置要保护源码目录,同时保证前台路由能正常转发。

分类:运维与部署 阅读:197
Nginx站点配置中容易忽略的细节示意图
Nginx站点配置中容易忽略的细节示意图

先分清要保护什么、要放行什么

Nginx 站点配置里,最容易出问题的不是某个指令写错,而是对“哪些路径必须挡、哪些路径必须放”没有形成清晰边界。PHP 项目通常只应该把 public 目录暴露给外部访问,appdatabasestoragetools 这些目录一旦被直接请求,就可能泄露源码、配置甚至备份文件。

但只做拦截还不够。前台路由依赖入口文件转发,如果规则顺序不对,拦截规则可能把正常请求也挡掉,或者伪静态失效,页面直接返回 404。配置的核心不是写一堆 location,而是让每条规则都回答一个问题:这个请求到底该交给谁处理。

配置前先确认三件事

动手改配置之前,先确认现有资料、最终用途和不能改动的部分。比如站点是否已有 HTTPS 证书、是否使用了反向代理、PHP 版本对应的 fastcgi 配置是哪种写法、是否有定时任务需要访问特定路径。这些信息决定了 location 规则怎么组织,也决定了改完以后要检查什么。

把工作拆成几个可以单独检查的步骤。每完成一项就能看到结果,而不是到最后才发现方向不对。通常按这个顺序处理:

  1. 先禁止访问敏感目录。
  2. 再让静态资源直接返回。
  3. 最后把不存在的路径统一交给入口文件。

这个顺序本身就是一个检查逻辑:拦截规则在最前面,静态资源规则次之,兜底转发放在最后。如果顺序颠倒,比如把 location / 的转发规则写在前面,后面的敏感目录拦截可能根本不会生效。

location 规则怎么组织才不容易出错

Nginx 的 location 匹配有优先级,不是按书写顺序从上到下执行。精确匹配(=)优先于前缀匹配(^~),前缀匹配优先于正则匹配(~~*),最后才是普通前缀匹配。很多人在这里出错,是因为写了多个 location 但没意识到它们之间的优先级关系。

一个常见的做法是,用 location ^~ 拦截敏感目录,确保这些路径不会被后面的正则规则接管:

```nginx
location ^~ /app/ { deny all; }
location ^~ /database/ { deny all; }
location ^~ /storage/ { deny all; }
location ^~ /tools/ { deny all; }
```

deny all 直接返回 403,比 return 404 更明确——404 会让人误以为路径不存在,而 403 明确表示“资源存在但不允许访问”。

静态资源单独处理。图片、CSS、JavaScript 文件不需要经过 PHP 解析,直接让 Nginx 返回文件即可,既减轻 PHP 进程负担,也避免这些请求落入转发规则:

```nginx
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff2?)$ {
expires 30d;
access_log off;
}
```

最后是前台路由的兜底转发。对于 ThinkPHP、Laravel 这类框架,通常需要把所有不存在的路径交给 index.php 处理:

```nginx
location / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}
```

try_files 的含义是:先尝试按请求的 URI 找真实文件,找不到就找目录,再找不到就转发给 index.php。这样伪静态规则由框架内部解析,Nginx 层不需要写死每个路由。

验证配置不能只看页面能不能打开

配置改完,先执行 nginx -t 检查语法,确认无误后 nginx -s reload 重载。但语法正确不代表行为正确,必须逐项验证:

  • 直接访问 https://你的域名/app/,应该返回 403。
  • 访问 https://你的域名/storage/logs/,同样应该被拒绝。
  • 访问一个不存在的伪静态路径,应该正常返回页面而不是 404。
  • 访问真实的静态资源文件,应该直接返回文件内容,响应头里能看到 Nginx 而不是 PHP 的处理痕迹。

换一个使用环境重新查看也很重要。页面要检查电脑和手机,服务器设置要检查日志和备份。只盯着浏览器看页面是否正常,很容易漏掉错误日志里反复出现的 403 或 500。

容易忽略的地方

只关注网站能打开,忽略错误日志、备份和磁盘空间,是运维里最常见的盲区。站点能访问不代表配置健康,错误日志里可能已经堆满了扫描器对敏感路径的探测记录,磁盘空间可能因为日志文件过大而告警。

把后台、上传目录和私有资源暴露给搜索引擎抓取,是另一个容易被忽略的问题。robots.txt 只能约束遵守协议的搜索引擎,不能阻止恶意抓取。上传目录如果允许 PHP 执行,攻击者上传一个脚本文件就可能直接拿下站点。这类目录应该单独配置为不解析 PHP:

```nginx
location ^~ /uploads/ {
location ~ \.php$ { deny all; }
}
```

没有记录变更和登录行为,后期排查问题缺少依据。改了什么配置、什么时候改的、为什么改,这些信息如果不记录,等出问题的时候只能靠回忆。每次修改配置前先备份原文件,修改后记录变更内容,这是成本最低的恢复手段。

遇到异常时应先保留现场和记录,再逐项排除。不要在原因不明时连续修改多个地方——改得越多,越难判断到底是哪一步导致了问题。先看错误日志,确认是权限问题、路径问题还是转发问题,再针对性地修改。

上线前后的检查边界

上线前检查环境、备份、日志、HTTPS、权限和性能。上线后同样要观察一段时间,确认没有异常请求和错误日志。恢复边界要提前想清楚:配置备份放在哪里、怎么回滚、回滚后是否需要重新加载 PHP 进程。

后续可以加入安全响应头和访问日志分析。能公开的设置、过程和结果,补进对应文章,方便下次维护时直接参考。

评论

登录后可发表评论。