How should I enable letsencrypt while discourse is beside other websites


(Hosein Naseri) #1

I’m running discourse with other websites and I’ve configured that according to this guide.

now I want to use letsencrypt to secure my discourse. However in this topic, it says we shouldn’t follow it if we run other websites. and I didnt find other how to topics about this situation.

can someone elaborate what should we do in this situation?


(Felix Freiberger) #2

You can puzzle the steps together by following my guide about setting up an offline page:

The guide assumes you start out with Discourse not running behind nginx and guides you through setting up nginx including Let’s Encrypt and setting up an offline page. You should be able to simply skip what you’ve done already, and stop as soon as the offline page work starts :slight_smile:

(The core idea is to set up Certbot on the host, configure nginx to redirect most HTTP traffic to HTTPS but answer acme-challenge queries from the webroot, and teach nginx to use the resulting cert.)


(Matt Palmer) #3

The second sentence of the topic you linked to provides the answer:

How you do that is dependent on how you’ve setup the host system, and is beyond the scope of what a Discourse-specific guide can provide. There are no shortage of guides on the Internet for setting up Let’s Encrypt in all manner of situations.


(Christoph) #4

I also followed those guides and was puzzled until I realized that it basically means, I don’t need to do anything because my outer NGINX is already taking care of SSL (there is also an inner NGINX running in the docker container but you don’t have to do anything with that one in your setup. Or rather: it doesn’t have to know anything about SSL, which is why you’re supposed to remove "templates/web.ssl.template.yml" from your app.yml).

I’m not sure it’s helpful when I say that you “don’t have to do anything” because of course you have to setup your outer NGINX according to the guide you linked:

But once you’ve done that, you’re fine.

For a better understanding: the discourse.conf becomes part of the nginx.conf and it basically tells NGINX that all traffic going to your discourse forum should also be SSL encrypted.


(Hosein Naseri) #5

I have read your guide and it does make sense for me. However when I want to apply it, I have so many difficulties. The thing is right now I have two conf files for nginx to make discourse work.
the first one is in /etc/nginx/conf.d/discourse.conf and it includes:

server {
listen      185.51.200.214:80;
server_name talk.zabanshenas.com www.talk.zabanshenas.com;
error_log  /var/log/httpd/domains/talk.zabanshenas.com.error.log error;
access_log     /var/log/httpd/domains/talk.zabanshenas.com.log combined;
access_log     /var/log/httpd/domains/talk.zabanshenas.com.bytes bytes;

location / {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_http_version 1.1;
}

include /home/admin/conf/web/nginx.talk.zabanshenas.com.conf*;
}

the second one is in home/admin/conf/web/nginx.conf and it contains:

server {
    listen      185.51.200.214:80;
    server_name talk.zabanshenas.com www.talk.zabanshenas.com;
    error_log  /var/log/httpd/domains/talk.zabanshenas.com.error.log error;

    location / {
        proxy_pass      http://185.51.200.214:8080;
        location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|htm|html|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
            root           /home/admin/web/talk.zabanshenas.com/public_html;
            access_log     /var/log/httpd/domains/talk.zabanshenas.com.log combined;
            access_log     /var/log/httpd/domains/talk.zabanshenas.com.bytes bytes;
            expires        max;
            try_files      $uri @fallback;
        }
    }

    location /error/ {
        alias   /home/admin/web/talk.zabanshenas.com/document_errors/;
    }

    location @fallback {
        proxy_pass      http://185.51.200.214:8080;
    }

    location ~ /\.ht    {return 404;}
    location ~ /\.svn/  {return 404;}
    location ~ /\.git/  {return 404;}
    location ~ /\.hg/   {return 404;}
    location ~ /\.bzr/  {return 404;}

    include /home/admin/conf/web/nginx.talk.zabanshenas.com.conf*;
}

now can you take a look at these and tell me what part should I change?

Christoph if you also take a look at these two files and tell me which one is inner and which one is outer nginx from your definition, that would be great.


(Felix Freiberger) #6

Both files configure the outer nginx. They need to be changed to serve https on port 443, and be updated to include the ssl settings.

In addition, you need a third server block for HTTP.


(Christoph) #7

As I said, you have no business with the inner NGINX so all NGINX config files you are fiddling with are outer NGINX and that is how it’s supposed to be.

