<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>2fa – Serverküche</title><link>https://serverkueche.de/tags/2fa/</link><description>2fa – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>de-DE</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Sun, 19 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/tags/2fa/index.xml" rel="self" type="application/rss+xml"/><item><title>Nextcloud absichern &amp; optimieren: alle Warnungen abarbeiten (Teil 2)</title><link>https://serverkueche.de/tutorials/nextcloud-optimieren-absichern/</link><pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/tutorials/nextcloud-optimieren-absichern/</guid><description>Die Admin-Übersicht deiner Nextcloud grün bekommen: HSTS-Header, E-Mail-Versand, Zwei-Faktor-Pflicht und Brute-Force-Schutz mit echten IPs einrichten.</description><content:encoded><![CDATA[<p>Deine Nextcloud läuft – aber in der Admin-Übersicht leuchten gelbe Warnungen, es gibt
keine funktionierende E-Mail und kein zweiter Faktor schützt deine Konten. In diesem
zweiten Teil machen wir aus „läuft&quot; ein „sauber abgesichert und flott&quot;: Wir arbeiten
jede Warnung ab, bis die Übersicht grün ist.</p>
<h2 id="was-bauen-wir">Was bauen wir?</h2>
<p>Am Ende zeigt die <strong>Sicherheits- &amp; Einrichtungsübersicht</strong> deiner Nextcloud keine
Warnungen mehr. Konkret bauen wir auf der Installation aus
<a href="/tutorials/nextcloud-eigene-cloud/">Teil 1</a> auf und ergänzen: den fehlenden
<strong>HSTS-Sicherheitsheader</strong> über Traefik, ein konfiguriertes <strong>Wartungsfenster</strong>, den
funktionierenden <strong>E-Mail-Versand</strong> (für Passwort-Resets und Benachrichtigungen), eine
<strong>erzwungene Zwei-Faktor-Authentifizierung</strong> und einen <strong>Brute-Force-Schutz, der die
echten Angreifer-IPs sieht</strong> – die Grundlage für Fail2ban.</p>
<p>Getestet ist alles gegen <strong>Nextcloud 34.0.1</strong> hinter <strong>Traefik v3.7</strong> auf Debian 13 mit
PHP 8.5. Das ist Fleißarbeit, aber genau die Fleißarbeit, die in 90 % aller
Nextcloud-Anleitungen fehlt – und die den Unterschied zwischen „irgendwie online&quot; und
„vernünftig betrieben&quot; ausmacht.</p>
<h2 id="voraussetzungen">Voraussetzungen</h2>
<ul>
<li>Eine <strong>laufende Nextcloud</strong> wie in
<a href="/tutorials/nextcloud-eigene-cloud/">Nextcloud selbst hosten (Teil 1)</a> aufgesetzt:
klassisches <code>nextcloud</code>-Image hinter Traefik, mit MariaDB, Redis und Cron-Sidecar.
Die Container-Namen aus Teil 1 (<code>nc-app</code>, <code>nc-db</code>, <code>nc-redis</code>, <code>nc-cron</code>) und der
Compose-Ordner <code>~/nextcloud</code> sind hier die Basis.</li>
<li><strong>SSH-Zugriff</strong> auf den Server und das Kommandozeilen-Werkzeug <strong><code>occ</code></strong> – wir rufen es
wie in Teil 1 im App-Container auf: <code>docker exec -u www-data nc-app php occ &lt;befehl&gt;</code>.</li>
<li>Ein <strong>Traefik-Reverse-Proxy</strong> mit dem <code>proxy</code>-Netz und dem Resolver <code>le</code> wie im
Tutorial <a href="/tutorials/reverse-proxy-traefik/">Reverse Proxy mit Traefik</a> – die
Sicherheits-Header hängen wir als Traefik-Middleware an.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>occ im Griff behalten
  </p>
  <div class="prose-kitchen text-sm"><p><code>occ</code> ist Nextclouds Admin-Werkzeug. Weil die Container in Teil 1 feste Namen bekommen
