出于安全考虑,我认为默认情况下,当在浏览器中直接导航到 IP 地址时,Discourse 论坛不应可见。
原因如下:
- 允许在不使用 HTTPS 的情况下使用站点,既适用于用户,也适用于管理员的初始配置。
- 会泄露源服务器地址。如果您使用 Cloudflare 或类似服务来保护源 IP 免受 DDoS 攻击或服务器入侵尝试(尤其是当黑客认为服务器具有高价值时),这非常不利。目前有一些人在运行扫描所有网络托管商 IP 范围的机器人。
此外,现在的 Discourse 安装程序会确认域名/子域名是否配置正确,否则不会继续安装。
只需在 Docker 容器内的 /etc/nginx/conf.d/discourse.conf 文件底部添加以下内容:
server {
listen 80;
server_name 1.1.1.1;
server_tokens off;
return 404;
}
其中 1.1.1.1 是服务器的公网 IP 地址。可能有一种更优雅的方式来包含 IP 地址,而不是硬编码。我尝试了几种方法,但未能成功。
对我来说效果很好(包括使用 Cloudflare 代理的情况)。我想不出有多少情况下允许直接通过 IP 进行 Web 访问是实用或必要的。禁止这种访问似乎是相当普遍的做法。不过,我很乐意听到任何反对这样做的理由!
1 个赞
Falco
(Falco)
2
既然我们的默认指南能让您的网站在仅使用 HTTPS 的情况下正常运行,为什么要进行任何更改呢?
有特殊需求的用户可以自行调整,但我们的默认设置将保持不变,即默认使用可正常工作的域名和 HTTPS。
9 个赞
客观来说,这并不准确。它并非仅支持 HTTPS,因为你仍然可以通过非 HTTPS 的 IP 地址直接访问该网站。
区别在于禁止在不使用 HTTPS 的情况下进行不安全连接,并暴露服务器的源 IP 地址。我不知道这样做有什么好处。
如果你对全球前 50 大网站进行 DNS 查询,你会发现其中没有一个可以通过 IP 地址直接以不安全的方式访问。我认为假设全球前 50 大网站采用最佳实践并非不合理。
这是一个相当准确的前列网站列表:
这是一个 DNS 查询工具:
Falco
(Falco)
5
默认情况下,尝试通过 IP 访问会返回一个 301 重定向 到正确的域名:
$ curl 159.203.68.6 -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.1
Date: Mon, 29 Jun 2020 20:24:41 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://falcoland.falco.dev/
您提出的方案是将 301 改为 404 吗?
3 个赞
8 次安装中有 8 次通过 DigitalOcean 镜像完成,无论是通过 Communiteq(原 DiscourseHosting)安装(随后迁移)还是按照本指南 discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub 手动安装,默认情况下均可通过 IP 地址以不安全的方式访问。其中两个是上周安装的(使用上述 GitHub 指南)。
是不是我漏掉了某个额外步骤?我认为返回 404 错误比 301 重定向更好,毕竟大多数随意探查 IP 地址的人可能心怀不轨。不过,301 重定向总比允许不安全访问要好。
无法复现……
http://38.242.24.122 已正确将重定向到 https://discourse.codinghorror.com/。
4 个赞
嗯,也许是 Cloudflare 模板。这很可能是它们与完全原生安装之间唯一一致的区别。
1 个赞
Stephen
(Stephen)
9
如果您采取的步骤未在云安装列表中列出,那么从定义上讲,它就不是“原生安装”。
Cloudflare 模板并未做任何明显会干扰重定向的操作:
run:
- file:
path: /tmp/add-cloudflare-ips
chmod: +x
contents: |
#!/bin/bash -e
# 下载 CloudFlare IP 列表
wget https://www.cloudflare.com/ips-v4/ -O - > /tmp/cloudflare-ips
wget https://www.cloudflare.com/ips-v6/ -O - >> /tmp/cloudflare-ips
# 转换为 nginx 命令并转义,以便嵌入到 sed 追加命令中
CONTENTS=$(</tmp/cloudflare-ips sed 's/^/set_real_ip_from /' | sed 's/$/;/' | tr '\n' '\\' | sed 's/\\/\\n/g')
echo CloudFlare IPs:
echo $(echo | sed "/^/a $CONTENTS")
# 插入到 discourse.conf 中
sed -i "/sendfile on;/a $CONTENTS\nreal_ip_header CF-Connecting-IP;" /etc/nginx/conf.d/discourse.conf
# 清理
rm /tmp/cloudflare-ips
- exec: "/tmp/add-cloudflare-ips"
- exec: "rm /tmp/add-cloudflare-ips"
它会获取 IP 范围,临时存储为 cloudflare-ips,并添加对 CF-Connecting-IP 的支持。
2 个赞
没错,我并没有声称它们是“原生安装”。
因此,我在其中一台服务器上测试了移除官方 Cloudflare 模板后重新构建,但遗憾的是并未产生任何改变。它仍然可以通过 IP 不安全地访问。
实在想不出这些安装之间还有什么其他异常之处。该实例上唯一的插件是默认自带的 Docker 管理器和官方广告插件。它运行在稳定分支上,但其他同样存在该问题的网站则分别运行在稳定版、测试版和测试通过版上。
neounix
(Dark Matter)
11
这不针对任何特定配置或 Cloudflare,只是另一个数据点和观点:
我们可以通过 Apache2 和 Nginx 以多种方式设置代理,将“裸 IP 地址(例如端口 80)”重定向到任意其他 FQDN。
实现方法有很多(如重写并重定向、虚拟主机并重定向等)。
例如,我们可以在反向代理上创建一个虚拟主机,让该反向代理监听特定 IP 地址的 80 端口,并将所有请求重定向到我们选择的任意 FQDN(或 IP 地址)。
我们也可以使用 Apache2 的 mod_rewrite 模块或 Nginx 的重写规则,通过反向代理实现相同功能。
在我们所有 Discourse 部署(生产环境)中,Discourse 前面都部署了反向代理(部分使用 Apache2,部分使用 Nginx)。通过配置反向代理来处理此类问题及特殊情况,可以轻松地缓解这些问题(当它们出现时)。
话虽如此,我并未将 Cloudflare 作为反向代理的特殊案例来使用,但看起来任何代理都可以配置为管理此类问题,就像任何反向代理都可以配置为将“几乎任何内容重定向到任何其他内容”一样。
更进一步,如果我是商业代理用户(如 Cloudflare),并且希望将某个特定 IP 地址或域名重定向(或黑洞化),我会配置(或请求)该代理(此处为 Cloudflare)将“端口 80 上的裸 IP 地址”重定向到我选择的 FQDN(或任意位置)。
这正是代理设计用来处理的功能;如前所述,使用 Apache2 或 Nginx 可以轻松实现此类重定向,因此我推测(虽然我不是 Cloudflare 用户),像 Cloudflare 这样的商业服务也能轻松管理此类简单的重定向。
3 个赞
elijah
(Eli the Bearded)
12
我使用以下配置,将直接通过 IP 访问的机器人重定向到特殊页面:
server {
listen 80;
# listen [::]:80;
server_name ~^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+;
root /var/www/ip-address;
default_type text/plain;
index nothing.doing;
location / {
try_files $uri /nothing.doing;
}
}
但我和其他人一样,也无法在我的私有论坛中通过 IP 直接访问。我总会收到重定向。而且我的论坛没有任何特殊配置,没有使用 Cloudflare,并且实际上运行在一台每月 0 美元的虚拟服务器上,没有任何额外功能。
3 个赞
michaeld
(Michael - Communiteq)
13
但如果你仔细想想,可能会意识到它们都运行在负载均衡的架构上,这些基础设施的成本高达(数千万)美元。因此,它们同样不具备代表性。
迁移并不会复制任何 nginx 设置,因此这实际上是一次全新安装。
2 个赞
太好了,感谢分享这段代码片段 @elijah,非常感谢!我会用你的正则表达式替换硬编码的 IP,或者直接使用完整的代码片段。
2 个赞
是的,这进一步表明这些网站很可能无法通过任何直接 IP 地址在 Web 上访问。无论如何,似乎没有人支持允许通过 Web 进行不安全的直接 IP 访问。
是的,你说得对。
1 个赞
我刚刚测试了在 Digital Ocean 上使用其市场应用快速启动两个 Discourse 实例。
我想在几乎无需自定义配置的情况下进行测试,只需编辑 SMTP、开发邮箱和 discourse_hostname,填入虚假详情(以允许重建)。
由于我设置的域名/子域名未能通过域名验证步骤,安装程序停止了(并建议手动编辑 app.yml 文件后重新构建)。
在编辑 app.yml 并重新构建后(仅修改了 SMTP、开发邮箱和 discourse_hostname),网站可以通过 IP 地址以不安全的方式访问,无需涉及 Cloudflare,也不会重定向到设置的 discourse_hostname。
我的大多数安装并未使用 Digital Ocean 市场应用进行设置,而是通过标准的 Docker 安装指南手动完成的。
需要注意的是,由于无法验证域名而导致安装程序停止的情况,也发生在我最近进行的两次使用 Cloudflare 的安装中,这可能是因为代理设置。其他安装则是在安装程序中尚未加入域名验证步骤之前完成的。
编辑:请注意,在初始安装过程中,8 个 Discourse 实例中仅有 2 个出现了域名验证问题(不包括上述两个测试实例)。Discourse 设置脚本建议在出现域名验证错误时手动编辑 app.yml 并重新构建。如果这没什么用也没关系,这对我自己来说并非解决方案。
编辑:通常使用 Cloudflare 的灵活 SSL,而不是 Let’s Encrypt(后者会更好)。感谢 @neounix。
neounix
(Dark Matter)
17
供参考 @markersocial
我们所有的 Discourse 安装都会将 http://the.ip.add.res 重定向到 .yml Discourse 容器文件中通过启用 LETSENCRYPT 配置的 https://FQDN。
要使这一切正常工作,并且让 LETSENCRYPT 证书生效,您需要一个完全正常的 SSL 配置(通常使用 LETSENCRYPT),这一点您应该已经知道了。
只是提醒一下……希望这能帮到您。
2 个赞
Falco
(Falco)
18
Vanilla 拥有有效域名并使用 discourse 设置脚本。
如果您两者都不做,结果不同也就不足为奇了。
此主题没有可操作的信息,而且如果按照说明操作,我们无法复现该问题。
7 个赞