应为每个Web服务创建专用系统账户(UID 1–999),禁用登录,且服务进程须明确以该账户运行;配置需覆盖用户创建、服务启动设置、端口权限、文件归属与权限、日志路径及进程验证。

为什么不能用 root 或普通用户跑 Web 服务
root 运行 Web 服务(如 Nginx、Apache)等于把整个系统暴露给 HTTP 请求入口;而直接用运维人员的普通账号(如 alice)运行,则混杂了人机权限、审计难分离、密码策略冲突。真正的安全起点是:**为每个服务创建专用账户,UID 在 1–999 区间,禁止交互登录,且不共享任何已有用户身份**。
创建 Web 服务专用账户的正确步骤
以 Nginx 为例,目标是创建 www-data(Debian/Ubuntu 默认)或 nginx(RHEL/CentOS 默认),但你要亲手建,而不是依赖包管理器自动创建——因为自动创建可能没禁用 shell 或设错 UID。
- 用
useradd -r -s /usr/sbin/nologin -d /var/www -M nginx创建系统用户:-r表示创建系统用户(自动分配 1–999 UID),-s /usr/sbin/nologin确保无法登录,-M不创建家目录(避免冗余),-d /var/www仅作语义归属(不影响实际运行) - 检查 UID 是否落在系统用户区间:
id nginx应返回类似uid=997(nginx) gid=995(nginx)—— 若 UID ≥1000,说明没生效,需加-r或显式指定-u 997 - 确认
/etc/passwd中该行第七字段是/usr/sbin/nologin,不是/bin/bash或空值
让服务进程真正以该账户运行的关键配置
光建账户没用,必须让服务二进制在启动时切换到它。不同服务方式处理不同:
- Nginx:编辑
/etc/nginx/nginx.conf,确保首行是user nginx;(不是www-data,除非你建的是那个名);systemd 启动时会忽略此行,所以还要检查/lib/systemd/system/nginx.service中是否有User=nginx和Group=nginx,没有就加上并systemctl daemon-reload - 自研 Node.js 服务:不要用
sudo node app.js,改用sudo -u nginx node app.js;更稳妥的是写 systemd unit,明确设User=nginx、Group=nginx、PermissionsStartOnly=true(避免启动脚本权限问题) - 注意:若服务监听 80/443,又不想用 root 启动,得配
authbind或setcap 'cap_net_bind_service=+ep' /usr/bin/node,否则即使User=nginx也会因端口权限失败
权限继承与文件归属的常见翻车点
服务账户能跑起来 ≠ 安全落地。常被忽略的是静态资源和日志路径的归属与权限:
-
/var/www目录应chown -R nginx:nginx /var/www,但禁止递归给chmod 777—— 静态文件只需644,目录755,上传目录(如有)才单独设750并限组写 - 日志目录如
/var/log/nginx必须chown nginx:adm /var/log/nginx(adm组允许轮转读取),否则logrotate可能因权限不足失败 - 若用
systemd,启用ProtectSystem=strict和ReadOnlyDirectories=/可进一步限制进程能写的路径,但要提前把/var/log、/var/www加入ReadWriteDirectories=
最易被跳过的一步:定期用 ps aux | grep nginx 确认 WORKER 进程的 USER 列确实是 nginx,而不是 root —— 很多配置改了主进程,却忘了 worker 进程仍继承父进程 UID。


