haben (<code>container_name</code>), sprichst du den App-Container direkt an – egal, in welchem
Verzeichnis du bist:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ status</span></span></code></pre></div>
</div>
<p>Du solltest <code>installed: true</code> und deine Version sehen. Diesen Präfix
(<code>docker exec -u www-data nc-app php occ …</code>) kürzen wir im Folgenden nicht ab – so kannst
du jeden Befehl direkt kopieren. Nur die wenigen <code>docker compose …</code>-Befehle (etwa der
Container-Neustart in Schritt 3) führst du weiterhin aus dem Ordner <code>~/nextcloud</code> aus.</p>
</div>
</div>
<h2 id="schritt-für-schritt">Schritt für Schritt</h2>
<h3 id="schritt-1-die-admin-übersicht-als-bestandsaufnahme-lesen">Schritt 1: Die Admin-Übersicht als Bestandsaufnahme lesen</h3>
<p>Melde dich als Administrator an und öffne <strong>Administrationseinstellungen → Übersicht</strong>.
Oben steht der Abschnitt <strong>„Sicherheits- &amp; Einrichtungswarnungen&quot;</strong>. Direkt nach einer
Standardinstallation sieht das so aus:</p>
<p><figure class="my-6"><img src="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_ded0bba1c144426e.webp" srcset="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_a4ebfe3ed3a25ade.webp 480w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_ded0bba1c144426e.webp 768w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_bbc66bad38685276.webp 1200w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_2de722e751877ff1.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-warnungen_hu_9a42eb97ca12bc11.webp"
    alt="Die Nextcloud-Admin-Übersicht listet mehrere gelbe Warnungen zu Wartungsfenster, MIME-Type-Migrationen und HTTP-Headern auf" title="Ausgangslage: drei Warnungen und mehrere Hinweise in der Admin-Übersicht"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Ausgangslage: drei Warnungen und mehrere Hinweise in der Admin-Übersicht</figcaption></figure></p>
<p>Nextcloud unterscheidet drei Stufen: <strong>gelbe Warnungen</strong> (⚠, solltest du beheben),
<strong>blaue Hinweise</strong> (ℹ, meist optional) und stillschweigend bestandene Prüfungen. Bei
unserer frischen Instanz stehen drei Warnungen und ein paar Hinweise an:</p>
<ul>
<li>⚠ <strong>Beginn des Wartungsfensters</strong> ist nicht gesetzt (Schritt 2)</li>
<li>⚠ <strong>MIME-Type-Migrationen verfügbar</strong> (Schritt 2)</li>
<li>⚠ <strong>HTTP-Header</strong> – der <code>Strict-Transport-Security</code>-Header fehlt (Schritt 3)</li>
<li>ℹ <strong>E-Mail-Test</strong> – noch kein Mailserver hinterlegt (Schritt 4)</li>
<li>ℹ <strong>Zwei-Faktor-Konfiguration</strong> – 2FA ist verfügbar, aber nicht verpflichtend (Schritt 5)</li>
</ul>
<p>Denselben Bericht bekommst du auch auf der Kommandozeile – praktisch, um den Fortschritt
zwischendurch zu prüfen, ohne durch die Weboberfläche zu klicken:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ setupchecks</span></span></code></pre></div>
</div>
<p>Der Befehl gibt jede Prüfung mit ✓, ⚠ oder ✗ aus. Genau diese Liste arbeiten wir jetzt
von oben nach unten ab.</p>
<h3 id="schritt-2-die-zwei-schnellen-warnungen-beheben">Schritt 2: Die zwei schnellen Warnungen beheben</h3>
<p>Zwei Warnungen sind mit je einem Befehl erledigt.</p>
<p><strong>Wartungsfenster festlegen.</strong> Nextcloud führt einmal täglich rechenintensive
Aufräumjobs aus (Vorschauen, Aktivitäten, Kalender-Wiederholungen). Ohne definiertes
Zeitfenster laufen die <em>irgendwann</em> – auch mitten am Tag. Leg einen Startzeitpunkt fest,
zu dem kaum jemand arbeitet. Der Wert ist eine <strong>volle Stunde in UTC</strong>; <code>1</code> legt den
Beginn auf 01:00 UTC – der Check meldet danach das Fenster von 1:00 bis 7:00 UTC:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ config:system:set maintenance_window_start --type<span class="o">=</span>integer --value<span class="o">=</span><span class="m">1</span></span></span></code></pre></div>
</div>
<p>Zur Kontrolle bestätigt der Setup-Check danach:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">✓ Maintenance window start: Maintenance window to execute heavy background jobs is between 1:00 UTC and 7:00 UTC</span></span></code></pre></div>
</div>
<p><strong>MIME-Type-Migrationen ausführen.</strong> Gelegentlich lernt Nextcloud neue Dateitypen (etwa
für bessere Icons und Vorschauen). Diese Migration läuft bei Updates <em>nicht</em> automatisch,
weil sie auf großen Instanzen dauern kann. Auf einer frischen Cloud ist sie in Sekunden
durch:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ maintenance:repair --include-expensive</span></span></code></pre></div>
</div>
<p>Du siehst eine Liste abgearbeiteter Reparaturschritte (u. a. <code>Repair mime types</code>).
Danach meldet der Check <code>Mimetype migrations available: None</code>. Zwei Warnungen weniger.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-sky-300 bg-sky-50 dark:border-sky-800 dark:bg-sky-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">ℹ️</span>Und die blauen Hinweise?
  </p>
  <div class="prose-kitchen text-sm">Die Hinweise <strong>„AppAPI-Bereitstellungs-Daemon&quot;</strong> und <strong>„Konfiguration Server-ID&quot;</strong> kannst
