Setting up Nextcloud behind https nginx proxy
(Updated: )
I’ve been enjoying the free tier of TransIPs 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 Oceans 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)