Sunday, August 25, 2019

Add HTTPS to FreeNAS Nextcloud plugin

Using Let's Encrypt and certbot with auto-renewal.

I installed the Nextcloud plugin some time ago in FreeNAS and found it useful, but it had no support for HTTPS at all. Initially I only used it internally so that was okay-ish, but wanted to roam, and even internally certain integrations just won't work at all without it (WebDAV, see my previous post). So I had a working install and didn't want to have to redo it all, I just wanted to add HTTPS. Of course, it is rare to find a straightforward, and complete answer on the Internet to a specific circumstance, even one that seems like it should be common.

If I wasn't time-poor, or was starting from scratch and was aware of this limitation I'd probably have used this automation script or this guide to hardening instead, or even better, a Docker container with configuration as code, but for that to work I'd have to get Docker working again...

My instructions are partly from https://www.ixsystems.com/community/threads/nextcloud-lets-encrypt-nginx.72643/ but I did NOT allow SSH direct to the nextcloud host, I go through the FreeNAS host using jexec. You could also use the shell in the UI but it's painful.

Prerequisites:
  • A domain name which you can point to your FreeNAS host, perhaps with a subdomain using a CNAME record. 
  • Control over port forwarding to FreeNAS - you'll need to enable port 80 for certbot to work (though I am unsure if it needs to be to the Nextcloud instance, actually) 
  • Basic command line knowledge including how to connect to the specific jail 

Brief steps:
  • Connect to your nextcloud host command line - if you don't know how to do that, this guide is too brief for you, sorry :) 
  • Allow installing packages: vi /usr/local/etc/pkg/repos/FreeBSD.conf and change no to yes. (Recommended to change it back later)
  • You may want to install a more preferable editor than vi at this point. 
  • Install certbot: pkg install py27-certbot
  • certbot certonly --webroot -w /usr/local/www/nextcloud -d your-domain-name.com
  • certbot renew --dry-run
  • crontab -e and add this to regularly check and renew if necessary: 
    • 0 0,12 * * * /usr/local/bin/python2.7 -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot renew --quiet
  • Now you have a certificate and all the automation to keep it up to date!
  • Next we add HTTPS listener and redirect from HTTP - this was missing from other instructions I saw. 
  • edit /usr/local/etc/nginx/conf.d/nextcloud.conf
  • There will just be a server entry for port 80. Break it up like this:
    • server {
    •   listen 80;
    •   server_name _;

    •   return 301 https://$host$request_uri;
    • }

    • server {
    •   listen 443 ssl;
    •   ssl on;
    •   ssl_certificate "/usr/local/etc/letsencrypt/live/your-domain-name/fullchain.pem";
    •   ssl_certificate_key "/usr/local/etc/letsencrypt/live/your-domain-name/privkey.pem";

    •   server_name _;

  • service nginx configtest
  • If the above is ok: service nginx reload
  • https://scan.nextcloud.com/ to check your security 
  • Turn off the package repos again to reduce attack surface. 
It's probably a good idea to upgrade Nextcloud while you're there:

$ pkg update
$ pkg upgrade nextcloud-php71
$ cd /usr/local/www/nextcloud
$ su -m www -c "php ./occ upgrade"


No comments: