上一篇 分享链接 返回 返回顶部

日本IIJ线路服务器网站报403,如何检查服务身份、目录权限并按最小权限修复

发布人:Minchunlin 发布时间:8小时前 阅读量:12
日本IIJ线路服务器网站报403,如何检查服务身份、目录权限并按最小权限修复

网站首页、静态文件和后台是否都报403,是排查日本IIJ线路服务器访问故障的第一个分界点。如果只有目录首页报错,可能是首页文件或目录访问规则问题;如果部署后整站突然报错,更应检查发布目录、文件属主和服务运行身份。403表示某个HTTP处理层拒绝了请求,不能仅凭状态码认定是线路或文件权限故障。

建议按“确认403由谁返回 → 核对实际服务身份 → 检查完整路径权限 → 排查服务规则与安全策略 → 最小范围修复”的顺序处理。先取日志证据,再修改权限;不要把整站改成777,也不要为了消除报错让Web服务以root身份运行。

先确认:请求在哪里被拒绝

以下以Linux上的Nginx站点为例;动态页面如经PHP-FPM处理,还需单独核对PHP-FPM池的身份。操作前准备有sudo权限的维护账户、实际域名、站点配置和错误发生时间。示例域名、路径、用户名都应替换为现场值。

先对同一个URL发起GET请求,避免只用HEAD请求造成判断偏差:

curl -sS -D - -o /dev/null https://www.example.com/

如果站点前面存在代理或缓存,可在源站上保留域名与TLS主机名,直接请求本机监听地址:

curl --resolve www.example.com:443:127.0.0.1 \
  -sS -D - -o /dev/null https://www.example.com/

该命令只适用于Nginx在本机对应地址监听443的情况;否则应换成实际监听地址。连接失败或证书验证失败,不等于确认了403原因,也不应直接跳过证书校验来作判断。

观察结果优先判断下一步
公网403,直连源站正常前置代理、访问策略或两条请求路径的配置差异对照前置层日志与源站日志
两条路径都403,源站记录文件访问失败源站权限或安全策略问题检查服务身份与路径
/报403,已知静态文件正常首页缺失、首页配置或目录访问规则问题核对index与实际文件
静态文件正常,动态接口403应用鉴权、访问规则或动态服务身份问题查上游和应用日志

对比时还应保持请求方法、路径及登录状态一致。源站日志没有记录,也可能是查错了虚拟主机或访问日志被关闭,不能据此直接归因网络。

从日志建立分支:哪些403才需要改权限

对Nginx,可以先读取当前磁盘上的完整配置并检查语法:

sudo nginx -T

重点核对命中的server_namerootaliasindexlocation,以及该站点的access_logerror_log位置。输出可能包含敏感配置,不宜原样公开。该命令读取的是磁盘配置;若配置修改后尚未重载,还需结合运行日志判断当前生效状态。

按配置中的实际路径读取错误日志:

sudo tail -n 100 /实际路径/error.log

常见线索有以下区别:

  • Permission denied:文件访问被系统拒绝,继续检查传统权限、ACL、SELinux或服务隔离;它并不只代表缺少某个chmod权限位。
  • directory index ... is forbidden:请求落到目录,且没有按配置找到可用首页、目录列表又未开启。应检查首页文件和映射,不是直接放开目录写权限。
  • access forbidden by rule:优先检查匹配到的访问规则,例如denyallow或显式返回403的配置。
  • 应用记录了鉴权失败并返回403:检查登录状态、角色、令牌及业务规则;修改文件权限通常无效。

如果是首页文件缺失,应通过发布流程恢复首页或修正indexroot。不要用开启目录列表的方式掩盖问题,否则可能暴露站点文件名。

核对服务身份:谁真正读取这些文件

Nginx主进程可能以root运行,但通常由非特权worker读取静态文件。只看主进程身份,容易误判。

ps -eo user,group,pid,args | grep -E '[n]ginx|[p]hp-fpm'

同时核对Nginx配置中的user,以及实际PHP-FPM池配置中的usergroup。不要假定所有系统都使用www-datanginx

若要确认某个worker实际持有的UID、GID和补充组,可用查到的PID执行:

sudo grep -E '^(Uid|Gid|Groups):' /proc/实际PID/status

id 用户名显示的是当前账户数据库信息,不一定等于已运行进程的组集合。刚调整用户组后,旧进程可能仍持有旧组权限,需要通过该服务适用的重载或重启方式重新创建工作进程,并再次检查。

Nginx与PHP-FPM不必使用同一身份。 Nginx读取静态文件,PHP-FPM读取并执行PHP代码;缓存、会话、上传目录的写权限应给实际执行写入的身份,而不是笼统给所有Web进程。

沿完整路径检查:文件可读不代表能访问

假设日志显示目标文件是:

/srv/www/site/public/index.html

检查整个路径,而不是只看最后一个文件:

namei -l /srv/www/site/public/index.html
sudo getfacl -p /srv /srv/www /srv/www/site \
  /srv/www/site/public /srv/www/site/public/index.html

namei可展示逐级目录的属主和权限;getfacl用于查看ACL,需系统已安装相应工具。如果路径经过软链接,还要检查软链接实际指向的完整路径。