du auf einer normalen Ein-Server-Installation ignorieren. Der erste betrifft nur die
Installation externer „Ex-Apps&quot; über einen Docker-Daemon, der zweite nur Setups, die über
mehrere PHP-Server verteilt laufen. Beides brauchst du hier nicht – deshalb bleiben es
Hinweise und keine Warnungen.</div>
</div>
<h3 id="schritt-3-den-hsts-sicherheitsheader-über-traefik-setzen">Schritt 3: Den HSTS-Sicherheitsheader über Traefik setzen</h3>
<p>Die dritte Warnung ist die wichtigste: Der <strong><code>Strict-Transport-Security</code>-Header</strong> (HSTS)
fehlt. Er weist den Browser an, diese Domain <strong>ausschließlich über HTTPS</strong> anzusprechen –
auch dann, wenn jemand <code>http://</code> eintippt oder ein Angreifer die Verbindung umzubiegen
versucht. Ohne HSTS bleibt ein kleines Zeitfenster für Downgrade-Angriffe offen.</p>
<p>Weil unsere Nextcloud hinter Traefik sitzt, setzen wir den Header <strong>im Proxy</strong>, nicht in
Nextcloud – dort gehört er hin, denn Traefik terminiert das TLS. Ergänze in der
<code>compose.yaml</code> deiner Nextcloud (aus Teil 1) die Middleware <code>nc-secure</code> und häng sie an
den Router. Konkret ändern sich zwei Stellen im <code>labels</code>-Block von <code>nc-app</code>.</p>
<p>Erstens die Router-Zeile um <code>nc-secure</code> erweitern:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.nc.middlewares=nc-dav,nc-secure&#34;</span></span></span></code></pre></div>
</div>
<p>Zweitens die Header-Middleware definieren (direkt bei den anderen <code>nc-app</code>-Labels):</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.middlewares.nc-secure.headers.stsSeconds=15552000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.middlewares.nc-secure.headers.stsIncludeSubdomains=true&#34;</span></span></span></code></pre></div>
</div>
<p><code>stsSeconds=15552000</code> sind 180 Tage – der von Nextcloud geforderte Mindestwert. Übernimm
die Änderung und lade nur den App-Container neu:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d nc-app</span></span></code></pre></div>
</div>
<p>Prüfe nach ein paar Sekunden von deinem eigenen Rechner aus, dass der Header wirklich
ausgeliefert wird:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sS -I https://cloud.DEINE_DOMAIN/ <span class="p">|</span> grep -i strict-transport</span></span></code></pre></div>
</div>
<p>Du solltest genau das sehen:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">strict-transport-security: max-age=15552000; includeSubDomains</span></span></code></pre></div>
</div>
<p>In der Admin-Übersicht wird die HTTP-Header-Warnung damit grün: <em>„Your server is correctly
configured to send security headers.&quot;</em> Die übrigen Header (<code>X-Content-Type-Options</code>,
<code>X-Frame-Options</code>, <code>Referrer-Policy</code> …) liefert Nextcloud selbst aus – nur HSTS musste vom
Proxy kommen.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>preload ist eine Einbahnstraße
  </p>
  <div class="prose-kitchen text-sm"><code>stsIncludeSubdomains=true</code> erweitert den HTTPS-Zwang auf alle Subdomains <strong>von
