Tim's blah blah blah

Setting up Nextcloud behind https nginx proxy

(Updated: )

I’ve been enjoying the free tier of TransIP’s stack (transip.nl) for years, but that’s cometo an end (tweakers.net). Instead of paying for an ‘upgraded’ account, I’ve decided to self-host using a Nextcloud (nextcloud.com) snap on Ubuntu LTS served by nginx.

On Ubuntu, Nextcloud is only available via source or snap (not apt). I went for snap to benefit from automatic updates. This guide is based onDigital Ocean’s guide (digitalocean.com) (A (archive.org)).


I want to achieve the following setup:


  1. Install nextcloud snap

    sudo snap install nextcloud

  2. Create admin account before going live

    sudo nextcloud.manual-install <user> <passwd>

  3. Set custom ports (e.g. 9081 and 9443) because we are behind nginx

    1. Find free port (linuxize.com) sudo netstat -tunlp
    2. Set nextcloud listening ports
      sudo snap set nextcloud ports.http=9081
      sudo snap set nextcloud ports.https=9443
  4. Set nginx virtual host with reverse proxy for port 80 acme challenge and port 443 for regular use. This can either be achieved via a server {} block (info 1 (nginx.com) (A (archive.org)) info 2 (digitalocean.com) (A (archive.org)) info 3 (samueldowling.com)) - requires ssl cert to be served by nginx — preferred because we trust nginx ssl more than apache bundled with the nextcloud package, also easier to combine with existing virtual host config. Alternatively we can use a stream {} block with ssl pass-through (info 1 (stackoverflow.com) info 2 (stackoverflow.com)) - also allows handling of certificates by back-end — not preferred, also unclear how to mix virtual hosts that have stream {} and server {} ssl handling.

    1. Forward ssl port to non-ssl port of snap
      server {
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
          server_name <domain3>;
          location / {
              proxy_set_header Host $host;
              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 X-Forwarded-Host $server_name;
              client_max_body_size 1G;
    2. Disable https in snap (we use the simpler/faster http from nginx -> nextcloud) sudo nextcloud.disable-https
  5. Add subdomain to letsencrypt certificate. My nginx http server is locally running on port 9080, so we need to tell certbot to honor this.

    sudo certbot certonly --http-01-port 9080 --cert-name <certname> -d <domain1>,<domain2>,<domain3>
  6. Enable file uploads >2M

    1. In php.ini: forgot whether this is actually necessary (github.com) Also see here (github.com)
    2. In nginx: add client_max_body_size 1G;
  7. Get clients

    1. iOS: via App
    2. macOS: via app
      1. Ensure https is used for granting access (nextcloud.com) (A (archive.org))
        sudo vim /var/snap/nextcloud/current/nextcloud/config/config.php
        'overwriteprotocol' => 'https'
  8. Profit!

Configure & secure

  1. Set-up TOTP two-factor authentication (2FA) (nextcloud.com) for admins
    1. Log in as admin user
    2. Got to the ‘Apps’ menu, in top-right
    3. Get ‘Two-Factor TOTP Provider’
      1. In the Apps menu, tick ‘Limit to groups: admin’
    4. Under Settings > Personal > Security, enable & test TOTP for the current user
    5. Optionally generated backup codes (recommended)
    6. Under Settings > Administration > Security, enforce Two-Factor Authentication for included groups ‘admin’
    7. Profit!
  2. Harden Nextcloud access via fail2ban (nextcloud.com)
    1. Add /etc/fail2ban/filter.d entry nextcloud.conf
    2. Add /etc/fail2ban/jail.d named nextcloud.local
    3. Restart fail2ban: sudo systemctl restart fail2ban
    4. Check status: fail2ban-client status nextcloud
  3. Limit access by geography (e.g. allow only home country + common holiday)
    1. Source: rackspace (rackspace.com) and blog post (internetstaff.com)

#Nginx #Nextcloud #Ubuntu #Transip