权限判断遵循以下规则:

  • 读取已知路径下的文件,需要对每一级父目录有搜索权限x,并对文件有读权限r
  • 目录的r用于列出目录项,不能替代进入目录所需的x
  • 静态文件通常不需要执行权限,提供静态访问也不要求目录可写。
  • 普通权限按属主、匹配组、其他人的对应类别判断,不是把所有类别权限累加。
  • ACL中的命名用户或组权限可能受mask限制,应关注getfacl输出中的有效权限。

因此,即使index.html644,上层目录若为700且属于部署账户,Web worker仍可能无法读取。

可用实际服务账户做初步验证:

sudo -u 实际服务用户 -- test -x /srv/www/site/public
echo $?

sudo -u 实际服务用户 -- test -r /srv/www/site/public/index.html
echo $?

返回0表示该项测试通过,非零表示未通过。但这只能模拟账户访问,不能完整复现运行中服务的补充组、SELinux域、容器挂载或systemd隔离环境;最终仍以真实请求为准。

定位后修复:只开放所需路径与操作

单个读取身份缺权限:可以考虑定点ACL

下面适用于一个明确场景:已确认Nginx worker为非文件属主,目标只是读取首页,文件系统支持ACL,相关路径不存在需要特殊保留的复杂ACL。示例中假设核验后的账户是www-data,其他环境必须替换。

先保存所有待修改对象的权限与ACL,再授权:

WEBUSER=www-data
ACL_BACKUP=$(mktemp /var/tmp/site-acl.XXXXXX)

sudo getfacl -p /srv /srv/www /srv/www/site \
  /srv/www/site/public /srv/www/site/public/index.html \
  > "$ACL_BACKUP"

printf '权限备份:%s\n' "$ACL_BACKUP"

确认备份成功、内容完整后再执行:

sudo setfacl -m "u:${WEBUSER}:--x" \
  /srv /srv/www /srv/www/site /srv/www/site/public

sudo setfacl -m "u:${WEBUSER}:r--" \
  /srv/www/site/public/index.html

这只给予目录搜索和目标文件读取权限,不赋予写入权限。需要注意两项影响:

  • 父目录搜索权限可能使该身份能够到达其他原本可读的子项,应先检查同层目录边界。
  • setfacl可能重算ACL的mask,进而改变其他已有ACL条目的有效权限;复杂ACL不能直接套用示例,应先比较现有条目及有效权限。

修改后用getfacl复核。需要回滚时,使用刚才记录的备份文件:

sudo setfacl --restore="$ACL_BACKUP"

回滚会恢复备份时这些对象的权限状态,可能覆盖其后的合法权限调整,应在同一维护窗口内操作。上述示例只修复该首页的读取条件;CSS、图片等资源需按实际公开文件集合核对,不能视为整站已修复。

长期权限布局:部署者可写,服务按需读写

对于整站,应把代码所有权保留给部署账户或受控维护账户,再通过专用读取组或ACL给服务必要权限。只读目录可采用750、普通文件可采用640,但成立条件是服务身份确实匹配读取组,且所有父目录都可搜索;这些数字不是通用修复答案。

写权限仅限应用确认需要的缓存、会话或上传目录。代码目录、配置文件和密钥不应因Web访问失败而一并变成可写。涉及递归权限调整前,应先盘点文件、备份权限,并明确哪些目录需要不同策略,不要执行整站chmod -R 777或把全部代码递归交给Web用户。

普通权限正常:继续检查安全策略与服务隔离

启用SELinux的系统可以先做只读检查:

getenforce
ls -Zd /srv/www/site/public
sudo ausearch -m AVC -ts recent

这些命令适用于已安装对应工具的SELinux环境。若存在与本次访问关联的拒绝记录,应核对该发行版的Web内容标签策略;不要直接关闭SELinux。可先预览标准标签恢复是否会改变目标:

sudo restorecon -nRv /srv/www/site/public

非标准站点路径可能需要先建立正确的持久标签映射,不能认为直接运行restorecon必然有效。实际调整前应保存原标签与映射配置,并限定到站点所需范围。

如果使用AppArmor或systemd服务隔离,还需检查相关拒绝日志、InaccessiblePathsRootDirectory等设置。进程根本看不到该路径时,主机上的文件权限正确也不足以恢复访问。

验证恢复,并盯住下一次发布

修复后应重复最初的请求,确认预期公开页面返回正常响应,同时观察同一时间段的错误日志。文件权限和ACL变更通常即时生效,无需为此重启Nginx;若修改了配置,应先完成语法检查,再对已核验的服务单元执行重载,并保留原配置以便回退。

至少验证以下项目:

1. 首页、嵌套目录文件、CSS或图片,以及动态页面分别符合预期。

2. 日志不再出现本次相关的权限拒绝,新出现的403另按请求路径分析。

3. 私有配置、密钥和非公开目录仍不能通过HTTP读取。

4. 服务账户能读取所需内容,但不能修改代码;应用只在指定目录内可写。

若当前恢复、下一次发布又复发,应检查部署工具是否保留ACL、发布账户的umask、新目录属组,以及软链接切换后的真实路径。将“worker身份变化、发布目录权限变化、权限拒绝日志、403比例异常”纳入监控,比反复扩大目录权限更能稳定地解决日本IIJ线路服务器上的此类故障。

目录结构
全文