Nginx sicherer machen

Sicherheit ist bei jedem Webserver ein wichtiges Thema, über das man sich nie zu wenig Gedanken machen kann.

Ich möchte hier einige, u.a. auch vom Apache bekannte, Möglichkeiten vorstellen, wie man seinen nginx-Webserver sicherer machen kann.

Es sind natürlich nur Empfehlungen und besonders bei den Veränderungen am Source-Code von nginx möchte ich noch einmal bemerken, das ichkeine Haftung für Schäden jeglicher Art übernehme, die durch hier vorgeschlagene Änderungen entstanden sind! Wenn ihr also nicht wisst, was ihr tut, lasst lieber erst einmal die Finger davon! ;)

Änderungen an der Serverkonfigurationsdatei

Die Konfigurationsdatei des nginx /etc/nginx/nginx.conf bieteteinfache Einstellmöglichkeiten, welche lediglich einen Reload bzw.Restart des Webservers benötigen um übernommen zu werden. Um dabei zu verhindern, dass der Server nach einem Neustart nichtmehr funktioniert, weil zum Beispiel ein Syntaxfehler vorliegt, könnt ihr mit dem Befehl

$> /usr/sbin/nginx -t

die Konfiguration testen. Dabei kann das Verzeichnis in dem die nginx-Binary liegt je nach Distribution etwas abweichen.

Es einige Möglichkeiten, die eure Serversicherheit erhöhen - hier einige Beispiele dazu:

Serversignatur in den HTTP-Headers austellen

Bei jeder HTTP-Anfrage an euren Webserver werden bei einer Antwort einige Infomationen mitgeschickt die Auskunft über den Server,eingesetzte Zusatzsoftware, etc. beinhalten. Da ein Konzept der Sicherheit ist, so wenig wie nötig an Informationen preis zu geben, werden wir diese Informationen im Folgenden ausblenden oder ändern um etwaigen Angreifern das Leben etwas schwerer zu machen.

Die Serversignatur kann dabei Informationen über den Webserver, dessen Version oder z.B. auch ob PHP installiert ist, enthalten. Sieabzustellen, bedeutet, das Angreifer weniger Informationen - und das ohne großen Aufwand, denn es muss lediglich eine Zeile in der Konfiguration geändert werden:

server_tokens off;

Nicht benötigte Requests

Auf einem Server können - größtenteils durch Spambots verursacht - Requests auflaufen, die nicht benötigt oder erwünscht sind. Auch hierfürgibt es einige einfache Eigenschaften der Konfiguration, um diese zu Sperren.

Die erste davon wäre, alle Requests, deren Methode nicht "GET", "HEAD" oder POST ist zu sperren:

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 444;
}

Man könnte hier natürlich auch - wenn man z.B. nur statische HTML-Seiten hat auf einem VHost hat - die POST nicht verwenden, dieses auch sperren.

Eine andere Möglichkeit, die einem viel Traffic sparen kann, ist unerwünschte Crawler, die z.B. nach System-schwachstellen suchen oderals Spambots bekannt sind, per User-Agent auszusperren. Das ganze funktioniert ähnlich:

if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
    return 403;
}

Die Pipes( | ) im Suchstring stellen dabei das logische Oder dar, daher es wird für alle User-Agents die entweder LWP::Simple ODER BBBike ODER wget nutzen, der 403 Statuscode zurückgeliefert. Vorsicht sollte man allerdings bei User-Agents wie wget walten lassen - dies ist das Standardtool auf den meisten Linux-Shells, um Dateien herunter zu laden. wenn ihr also Dateien anbietet, die möglicherweise damit runtergeladen werden könnten( wie z.B. Source-Code-Packages) solltet ihr die Dateien entweder selektiv Freigeben oder den User-Agent nicht sperren.

HTTP-Referer prüfen

Es gibt Fälle, da möchte man Traffic von bestimmten Seiten einfachvermeiden. Ist das der Fall kann man das mit Hilfe des HTTP-Referersprüfen und dann ggf. dem User eine Fehlerseite anzeigen. Das ganze lässt sich recht einfach mit der Variable \$http_referer umsetzen, wie etwa in folgendem Beispiel:

if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) {
    return 403;
}

Eine andere Möglichkeit, die vielleicht seltener anwendbar ist, aber dafür in ihrer Genauigkeit kaum zu schlagen, ist die Whitelist-Prüfung mit der valid_referers Liste, ganz einfach umzusetzen wie in folgendem Beispiel:

valid_referers blocked www.example.com example.com;

if ($invalid_referer) {
    rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last;
}

Hier wird eine Liste mit Hosts festgelegt, die als valide Referer erlaubt sind und Zugriffe von allen anderen Hosts werden auf ein spezielles Bild weitergeleitet. Dies ist ein beliebtes Anwendungsgebiet für die Unterbindung des sogenannten "Image Hotlinkings", bei welchem andere Seiten die Grafiken der eigenen Seite einbinden. Dies kann unter anderem Unerwünscht sein, wenn man Bilder anbietet, die eigentlich nur mit einem Login einsehbar sind. Mit einer ähnlichen Methode werden so z.B. Zugriffe auf die Bilder der User der VZ-Netzwerke unterbunden.

