downey
(Michael Downey)
1
当通过备份将 Discourse 从一个主机名迁移到另一个主机名时,管理员可能希望保留旧主机名,同时让 Web 服务器将请求重写为使用新的规范名称,例如:
https://old.example.org/t/my-great-topic/12345 
https://new.example.org/t/my-great-topic/12345
不幸的是,这并不像仅仅在 DNS 中更改 CNAME 或 A 记录那样简单;浏览器客户端会生成错误或警告,因为主机名与通过 Let’s Encrypt 由 Discourse 安装生成的证书不匹配。
在手动安装 Web 服务器的情况下,我会使用 certbot 工具为其 生成包含多个名称的证书。然而,Discourse 的配置仅将 Discourse 主机名传递给 Let’s Encrypt,并且在 Discourse 配置中似乎没有关于别名的概念。
有人设置过这样的配置吗?或者对如何实现它有什么想法吗? 我想这可能需要对 SSL 和 Let’s Encrypt 模板进行一些修改。
2 个赞
maiki
(maiki)
2
这并非 Discourse 特有的问题,但当我需要通过 HTTPS 进行重定向时,我通常会直接重定向所有内容。也就是说,由一台服务器负责将旧地址重定向到新地址。一些托管选项会在后台处理此事,有时被称为“域名重定向”或“转发”服务。
我现在甚至不再考虑其他方案了,因为每次尝试其他方法都会非常麻烦。
2 个赞
michaeld
(Michael - Communiteq)
3
Discourse 只会响应一个主机名。如果您需要多个主机名——而您的用例(支持旧主机名)是最常见的情况——那么您需要将其中一个重定向到另一个。
我建议在该操作在 Discourse 外部进行。只需创建一个 nginx 配置,该配置拥有自己的证书,为旧主机名设置 server_name,并将所有内容重定向到新主机名。
3 个赞
downey
(Michael Downey)
4
实际上,如果您使用的是基于 Docker 的单实例单服务器安装,它可以正常响应任意数量的 DNS 条目(nginx 正在端口 80 和 443 上监听所有主机名),并正确地将 URL 重写为规范的“新”主机名。这部分运行良好且毫无问题。(有意测试此功能的人可以尝试在机器的 hosts 文件中添加一个假域名,并将其指向您喜欢的 Discourse 站点的 IP 地址。)
我遇到的唯一问题是 SSL 警告,因为 nginx 的重写响应来自 https://old.example.org/foo,并发送 HTTP 302 重定向到新 URL。
如果可以的话,我更不愿意为了执行重写规则而维护一个单独的 Web 服务器。
1 个赞
michaeld
(Michael - Communiteq)
5
你不需要这样做,只需要在配置中添加一个额外的 server 部分即可。
2 个赞
pfaffman
(Jay Pfaffman)
6
2 个赞
downey
(Michael Downey)
7
更新: 已在独立安装中成功配置辅助域名,并签发了 Let’s Encrypt 证书以同时处理新旧域名。
前提条件:我尚未更改 DNS 将用户指向新站点;我希望提前确保一切正常运行。因此,我在测试机上使用了 localhost 条目。这意味着我无法进行常规的 Let’s Encrypt 验证,而必须使用 acme.sh 的“DNS”方法。该方法通常不推荐,因为它无法自动续期。但这对我而言没问题,因为我将在“初始”(新签发的双域名)证书的 30 天有效期内完成切换。
- 在我的
web_only.yml 文件(您可能使用的是 app.yml)中,在 hooks: 部分下、插件之前,添加以下内容:
after_ssl:
- replace:
filename: "/etc/runit/1.d/letsencrypt"
from: /--keylength/
to: "-d second-domain.com --keylength"
-
在 DNS 中,为 _acme-challenge.old.example.org 设置一个虚假/临时的 TXT 记录,TTL 设为 5 分钟(您也可以设置得更短),并等待其传播,以便快速使用 acme.sh(Let’s Encrypt)验证密钥进行更改。
-
停止站点并执行调试(测试)验证,使系统感知到新条目的短 TTL:
./launcher enter app
sv stop nginx
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
LE_WORKING_DIR=/shared/letsencrypt DEBUG=1 /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force
- 这次运行实际请求,不带调试设置。这将给出一个警告,其中包含您在第 2 步中创建的条目在 DNS 中应使用的值:
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force
-
更新 DNS,然后等待 5 分钟。是的,您应该等待整整这段时间,以避免触及 Let’s Encrypt 的限制。
-
运行与上一条命令类似的命令,但使用 renew 模式:
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force --renew
- 您应该收到确认信息。运行以下命令以清理环境并将新证书部署到位:
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --installcert -d new.example.org -d old.example.org --fullchainpath /shared/ssl/new.example.org.cer --keypath /shared/ssl/new.example.org.key --reloadcmd "sv reload nginx"
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
exit
- 最后一步,在您已退出 launcher 后:
rm -rf /var/discourse/shared/standalone/ssl
rm -rf /var/discourse/shared/standalone/letsencrypt
./launcher rebuild app
站点重新上线后,应已使用新证书运行。您可能需要清除浏览器中存储的证书,这留作读者练习,并可借助您常用的搜索引擎完成。
感谢那些为我指明正确方向的朋友们!
2 个赞
Stephen
(Stephen)
8
这是 Cloudflare 规则的理想应用场景——无需配置服务器。只需将相同的 URL 参数指向新域名即可。
需要为旧域名启用橙色云(代理)功能。
2 个赞
downey
(Michael Downey)
9
是的,像 Cloudflare(或者我想你也可以选择在你 Discourse 站点前部署自己的反向代理)这样的反向代理场景,可以通过在“更上层”实现重写规则来绕过这个问题。不过在这种情况下,出于安全和道德原因,Cloudflare 并不是一个可行的选项。
(请参见上文关于独立解决方案的说明。)
2 个赞
system
(system)
关闭
10
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.