Nginx站点隔离防跨站入侵教程

Nginx站点隔离防跨站入侵设置教程,新手也能搞定

跨站入侵指的是同一台服务器上某个站点被入侵后,攻击者利用系统漏洞读取或篡改其他站点的文件。
对使用Nginx+PHP的建站环境来说,做好站点隔离就能有效阻断这种横向扩散。
本文的步骤完全面向零基础用户,你只需SSH连上服务器,复制命令执行即可。

准备工作

开始操作前,请确认以下条件:

  • 你拥有服务器的root或sudo权限。
  • Nginx和PHP-FPM已经安装且正常运行。
  • 至少有两个站点(例如 example.com 和 test.com),方便后续验证隔离效果。
  • 建议先备份现有配置:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

第一步:为每个站点分配独立的操作系统用户

默认情况下,Nginx 的 worker 进程通常以 www-datanginx 用户运行,所有站点共用一个用户,一个站点被入侵就能访问其他站点的文件。
最佳实践是为每个站点创建独立的系统用户和组。

执行以下命令创建用户和组(以站点 example.com 为例):

sudo useradd -m -s /bin/false nginx_example
sudo groupadd nginx_example
sudo usermod -a -G nginx_example nginx_example

然后将站点根目录的所有权改为此用户:

sudo chown -R nginx_example:nginx_example /var/www/example.com
sudo chmod 750 /var/www/example.com
解释useradd -m 创建用户主目录,-s /bin/false 禁止该用户登录,只用于文件权限。chmod 750 表示所有者可读写执行,同组可读执行,其他人无权限。

第二步:修改PHP-FPM池配置,绑定用户

每个站点使用独立的PHP-FPM pool,并指定为用户本身。
编辑PHP-FPM的pool配置文件(通常位于 /etc/php/*/fpm/pool.d/),创建或修改对应站点的配置文件。

例如建立 example.conf,内容如下:

[example]
user = nginx_example
group = nginx_example
listen = /run/php/php8.1-fpm-example.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
注意listen 使用Unix socket时,要保证Nginx能访问。这里监听socket文件的所有者是 www-data(Nginx运行用户),权限 0660 让Nginx和PHP-FPM双方可读写。

修改完成后重启PHP-FPM:

sudo systemctl restart php8.1-fpm   # 请根据你的PHP版本调整

第三步:配置Nginx站点,使用独立PHP-FPM socket

编辑Nginx的站点配置(例如 /etc/nginx/sites-available/example.com),
修改 location ~ \.php$ 块,
使用对应的socket:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.1-fpm-example.sock;
}

同时设置站点根目录的 rootindex
整个配置大致如下:

server {
    listen 80;
    server_name example.com;
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm-example.sock;
    }
}

检查配置并重载Nginx:

sudo nginx -t
sudo systemctl reload nginx

第四步:开启PHP open_basedir 限制(双重保险)

单纯靠用户隔离还不够,攻击者可能利用 file_get_contents() 等函数访问系统文件。
PHP内置的 open_basedir 可以限制脚本能访问的目录范围。
在PHP-FPM pool配置中(同一个 pool 文件),添加:

php_admin_value[open_basedir] = /var/www/example.com/:/tmp/
说明:这表示PHP脚本只能访问 /var/www/example.com//tmp/ 目录,无法读取其他站点的文件或系统敏感目录。注意 :/tmp/ 前面的冒号是分隔多个目录。

然后重启PHP-FPM:

sudo systemctl restart php8.1-fpm

第五步:额外限制Nginx目录穿越

有些情况下,攻击者可能利用Nginx的别名或路径配置漏洞访问上级目录。
建议在 server 块中增加以下规则:

# 禁止访问 . 开头的文件(如 .git .env)
location ~ /\. {
    deny all;
}
# 禁止直接访问保留文件
location ~ /(README|LICENSE|CHANGELOG) {
    deny all;
}

同时确保 root 指令不包含可猜测的路径。
重启Nginx即可。

避坑指南(新手常见错误)

  1. 不要只改Nginx用户:如果PHP-FPM仍然以 www-data 运行,站点隔离效果几乎为零。必须同时改PHP-FPM pool的用户。
  2. open_basedir 写错路径:检查路径末尾是否有斜杠,多目录用冒号分隔,不要用分号。
  3. 忘记给 socket 文件正确权限:如果Nginx用户无法读取socket,站点会报502错误。记得 listen.mode = 0660listen.owner/group 设置为Nginx运行用户。
  4. 测试前清空浏览器缓存:有时候旧的PHP进程缓存会导致权限检查不生效。

效果验证

在每个站点的根目录下创建一个测试文件 test.php

通过浏览器分别访问两个站点的 test.php,如果都输出“无法访问其他站点文件”,说明隔离成功。
你还可以尝试 open_basedir 测试:在脚本中加入 phpinfo();,查看 open_basedir 的值是否只包含本站目录和 /tmp/

常见问题

Q:我的服务器上站点很多,每个建一个用户太麻烦,有快速方法吗?
A:可以使用脚本批量创建,但数量超过几十个时建议使用容器或虚拟化方案,比如 Docker 或 LXC,隔离更彻底。

Q:开启 open_basedir 后,网站报错“open_basedir restriction in effect”。
A:说明脚本访问了限制以外的路径,请在 open_basedir 中添加所需的目录(例如文件上传目录 /var/www/example.com/uploads,或 :/tmp/)。

Q:Nginx 站点配置里 fastcgi_param 用不用改?
A:主要依赖上面几步,fastcgi_param 通常不需要手动修改,但注意保留默认的 SCRIPT_FILENAME 等参数。

如果你正在配置多站点环境,建议先按照本文步骤完成所有站点的隔离,再投入使用。
遇到报错时先回看避坑部分,通常能解决七成问题。
想要进一步了解Nginx安全配置,可以查阅官方文档或站内相关教程。

分享到:
上一篇
宝塔面板批量新建跨境站点:从零开始的全流程实操教程
下一篇
服务器swap分区扩容缓解OOM
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意