<code>cloud.DEINE_DOMAIN</code></strong> (nicht auf Geschwister wie <code>www.DEINE_DOMAIN</code> – der Header gilt
immer nur für den Host, der ihn ausliefert). Bewusst <strong>nicht</strong> gesetzt ist
<code>stsPreload=true</code>: Damit würdest du signalisieren, dass du die Domain in die
<a href="https://hstspreload.org/">HSTS-Preload-Liste</a> der Browser eintragen lassen willst – und
so ein Eintrag ist nur mit wochenlangem Vorlauf wieder rückgängig zu machen. Falls du
das eines Tages bewusst willst: Die Preload-Liste akzeptiert nur <code>max-age</code> ≥ 31536000
(1 Jahr) – mit den 15552000 oben wäre das Flag ohnehin wirkungslos. Setze <code>preload</code>
nur, wenn wirklich <em>jeder</em> Dienst unter der Domain dauerhaft HTTPS spricht; der Header
ist auch ohne vollwertig.</div>
</div>
<h3 id="schritt-4-e-mail-versand-einrichten">Schritt 4: E-Mail-Versand einrichten</h3>
<p>Ohne funktionierenden Mailversand kann Nextcloud keine <strong>Passwort-Resets</strong> verschicken,
keine <strong>Freigabe-Benachrichtigungen</strong> und keine <strong>Sicherheitswarnungen</strong> – und der
Hinweis „E-Mail-Test&quot; bleibt stehen. Das holen wir nach.</p>
<p>Öffne <strong>Administrationseinstellungen → Grundeinstellungen</strong> und scroll zum Abschnitt
<strong>„E-Mail-Server&quot;</strong>. Trag die Zugangsdaten deines Mail-Anbieters ein:</p>
<ul>
<li><strong>Sendemodus:</strong> <code>SMTP</code></li>
<li><strong>Verschlüsselung:</strong> <code>SSL/TLS</code> (Port <strong>465</strong>) oder <code>STARTTLS</code> (Port <strong>587</strong>) – nie
unverschlüsselt</li>
<li><strong>Absenderadresse:</strong> z. B. <code>cloud</code> @ <code>DEINE_DOMAIN</code></li>
<li><strong>Serveradresse:</strong> Host und Port deines Anbieters</li>
<li><strong>Authentifizierung:</strong> einschalten und Benutzername/Passwort hinterlegen</li>
</ul>
<p>Trag oben unter <strong>Persönliche Informationen</strong> eine E-Mail-Adresse für dein Admin-Konto
ein (dorthin geht die Testmail). Dann klick auf <strong>„Test-E-Mail senden&quot;</strong>. Kommt die Mail
an, bestätigt Nextcloud das mit einer grünen Meldung:</p>
<p><figure class="my-6"><img src="/tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_f1a5ed435fa3db91.webp" srcset="/tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_5adf7017629a931a.webp 480w, /tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_f1a5ed435fa3db91.webp 768w, /tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_5646fac37d8678c9.webp 1200w, /tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_4e4b07dca9cf3d75.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/nextcloud-optimieren-absichern/nc-email-test_hu_39bdda64e2c97535.webp"
    alt="Der E-Mail-Server ist mit SMTP konfiguriert, ein Test-Versand wird oben rechts mit „E-Mail wurde versandt&quot; bestätigt" title="Erfolgreicher Test-Versand – die Werte im Bild stammen aus einem internen Test-Mailserver und sind NICHT für echte Postfächer zu übernehmen; dort gehören Host, Port 587/465 mit STARTTLS/SSL und die Zugangsdaten deines Anbieters hin"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Erfolgreicher Test-Versand – die Werte im Bild stammen aus einem internen Test-Mailserver und sind NICHT für echte Postfächer zu übernehmen; dort gehören Host, Port 587/465 mit STARTTLS/SSL und die Zugangsdaten deines Anbieters hin</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>App-Passwort statt Kontopasswort
  </p>
  <div class="prose-kitchen text-sm">Nutzt dein Mail-Anbieter selbst Zwei-Faktor-Authentifizierung (Gmail, Mailbox.org, viele
andere), funktioniert dein normales Login-Passwort hier <strong>nicht</strong>. Leg im Konto deines
Anbieters ein dediziertes <strong>App-Passwort</strong> an und trag das ein. Das lässt sich zudem
gezielt widerrufen, ohne dein Haupt-Passwort zu ändern.</div>
</div>
<h3 id="schritt-5-zwei-faktor-authentifizierung-erzwingen">Schritt 5: Zwei-Faktor-Authentifizierung erzwingen</h3>
<p>Ein gestohlenes Passwort ist der häufigste Weg, wie Konten übernommen werden. Ein
<strong>zweiter Faktor</strong> (ein zeitbasierter Code aus einer Authenticator-App, TOTP) macht das
Passwort allein wertlos. Nextcloud bringt den passenden Anbieter schon mit – wir müssen
ihn nur aktivieren und zur Pflicht machen.</p>
<p>Aktiviere zunächst die TOTP-App (sie ist im Lieferumfang enthalten):</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ app:enable twofactor_totp</span></span></code></pre></div>
</div>
<p>Jeder Nutzer richtet seinen zweiten Faktor danach selbst ein – unter <strong>Persönliche
Einstellungen → Sicherheit → „TOTP (Authenticator-App)&quot;</strong>. Beim Aktivieren zeigt
Nextcloud einen QR-Code, den man mit einer App wie Aegis, andOTP oder Google Authenticator
scannt. Zusätzlich empfiehlt sich die App <strong>„Zwei-Faktor-Backup-Codes&quot;</strong> – die einmaligen
Codes retten dich, wenn das Handy verloren geht.</p>
<p>Damit niemand die Absicherung „vergisst&quot;, erzwingst du 2FA für die Administratoren. Im Web
findest du das unter <strong>Administrationseinstellungen → Sicherheit → „Zwei-Faktor-
Authentifizierung erzwingen&quot;</strong>, per Kommandozeile geht es so:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ twofactorauth:enforce --on --group<span class="o">=</span>admin</span></span></code></pre></div>
</div>
<p><figure class="my-6"><img src="/tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_a132ce2453d02b15.webp" srcset="/tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_94f90414c751c23b.webp 480w, /tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_a132ce2453d02b15.webp 768w, /tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_34a2ce03c7d7cb52.webp 1200w, /tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_6beccff3d885822a.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/nextcloud-optimieren-absichern/nc-zweifaktor_hu_21452c4f02d2cd91.webp"
    alt="Die Sicherheits-Einstellungen zeigen die erzwungene Zwei-Faktor-Authentifizierung für die Gruppe „admin“ sowie den Brute-Force-Status mit korrekt erkannter Client-IP" title="Zwei-Faktor-Pflicht für die Gruppe „admin“ – und darüber der Beleg, dass Nextcloud die echte Client-IP erkennt"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Zwei-Faktor-Pflicht für die Gruppe „admin“ – und darüber der Beleg, dass Nextcloud die echte Client-IP erkennt</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-paprika-400 bg-paprika-50 dark:border-paprika-700 dark:bg-paprika-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🔥</span>Sperr dich nicht selbst aus
  </p>
  <div class="prose-kitchen text-sm">Sobald die Erzwingung aktiv ist, <strong>muss</strong> jedes Mitglied der Gruppe beim nächsten Login
