头像、站点徽标和证书错误

这是其中一个实例的链接:
https://discourse.mobiusnode.io

它已关闭。X-Forwarded-Proto 已包含在我的服务器块中。因此,根据您们分享的所有链接,我尚未采用的唯一元素(或元素组)如下:

# 使用的基础模板;可裁剪以减少每个容器模板的功能:
# - "templates/cron.template.yml" # cron 现已包含在基础镜像中
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/sshd.template.yml"
- "templates/web.template.yml"
# - "templates/web.ssl.template.yml" # 移除 - HTTPS 将由外部 Nginx 处理
- "templates/web.ratelimited.template.yml"
- "templates/web.socketed.template.yml" # <-- 已添加
# 需要暴露哪些端口?
# expose: 注释掉整个部分

我在三个浏览器(Edge、Firefox 和 Chrome 移动版)中加载了该站点,作为匿名用户时获得了完全合法的证书。请提供您复现此问题的具体步骤。

以用户身份注册,注册并登录后,问题便接踵而至,并出现之前提到的错误。

好的,我现在就用 Firefox 注册一个假用户。

您的邮件从未到达我的收件箱。我已尝试重新发送,但无果。你们这里只是手动激活账户吗?

没有。它们很可能被归入了垃圾邮件或垃圾箱。目前没有任何用户就此提出投诉。

这里并没有出现严重问题。一个潜在的问题是您的邮件中仍包含 http:// 链接。
不过,我在激活账户时被正确重定向到了 HTTPS 站点,且此处未看到任何与 SSL 相关的错误。

所以,是的,我有 99% 的把握认为您的 force_https 未启用,或者您的安装存在非常严重的问题,导致了这种情况。

我的服务器块中已配置了重定向,因此那里显示哪个链接并不重要。它始终会重定向到 https。

你错了。如果启用了强制 HTTPS,Discourse 必须将所有链接以 HTTPS 形式发出。与论坛相关的每一个链接都必须通过 HTTPS 加载。如果你仍然做些奇怪的事情,而不按建议的方式操作,那就只能靠你自己了。我们只能提供标准流程范围内的帮助,超出范围的就无能为力了。

这对我来说不太合理。如果我们从逻辑上拆解一下,我实际上是在用 server 块做 force-https 本意要做的事情。

另外,当我启用 force-https 时,我的网站会出错,用户也无法进行身份验证。

force_https 不仅仅是一个重写规则,它在内部还执行了更多操作。如果您希望问题得到解决,我们已经提供了相应的方案。如果您拒绝该方案,请自行着手处理并探索其他途径。

这是因为您的反向代理不稳定。您必须自行排查问题所在,并采用正确的方式处理。我们无法为您的自定义方案提供支持。

所有已提供的“解决方案”都不符合我的具体使用场景:

  • 远程服务器(位于同一网络内)——我认为所有示例都假设 Nginx 与 Discourse 运行在同一台服务器上,而我使用的是 proxy_pass 来访问另一个内部 IP。

我为什么要这样做?是为了更高的安全性和资源分散。这也是我将服务按容器和虚拟机两种方式拆分的原因。所建议的文档似乎倾向于所有服务都运行在同一台服务器上的场景。

我想上述条件应该相当常见。如果其中任何条件能够适应 proxy_pass 的场景,我非常乐意调整我的设置以符合要求。我只是觉得,仅仅因为我想避免“把所有鸡蛋放在一个篮子里”的情况,就给出一个笼统的“自求多福”的声明,未免有些欠妥。

proxy_pass 192.168.20.10:8080

在 Discourse 中,暴露 192.168.20.10:8080:80

移除套接字模板。

启用 force_https。

大功告成。

这比你刚才写的内容要复杂得多,有很多影响需要我进一步调查——我们本可以从那里开始。:wink:

立即可问的问题:

  1. 在 app.yml 中将默认监听端口改为 8080?
  2. 那 SSL 443 端口呢?保留 443 吗?
  3. 从 Nginx 服务器块中移除 80 端口的重定向?
  4. 如果我只是在内部侧更改 proxy_pass,那么第 3 点重要吗?可能不重要?我只是将流量重路由到 8080 吗?
  5. 最大的问题:为什么?为什么从 80 改为 8080 会有区别?
  6. 保持所有其他模板处于激活状态?只注释掉 socketed

感谢你的帮助和耐心。

这只是你的个人偏好,我写的时候只是作为示例。你也可以选择暴露 80 端口。

在局域网内启用 SSL 没有任何好处或意义。

这个必须保留。

server {
    listen 80;
    server_name discourse.example.com;
    return 301 https://example.com$request_uri;
}

正是如此。你正在将所有由代理/入口接收到的请求转发到内部后端(即 Discourse)的 8080 端口。

第 1 点已经回答过了,这只是个人偏好,你可以随意选择喜欢的端口。

你特别不需要任何与内部服务器上的套接字或 SSL 相关的内容。SSL 应该在反向代理上正确终止。

注意:其中大部分是基于客户部署的个人偏好。

好的,谢谢您的评论。

以下是我的 Nginx 服务器块配置,供您参考:

server {
# ssl
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name discourse.mobiusnode.io;
location / {
# http 流量
proxy_pass http://192.168.86.108;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
ssl on; ssl_certificate /path/to/certificate/domain.io/fullchain.pem; # 由 Certbot 管理
ssl_certificate_key /path/to/certificate/domain.io/privkey.pem; # 由 Certbot 管理
ssl_ciphers ‘ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256’; ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000;";
ssl_stapling on; ssl_stapling_verify on;
client_max_body_size 0;
}
server { if ($host = discourse.mobiusnode.io) {
return 301 https://$host$request_uri; } # 由 Certbot 管理
listen 80;
listen [::]:80;
server_name discourse.mobiusnode.io; return 404; # 由 Certbot 管理
}`

我遇到的行为是在上述条件下发生的。

app.yml 的开头如下:

## 这是 Discourse Docker 容器的全功能独立模板
##
## 修改此文件后,您必须重新构建
## /var/discourse/launcher rebuild app
##
## 编辑时请*非常*小心!
## YAML 文件对空格或对齐错误极其敏感!
## 如需验证此文件,请访问 http://www.yamllint.com/

templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## 如果您想添加 Lets Encrypt (https),请取消注释以下两行
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"

## 此容器应暴露哪些 TCP/IP 端口?
## 如果您希望 Discourse 与另一个 Web 服务器(如 Apache 或 nginx)共享端口,
## 请参阅 https://meta.discourse.org/t/17247 了解详情
expose:
- "80:80" # http
- "443:443" # https

params:
db_default_text_search_config: "pg_catalog.english"

## 将 db_shared_buffers 设置为总内存的最大 25%。
## 将根据检测到的 RAM 由引导程序自动设置,您也可以覆盖此值
db_shared_buffers: "1024MB"

## 可能改善排序性能,但会增加每个连接的内存使用量
#db_work_mem: "40MB"

## 此容器应使用哪个 Git 修订版本?(默认:tests-passed)
#version: tests-passed

您正在连接到第二台 nginx 的 80 端口,因此它认为您是通过 http 而非 https 进行连接。

请尝试在内部 nginx 中查找 X-Forwarded-Proto,并将 proxy_set_header X-Forwarded-Proto $thescheme; 修改为 proxy_set_header X-Forwarded-Proto https;

或者将您的流量转发至 https:proxy_pass https://192.168.86.108

这部分需要修改