Having said that, I’m not sure why you’re editing the nginx.conf directly. While, in principle, there’s nothing wrong with that, it seems to be common practice to leave nginx.conf more or less alone and make your adjustments in /etc/nginx/sites-enabled/default (which is identical with /etc/nginx/sites-available/default).

But I’m a newbie at this myself, so I am not able to just read your files and pinpoint to where the problem lies, especially since you are not saying anything about the issues you are having. One thing I notice, though, is that you have included your /home/admin/conf/web/nginx.talk.zabanshenas.com.conf*; twice. That makes no sense. And generally, those two files don’t look familiar to me at all. Are you sure you followed the guides you linked earlier?


(Felix Freiberger) #8

Here’s a slightly more detailed battle plan:

  • Backup /etc/nginx!
  • Update your existing configurations to listen on port 443. That’s invalid (nginx will speak HTTP on port 443), but we’ll fix that once we have the certificate. Doing so will free up port 80, so your existing configs cannot conflict with getting your first cert.
  • Add the first configuration snippet after the Add HTTPS section header in my offline guide to either one of your config files, or an additional one in sites-available that you link to in sites-enabled.
  • service nginx reload
  • Install Certbot and get a certificate. Follow the instructions in my guide to do so. Supply multiple domains (with multiple -d arguments) to Certbot so you get one cert that covers all relevant domains (talk.zabanshenas.com and www.talk.zabanshenas.com).
  • When you got the cert, adapt your existing configs (that you already changed to port 443) to match the last configuration snippet in the Add HTTPS section header in my guide: Update the listen line and add the lines that configure SSL. Leave the rest as is.
  • service nginx reload

If all went well, your sites should be served via HTTPS, and there should be an automatic redirect to HTTPS.


(Hosein Naseri) #9

that also makes no sense to me too. However I’ve got that from @Sergiz in this topic. I removed it from my /etc/nginx/conf.d/discourse.conf and It works. so I suppose that was a redundant line?

anyway, I think I got it working However I’m not pretty much sure if I’m doing everything right. so I share it here.

for future reference. My discourse is running with VestaCP on Centos 7, which I managed to configure it here.

to make it working with https, I changed the following files thanks to @fefrei and @riking

1- /etc/nginx/conf.d/discourse.conf:

server {
listen      185.51.200.214:80;
server_name talk.zabanshenas.com;
location /.well-known/acme-challenge/ {
root /home/admin/web/talk.zabanshenas.com/public_html;
}
location / {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_http_version 1.1;
}

}
server {
  listen 185.51.200.214:443 http2 ssl;
  server_name talk.zabanshenas.com;  # <-- change this

  ssl on;
  ssl_certificate      /etc/letsencrypt/live/talk.zabanshenas.com/fullchain.pem;
  ssl_certificate_key  /etc/letsencrypt/live/talk.zabanshenas.com/privkey.pem;

  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 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;

  add_header Strict-Transport-Security "max-age=63072000;";
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
  ssl_stapling on;
  ssl_stapling_verify on;

  client_max_body_size 0;

  location / {
    proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
    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;
  }
}

2- /home/admin/conf/web/snginx.conf :

server {
    listen      185.51.200.214:443 http2 ssl;
    server_name talk.zabanshenas.com;
    ssl         on;
    ssl_certificate      /etc/letsencrypt/live/talk.zabanshenas.com/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/talk.zabanshenas.com/privkey.pem;
    error_log  /var/log/httpd/domains/talk.zabanshenas.com.error.log error;

    location / {
        proxy_pass      https://185.51.200.214:8443;
        location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|odt|ods|odp|odf|tar|wav|bmp|rtf|js|mp3|avi|mpeg|flv|html|htm)$ {
            root           /home/admin/web/talk.zabanshenas.com/public_html;
            access_log     /var/log/httpd/domains/talk.zabanshenas.com.log combined;
            access_log     /var/log/httpd/domains/talk.zabanshenas.com.bytes bytes;
            expires        max;
            try_files      $uri @fallback;
        }
    }

    location /error/ {
        alias   /home/admin/web/talk.zabanshenas.com/document_errors/;
    }

    location @fallback {
        proxy_pass      https://185.51.200.214:8443;
    }

    location ~ /\.ht    {return 404;}
    location ~ /\.svn/  {return 404;}
    location ~ /\.git/  {return 404;}
    location ~ /\.hg/   {return 404;}
    location ~ /\.bzr/  {return 404;}

    include /home/admin/conf/web/snginx.talk.zabanshenas.com.conf*;
}