einen zweiten Faktor einrichten. Richte deshalb <strong>zuerst deinen eigenen</strong> zweiten Faktor
ein und bewahre die Backup-Codes sicher auf, bevor du die Pflicht scharf schaltest. Falls
doch etwas schiefgeht, hebst du die Erzwingung über die Kommandozeile wieder auf:
<code>docker exec -u www-data nc-app php occ twofactorauth:enforce --off</code>. Einen
einzelnen festgefahrenen Faktor entfernst du mit
<code>… php occ twofactorauth:disable BENUTZER totp</code>.</div>
</div>
<h3 id="schritt-6-brute-force-schutz-mit-echten-ips--basis-für-fail2ban">Schritt 6: Brute-Force-Schutz mit echten IPs – Basis für Fail2ban</h3>
<p>Nextcloud drosselt fehlgeschlagene Logins von Haus aus: Nach mehreren Fehlversuchen
verzögert es weitere Anfragen <strong>derselben IP</strong>. Dieser Schutz steht und fällt aber damit,
dass Nextcloud die <strong>echte Client-IP</strong> sieht – und nicht die interne IP von Traefik. Genau
das leistet die <code>TRUSTED_PROXIES</code>-Einstellung aus Teil 1.</p>
<p>Ob es funktioniert, siehst du unter <strong>Administrationseinstellungen → Sicherheit</strong> im
Kasten „Brute-Force-Zulassungsliste&quot; (im Screenshot oben). Dort steht deine aktuelle,
korrekt erkannte öffentliche IP:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Ihre aktuelle IP-Adresse wird als &#34;DEINE_IP&#34; erkannt. Diese Adresse wird derzeit nicht gedrosselt.</span></span></code></pre></div>
</div>
<p>Steht da stattdessen eine <code>172.x.x.x</code>-Adresse aus dem Docker-Netz, greift <code>TRUSTED_PROXIES</code>
nicht – dann würde der Brute-Force-Schutz alle Nutzer über einen Kamm scheren und im
Zweifel Traefik selbst sperren. In dem Fall zurück zu Teil 1, Schritt 2/3.</p>
<p><strong>Harte Sperren mit Fail2ban.</strong> Die eingebaute Drosselung verzögert nur; wer Angreifer
richtig aussperren will, kombiniert Nextcloud mit
<a href="/tutorials/fail2ban-einrichten/">Fail2ban</a>. Nextcloud protokolliert jeden Fehlversuch im
JSON-Log – und dank <code>TRUSTED_PROXIES</code> mit der echten IP:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">{&#34;level&#34;:2,&#34;time&#34;:&#34;2026-07-18T08:14:05+00:00&#34;,&#34;remoteAddr&#34;:&#34;203.0.113.47&#34;,&#34;user&#34;:&#34;--&#34;,&#34;app&#34;:&#34;no app in context&#34;,&#34;method&#34;:&#34;POST&#34;,&#34;url&#34;:&#34;/login&#34;,&#34;message&#34;:&#34;Login failed: BENUTZER (Remote IP: 203.0.113.47)&#34;}</span></span></code></pre></div>
</div>
<p>Dieses Log liegt im Nextcloud-Volume. Den Pfad auf dem Host findest du so:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker inspect -f <span class="s1">&#39;{{ range .Mounts }}{{ if eq .Destination &#34;/var/www/html&#34; }}{{ .Source }}{{ end }}{{ end }}&#39;</span> nc-app</span></span></code></pre></div>
</div>
<p>Darunter liegt die Datei <code>data/nextcloud.log</code>. Auf die zeigst du einen Fail2ban-Filter,
der auf <code>remoteAddr</code> matcht, plus ein Jail nach dem Muster aus dem
<a href="/tutorials/fail2ban-einrichten/">Fail2ban-Tutorial</a>. So wandert nach ein paar
Fehlversuchen die Angreifer-IP direkt in die Firewall – bevor die Anfrage Nextcloud
überhaupt erreicht.</p>
<h3 id="schritt-7-caching--php-prüfen--das-performance-fundament">Schritt 7: Caching &amp; PHP prüfen – das Performance-Fundament</h3>
<p>Zum Schluss vergewissern wir uns, dass die Performance-Basis steht. Vieles davon hat Teil 1
über die <code>REDIS_HOST</code>-Variable schon automatisch eingerichtet – prüfen schadet trotzdem
nicht, denn genau hier wird eine Nextcloud zäh oder flott.</p>
<p>Nextcloud nutzt <strong>drei</strong> Cache-Rollen. Kontrolliere alle drei:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ config:system:get memcache.local
</span></span><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ config:system:get memcache.distributed
</span></span><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php occ config:system:get memcache.locking</span></span></code></pre></div>
</div>
<p>Erwartet:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">\OC\Memcache\APCu
</span></span><span class="line"><span class="cl">\OC\Memcache\Redis
</span></span><span class="line"><span class="cl">\OC\Memcache\Redis</span></span></code></pre></div>
</div>
<ul>
<li><strong>Lokaler Cache (APCu):</strong> hält häufig genutzte Daten im RAM des PHP-Prozesses – der
spürbarste Beschleuniger im Alltag.</li>
<li><strong>Verteilter Cache (Redis):</strong> teilt Cache-Daten über Prozesse hinweg, wichtig sobald
App- und Cron-Container zusammenspielen.</li>
<li><strong>File-Locking (Redis):</strong> verhindert, dass zwei Zugriffe dieselbe Datei gleichzeitig
verändern und sie beschädigen. Der Grund, warum wir in Teil 1 überhaupt Redis eingebaut
haben.</li>
</ul>
<p>Passt das Zusammenspiel, meldet <code>docker exec -u www-data nc-app php occ setupchecks</code> die
Zeile <code>✓ Memcache: Configured</code>. (Bestandene Prüfungen zeigt die Web-Übersicht nicht an –
dort tauchen nur Warnungen und Hinweise auf, deshalb kontrollierst du das hier per CLI.)</p>
<p><strong>OPcache</strong> – der Bytecode-Cache von PHP – ist im offiziellen <code>nextcloud</code>-Image bereits
sinnvoll vorkonfiguriert (u. a. <code>opcache.interned_strings_buffer=32</code>). Du musst hier also
nichts nachziehen; die früher berüchtigte OPcache-Warnung taucht mit aktuellen Images gar
nicht mehr auf. Nachschauen kannst du bei Bedarf so:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker <span class="nb">exec</span> -u www-data nc-app php -i <span class="p">|</span> grep opcache.interned_strings_buffer</span></span></code></pre></div>
</div>
<p>Damit ist die Übersicht warnungsfrei:</p>
<p><figure class="my-6"><img src="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_e398290706625ab9.webp" srcset="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_e354f69e1443ecd8.webp 480w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_e398290706625ab9.webp 768w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_d2ede7a8e25e526d.webp 1200w, /tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_77659c13bfe90ad3.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/nextcloud-optimieren-absichern/nc-uebersicht-gruen_hu_c26ff36bf5d6b604.webp"
    alt="Die Nextcloud-Admin-Übersicht zeigt keine gelben Warnungen mehr, nur noch zwei optionale Hinweise, und meldet die aktuelle Version" title="Ergebnis: keine Warnungen mehr, Version aktuell – nur die zwei optionalen Hinweise bleiben"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Ergebnis: keine Warnungen mehr, Version aktuell – nur die zwei optionalen Hinweise bleiben</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Vorschaubilder gezielt erzeugen
  </p>
  <div class="prose-kitchen text-sm">Wenn deine Nutzer viele Fotos ablegen, lohnt sich die App <strong>„Preview Generator&quot;</strong>: Ein
