apache应以非root用户(如apache或www-data)运行worker进程,通过user/group指令配置、站点目录属主权限(750)、中require group apache及禁用危险模块实现多站安全隔离。

Apache 默认以 root 或特定系统用户(如 apache 或 www-data)启动主进程,但子进程(处理请求的 worker)可以且应该以非 root 用户身份运行,尤其当虚拟主机托管多个站点、涉及用户上传或自定义脚本时。安全配置的关键不是让每个 VirtualHost 绑定独立用户(Apache 本身不支持 per-VirtualHost user),而是通过权限隔离 + 进程降权 + 目录最小权限控制来实现“逻辑上按用户隔离”。以下是实际可行、生产环境常用的方法:
确保 Apache 主进程以非 root 身份启动并派生子进程
Apache 主进程必须由 root 启动(用于绑定 80/443 端口),但应立即切换到低权限用户运行 worker。这由 User 和 Group 指令控制,而非 VirtualHost 内部设置:
- 编辑主配置文件(CentOS/RHEL:/etc/httpd/conf/httpd.conf;Ubuntu/Debian:/etc/apache2/apache2.conf)
- 确认存在且未被注释的两行:
User apache(CentOS)或User www-data(Ubuntu)Group apache或Group www-data - 不要设为
root或空值;推荐使用系统预建的专用用户(如apache),而非任意普通用户 - 重启服务后执行
ps aux | grep httpd或ps aux | grep apache2,验证 worker 进程 UID 显示为apache或www-data,而非root
为每个虚拟主机目录设置严格的属主与权限
这是隔离不同站点的核心手段。即使所有 worker 共用同一系统用户,也能通过文件系统权限阻止跨站访问:
PHP中文网提供Apache 2.4.62 官方 tar.gz 源码包下载,通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
- 为每个站点创建独立根目录,例如:
/var/www/site-a.example.com/public_html/var/www/site-b.example.com/public_html - 将每个目录属主设为对应开发者或管理用户,组设为 Apache 运行组(如
apache):sudo chown -R alice:apache /var/www/site-a.example.comsudo chown -R bob:apache /var/www/site-b.example.com - 设置目录权限为
750(所有者读写执行,组读执行,其他无权限):sudo chmod -R 750 /var/www/site-a.example.com - 确保
public_html及其子目录对apache组可读可执行(否则 403 错误)
在 VirtualHost 中启用基于组的访问控制
仅靠文件权限还不够,需在配置中显式声明允许哪个组访问该目录:
- 在每个
<virtualhost></virtualhost>块内,添加<directory></directory>段落: - 示例(CentOS):
<directory><br> Require group apache<br> Options -Indexes +FollowSymLinks<br> AllowOverride None<br></directory>
-
Require group apache表示只允许属于apache组的用户(即 Apache worker 进程)访问 —— 即使目录属主是alice,只要组正确且权限开放,就能正常服务,同时阻止其他普通用户直接读取 - 避免使用
Require all granted,除非明确需要开放给所有本地用户(极不推荐)
禁用危险模块与功能,降低攻击面
非 root 运行只是基础,还需配合配置收紧:
- 禁用
mod_userdir(防止通过~username访问用户家目录):sudo a2dismod userdir(Debian/Ubuntu)或注释掉LoadModule userdir_module(CentOS) - 关闭
AllowOverride(除非必须用 .htaccess):
设为None可防止用户通过 .htaccess 提升权限或绕过限制 - 禁止 CGI 执行(除非必要):
在<directory></directory>中添加Options -ExecCGI,并确保.cgi/.pl文件不被解析 - 日志目录(
ErrorLog/CustomLog)也应归属apache:apache并设为640,防止普通用户读取敏感请求信息
不复杂但容易忽略 —— 安全不是靠某一个开关,而是用户、权限、配置三者协同约束的结果。










