如何在Apache虚拟主机中覆盖主配置设置的Header响应头
Apache CSP响应头覆盖失败解决方法
问题根因
- Apache的
Header指令分为always和onsuccess两个独立的响应头集合,你在主配置用always参数设置的头,仅用同参数的set不一定能直接覆盖;如果主配置的规则放在了<Directory>、<Location>这类优先级更高的块中,虚拟主机根配置的规则默认会被覆盖。 - PHP层面调用
header()函数只能处理PHP自身输出的响应头,无法移除Apache在后续输出阶段追加的头,所以只会出现重复的响应头,浏览器会默认采用更严格的CSP规则(也就是主配置的frame-ancestors 'self'),导致你的配置不生效。
可用解决方案
方案1:调整虚拟主机配置(推荐)
在当前虚拟主机的Header配置前,先添加unset指令清除原有头,再设置新规则,修改后的虚拟主机对应配置如下:
<VirtualHost *:443> ServerName example.com DocumentRoot /var/www/example/app ServerAdmin admin@example.com SSLEngine on SSLCertificateFile /etc/apache2/ssl/certs/default.crt SSLCertificateKeyFile /etc/apache2/ssl/private/default.key # 先清除主配置设置的同参数CSP头 Header always unset Content-Security-Policy # 再设置当前站点专属的CSP规则 Header always set Content-Security-Policy "frame-ancestors https://example2.com https://example3.com;" </VirtualHost>
修改配置后执行sudo systemctl restart apache2重启Apache即可生效。
方案2:调整主配置的作用范围
如果你只需要给大部分站点设置通用CSP、少数站点例外,可以把主配置的Header规则移到全局的默认<VirtualHost>配置块中,而非全局主配置根节点,这样自定义的虚拟主机配置会自动覆盖默认虚拟主机的规则,不需要额外执行unset操作。
内容的提问来源于stack exchange,提问作者BadHorsie
相关产品推荐
相关产品推荐