<code>occ</code>-Cronjob erzeugt Vorschaubilder im Voraus, statt sie beim ersten Öffnen langsam on
the fly zu berechnen. Ergänzt du sie, begrenze über
<code>occ config:system:set preview_max_x --value=2048</code> (und <code>preview_max_y</code>) die maximale
Vorschaugröße, sonst wächst der Speicherbedarf schnell.</div>
</div>
<h2 id="wenn-es-nicht-funktioniert">Wenn es nicht funktioniert</h2>
<p><strong>Symptom:</strong> Nach dem Traefik-Neustart erscheint der HSTS-Header nicht in der <code>curl</code>-Ausgabe.</p>
<p><strong>Ursache &amp; Lösung:</strong> Meist ist die Middleware nicht am Router. Prüfe, dass die Zeile
<code>traefik.http.routers.nc.middlewares</code> <strong>beide</strong> Middlewares nennt (<code>nc-dav,nc-secure</code>) und
dass die drei <code>nc-secure</code>-Header-Labels im <code>nc-app</code>-Block stehen. Danach
<code>docker compose up -d nc-app</code>. Traefik übernimmt geänderte Labels erst beim Neu-Erstellen
des Containers.</p>
<p><strong>Symptom:</strong> Der E-Mail-Test schlägt fehl („Es gab ein Problem beim Senden der E-Mail&quot;).</p>
<p><strong>Ursache &amp; Lösung:</strong> Fast immer Port/Verschlüsselung oder Authentifizierung. Kombiniere
<code>SSL/TLS</code> mit Port <strong>465</strong> oder <code>STARTTLS</code> mit Port <strong>587</strong> – nicht kreuzweise. Nutzt dein
Anbieter 2FA, brauchst du ein <strong>App-Passwort</strong> (siehe Schritt 4). Details stehen im
Nextcloud-Log: <code>docker exec -u www-data nc-app php occ log:tail 20</code>.</p>
<p><strong>Symptom:</strong> Du kommst nach dem Erzwingen von 2FA selbst nicht mehr rein.</p>
<p><strong>Ursache &amp; Lösung:</strong> Du hattest noch keinen zweiten Faktor eingerichtet. Hebe die Pflicht
per Kommandozeile auf, richte deinen Faktor in Ruhe ein und schalte sie danach wieder
scharf: <code>docker exec -u www-data nc-app php occ twofactorauth:enforce --off</code>.</p>
<p><strong>Symptom:</strong> Im Brute-Force-Kasten steht eine <code>172.x.x.x</code>-Adresse statt deiner echten IP.</p>
<p><strong>Ursache &amp; Lösung:</strong> <code>TRUSTED_PROXIES</code> passt nicht zum tatsächlichen <code>proxy</code>-Subnetz.
Ermittle es mit <code>docker network inspect proxy -f '{{(index .IPAM.Config 0).Subnet}}'</code> und
trag den Wert in der <code>nc-app</code>-Umgebung ein (Teil 1, Schritt 2). Sonst sperrt der
Brute-Force-Schutz im Ernstfall den Proxy und damit alle Nutzer.</p>
<p><strong>Symptom:</strong> Nach einem Reboot meldet Nextcloud „Redis went away&quot; oder wird sehr langsam.</p>
<p><strong>Ursache &amp; Lösung:</strong> Der App-Container ist vor Redis gestartet. Stelle sicher, dass
<code>nc-redis</code> in <code>depends_on</code> steht (Teil 1) und mit <code>restart: unless-stopped</code> läuft – dann
fängt Docker den Startreihenfolge-Fall selbst ab.</p>
<h2 id="wartung--backups">Wartung &amp; Backups</h2>
<ul>
<li><strong>Übersicht nach jedem Update prüfen.</strong> Neue Nextcloud-Versionen bringen neue Checks
mit. Wirf nach jedem Upgrade einen Blick auf <strong>Administrationseinstellungen → Übersicht</strong>
oder lass <code>occ setupchecks</code> laufen – so fängst du neue Warnungen früh ab.</li>
<li><strong>Regelmäßig den offiziellen Security-Scan nutzen.</strong> Der
<a href="https://scan.nextcloud.com/">Nextcloud Security Scan</a> prüft deine Domain von außen und
vergibt eine Note. Mit HSTS und aktuellen Versionen ist <strong>A/A+</strong> das realistische Ziel;
fällt die Note, ist meist ein Update überfällig.</li>
<li><strong>Zweite Faktoren im Blick behalten.</strong> Bewahre die Backup-Codes getrennt vom Handy auf.
Verliert ein Nutzer sein Gerät, entfernst du seinen Faktor mit
<code>occ twofactorauth:disable BENUTZER totp</code>, danach richtet er ihn neu ein.</li>
<li><strong>App-Passwörter aufräumen.</strong> Jeder verbundene Client (Desktop, Handy) bekommt ein
eigenes App-Passwort. Unter <strong>Persönliche Einstellungen → Sicherheit</strong> siehst du alle
Geräte und kannst einzelne bei Verlust gezielt widerrufen.</li>
<li><strong>Die Absicherung ersetzt kein Backup.</strong> All das schützt vor fremdem Zugriff, nicht vor
Datenverlust. Die konsistente Sicherung aus Datenbank-Dump und Datenverzeichnis bleibt
Pflicht – siehe den Wartungsabschnitt in <a href="/tutorials/nextcloud-eigene-cloud/">Teil 1</a> und
<a href="/tutorials/backups-mit-restic/">Backups mit Restic</a>. Ehrlich zum Aufwand: Plane den
monatlichen Update-Durchgang mit einem kurzen Blick auf die Übersicht fest ein – dann
bleibt deine Cloud dauerhaft grün.</li>
</ul>
]]></content:encoded></item></channel></rss>