How To: Let's Encrypt and NodeBB
-
Let's Encrypt and NodeBB
Summary
NodeBB is a special beast. One that takes careful grooming and maintenance. Ah, gone are the golden days of LAMP. That glorious "P", so easy to use but oh so poor on performance. With Node.js and socket.io living behind your webserver you no longer have the easy liberty of throwing down files and opening directory access any where you would like. What's that? You have to shutdown your NodeBB just to renew your Let's Encrypt SSL certificates? You are using SSL right? Shame, shame if you are not.
Take notice! You no longer need to shutdown your webserver and NodeBB just to renew those Let's Encrypt certificates if you make a simple change to your webserver configuration.
Back story
Let's Encrypt is a free SSL certificate authority. You run their software on your server that authenticates with their master control. The key is proving that you have rights to the domain you are requesting a certificate for. Their software is a webserver so you can't already be running one on port 80. Theirs needs to bind to that port. To run their software, to renew my certificate, I have had to shutdown my webserver (which makes my NodeBB forum unavailable). It doesn't take long but I was annoyed that my NodeBB forum would have to be offline during that time. I knew there must be a solution to this problem and there is in their "webroot" option.
The webroot flag keeps their software from needing to run as a webserver and just places special authentication files in your already existing webserver's html path. That is all fine-and-dandy for a typical LAMP setup but doesn't behave as well with Node.js, socket.io and NodeBB. It can behave though if you tell your webserver to exclude the super secret Let's Encrypt webroot path from going to NodeBB and point off somewhere else.
Webserver
We must tell the webserver that the
.well-known/acme-challenge
directory is not to be proxied off to socket.io like it needs to be for NodeBB.Nginx
These configurations need to be in the unencrypted (port 80) section of your webserver configuration.
Change yourdomainhere.com with your actual domain name.
server { listen 80; server_name yourdomainhere.com; root /var/www/yourdomainhere.com/html; ...
Add a location block for the Let's Encrypt directory
location /.well-known/acme-challenge/ { try_files $uri =404; }
Bonus: If you want to only serve https traffic for your NodeBB forum make your root location block something like this
location / { rewrite ^(.*) https://yourdomainhere.com$1 permanent; }
Reload Nginx for the changes to take affect.
sudo systemctl reload nginx
Apache (and others)
You will need to research how to setup the proper exclusion of the .well-known/acme-challenge directory from being proxied to socket.io.
Let's Encrypt
Linux
When it is time to renew your certificate (or create your certificate) you would run the following command.
Change yourdomainhere.com with your actual domain name.
sudo ./letsencrypt-auto certonly --webroot -w /var/www/yourdomainhere.com/html -d yourdomainhere.com -d www.yourdomainhere.com
certonly
means to only have the certificates generated and do not try to modify any webserver (Nginx) configuration files. That task is left to the student (you).--webroot
tells Let's Encrypt to not run as a webserver and not to bind to port 80-w
points to the actual path on disk that Nginx can serve files from. This is the place that the.well-known/acme-challenge
directory will be created in and inside of that directory Let's Encrypt will place temporary authorization files-d
the domain name that this certificate will authenticate for. Add additional-d
flags for each of the names you may have.
Windows (and others)
You will need to research the syntax to execute the letsencrypt-auto command but the flags should be very similar to the Linux ones shown above.
Caveats
Symbolic Links
It has been reported that symbolic links do not work well with the Let's Encrypt software. Therefore please avoid attempting to sym link the
.well-known/acme-challenge
directory to another location on your file system.Conclusion
What I have left out is the initial configuration of your webserver to accept SSL connections. There are numerous documents online to help with that portion. If it is done correctly for Let's Encrypt the certificate path will point to a live directory. Renewing the certificates only updates the files in the live directory and your webserver configuration is not touched.
With this configuration I am able to run the command to update my certificates without having to shutdown my webserver thus making NodeBB unreachable from my webserver proxy.
Contact me https://community.nodebb.org/user/rod#
-
I already covered this in my "High performance stack" tutorial. Still a nice tutorial.
-
@rod, is the root you specify in the nginx config arbitrary, an empty directory path that actually exists, or does it need to be the actual root of the public folder? I have a non-standard configuration where I have a dedicated user for running NodeBB, and the actual root location is in the home folder of that user (which is also non-standard, in the /usr/share/nginx dir)
EDIT: nvm, I forgot to specify the folder to save the file in with the
-w
flagThanks!
-
@Bri
root /var/www/yourdomainhere.com/html;
this one?It's not used by NodeBB, only by Let's Encrypt.
It will try to access the file located in
/.well-known/acme-challenge/
, and that is relative to theroot
as defined.For my Let's Encrypt setup, I instead use:
location "/.well-known/acme-challenge" { root /usr/share/nginx/html; }
... as that folder is served by nginx already, so less configuration (I modify my
./letsencrypt-auto
command according as well, of course) -
Cool, didn't know that you could put the "root" inside the location block, thanks!
-
@rod hi rod, im doing exactly what u r saying but i have a problem is where should i put the verification files? another saying is where to put these two files below to upload into
.well-known/acme-challenge/ directory?nOmtkseci4NqOwrx9OYnmtQaoNsPrqq7_JG3Kf4iVd8
NJpedX-UNHPAVRaur_ZNyiSjwpqrudSPuX2eL8PY010thanks.
-
I'm using a Lets Encrypt based service at https://www.sslforfree.com which allows DNS authentication instead of the two file uploads. Too much hassle to get that directory working ..
-
@01 You tell nginx where to look for the files.
server { listen 80; server_name yourdomainhere.com; ... location "/.well-known/acme-challenge" { root /usr/share/nginx/html; } }
This would mean the files you create are:
/usr/share/nginx/html/nOmtkseci4NqOwrx9OYnmtQaoNsPrqq7_JG3Kf4iVd8
/usr/share/nginx/html/NJpedX-UNHPAVRaur_ZNyiSjwpqrudSPuX2eL8PY010
-
@yariplus said in How To: Let's Encrypt and NodeBB:
@01 You tell nginx where to look for the files.
server { listen 80; server_name yourdomainhere.com; ... location "/.well-known/acme-challenge" { root /usr/share/nginx/html; } }
This would mean the files you create are:
/usr/share/nginx/html/nOmtkseci4NqOwrx9OYnmtQaoNsPrqq7_JG3Kf4iVd8
/usr/share/nginx/html/NJpedX-UNHPAVRaur_ZNyiSjwpqrudSPuX2eL8PY010
Thank you @yariplus, I have tried to reverse proxy these files over but didn't work. So I found a very easy way to do it.
I downloaded Caddy which is a tiny open source server, and verified the files use the caddy server. Everyone use LE ssl on nodebb should do it this way, much easier.Now I'm encountering a new problem, I tried to setup the certificates for my nodebb but it doesn't work.
This is my nginx config
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name mydomain.com; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:4567; proxy_redirect off; # Socket.IO Support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } server { # listen on ssl, deliver with speedy if possible listen 443 ssl http2; server_name mydomain.com; # change these paths! ssl_certificate /cert/bundle.crt; ssl_certificate_key /cert/mydomain.key; # enables all versions of TLS, but not SSLv2 or 3 which are weak and now deprecated. ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # disables all weak ciphers ssl_ciphers 'AES128+EECDH:AES128+EDH'; ssl_prefer_server_ciphers on; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:4567/; proxy_redirect off; # Socket.IO Support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } }
nodebb config
{ "url": "https://mydomain.com", "secret": "************************", "database": "mongo", "mongo": { "host": "127.0.0.1", "port": "*****", "username": "****", "password": "*****", "database": "****", "uri": "" }, "port": "4567" }
Any idea why it doesn't work?
-
@01 it's not "much easier", it's just wrong. If you don't use nginx to do it, you'll not be able to do automatic renewal correctly.
Is nginx running? It doesn't look like you actually modified your nginx config to include the static serving for acme challenge. Have you verified that the nginx config is valid?
-
@PitaJ said in How To: Let's Encrypt and NodeBB:
@01 it's not "much easier", it's just wrong. If you don't use nginx to do it, you'll not be able to do automatic renewal correctly.
Is nginx running? It doesn't look like you actually modified your nginx config to include the static serving for acme challenge. Have you verified that the nginx config is valid?
@PitaJ Sorry for the confusion, these two configs are for trying to setup ssl certificates on my nodebb, I have already verified with the acme challenge with the static server. I have got the ssl certificates already with the static server, with nginx I just don't know how to get it to work. So I gave up.
Im trying to get ssl work on my nodebb and I've been search everywhere but still can't get it to work, any suggestions? I think this nginx config should be valid, because nginx runs with this cinfg file. if there are errors in the config normally nginx wont run at all.
I got my certificates issued from this website https://zerossl.com/, to renew the certificates they said only require the csr file, so I have to manually renew it anyway. I hosted my nodebb on windows 10 so it's different to many of the docs and so hard to get everything to work.