Ich bringe mal wieder eine mehrteilige Artikelserie auf, weil das Thema etwas komplexer ist und sich mit den Teilen gut aufteilen lässt. Außerdem sollte dies jedem, der einen Webserver im Internet zur Verfügung stellt bewußt sein.
Es soll heute darum gehen, wie ich meine Webserver, der ja aus dem Internet erreichbar ist, etwas besser absichern kann.
Dies ist nicht der ultimative Weg, soll aber zeigen, wie man den Webserver als Dienst ganz gut absichern kann.
Erste Voraussetzung ist, dass der Webserver immer auf die aktuelle Version gebracht wird. Es nützt nichts, immer zu sagen, ja, meine Internetseite ist doch so unbedeutend, da wird schon nichts passieren. Diese Annahme ist schon aus 2 Gründen falsch.
- Für einen potenziellen Hacker ist alle Zugänge zu einem Webserver interessant. Egal ob das ein gut-laufendes Unternehmen oder der Blog der Familie ist oder der kleine Garten-Verein um die Ecke. Von solchen Webservern kann man angriffe starten.
- Für die Welt mag der Internet-Auftritt vielleicht nicht der Hit sein oder die Lösung aller Probleme bringen, ABER (!) für die Betreiber und die Besucher der Seite ist der Inhalt wichtig. Werden diese verschlüsselt, dann sind die Daten weg.
Also gibt es hier ein bestimmtes Interesse, seinen Seite vor Angriffen zu schützen.
Mein Weg geht nun auf die Server Ebene. Die eingesetzte Software, egal ob es sich um statische HTML-Seiten, einen WordPress-Blog oder einen kleinen Webshop handelt, sollte man immer wieder, wie bereits gesagt aktualisieren. In welchem Zeitraum, ist egal, nur sollte man sich regelmäßig darum kümmern.
So, ist das verstanden, sollte man sich den Aufbau des Server-Setups noch einmal genauer ansehen. Viel wichtiger, man sollte sich einmal das error.log seines Webservers ansehen. Denn dort werden die Schwachstellen in der Konfiguration schnell sichtbar, denn wenn ein „Besucher“ gerne mehr über einen Webserver erfahren möchte, so wird er versuchen, eben auf Fehler im System zu stoßen.
Gehen wir aber die Konfiguration erste einmal von der Struktur durch.
Grundsätzlich sollte man darauf achten, dass die Anwendung nicht direkt im root-Verzeichnis des Webservers läuft. Ja, auch wenn man nur eine Anwendung nutzt, so hat es Vorteile, wenn man sogenannte virtuelle Hosts auf seinen Server einrichtet. Apache, nginx, sowie lighttp können dies. Eine Anleitung, wie man dies in dem entsprechenden Ordner macht findet Ihr hier.
- apache Webserver (https://httpd.apache.org/docs/2.4/vhosts/examples.html)
- nginx Webserver (https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04)
- lighttp Webserver (https://www.itzgeek.com/how-tos/linux/how-to-setup-virtual-hosts-in-lighttpd-server.html)
Wichtig ist, dass jeder eingesetzte Host in einem Unter-Ordner des Webroots eingesetzt wird. Also z.B:
/var/www/host1/
/var/www/host1/
Welche Name Ihr für die Hosts-Ordner verwendet, bleibt euch überlassen.
Wenn die Hosts so eingerichtet sind, solltet Ihr euch überlegen, was Ihr mit Besuchern macht, die gerne in das Webroot-Verzeichnis sehen wollen, denn da wollen die „Besucher“ zuerst suchen.
Bei meinen Untersuchungen habe ich festgestellt, dass zwar immer noch manche „Besucher“ mit verschiedenen IP-Adressen immer wieder die selbe Abfrage versuchen, aber es gibt auch mittlerweile auch Situationen, in der viele Abfragen von der selben IP-Adresse kommen. Im Moment aus Russland. Um sich davor zu schützen ist die Struktur mit Unterordnern und virtuellen Hosts schon ein guter Anfang.
Damit die Server auch auf Fehler richtig reagiert, sollten man sich das Errror-Handling seines Servers ansehen und einrichten. Dies ist lästig, weil man sichhier mit Fehlern beschäftigen muss, gehört zu einer guten Webserver-Konfiguration aber mit dazu.
Z.B. kann man bei einem nginx einrichten, dass allgemein Fehler in eine Log-Datei geschrieben werden soll. Folgender Code ist hier hilfreich.
error_log /var/log/nginx/error.log; error_page 403 404 500 502 503 504 /error-doc/error.html; location = /error.html { root /var/www/error-doc/; }
Falls ein Fehler mit den folgender Fehlercodes auf dem Server passieren, dann wird man nicht nur auf die Fehlerseite error.html weitergeleitet (diese liegt im Ordner /var/www/error-doc/), sondern auch das Webroot wird auf diesen Ordner verschoben und der „Besucher“ wird hier festgesetzt.
Die möglichen Fehler sind:
- 404 Not Found
- 403 Forbidden
- 500 Internal Server Error
- 502 Bad Gateway
- 503 Service Unavailable
- 504 Gateway Timeout
Dies sind nun nur Beispiel-Fehlercodes und diese können auch gerne nach eigenen Belieben angepasst werden (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
Das error-Log sollte allgemein für den Webserver eingerichtet werden, da dies ja egal wie viele Webauftritte auf dem Webserver laufen, alle Fehler sammeln soll.
Hat man nun alle Auftritt in virtuelle Hosts umgezogen und das error.log für seinen Webserver eingerichtet, dann sollte man sich nun noch um das Webroot selber kümmern. Eine allgemein gültige Methode, die auf allen Webservern gleich ist, wäre die Nutzung einer robots.txt, da diese ein allgemeiner Standard im Web ist.
Manche werden nun sagen, Moment mal, die robots.txt nutzt man doch für SEO (https://developers.google.com/search/docs/advanced/robots/robots_txt)? Das ist richtig, aber die SEO wird nun in den Webroot-Ordner der einzelnen Webauftritt passieren und nicht mehr im Webroot des Webservers. Deshalb nutzen wir diese nun hier, da diese wirklich gut greift.
In den Webroot-Ordner kommt nun neben die Ordner der einzelnen vHosts eine Textdatei mit folgenden Inhalt.
User-agent: *
Disallow: /
Jedem SEOler wird sich nun der Magen umdrehen, weil der gesamte Zugriff auf den Webroot-Ordner direkt für alle Aufrufe verboten wird, also der Status 403 erzeugt wird.
In dem Webroot-Ordner hat niemand etwas zu suchen und deshalb wird der Zugriff unterbunden. Habt ihr ein allgemeines error.log für euren Webserver eingerichtet, dann startet euren Webserver nun neu und Ihre werdet sehen, dass mit der Zeit sich im error.log Einträge zeigen werden, wie z.B. bei mir:
2022/04/01 17:34:49 [error] 7078#100255: *20530 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/01 17:52:28 [error] 7078#100255: *20879 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy", referrer: "http://yy.yy.yy.yy/"
2022/04/01 18:23:09 [error] 7077#101698: *21221 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy", referrer: "http://yy.yy.yy.yy/"
2022/04/01 18:41:11 [error] 7080#100847: *21378 open() "/var/www/.git/config" failed (2: No such file or directory), client: xx.xx.xx.xx, server: webserver, request: "GET /.git/config HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/01 19:02:42 [error] 7080#100847: *21577 open() "/var/www/owa/auth/logon.aspx" failed (2: No such file or directory), client: xx.xx.xx.xx, server: webserver, request: "GET /owa/auth/logon.aspx HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/01 21:31:25 [error] 7080#100847: *22789 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy:443"
2022/04/01 23:35:26 [error] 7078#100255: *24234 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/01 23:51:21 [error] 7079#100431: *24639 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/01 23:51:23 [error] 7080#100847: *24643 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/02 00:09:25 [error] 7079#100431: *24769 open() "/var/www/epa/scripts/win/nsepa_setup.exe" failed (2: No such file or directory), client: xx.xx.xx.xx, server: webserver, request: "HEAD /epa/scripts/win/nsepa_setup.exe HTTP/1.1", host: "yy.yy.yy.yy:443"
2022/04/02 00:38:59 [error] 7080#100847: *24992 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.0", host: "yy.yy.yy.yy"
2022/04/02 01:32:34 [error] 7079#100431: *25318 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.0", host: "yy.yy.yy.yy"
2022/04/02 03:52:02 [error] 7078#100255: *27123 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "POST /?class.module.classLoader.URLs%5B0%5D=0 HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/02 03:52:02 [error] 7078#100255: *27123 open() "/var/www/favicon.ico" failed (2: No such file or directory), client: xx.xx.xx.xx, server: webserver, request: "GET /favicon.ico HTTP/1.1", host: "yy.yy.yy.yy"
2022/04/02 04:09:52 [error] 7078#100255: *27245 directory index of "/var/www/" is forbidden, client: xx.xx.xx.xx, server: webserver, request: "GET / HTTP/1.1", host: "yy.yy.yy.yy"
In jeder Zeile werden die direkten Zugriff auf meinen Webserver über die IP-Adresse eingetragen und blockiert. Es wird immer auf unterschiedliche Art verucht Daten von dem Server abzurufen oder vermeintliche Webseiten abgefragt.
Versuche, mehr über meinen Webserver zu erfahren, laufen ins Leere, bzw. werden blockiert
Somit ist der Server erst einmal auf Service-Ebene geschützt.
Ich kann nur wiederholen, dass dies nicht der ultimative Weg ist, sondern einer von vielen. Man sollte immer folgendes beachten, wenn man einen Webserver im Internet bereitstellt.
- Software-Version des Webservers regelmäßig aktualiseren
- Software der Webanwendung regelmäßig aktualisieren
- error.logs regelmäßig auf Auffälligkeiten untersuchen.
Im nächsten Teil gehen wir einen Schritt weiter und werden die Daten nutzen um Maßnahmen dagegen zu ergreifen.