{"id":3120,"date":"2022-02-28T07:00:00","date_gmt":"2022-02-28T06:00:00","guid":{"rendered":"https:\/\/www.my-it-brain.de\/wordpress\/?p=3120"},"modified":"2022-02-25T21:10:11","modified_gmt":"2022-02-25T20:10:11","slug":"nextcloud-im-container-teil-3-mit-reverse-proxy","status":"publish","type":"post","link":"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-3-mit-reverse-proxy\/","title":{"rendered":"Nextcloud im Container &#8212; Teil 3: Mit Reverse-Proxy"},"content":{"rendered":"\n<p>In diesem Teil beschreibe ich die Konfiguration von NGINX als Reverse-Proxy f\u00fcr mein Wochenend-Projekt &#8222;Nextcloud im Container&#8220;. Und was so langweilig klingt, wie lediglich die Direktive <code>proxy_pass<\/code> in die NGINX-Konfiguration einzuf\u00fcgen, dauerte dann doch \u00fcberraschend lange.<\/p>\n\n\n\n<p>Dar\u00fcber hinaus dokumentiere ich die Konfiguration von <a href=\"https:\/\/www.fail2ban.org\/wiki\/index.php\/Main_Page\">fail2ban<\/a>, um die Anmeldemaske der Nextcloud vor <a href=\"https:\/\/de.wikipedia.org\/wiki\/Brute-Force-Methode\">Brute-Force-Angriffen<\/a> zu sch\u00fctzen.<\/p>\n\n\n\n<p>Falls ihr <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-1-der-plan\/\" data-type=\"post\" data-id=\"2993\">Teil 1<\/a> und <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-2-die-ansible-rolle\/\" data-type=\"post\" data-id=\"2996\">Teil 2<\/a> dieser Reihe noch nicht kennt, empfehle ich euch, diese Teile zuerst zu lesen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"die-fehlschlage\">Die Fehlschl\u00e4ge<\/h2>\n\n\n\n<p>Bevor ich zur <a href=\"#current-config\">aktuellen Konfig<\/a> komme, m\u00f6chte ich kurz die Fehlschl\u00e4ge auf dem Weg dorthin festhalten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"nextcloud-im-unterverzeichnis-nicht-so-einfach-wie-gedacht\">Nextcloud im Unterverzeichnis nicht so einfach wie gedacht<\/h3>\n\n\n\n<p>Auf meinem Server l\u00e4uft bereits ein Dienst, welcher unter der URL <code>https:\/\/www.example.com\/service1<\/code> erreichbar ist. Mir gefiel die Idee, die Nextcloud unter einer URL wie <code>https:\/\/www.example.com\/service2<\/code> erreichbar zu machen.<\/p>\n\n\n\n<p>Die Dokumentation des Container-Repos [<a href=\"#quellen-links\">3<\/a>] ist in meinen Augen zu kurz geraten und reicht f\u00fcr eine erfolgreiche Konfiguration l\u00e4ngst nicht aus.<\/p>\n\n\n\n<p>Nachdem ich einiges \u00fcber die Generierung von Back-to-URLs und Redirects gelesen und im <a href=\"https:\/\/help.nextcloud.com\/\">Nextcloud-Forum<\/a> gest\u00f6bert hatte, lie\u00df ich die Idee fallen. Ich warte mal ab, wie sich <a href=\"https:\/\/github.com\/nextcloud\/docker\/issues\/401\">Issue #401<\/a> entwickelt. Vielleicht greife ich die Idee sp\u00e4ter nochmal auf.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"falsche-back-to-urls-und-protokoll-probleme\">Falsche Back-to-URLs und Protokoll-Probleme<\/h3>\n\n\n\n<p>Im n\u00e4chsten Versuch, sollte Nextcloud unter einer eigenen Domain wie <code>nextcloud.example.com<\/code> erreichbar sein. Doch auch hier klemmte es zun\u00e4chst. Zuerst stolperte ich in den bekannten Untrusted-Domain-Fehler.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-45-10.png\" alt=\"access-through-untrusted-domain-error.png\" class=\"wp-image-3123\" width=\"655\" height=\"275\" srcset=\"https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-45-10.png 717w, https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-45-10-300x126.png 300w, https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-45-10-624x263.png 624w\" sizes=\"auto, (max-width: 655px) 100vw, 655px\" \/><figcaption>Bekannte Fehlermeldung, wenn <code>trusted_domains<\/code> in <code>config.php<\/code> nicht korrekt gesetzt ist.<\/figcaption><\/figure>\n\n\n\n<p>Diesen Fehler konnte ich schnell abstellen, da ich lediglich vergessen hatte die Variable <code>NEXTCLOUD_TRUSTED_DOMAINS<\/code> mit einem Wert zu belegen. Als Wert ist der FQDN einzutragen, unter dem die Nextcloud erreichbar sein soll. Dieser ist explizit anzugeben, da der Apache-Prozess innerhalb des Nextcloud-Containers den FQDN, auf den der NGINX-Reverse-Proxy lauscht und welcher im HTTP-Header \u00fcbertragen wird, nicht kennt.<\/p>\n\n\n\n<p>Des Weiteren musste ich noch die Variablen <code>NEXTCLOUD_OVERWRITEPROTOCOL<\/code> und <code>NEXTCLOUD_OVERWRITECLIURL<\/code> in <code>vars\/main.yml<\/code> mit Werten belegen, um die entsprechenden Umgebungsvariablen f\u00fcr die Container-Instanz zu setzen (vgl. [<a href=\"#quellen-links\">3<\/a>]). Dies ist notwendig, da die Anwendung im Nextcloud-Container andernfalls Back-to-URLs f\u00fcr das HTTP-Protokoll generiert. Versucht der Browser diese aufzurufen, erscheint ein Fehler oder man landet in einer endlosen Redirect-Schleife.<\/p>\n\n\n\n<p>Nachdem ich die Nextcloud mit Hilfe der Ansible-Rolle [<a href=\"#quellen-links\">2<\/a>] erneut deployt habe, war der Login-Screen erreichbar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-50-49.png\" alt=\"login-screen.png\" class=\"wp-image-3124\" width=\"326\" height=\"301\" title=\"Nextcloud-Login-Screen\" srcset=\"https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-50-49.png 326w, https:\/\/www.my-it-brain.de\/wordpress\/wp-content\/uploads\/2022\/02\/Screenshot-from-2022-02-05-21-50-49-300x277.png 300w\" sizes=\"auto, (max-width: 326px) 100vw, 326px\" \/><figcaption>Nextcloud-Login-Screen<\/figcaption><\/figure>\n\n\n\n<p>Der Weg hierher war f\u00fcr meinen Geschmack aufw\u00e4ndiger als er h\u00e4tte sein m\u00fcssen. Nur durch Lekt\u00fcre und Recherche der Quellen unter [<a href=\"#quellen-links\">4<\/a>], [<a href=\"#quellen-links\">5<\/a>] und [<a href=\"#quellen-links\">6<\/a>] konnte ich mich von Problem zu Problem hangeln und diese l\u00f6sen. Hier ist in meinen Augen noch Raum f\u00fcr Verbesserungen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"current-config\">Die aktuell funktionierende Konfiguration<\/h2>\n\n\n\n<p>Meine NGINX-vHost-Konfiguration habe ich mir mithilfe von [<a href=\"#quellen-links\">4<\/a>], [<a href=\"#quellen-links\">5<\/a>] und [<a href=\"#quellen-links\">6<\/a>] zusammengesucht und bin bei folgender Konfig gelandet (es werden nur relevante Abschnitte wiedergegeben):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n\tlisten 80;\n\tlisten &#91;::]:80;\n\tserver_name nextcloud.example.com;\n\troot \/var\/www\/nextcloud.example.com;\n\tindex index.html;\n&#91;...]\n\treturn 301 https:\/\/$server_name$request_uri;\n\tlocation ^~ \/.well-known\/acme-challenge\/ {\n\tdefault_type \"text\/plain\";\n\troot \/var\/www\/nextcloud.example.com;\n\t}\n\tlocation = \/.well-known\/acme-challenge\/ {\n\treturn 404;\n\t}\n}\nserver {\n    # Listen on Port 443\n    listen 443 ssl http2;\n    listen &#91;::]:443 ssl http2;\n    server_name nextcloud.example.com;\n&#91;...]\n    root \/var\/www\/nextcloud.example.com;\n&#91;...]\n\tlocation ^~ \/.well-known\/acme-challenge\/ {\n\tdefault_type \"text\/plain\";\n\troot \/var\/www\/nextcloud.example.com;\n\t}\n\tlocation = \/.well-known\/acme-challenge\/ {\n\treturn 404;\n\t}\n\n        location \/ {\n\tproxy_set_header Host $host;\n\tproxy_set_header X-Forwarded-Proto $scheme;\n\tproxy_set_header X-Real-IP $remote_addr;\n\tproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\tadd_header Front-End-Https on;\n       \tproxy_pass http:\/\/127.0.0.1:40231;\n        }\n\n\tlocation \/.well-known\/carddav{\n\t\treturn 301 $scheme:\/\/$host\/remote.php\/dav;\n\t}\n\n\tlocation \/.well-known\/caldav {\n\t\treturn 301 $scheme:\/\/$host\/remote.php\/dav;\n\t}\n}<\/code><\/pre>\n\n\n\n<p>Ob dies eine gute Konfiguration ist, mag ich nicht beurteilen. Sie funktioniert zumindest. Die Nextcloud ist erreichbar und \u00fcber die Weboberfl\u00e4che k\u00f6nnen weitere Einstellungen vorgenommen, Nutzerkonten erstellt und Apps installiert werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fail2ban-fur-nextcloud\">Fail2ban f\u00fcr Nextcloud<\/h2>\n\n\n\n<p>Nun steht die Nextcloud mit ihrer Login-Maske im Wind. Sie stellt damit ein sch\u00f6nes Ziel f\u00fcr Brute-Force-Angriffe dar. Um es den Angreifern nicht zu leicht zu machen, habe ich f\u00fcr den Nextcloud-Admin keinen einfach zu erratenen Namen wie Admin, Nextcloud-Admin oder meinen Namen verwendet. Um Angreifer weiter auszubremsen, konfiguriere ich <a href=\"https:\/\/www.fail2ban.org\/wiki\/index.php\/Main_Page\">fail2ban<\/a>. Wie dies installiert wird, schlagt bitte in der Dokumentation eurer Distribution nach. Ich gehe hier nicht auf die Installation ein.<\/p>\n\n\n\n<p>Damit fail2ban fehlgeschlagene Anmeldeversuche erkennt, habe ich die Datei <code>\/etc\/fail2ban\/filter.d\/filter.d\/jk_nextcloud.conf<\/code> mit folgendem Inhalt erstellt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Definition]\n_groupsre = (?:(?:,?\\s*\"\\w+\":(?:\"&#91;^\"]+\"|\\w+))*)\nfailregex = ^\\{%(_groupsre)s,?\\s*\"remoteAddr\":\"&lt;HOST&gt;\"%(_groupsre)s,?\\s*\"message\":\"Login failed:\n            ^\\{%(_groupsre)s,?\\s*\"remoteAddr\":\"&lt;HOST&gt;\"%(_groupsre)s,?\\s*\"message\":\"Trusted domain error.\ndatepattern = ,?\\s*\"time\"\\s*:\\s*\"%%Y-%%m-%%d&#91;T ]%%H:%%M:%%S(%%z)?\"<\/code><\/pre>\n\n\n\n<p>Dieser Filter wird in der Datei <code>\/etc\/fail2ban\/jail.d\/jk_nextcloud.local<\/code> referenziert:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;jk_nextcloud]\nbackend = auto\nenabled = true\nport = 80,443\nprotocol = tcp\nfilter = jk_nextcloud\nmaxretry = 3\nbantime = 86400\nfindtime = 43200\nlogpath = \/home\/tronde\/.local\/share\/containers\/storage\/volumes\/nc_data\/_data\/nextcloud.log<\/code><\/pre>\n\n\n\n<p>Wenn innerhalb der <code>findtime<\/code> von 43200 Sekunden von einer IP-Adresse mehr als drei fehlgeschlagene Anmeldeversuche (<code>maxretry<\/code>) registriert werden, wird die entsprechede IP-Adresse f\u00fcr 86400 Sekunden (<code>bantime<\/code>) gesperrt. Eine Statusabfrage ist wie folgt m\u00f6glich:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sudo fail2ban-client status jk_nextcloud\n&#91;sudo] password for tronde: \nStatus for the jail: jk_nextcloud\n|- Filter\n|  |- Currently failed:\t1\n|  |- Total failed:\t5\n|  `- File list:\t\/home\/tronde\/.local\/share\/containers\/storage\/volumes\/nc_data\/_data\/nextcloud.log\n`- Actions\n   |- Currently banned:\t0\n   |- Total banned:\t1\n   `- Banned IP list:<\/code><\/pre>\n\n\n\n<p>Es ist zu erkennen, dass aktuell keine IP-Adresse gesperrt ist. In der Vergangenheit wurde jedoch bereits eine IP gebannt.<\/p>\n\n\n\n<p>F\u00fcr mich stellt fail2ban einen Baustein zur Sicherung der Nextcloud bereit. Zus\u00e4tzlich werde ich eine <a href=\"https:\/\/de.wikipedia.org\/wiki\/Zwei-Faktor-Authentisierung\">Zwei-Faktor-Authentisierung<\/a> konfigurieren, um die Sicherheit weiter zu steigern.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"zusammenfassung\">Zusammenfassung<\/h2>\n\n\n\n<p>An diesem Punkt meines Wochenend-Projekts kann ich eine Nextcloud-Instanz mit meiner Ansible-Rolle deployen und hinter einem Reverse-Proxy nutzen. Bisher sch\u00fctzt fail2ban vor Brute-Force-Angriffen. Zuk\u00fcnftig wird jedoch eine Zwei-Faktor-Authentisierung diesen Schutz verst\u00e4rken.<\/p>\n\n\n\n<p>Eine lauff\u00e4hige Konfiguration zu erstellen, hat dabei l\u00e4nger gedauert, als ich mir vorgestellt habe. Dabei hat mir missfallen, dass dies nicht mit der Dokumentation allein gelang, sondern das Forum [<a href=\"#quellen-links\">5<\/a>] und die Internetsuchmaschine meines geringsten Misstrauens zurate gezogen werden mussten. Damit ist dieses Projekt jedoch bei weitem kein Einzelfall.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/nextcloud\/docker\/issues\">307 offene Issues<\/a> (Stand 05.02.2022) zeugen davon, dass hier noch l\u00e4ngst nicht alles rund l\u00e4uft. Von der Idee, dass es sich hierbei um ein Fire-and-Forget-Projekt handeln k\u00f6nnte, verabschiede ich mich lieber. So bin ich auch gleich in das unter [<a href=\"#quellen-links\">7<\/a>] beschriebene Problem getreten. Erfreulicher Weise hat die dort beschriebene L\u00f6sung funktioniert, so dass meine Cloud mir jetzt E-Mails senden kann. Ich werde mir Gedanken machen, wie die entsprechenden Abschnitte in der Dokumentation verbessert werden k\u00f6nnen und dem Projekt einen Pull-Request senden. Mal schauen wie man darauf reagiert.<\/p>\n\n\n\n<p>Damit sind die in <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-1-der-plan\/\" data-type=\"post\" data-id=\"2993\">Teil 1<\/a> formulierten Ziele 1-3 erreicht. In Teil 4 besch\u00e4ftige ich mich mit einigen weiteren Steinen, \u00fcber die ich gestolpert bin, bevor ich mich dann in Teil 5 dem Thema Backup &amp; Recovery widme.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"quellen-links\">Quellen und weiterf\u00fchrende Links<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-1-der-plan\/\" data-type=\"post\" data-id=\"2993\">Nextcloud im Container &#8212; Teil 1: Der Plan<\/a><\/li><li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-2-die-ansible-rolle\/\" data-type=\"post\" data-id=\"2996\">Nextcloud im Container &#8212; Teil 2: Die Ansible-Rolle<\/a><\/li><li><a href=\"https:\/\/github.com\/nextcloud\/docker#using-the-apache-image-behind-a-reverse-proxy-and-auto-configure-server-host-and-protocol\">Using the apache image behind a reverse proxy and auto configure server host and protocol<\/a><\/li><li><a href=\"https:\/\/github.com\/nextcloud\/docker\">https:\/\/github.com\/nextcloud\/docker<\/a><\/li><li><a href=\"https:\/\/help.nextcloud.com\/\">https:\/\/help.nextcloud.com\/<\/a><\/li><li><a href=\"https:\/\/docs.nextcloud.com\/server\/latest\/admin_manual\/\">https:\/\/docs.nextcloud.com\/server\/latest\/admin_manual\/<\/a><\/li><li><a href=\"https:\/\/help.nextcloud.com\/t\/email-settings-gets-wrong-sender-domain-fails-due-to-not-rfc-compliant\/55666\">Email settings gets wrong senEmail settings gets wrong sender domain, fails due to not RFC compliant<\/a><\/li><\/ol>\n","protected":false},"excerpt":{"rendered":"<p>In diesem Teil beschreibe ich die Konfiguration von NGINX als Reverse-Proxy f\u00fcr mein Wochenend-Projekt &#8222;Nextcloud im Container&#8220;. Und was so langweilig klingt, wie lediglich die Direktive proxy_pass in die NGINX-Konfiguration einzuf\u00fcgen, dauerte dann doch \u00fcberraschend lange. Dar\u00fcber hinaus dokumentiere ich die Konfiguration von fail2ban, um die Anmeldemaske der Nextcloud vor Brute-Force-Angriffen zu sch\u00fctzen. Falls ihr<span class=\"continue-reading\"> <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/nextcloud-im-container-teil-3-mit-reverse-proxy\/\">[Weiterlesen&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_metis_text_type":"","_metis_text_length":0,"_post_count":0,"footnotes":""},"categories":[57],"tags":[669,685,304,610],"class_list":["post-3120","post","type-post","status-publish","format-standard","hentry","category-wochenend-projekte","tag-fail2ban","tag-nextcloud-container","tag-nginx","tag-reverse-proxy"],"_links":{"self":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/3120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/comments?post=3120"}],"version-history":[{"count":6,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/3120\/revisions"}],"predecessor-version":[{"id":3139,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/3120\/revisions\/3139"}],"wp:attachment":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/media?parent=3120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/categories?post=3120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/tags?post=3120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}