如何放宽内容安全策略

您好

我想在不一定通过其配置的公共域名的情况下测试 Discourse。例如,如果 Discourse 已安装并配置为 https://uat.mysite.com,那么我显然可以在浏览器中访问 https://uat.mysite.com,这意味着我的浏览器将从内部网络访问公共 Internet 以解析域名到其公共 IP 地址,并通过其公共 IP 地址加载页面。

我刚刚尝试通过服务器的内部 IP 地址(例如下面显示的 192.168.1.2)访问 Discourse,但由于内容安全策略(Content Security Policy)而无法加载。我收到的错误如下所示。

Refused to load the script 'http://192.168.1.2:12000/assets/locales/en-a9c88e45eb548bd7c807aecfd37d218891e213b5c1fd254857e0f16c72d73996.js' because it violates the following Content Security Policy directive: "script-src http://uat.mysite.com/logs/ http://uat.mysite.com/sidekiq/ http://uat.mysite.com/mini-profiler-resources/ http://uat.mysite.com/assets/ http://uat.mysite.com/brotli_asset/ http://uat.mysite.com/extra-locales/ http://uat.mysite.com/highlight_js/ http://uat.mysite.com/javascripts/ http://uat.mysite.com/plugins/ http://uat.mysite.com/theme-javascripts/ http://uat.mysite.com/svg-sprite/ 'sha256-rwfDVOTzygQmkOwFNAeX564B66beHoel4+gRLgQUgHg='". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
                                           ---------------------------------------------
                                          |                                             |
                                           ------------
uat.mysite.com resolves to 98.1.2.3 -->   |  Public IP |  Server running Discourse.     |
                                          |  96.1.2.3. |
                                           ------------                                 |
                                          |                                             |
                                          |                  ----------------           |
                                          |                  |  Private IP  |           |
                                          |                  | 192.168.1.2  |           |
                                           ---------------------------------------------
                                                                         ^
                                                                         |
192.168.1.2   ------------------------------------------------------------

我之所以想通过服务器的内部 IP 地址访问 Discourse,是因为我想进行测试。例如,如果我想进行加载测试,不一定想加载服务于 Internet 的网络。或者,如果我想在我的笔记本电脑或构建服务器上安装一个测试实例,而不必设置 DNS。

我想我总是可以通过在 /etc/hosts 中设置自定义条目来覆盖它,但有没有办法禁用 CSP 或将其设置为信任其他源以允许测试?

1 个赞

然后配置您的计算机,将该地址解析为 discourse 服务器的本地 IP。有很多方法可以做到这一点,但它们依赖于操作系统,因此您应该在 Google 搜索中包含操作系统。(在 Linux 中,我认为 Mac 也是如此,您可以直接编辑 /etc/hosts。)

1 个赞

我实际上尝试过 /etc/hosts,但由于 CSP 仍然出现相同的错误。我本以为会有一个标志或设置可以用来切换它,以便开发人员可以在他们的笔记本电脑内完成所有操作,而无需设置 DNS 解决方案。查看 在 macOS 上为开发安装 Discourse - 文档 / 开发人员 - Discourse Meta,它似乎会引导到一个与 http://localhost:3000 配合使用的东西,而不是 IP 地址。

我面临的挑战是我有自动化安装 Discourse 的流程,并且希望使用相同的流程来设置开发、UAT 和生产环境,而且我不一定希望开发环境可以从公共互联网访问,而这似乎是目前的要求,因为它需要解析一个正确的 FQDN。有多种用例,其中一种是例如每周自动升级开发环境中的 Discourse,并运行一些测试以查看是否有任何东西中断。

无论如何,如果有一种方法可以放宽要求以允许通过 IP 地址直接访问,那就太好了。否则,我想唯一的其他解决方案是建立一个小型的 DNS 服务,然后将笔记本电脑指向使用自定义 DNS 服务,但这似乎有点麻烦。

有一个名为 content security policy 的站点设置。您可以取消选中并保存以禁用 CSP。

只要不在生产实例中执行此操作即可。

3 个赞

那不是个好主意。这永远行不通。开发环境是绝对不同的,因为它有预编译的资产和许多其他使开发不可能的东西。除非你正在开发插件,否则你根本不需要开发环境。所以,如果是这种情况,那么你的开发环境可以是一个 Docker 安装,它只是不被称为这里的开发环境。

你想按照标准安装中的描述,使用 Docker 来启动你的暂存和生产环境。

3 个赞

您好!我经常这样做,但使用的是 Docker 安装。假设您在生产环境中使用我们标准的 Docker 安装,那么对于您的验收测试,您应该使用相同的方法。开发和 Docker 安装之间存在很大的差异(配置、gem 和 JS 包版本等),这可能会在部署时引起头痛。

Docker 安装默认使用并强制执行 HTTPS。除非您想自定义容器模板(我发现它有一些隐藏的复杂性),否则您可以通过另一个站点设置来关闭 HTTPS 强制执行。

这是我用于“放宽本地 Docker 安装中的安全性”的片段,在进入生产环境之前可以轻松恢复:

SiteSetting.content_security_policy = false
SiteSetting.force_https = false

然后,您只需确保您的浏览器可以在 http://uat.mysite.com 找到 Docker 容器上的端口 80——请注意,您将使用 http 而不是 https

为此,@pfaffman/etc/hosts 技巧是可行的方法;每个操作系统的详细信息请参见此处

2 个赞