安装 Let's Encrypt SSL 时 www 和非 www 的问题

TLDR:只有一个版本(www 或非 www)能配合 SSL 正常工作,必须与安装时提供的主机名一致。

这与 Let’s Encrypt SSL 安装有关,具体说明见 文档

因此,在启动安装程序后,系统会提示输入:

您的 Discourse 主机名?[discourse.example.com]: 

我输入了 example.app

接下来,安装 Discourse 后,我发现 SSL 在 www 版本上无法正常工作,而非 www 版本则正常。

理想情况下,我希望 www 和非 www 版本都能启用 SSL。


这次我使用 www.example.com 作为主机名重复了整个安装过程,结果非 www 版本的 SSL 无法正常工作。

我遗漏了什么?

An easy solution without much messing with the core will be to run discourse behind an nginx reverse proxy and configuring ssl from there.

Other way (I’m not very sure of it) may be to add a letsencrypt command to the ‘after commands’ in app.yml.

My problem is similar to SSL working on root, but not on www
I am not getting whole point. In my case, DNS record is also fine. I followed the step by step instruction, I believe it should work, but it’s not working.

Your topic & the topic you mentioned seem unrelated as discourse generates a valid certificate for the hostname you specify during install, in the other topic, when they install on www, their cert reports as invalid. I don’t think discourse supports multiple domains for standalone install natively.

Is there any solution for above problem?

Currently i have installed discourse on “example.com”. I have installed lets encrypt on example.com but did not work with www version.

I want to run discourse site as https://www.example.com

How can i do that?

@PoojaPatel
Assuming, www is your canonical version for Discourse. But you installed Let’s Encrypt only for apex domain.

Here’s fix…

  • Re-install Discourse
  • Install SSL for your www because that is your canonical
  • Restore Discourse backup
  • Setup Cloudflare
  • Go to DNS
  • Enable its DNS only for www CNAME or A record.
  • However must enable its DNS as well proxy for apex domain
  • Choose Flexible SSL
  • Force HTTPS

EXPECTED: HTTPS version should work fine for redirecting users from non-www to www version. Once I fixed SSL error this problem using this method.

Short version without re-installing SSL at www as per your canonical URL, That I cannot recommend.
(Setup Cloudflare proxy completely over www and non-www)

An easier solution is to run discourse behind a reverse proxy like nginx and setting up the SSL and appropriate redirects from there as enabling cloudflare for discourse brings in a whole lot of problems on it’s own.

When I re-install discourse, is my website hostname as www.example.com?

I have installed discourse One-Click Application from DO. Which method are you recommend, One click or Linux command?

Install SSL for your www because that is your canonical

When i installing SSL from below method, I have not entered my domain details, so where i have to add www version of my website address?

However must enable its DNS as well proxy for apex domain

Pls, can you let me more, how to do above step?

Force HTTPS - which option i have to select because there are three option related to https?

  1. Always use HTTPS
  2. HTTP Strict Transport Security (HSTS)
  3. Automatic HTTPS Rewrites

This is how the Let’s encrypt template requests the certificate:

Specifically --issue -d $$ENV_DISCOURSE_HOSTNAME meaning that it only issues a request for the hostname given to discourse. In order to get both www and non-www you need to adjust the template to issue more than one -d argument.

Something like as shown here:
(read the replies, some adjustments to the original topic are necessary but I am unable to edit it)

Similar situation here. I installed Discourse on example.com and had a CNAME DNS record for www.example.com.

Now I went to https://check-your-website.server-daten.de and got a bad rating, because the SSL certificate was not valid for www.example.com and also http://www.example.com was forwarding to https://example.com.

Steps I took:

  • Replace CNAME record for www.example.com by A and AAAA records.
  • Add www.example.com as an additional domain to app.yml following
    Redirect additional domain(s) to your Discourse instance
      after_web_config:
      - replace:
          filename: /etc/nginx/nginx.conf
          from: /sendfile.+on;/
          to: |
            server_names_hash_bucket_size 64;
            sendfile on;
      - file:
          path: /etc/nginx/conf.d/discourse_redirect_1.conf
          contents: |
            server {
              listen 80;
              server_name www.example.com;
              return 301 $scheme://example.com$request_uri;
            }
    
  • Adjust SSL following Set up Let’s Encrypt with multiple domains / redirects
    after_ssl:
      - replace:
          filename: "/etc/runit/1.d/letsencrypt"
          from: /-k 4096 -w \/var\/www\/discourse\/public/
          to: |
            -d www.example.com -d example.com -k 4096 -w /var/www/discourse/public
    
      - replace:
          filename: "/etc/runit/1.d/letsencrypt"
          from: /-k 4096 --force -w \/var\/www\/discourse\/public/
          to: |
            -d www.example.com -d example.com -k 4096 --force -w /var/www/discourse/public
      - replace:
          filename: "/etc/nginx/conf.d/discourse.conf"
          from: /return 301 https.+/
          to: |
            return 301 https://$host$request_uri;
      - replace:
          filename: "/etc/nginx/conf.d/discourse.conf"
          from: /gzip on;[^\}]+\}/m
          to: |
            gzip on;
            add_header Strict-Transport-Security 'max-age=31536000';
    
  • ./launcher rebuild app

Now, the rating for the site has improved, but one issue remains:

Wrong redirect http ⇒ http

Somewhere there’s 301 redirect
http://www.example.com ⇒ http://example.com.
I guess it should be
http://www.example.com ⇒ https://www.example.com ⇒ https://example.com

Any idea how to achieve this?

FYI, for anybody referencing this post, the /etc/runit/1.d/letsencrypt file changed a little over a month ago and the replace regex in these for www and non-www won’t work anymore.

See this post, for updated info: Setting up Let’s Encrypt with Multiple Domains