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)).
Setup ¶
I want to achieve the following setup:
- nginx serving http & https on public port 80 & 443 (I already have this running)
- nextcloud running behind nginx proxy on dedicated virtualhost (this guide)
- nextcloud domain signed by letsencrypt certificate (this guide)
Howto ¶
-
Install nextcloud snap
sudo snap install nextcloud
-
Create admin account before going live
sudo nextcloud.manual-install <user> <passwd>
-
Set custom ports (e.g. 9081 and 9443) because we are behind nginx
- Find free port (linuxize.com)
sudo netstat -tunlp
- Set nextcloud listening ports
sudo snap set nextcloud ports.http=9081 sudo snap set nextcloud ports.https=9443
- Find free port (linuxize.com)
-
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 astream {}
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 havestream {}
andserver {}
ssl handling.- 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; proxy_pass http://127.0.0.1:9081; } }
- Disable https in snap (we use the simpler/faster http from nginx -> nextcloud)
sudo nextcloud.disable-https
- Forward ssl port to non-ssl port of snap
-
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>
-
Enable file uploads >2M
- In php.ini: forgot whether this is actually necessary (github.com) Also see here (github.com)
- In nginx: add
client_max_body_size 1G;
-
Get clients
- iOS: via App
- macOS: via app
- Ensure https is used for granting access (nextcloud.com) (A (archive.org))
sudo vim /var/snap/nextcloud/current/nextcloud/config/config.php 'overwriteprotocol' => 'https'
- Ensure https is used for granting access (nextcloud.com) (A (archive.org))
-
Profit!
Configure & secure ¶
- Set-up TOTP two-factor authentication (2FA) (nextcloud.com) for admins
- Log in as admin user
- Got to the ‘Apps’ menu, in top-right
- Get ‘Two-Factor TOTP Provider’
- In the Apps menu, tick ‘Limit to groups: admin’
- Under Settings > Personal > Security, enable & test TOTP for the current user
- Optionally generated backup codes (recommended)
- Under Settings > Administration > Security, enforce Two-Factor Authentication for included groups ‘admin’
- Profit!
- Harden Nextcloud access via fail2ban (nextcloud.com)
- Add
/etc/fail2ban/filter.d
entrynextcloud.conf
- Add
/etc/fail2ban/jail.d
namednextcloud.local
- Restart
fail2ban
:sudo systemctl restart fail2ban
- Check status:
fail2ban-client status nextcloud
- Add
- Limit access by geography (e.g. allow only home country + common holiday)