Man kann das ganze natürlich auch ganz unterbinden, ohne ein Fehler-Bild zurückzuliefern, im folgenden Beispiel wird dabei der Ordner imagesder Überprüfung unterzogen und Usern mit einem unerwünschtem Referer wird nur der Statuscode 403 zurückgeliefert( beziehungsweise dieentsprechende Fehlerseite dafür)

location /images/ {
    valid_referers none blocked www.example.com example.com;
    if ($invalid_referer) {
        return   403;
    }
}

Ein weiterer interessanter Ansatz ist, das ganze über eine map zu gestalten. Dieser Ansatz kam direkt von Igor Sysoev in einer Mailingliste( englisch).

Abschließend ist allerdings zu sagen, dass diese Methode nich immer funktioniert. Dies ist unter Umständen der Fall wenn der Browser desUsers keinen HTTP-Referer unterstützt oder die Prüfung durch Spoofing und ähnliche Techniken umgangen wird.

Veränderungen am Source-Code

Veränderungen am Source sind ein heikles Thema - läuft etwas schiefläuft der Webserver instabil oder garnicht mehr. Deshalb sindgrundlegende Kenntnisse in C (die Sprache, in der nginx geschrieben ist) auf jeden Fall voraussetzung. Bedenkt bitte auch, das der Server nicht nur einen schnellen Reload zum Ansehen der Veränderungen braucht - ihr müsst ihn für jede Änderung neu kompilieren, was, je nach Geschwindigkeit des Servers, einige Zeit in Anspruch nehmen kann.

Die nginx-Version ändern

Bei jeder Anfrage an den Server antwortet dieser in den HTTP-Headersunter anderem mit dem Namen und der Version des Webservers. Fakt ist,dass solche Informationen genutzt werden können, um Schwachstellen auszunutzen, die vielleicht sogar schon bekannt sind. Man kann also entweder garnichts mitteilen, oder aber eine falsche Version oder sogar einen falschen Servernamen angeben.

Das ganze funktioniert, in dem man im Source-Code von nginx die definierten Versionen abändert. Um die Versionsnummer zu ändern, gehtman dazu in die nginx.h, welche sich unter folgendem Pfad finden lässt:

src/core/nginx.h

Dort befindet sich die Definition der Versionsnummer. Sie sollte in etwa so aussehen ( hier wäre die Version z.B. 0.7.61 )

#define NGINX_VERSION      "0.7.61"

definiert wird ändern:

#define NGINX_VERSION      "1.2.3.4"

Serverversion, die sich in den HTTP-Headers in etwa so niederschlägt:

HTTP/1.1 200 OKServer: nginx/1.2.3.4

Doch auch der Name lässt sich verändern. Dazu ändert man zuerst in der gleichen Header-Datei, also der nginx.h, in der folgenden Zeile

#define NGINX_VER          "nginx/" NGINX_VERSION
#define NGINX_VER          "ExampleServerName/" NGINX_VERSION

Damit ist es jedoch noch nicht ganz getan. In der Datei

src/http/ngx_http_header_filter_module.c

Muss die Zeile

static char ngx_http_server_string[] = "Server: nginx" CRLF;

abgeändert werden. Um genauer zu sein, das Server: nginx. Hier kann man nginx wieder mit einem beliebigen String austauschen, wie etwa

static char ngx_http_server_string[] = "Server: ExampleServerName" CRLF;

Nach den Anpassungen und einem erneuten Kompilieren sieht der HTTP-Header dann in etwa so aus:

HTTP/1.1 200 OKServer: ExampleServerName/1.2.3.4

Kompilieren ohne ungenutzte Module

Ungenutzte oder ungewollte Module nicht in mit in die Binary zu kompilieren hat viele Vorteile. Der wichtigste in Punkto Sicherheit isteinfach zu erklären - je weniger in der finalen Binary enthalten ist, umso weniger ungewollte Angriffspunkte bietet diese. Das configure-Skript des Source-Codes bietet einfache Möglichkeiten, Module wegzulassen, wie zum Beispiel mit dem folgenden Befehl:

> ./configure --without-http_autoindex_module

Dies würde das Autoindex-Modul beim Kompilieren auslassen. Um eine vollständige Liste der unterstützten Befehle zu bekommen brauch man übrigens nur

> ./configure --help

eingeben. Ich würde jedoch empfehlen, die Ausgabe dann noch per less oder more aufteilen zu lassen, da es für kleinere Terminal-Fenster einfach zu viel ist.






Proudly powered by Microsoft IIS, Visual Basic .NET and DHTML. NOT.
Copyright © MKzero 2013
License Info