Nextcloud jsem zpřístupnil z internetu stejně jako weby, tedy přes IPv6 a Cloudflare proxy, protože doma mám IPv4 za CGNAT. Aby to bylo bezpečné, musel jsem vyřešit několik věcí specifických pro Nextcloud: skutečnou IP adresu návštěvníka za proxy, dvoufázové ověření, hesla pro aplikace a přihlášení mobilu. Nakonec jsem zabezpečil i samotný kontejner.
Cesta požadavku
Princip je popsaný v článku Domácí server za CGNAT přes IPv6 a Cloudflare. Pro cloud jsem přidal tři věci:
- DNS v Cloudflare: záznam AAAA pro subdoménu
cloudna IPv6 adresu kontejneru, se zapnutou proxy (oranžový mráček). Vlastní záznam má přednost před wildcardem*, který jinak posílá všechny subdomény na web server. - MikroTik: nový address-list s adresou kontejneru a pravidlo, které povolí TCP 80 a 443 jen ze seznamu rozsahů Cloudflare.
- Certifikát:
certbot --apache --redirect. Ověření HTTP-01 projde přes proxy Cloudflare bez potíží.

Past: pořadí pravidel na MikroTiku
Nové pravidlo musí být před pravidlem, které zahazuje vše ostatní z WAN. Podle starších poznámek mělo drop pravidlo číslo 5, ale výpis /ipv6 firewall filter print čísluje i pravidla chainu input, takže skutečně mělo číslo 9. Proto vždy nejdřív vypsat pravidla a teprve pak použít place-before:
/ipv6 firewall address-list add list=cloud-server address=2001:db8::20/128
/ipv6 firewall filter add chain=forward action=accept protocol=tcp dst-port=80,443 \
in-interface-list=WAN src-address-list=cloudflare dst-address-list=cloud-server \
comment="Nextcloud jen z Cloudflare" place-before=CISLO_DROP_PRAVIDLADůvěryhodné proxy: proč na nich záleží
Za Cloudflare přicházejí do Nextcloudu všechny požadavky z adres Cloudflare. Nextcloud má vestavěnou ochranu proti hádání hesel, která zpomaluje přihlašování z adresy s neúspěšnými pokusy. Bez dalšího nastavení by viděl všechny návštěvníky jako několik málo adres Cloudflare. Jeden útočník by tak zpomalil přihlašování celé rodině.
Řešením je říct Nextcloudu, že Cloudflare je důvěryhodná proxy. Skutečnou adresu návštěvníka si pak přečte z hlavičky X-Forwarded-For. Rozsahy jsou stejné jako v address-listu na MikroTiku:
occ config:system:set trusted_proxies 0 --value=2400:cb00::/32
occ config:system:set trusted_proxies 1 --value=2606:4700::/32
occ config:system:set trusted_proxies 2 --value=2803:f800::/32
occ config:system:set trusted_proxies 3 --value=2405:b500::/32
occ config:system:set trusted_proxies 4 --value=2405:8100::/32
occ config:system:set trusted_proxies 5 --value=2a06:98c0::/29
occ config:system:set trusted_proxies 6 --value=2c0f:f248::/32Kontrola je jednoduchá. V Nastavení správy → Zabezpečení Nextcloud ukazuje aktuální adresu. U mě to byla adresa mého počítače, ne Cloudflare. Ověřil jsem to i v praxi: po několika neúspěšných pokusech o přihlášení Nextcloud zpomalil jen adresu mého počítače (o 800 ms), ne všechny návštěvníky přicházející přes Cloudflare. Zpomalení zmizí samo, případně jde zrušit příkazem occ security:bruteforce:reset ADRESA.
Domácí adresy jsem do výjimek z ochrany záměrně nepřidal. Kdyby se někdo dostal do domácí sítě, mohl by hesla zkoušet bez omezení.
Dvoufázové ověření
Administrátorský účet je dostupný z internetu, proto jsem zapnul dvoufázové ověření TOTP (aplikace twofactor_totp). Kódy generuje open-source aplikace Aegis v telefonu. Při nastavení jsem si vytvořil záložní kódy a uložil je mimo cloud, protože ke cloudu by se bez nich po ztrátě telefonu nedalo dostat.
Na dvě věci se snadno zapomene:
- Osobní 2FA se nastavuje v sekci Osobní → Zabezpečení, ne v sekci Správa. Ve Správě je volba vynutit 2FA pro všechny. Tu zapnu, až budou mít všichni v rodině nastavený telefon.
- Přihlašuje se uživatelským jménem. Přihlášení e-mailem funguje jen tehdy, když je e-mail u účtu uložený a nikdo jiný ho nemá.
Hesla pro aplikace a přihlášení mobilu
S 2FA se aplikace jako KeePass nebo kalendář nepřihlásí běžným heslem. Potřebují vlastní heslo pro aplikaci (Osobní → Zabezpečení → Zařízení a sezení). Chybová odpověď 401 v aplikaci obvykle znamená, že se zadalo běžné heslo místo hesla pro aplikaci nebo e-mail místo uživatelského jména.
Oficiální aplikace Nextcloud pro Android se přihlašuje přes prohlížeč. Na mém telefonu prohlížeč ohlásil úspěšné přihlášení, ale aplikace ho nepřevzala a znovu chtěla adresu serveru. Spolehlivě fungovalo přihlášení QR kódem: na PC vytvořit heslo pro aplikaci a zvolit Zobrazit QR kód pro mobilní aplikace, v aplikaci na přihlašovací obrazovce zvolit ikonu QR kódu.
Každý nedokončený pokus ale v seznamu Zařízení a sezení zanechal platný záznam. Po zprovoznění jsem je odvolal a nechal jen PC klienta, mobilní aplikaci a KeePass. Seznam je dobré procházet i při výměně telefonu.
Zabezpečení kontejneru
SSH jen klíčem
Do kontejneru jsem nahrál stejný veřejný klíč jako na web server a přihlašování heslem vypnul samostatným souborem v /etc/ssh/sshd_config.d/:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-passwordPast: reload SSH skončil chybou
Konfigurace byla v pořádku (sshd -t bez chyby), ale systemctl reload ssh selhal. V logu bylo Cannot bind any address. V kontejneru s Debianem 13 byly zapnuté současně ssh.socket i ssh.service a při reloadu si překážely o port. Ponechal jsem jen službu:
systemctl disable --now ssh.socket
systemctl restart ssh
systemctl reload sshBez opravy by mohla SSH shodit jakákoli budoucí automatická aktualizace, která dělá reload.
Aktualizace a proč bez fail2ban
Bezpečnostní opravy systému instaluje balíček unattended-upgrades. Samotný Nextcloud aktualizuji ručně a vždy se snapshotem předem. Fail2ban jsem v tomto kontejneru nenasadil: SSH není zvenku dostupné a Nextcloud má vlastní ochranu proti hádání hesel, která díky důvěryhodným proxy vidí skutečné adresy.
Shrnutí
- Za Cloudflare je nutné nastavit
trusted_proxies, jinak by ochrana proti hádání hesel trestala všechny uživatele najednou. - Pravidla na MikroTiku vkládat podle aktuálního výpisu, čísla zahrnují i chain input.
- 2FA pro účty s přístupem z internetu, záložní kódy mimo cloud a hesla pro aplikace pro vše ostatní.
- Když přihlášení mobilu přes prohlížeč selže, použít QR kód a odvolat nedokončená sezení.
- Na Debianu 13 v LXC zkontrolovat, že neběží současně
ssh.socketassh.service.
Článek je součástí série Privátní cloud Nextcloud na domácím Proxmoxu.