Apache动态内容安全头部配置关键在于启用mod_headers模块、全局使用Header always set指令,覆盖所有响应(含错误页),设置X-Content-Type-Options“nosniff”、CSP frame-ancestors防点击劫持及基础CSP策略,并在反向代理场景中显式重设头以避免被后端或CDN覆盖。

Apache 动态内容(如 PHP、Python CGI、Node.js 代理后端返回的 HTML/JSON/JS)的安全头部配置,关键在于**不依赖应用层输出、由 Web 服务器统一注入、覆盖所有响应类型(含错误页)**。静态资源和动态内容应一视同仁,不能只给 .php 加头而漏掉 API 接口的 JSON 响应。
必须启用 mod_headers 并作用于全局范围
Header 指令本身无效,除非模块已加载且配置位置正确:
- Debian/Ubuntu 执行:
a2enmod headers && systemctl reload apache2 - RHEL/CentOS 检查
httpd.conf中LoadModule headers_module modules/mod_headers.so已取消注释 - 验证命令:
apachectl -M | grep headers,输出含headers_module即成功 - 配置必须写在
<VirtualHost>外的主配置(如/etc/apache2/apache2.conf)或独立conf.d/security-headers.conf中,不要用 .htaccess —— 它无法控制 404/500 或重定向响应头
核心安全头必须用 Header always set
动态内容常触发错误响应(如 PHP fatal error 返回 500),普通 Header set 不生效,必须用 always 变体:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
X-Content-Type-Options: nosniff —— 阻止浏览器对 PHP 输出的 JS/JSON/HTML 做 MIME 嗅探,避免 XSS:
Header always set X-Content-Type-Options "nosniff" -
Content-Security-Policy: frame-ancestors —— 替代已废弃的
X-Frame-Options,防御点击劫持:Header always set Content-Security-Policy "frame-ancestors 'self';"(仅同站嵌入)
或允许多个可信域名:Header always set Content-Security-Policy "frame-ancestors 'self' https://admin.example.com;" -
基础 CSP 策略 —— 针对动态页面,禁用内联脚本与 eval 是关键:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self';"
若需兼容旧版内联 JS(不推荐),可加'unsafe-inline',但务必配合 nonce 或 hash
注意反向代理场景下的头继承问题
当 Apache 作为反向代理(如 ProxyPass 到 PHP-FPM、Node.js 或 Python WSGI)时,默认会丢弃原始响应头,必须显式保留或重设:
- 若后端已输出安全头,用
ProxyPassReverse+Header merge或Header append补充缺失项 - 更稳妥做法:在 Proxy 配置块中直接用
Header always set覆盖所有响应,确保头不被后端逻辑绕过 - 特别注意:PHP 的
header()函数或框架中间件可能覆盖 Apache 设置的头,此时应禁用后端重复设置,以 Apache 为准
验证是否真正生效
配置重启后,必须逐项验证,重点检查动态路径:
- 访问一个真实 PHP 页面(如
/info.php)、一个 404 路径(如/nonexistent.php)、一个 500 错误(如触发 PHP fatal error) - 用浏览器开发者工具 → Network → Response Headers 查看是否含
X-Content-Type-Options和Content-Security-Policy - 用在线工具(如 securityheaders.com)扫描,确认无缺失、无冲突(例如不要同时存在
X-Frame-Options和frame-ancestors) - 若使用 CDN(如 Cloudflare),需确认其未覆盖或剥离这些头 —— 应在 CDN 设置中开启“Preserve Origin Headers”或类似选项

