3- /home/admin/conf/web/shttpd.conf :

<VirtualHost 185.51.200.214:8443>

    ServerName talk.zabanshenas.com
    ServerAlias www.talk.zabanshenas.com
    ServerAdmin info@talk.zabanshenas.com
    DocumentRoot /home/admin/web/talk.zabanshenas.com/public_html
    ScriptAlias /cgi-bin/ /home/admin/web/talk.zabanshenas.com/cgi-bin/
    Alias /vstats/ /home/admin/web/talk.zabanshenas.com/stats/
    Alias /error/ /home/admin/web/talk.zabanshenas.com/document_errors/
    #SuexecUserGroup admin admin
    CustomLog /var/log/httpd/domains/talk.zabanshenas.com.bytes bytes
    CustomLog /var/log/httpd/domains/talk.zabanshenas.com.log combined
    ErrorLog /var/log/httpd/domains/talk.zabanshenas.com.error.log
    <Directory /home/admin/web/talk.zabanshenas.com/public_html>
        AllowOverride All
        SSLRequireSSL
        Options +Includes -Indexes +ExecCGI
        php_admin_value open_basedir /home/admin/web/talk.zabanshenas.com/public_html:/home/admin/tmp
        php_admin_value upload_tmp_dir /home/admin/tmp
        php_admin_value session.save_path /home/admin/tmp
    </Directory>
    <Directory /home/admin/web/talk.zabanshenas.com/stats>
        AllowOverride All
    </Directory>


    <IfModule mod_ruid2.c>
        RMode config
        RUidGid admin admin
        RGroups apache
    </IfModule>
    <IfModule itk.c>
        AssignUserID admin admin
    </IfModule>

    IncludeOptional /home/admin/conf/web/shttpd.talk.zabanshenas.com.conf*

</VirtualHost>

Now normally, I should put the following in the shttpd.conf

SSLEngine on
    SSLVerifyClient none
    SSLCertificateFile /etc/letsencrypt/live/talk.zabanshenas.com/cert.pem;
    SSLCertificateKeyFile /etc/letsencrypt/live/talk.zabanshenas.com/privkey.pem;
    SSLCertificateChainFile /etc/letsencrypt/live/talk.zabanshenas.com/chain.pem;

However when I added that and restarted httpd, It gave error telling that cert.pem is missing while it was obviously there. So I removed all of these lines and restarted httpd and it worked. So at this point, I dont know if I’m doing something wrong.


(Felix Freiberger) #10

Your Apache installation doesn’t need to know about HTTPS – nginx will handle all this, and pass through only HTTP :slight_smile:


(Hosein Naseri) #11

I followed these steps and were able to enable https. However I have a major problem. Now my discourse forum only supports TLS v1.2 and not TLS v1.1 and TLS v1. Not supporting TLS v1.1 and v1 means not supporting android version < 4.4 which is a huge deal. So is there anything I should do to fix this?

There is a template for ssl that can be included in app.yml. However I dont know if in this setup I should include that.

Any idea?


(Jeff Atwood) #12

It sounds to me like Chrome supports TLS 1.2 just fine on older Android

The only components affected are the built in OS browser components, which would never be used to render Discourse.


(Hosein Naseri) #13

My problem isn’t browser actually. My problem is api calls. Some api calls in my android app give SSL error in lower versions of android. So I really think I should support TLS v1.1 and v1.0


(Jeff Atwood) #14

This is not our problem, since it has nothing to do with Discourse.


(Hosein Naseri) #15

My question is whether I need to comment out SSL template that is provided in app.yml or not? In that template there is a section that I think enables TLS v1.1 and 1


(Hosein Naseri) #16

I mean this line
## Uncomment these two lines if you wish to add Lets Encrypt (https)
- “templates/web.ssl.template.yml”


(Jay Pfaffman) #17

You can try that.

Another solution might be to move Discourse to another port and have CaddyServer reverse proxy for you. It purports to support TLS down to 1.0.


(Matt Palmer) #18

Nginx supports TLS v1.0 as well, if you want to configure it that way. You need to fix your API calls to use TLS v1.2; older TLS versions are really, really awful. You know it’s bad when even the PCI people are banning it.