Seafile mit Fail2ban absichern

Schützen Sie Login sowie Up- und downloadlinks von Seafile mit Fail2ban.

Seafile ist einer der zentralen Dienste eines jeden datamate Servers. Besonders der Einsatz als sicherer Dropbox-Ersatz für Unternehmen und als Dateiaustauschplattform mit Geschäftspartnern ist sehr beliebt. Für diesen Einsatzzweck muss Seafile natürlich ins Internet freigegeben werden, weshalb der Zugriff auf Seafile besonders gesichert werden muss.

Seafile sichert bereits in der Standardkonfiguration den Login über die Weboberfläche mit einem Captcha ab. Die Up- und Downloadlinks werden jedoch nicht gesichert und vertrauen alleine auf die Macht von zufällig erzeugten Links.

Im folgenden Artikel zeigen wir die Absicherung von Seafile mit Hilfe des Logfile-Analysierers Fail2ban. Das Prinzip ist dabei denkbar einfach. Jeder Zugriffsversuch auf Seafile (egal ob Login-Versuch per Webbrowser oder per App, sowie der Aufruf eines Up- oder Downloadlinks) wird in den Log-Dateien des Servers protokolliert. Sobald in einer gewissen Zeitspanne mehrere fehlerhafte Zugriffe von einer IP-Adresse protokolliert werden, blockiert Fail2ban weiter Zugriffsversuche für einen gewissen Zeitraum.

Bei geschickter Wahl dieser beiden Parameter sperrt man einen vergesslichen Mitarbeiter nicht aus, verhindert aber wirkungsvoll Brute-Force-Angriffe, d.h. das automatische Durchprobieren von Login-Kombinationen oder von Up- und Download-Links.

Aus unserer Sicht ist diese Absicherung essentiell wichtig, sobald Seafile ins Internet freigegeben wird und sollte unter keinen Umständen ausgelassen werden.

Welche Schutzmechanismen bringt Seafile mit?

Standardmäßig verlangt Seafile nach mehreren fehlerhaften Login-Versuchen über die Webseite die Eingabe eines zusätzlichen Captcha.

Seafile schützt den Login nach mehreren Fehlversuchen mit einer Captcha-Eingabe.

Seafile schützt den Login nach mehreren Fehlversuchen mit einer Captcha-Eingabe.

Dies schützt zuverlässig vor Brute-Force-Angriffen, jedoch greift dieser Schutzmechanismus nicht bei App-Logins und bei den Up- und Downloadlinks, da hier keine Captchas verlangt werden, bzw. die Abfrage nicht möglich ist.

In den Einstellung von Seafile kann man festlegen, wie lange die erzeugten Down- und Uploadlinks sein sollen. Standardmäßig sind die Links 10 Stellen lang und haben die folgende Struktur:

Downloadlink: seafile-url/d/XXXXXXXXXX
Uploadlink: seafile-url/u/XXXXXXXXXX
X ist hier im Beispiel entweder eine Zahl von 0-9 oder a-f.

Mit 10 Stellen gibt es 16^10 mögliche Kombinationen, d.h. ca. 1.000.000.000.000 mögliche Kombinationen.

Müssen Upload- und Download-Links wirklich abgesichert werden?

Im ersten Moment mag man meinen, dass 1 Billion mögliche Kombinationen (alleine für die Download-Link) ausreichend sind um einen Hackerangriff unattraktiv zu machen. Dies halten wir jedoch für eine gefährliche Sicherheit, wie der folgenden Versuchsaufbau verdeutlichen soll. Das folgende Script probiert beispielsweise sämtliche dreistelligen Downloadlinks aus, indem es die entsprechende URL per curl anfragt und auf den String „Sorry, but the requested page could not be found“ prüft. Wenn dieser String gefunden wird, handelt es sich um eine Fehlerseite. Wenn diese String jedoch nicht gefunden wird, dann hat man eine gültige Download-Adresse gefunden.

#!/bin/bash
## Nur für lokale Demo-Zwecke. Dieses Script auf einen fremden Server loszulassen, kann eine Straftat darstellen.

start=`date +%s`
log="/tmp/brute-force-seafile.log"
echo "Brute-Force-Attack on Seafile Download-Links" > $log
echo "---" >> $log

for i in {a..f} {0..9};
  do for j in {a..f} {0..9};
    do for k in {a..f} {0..9};
      do
        gotcha=`curl --insecure --location --silent --url "https://10.37.102.7/seafile/d/$i$j$k" | grep "Sorry, but the requested"`
        if [ -n "$gotcha" ]; then
          echo "/seafile/d/$i$j$k = -";
        else
          echo "/seafile/d/$i$j$k = Treffer";
        fi
      done;
    done;
  done

end=`date +%s`
runtime=$((end-start))
echo "Runtime was $runtime seconds."
echo "--- finished ---"

Mit diesem Beispielscript konnten wir ungefähr 35 Kombinationen pro Sekunde abfragen. Dies mag im ersten Moment nicht viel erscheinen, da man dann ungefähr 1.000 Jahre benötigen würde um sämtliche Kombinationen durchzuprobieren. Doch es gibt mehrere Ansätze, wie sich der Brute-Force-Ansatz optimieren lassen könnte:

  • jede Anfrage lädt den kompletten Quellcode der Webseite, der nach dem String „Sorry, …“ durchsucht wird. Mit Sicherheit lässt sich anhand von intelligenteren Rückgabewerten eine effizientere Suche realisieren.
  • jede Anfrage muss neu initialisiert werden. Curl bietet die Möglichkeit mit einer Sitzungsanfrage mehrere URLs anzufragen. So kann bestimmt der Daten-Overhead reduziert werden.
  • es können beliebig viele Script parallelisiert beim Server anfragen. Das erste Script prüft sämtliche Links mit „a“ am Anfang und das nächste Script alle Links mit „b“.
  • bestimmt gibt es effizientere Wege als mit curl die Webseiteninhalte anzufragen.

Gleichzeitig sollte man nicht vergessen, dass man auch nicht bis zum Abschluß des Angriffs warten muss. Sobald die erste gültige URL gefunden wurde, kann man die Inhalte herunterladen. Das Angriffsszenario „Brute-Force“ auf Seafile-Download-Links ist somit aus unserer Sicht ein durchaus valides Szenario. Doch zum Glück können Sie sich ganz einfach dagegen schützen.

Seafile Logins zusätzlich absichern

Seafile macht den Schutz von fehlerhaften Login-Versuchen mit Fail2ban denkbar einfach. Nach dem dritten fehlerhaften Login-Versuch findet man folgende Logeinträge in der seahub.log:

2016-10-06 07:27:46,461 [WARNING] seahub.auth.views:197 login Login attempt limit reached, show Captcha, email/username: mr_x, ip: 192.168.7.200, attemps: 3
2016-10-06 07:28:12,461 [WARNING] seahub.auth.views:197 login Login attempt limit reached, show Captcha, email/username: mr_x, ip: 192.168.7.200, attemps: 4

Diese lassen sich denkbar einfach mit dem folgenden Einstellungen in Fail2ban abfangen. Zuerst legt man einen sogenannten Jail an, in dem man die zu durchsuchende Log-Datei sowie die zu überwachende Zeit und die zu blockende Zeit in Sekunden angibt.

# Seafile-Login Einstellungen in jail.local
[seafile-login]
enabled = true
port = http,https
filter = ionas-seafile-login
logpath = /home/seafile/logs/seahub.log
maxretry = 5
findtime = 3600
bantime = 600

Dann muss noch nach den Fail2ban-Filter definieren, nach dem die angegebene Log-Datei durchsucht werden soll.

# filter.d/ionas-seafile-login.conf
[Definition]
failregex = .*Login attempt limit reached.*ip: <HOST>, att.*
ignoreregex =
# Author: Christoph Dyllick-Brenzinger (www.ionas-server.com)

Sobald man Fail2ban neu startet sind sämtliche Logins per Webbrowser und per App geschützt. Testen Sie zuerst mit einer geringen Ban-Time wie z.B. 10 Sekunden um sich nicht vollständig aus Ihrem Server auszusperren.

Seafile Up- und Downloadlinks überwachen – Überwachung des Webservers nginx

Kryptische Up- und Downloadlinks werden auch in anderen Software-Lösugnen gerne genutzt um Zugriffe von Unbefugten zu verhindern. Doch wie unser vorheriges Testscript gezeigt hat, sind diese Links alles andere als sicher. Ein einfaches Script kann in wenigen Sekunden hunderte Links durchprobieren und es somit ist es nur eine Frage der Zeit bis ein entsprechender passender Link gefunden wird, wenn man sich nicht dagegen schützt.

Genau wie beim Schutz des Seafile-Logins muss zum Schutz der Download- und Uploadlinks jeweils ein Jail und ein Filter definiert werden. Mit diesem Sucht man nach den folgenden Einträgen in der seahub.access.log. (Der folgende Eintrag entsteht bei der Verwendung von nginx und Seafile 5.1.3)

192.168.5.45 - - [18/Oct/2016:16:51:59 +0200] "GET /seafile/d/1234567345/ HTTP/1.1" 404 1690 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36"

Der Eintrag in der Jail.local von Fail2ban lautet dann somit:

# Seafile-Links Einstellungen in jail.local
[seafile-url]
enabled = true
port = http,https
filter = ionas-seafile-url
logpath = /var/log/nginx/seahub.access.log
maxretry = 10
findtime = 3600
bantime = 600

Der entsprechende Filter muss dann folgendermaßen aussehen:

# filter.d/ionas-seafile-url.conf
[Definition]
failregex = <HOST>.*GET /seafile/(d|u|f)/.* 404 .*
ignoreregex =
# Author: Christoph Dyllick-Brenzinger (www.ionas-server.com)

Mit diesem Filter sind sowohl Folder-Download, File-Download und Uploads geschützt. Der Filter ist natürlich entsprechend anzupassen, wenn Seafile nicht über ein Subfolder Seafile aufgerufen wird.

Seafile Up- und Downloadlinks überwachen – Seafile Logs durch eigene Middleware

Die Analyse der Log-Dateien des Webservers funktioniert zuverlässig. Gerade jedoch bei eher schwachen Geräten wie z.B. einem Raspberry Pi empfehlen wir eine andere Art der Überwachung. Aufgrund der Größe der Log-Dateien des Webservers (welche schnell ein paar Megabyte groß wird) verlangt Fail2ban unnötig viel Ressourcen zur Überwachung dieser Datei. Mit ein bisschen Arbeit kann man den Ressourcenaufwand deutlich reduzieren. Hierzu schreiben wir in Seafile eine eigene Django-Middleware, welche ganz gezielt die passenden Log-Einträge bei fehlerhaften Zugriffsversuchen schreibt.

Legen Sie die folgende Datei /seahub/seahub/base/ionas.py an:

import logging

logger = logging.getLogger(__name__)

class CustomLog(object):
    def process_response(self, request, response):
        if response.status_code == 404:
            ip_address = request.META.get('REMOTE_ADDR')
            url = request.META.get('PATH_INFO')
            logger.warn('|| Code: 404, IP: %s, URL: %s' % (ip_address, url ))
 
        return response

Wichtig: Achten Sie auf die richtige Einrückung der Zeilen, da diese nicht beliebig ist. Nun müssen wir noch diese Middleware in Seafile bekannt machen, damit die Log-Dateien richtig geschrieben werden.

Hierzu fügen wir in der /seahub/seahub/settings.py im Bereich MIDDLEWARE_CLASSES am Ende noch die folgende Zeile ein:

MIDDLEWARE_CLASSES = (
    ...
    'seahub.base.ionas.CustomLog',
)

Zu guter Letzt wird Seafile noch neu gestartet und ab sofort wird jeder fehlerhafte Aufruf eines Up- oder Downloadslinks zu einer folgenden Fehlermeldung führen:

2016-10-06 07:23:16,281 [WARNING] seahub.base.ionas:10 process_response || Code: 404, IP: 192.168.7.200, URL: /u/d/114280491b

Diese Fehlermeldung kann man nun ganz einfach mit dem folgenden Filter abfangen und somit Brute-Force-Angriffe frühzeitig unterbinden.

# fail2ban filter configuration to protect the up-and downloadlinks of seafile against unlimited trial attempts
[Definition]

failregex = .*Code: 404, IP: <HOST>, URL:.*
ignoreregex =

# Author: Christoph Dyllick-Brenzinger (www.ionas-server.com)

Auch wenn dieser Ansatz etwas komplizierter erscheint, so bietet dieser Ansatz zwei Vorteile:

1. Eigene Middleware ist ressourcenschonender

Da Fail2ban die Log-Dateien konstant auslesen muss, spielt die Dateigröße der Log-Dateien eine wichtige Rolle in Bezug auf die Ressourcenauslastung. Dieser Unterschied mag bei einem ausgewachsenen Server vernachlässigbar sein, ist jedoch bei einem schwachbrünstigen System wie einem Raspberry Pi nicht zu vernachlässigen.

2. Die Log-Datei ist auch für Menschen einfacher zu lesen

Der zweite Aspekt ist ein Komfortaspekt. Bei der riesigen Log-Datei von nginx kann man den Wald vor lauter Bäumen nicht sehen. Bei einer Log-Datei, die fast nur relevante Einträge hat, findet sich das menschliche Auge schnell und einfach zurecht.

Einen Nachteil hat die eigene Middleware hingegen. Bei jedem Update von Seafile, muss die Middleware neu integriert werden, da der Symlink seafile-server-latest auf ein neu hinzugekommenes Verzeichnis mit der neuesten Version zeigt.

Schützen Sie Ihr Seafile mit Fail2ban

Seafile bietet entgegen der kommerziellen Anbieter Dropbox und GoogleDrive die vollkommene Datenhoheit. Diese Freiheit verlangt jedoch, dass man sich mit der Sicherheit des Systems auseinandersetzt. Die Captchas von Seafile sind ein guter erster Schutz, sichern jedoch nicht alle Bereiche von Seafile zuverlässig.

Natürlich ist und bleibt das größte Sicherheitsrisiko der Mensch selbst, welcher aus Bequemlichkeit unsichere Passwörter verwendet oder diese leichtfertig weitergibt. Doch mit Fail2ban lässt sich mit geringem Aufwand Seafile zuverlässig gegen Brute-Force-Angriffe absichern, weshalb dies ein Standardfeature eines jeden ionas-Servers ist.

geschrieben von

Christoph Dyllick-Brenzinger

Christoph ist Gründer und Chefentwickler von datamate.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.