Als Serveradministrator sollte man sich überlegen, wie man seinen Server am besten vor Eindringlingen absichern kann. Da ich in Zukunft vor habe, von einem Webhosting Angebot auf einen vServer umzusteigen, habe ich mich bereits jetzt informiert, wie ich den Server am besten absichern kann. Diese Tipps, Tricks und Ideen möchte ich euch nicht vorenthalten. Ich gehe hier von einem Debian 6 (Squeeze) release aus sowie einer bereits verbundenen Sitzung via SSH (PuTTY etc.)
Ich werde hierbei näher auf SSH, Apache2 mit php sowie MySQL eingehen.
SSH
Zuerst öffnen wir die SSH Config. Diese ist unter /etc/ssh/sshd_config zu finden.
nano /etc/ssh/sshd_config
SSH Port ändern
Es empfiehlt sich, den Standardport zu ändern. Viele Kiddys glauben, wenn der Port 22 nicht offen ist, dass es auch keine SSH Verbindung zu dem Server gibt. Dieser Port sollte ebenfalls nicht in Standard-PortScanner-Listen stehen.
Ich empfehle einen nicht standardisierten Port. Welche Ports standardisierten sind, können bei ICANN oder Wikipedia ausgelesen werden.
In der Konfigurationsdatei muss man hierbei die Zeile mit dem Inhalt „Port 22“ in einen anderen beliebigen Port ändern. Als Beispiel:
Port 17655
SSH Root Login verweigern
Kommt der Angreifer doch auf den richtigen Port, wird dieser versuchen, sich als Benutzer „root“ einzuloggen. Hierzu werden wahrscheinlich sog. Rainbowtables verwendet. Dies sind Standardpasswortlisten. Um auch diesen Web zu erschweren, verweigern wir den Login mittels Benutzerkonto root. Wichtig ist allerdings, dass zuvor noch ein neuer Benutzeraccount angelegt wird, damit man selbst noch Zugriff auf das System hat. Dieser Benutzername sollte keinem Namen ähneln. Das bedeutet, dass der Benutzername nicht thomas
oder unterhaltungsbox
sein darf. Somit muss der Angreifer nicht nur das Passwort, sondern auch den Benutzernamen finden.
Übrigens: Bei einem arp Angriff, kann der Benutzername sowie das Passwort des Benutzers bei einem Login ausgelesen werden. Deswegen ist der Weg über den zweiten Benutzer ebenfalls sicherer, da sich im Falle eines Fremdzugriffes der Benutzer sich nochmals als root anmelden muss.
Folgende Befehle müssen als Benutzer root ausgeführt werden.
Als erstes fügen wir einen neuen Benutzer hinzu. Ersetzte „bennuatmzeer“ mit deinem gewünschten Benutzernamen.
adduser bennuatmzeer
Lege Benutzer »bennuatmzeer« an ...
Lege neue Gruppe »bennuatmzeer« (1001) an ...
Lege neuen Benutzer »bennuatmzeer« (1001) mit Gruppe »bennuatmzeer« an ...
Erstelle Home-Verzeichnis »/home/bennuatmzeer« ...
Kopiere Dateien aus »/etc/skel« ...
Geben Sie ein neues UNIX-Passwort ein:MeinNeuesPasswort
Geben Sie das neue UNIX-Passwort erneut ein:MeinNeuesPasswort
passwd: Passwort erfolgreich geändert
Benutzerinformationen für bennuatmzeer werden geändert.
Geben Sie einen neuen Wert an oder drücken Sie ENTER für den Standardwert
Vollständiger Name []:
Raumnummer []:
Telefon geschäftlich []:
Telefon privat []:
Sonstiges []:
Sind die Informationen korrekt? [J/n]J
Nun sollte der Zugriff auf bennuatmzeer via SSH möglich sein. Sicherheitshalber überprüfen wir das, indem wir eine Verbindung als bennuatmzeer via SSH herstellen. Ist der Zugriff gelungen, versuchen wir uns als root anzumelden. Dazu verwenden wir den Befehl su
. Hat man das root Passwort eingegeben, besitzt man ab sofort über die root Berechtigungen.
Nun verweigern wir den Login via root. Dazu muss folgendes in der SSH Config geändert werden:
PermitRootLogin no
Um die Einstellungen zu übernehmen, starten wir nun SSH neu. Dazu führen wir /etc/init.d/ssh restart
aus. Wichtig ist nun, dass wir wiedermal versuchen, eine Verbindung herzustellen, ob alles funktioniert hat.
SSH Nur auf bestimmter Adresse lauschen
Besitzt der (v)Server mehr als eine IP Adresse, kann man auf einer von beiden den Zugriff unterbinden. Mit dieser Methode lauscht der Server nicht nach SSH Verbindungen. Um diese Einstellung(en) zu setzen, muss ListenAddress
ergänzt werden. Angenommen, der Server besitzt die IP’s 1.2.3.4 sowie 2.3.4.5. Nun lassen wir SSH nur an 1.2.3.4 lauschen. Kleines Beispiel:
ListenAddress 127.0.0.1
ListenAddress 1.2.3.4
Fail2Ban
Wenn du einen vServer besitzt, siehe „vServer Hoster wie Netcup“ etwas weiter unten.
Da wir Sicherheit lieben, sperren wir Benutzer, die öfters ein falsches Passwort eingegeben haben. Diese Sperre ist eine Stunde lang aktiv. Hierbei müssen wir fail2ban installieren:
apt-get install fail2ban
Nun geht es an die Konfiguration. Da man sich selbst am besten vertraut, fügen wir 127.0.0.1 in die Ausnahmeliste hinzu. Folgendes kann in der Konfiguration (/etc/fail2ban/jail.conf) abgeändert werden.
ignoreip = 127.0.0.1
bantime = 3600 # 60 x 60 Sekunden => 60 Minuten
maxretry = 4 # Anzahl der Versuche bis zur Sperre
Dies ist die globale Einstellung von Fail2Ban. Man kann natürlich auch eine für SSH spezifische Konfiguration erstellen. Dazu muss folgendes hinzugefügt werden:
[ssh]
enabled = true
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
port = 17655 # Falls der Port nicht verändert wurde, lass diese Zeile einfach weg
Um die Einstellungen zu übernehmen, muss Fail2Ban neu gestartet werden. /etc/init.d/fail2ban restart
vServer Hoster wie Netcup
Hoster wie netcup unterstützen keine Änderung der iptables. Hierfür gibt es dieses Script: Fail2Ban Script für die VCP API netcup.de Kundenforum.
Apache2 & php5
Auch Apache sowie php muss gesichert werden. Der Großteil aller Hacks gelingt über schlecht programmierte bzw. ungesicherte php Skripte. Da man nicht immer alle Skripte überwachen und durchsuchen kann, empfiehlt es sich, eine Ebene höher zu gehen. Das Absichern von Apache2 und php5.
Wer bin ich?
Es ist stets gut zu verbergen, welche Version von welcher Software genutzt wird. Ist man mal nachlässig mit den Aktualisierungen bemerkt es der Angreifer eventuell nicht, dass man noch eine alte, anfällige Software verwendet.
Hierzu muss in der /etc/apache2/apache2.conf
folgende Werte geändert/hinzugefügt werden.
ServerTokens ProductOnly
ServerSignature Off
Dies verändert den Server Parameter in der Header Ausgabe. Statt Apache/2.2.9 (Debian) mod_jk/1.2.26 PHP/5.2.6-1+lenny16 with Suhosin-Patch mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0
erhalten wir nun Apache
. PS.: Dies spart übrigens 155 Bytes pro Dateiaufruf, da nur ein verkürzter Header übergeben wird.
Wer bin ich? #2
PHP versendet ebenfalls einen eigenen Header, den sogenannten X-Powered-By Header. Um dies zu ändern, muss die Globale php.ini unter /etc/php5/apache2/php.ini
editiert werden. Auch das Unterdrücken von Fehlermeldungen ist hierbei mehr als wichtig. Es gibt fast nichts Schlimmeres als eine MySQL Fehlermeldung, wenn der Benutzer z.B. '
eingegeben hat. Hierzu muss folgendes verändert werden (Texte mit # am Anfang sind Kommentare. Diese müssen nicht mit übernommen werden):
expose_php = Off
#Entfernt den php Versions-header sowie die php Easter-Eggs.
register_globals = off
#Wenn eingeschalten, wird $_GET[‚username‘] zu $username Massive Sicherheitslücke!
display_errors = Off
#Fehlermeldungen werden nicht dem Benutzer mitgeteilt. Kann Pfäde, Datenbanken etc. verraten.
error_reporting = E_ALL & ~E_DEPRECATED
#Wenn display_errors eingeschalten ist, werden alle Fehlermeldungen angezeigt. Verbesserungen und Hinweise auf veraltete Funktionen jedoch ausgeblendet.
Zugriff einschränken
Erlangt ein Eindringling Zugriff auf die Webserverumgebung, wird dieser versuchen, root Rechte zu erlangen. Dazu wird gerne der Zugriff auf /etc/passwd
verwendet. Dies dürfen wir natürlich nicht zulassen.
Apache2 ohne Virtuelle Hosts
Die Einstellungen müssen in der php.ini vorgenommen werden(/etc/php5/apache2/php.ini
).
Hierzu verändern wir den include_path sowie open_basedir.
include_path = ".:/usr/share/php:/usr/share/pear:/var/www/" # Dies limitiert den Zugriff auf die php und pear Ressourcen, sowie alle Dateien, die sich in /var/www/ befinden. Dieser Parameter hat Einfluss auf die include sowie require Funktion in php.
open_basedir = „/usr/lib/php/:/var/www/“ # Beschränkt Dateizugriffe von Funktionen wie fsockopen oder file_get_contents. Diese Zugriffe sind dann nur innerhalb der Struktur /var/www/ möglich.
Apache2 mit Virtuelle Hosts
Hierbei sollten wir die globale php.ini nicht ändern. Da sonst eine Domain auf eine andere Zugriff hat. Wenn wir eine Apache Konfigurationsdatei (Virtuelle Host Datei) anlegen, müssen wir nur ein paar php_admin_value
Befehle mit einfügen.
# ...
php_admin_value open_basedir "/usr/lib/php/:/var/www/example.com/"
php_admin_value include_path ".:/usr/share/php:/usr/share/pear:/var/www/example.com/"
# …
Hierbei bitte example.com etc. dem entsprechendem Pfad anpassen.
MySQL
Hierbei wäre es gut, die Funktion bind-address
zu verwenden. Damit lässt sich MySQL nur noch unter der angegebenen Adresse ansprechen. Diese Funktion empfiehlt sich, wenn man MySQL nur lokal verwendet.
Die Datei, die geändert werden muss befindet sich im Verzeichnis /etc/mysql/
und nennt sich my.cnf
Darin sollte folgender Befehl enthalten sein:
bind-address 127.0.0.1
Ist keine Raute (#) am Angang der Zeile, ist der MySQL Server nur intern verfügbar.
Möchte man MySQL allerdings öffentlich verwenden, damit andere Server Zugriff auf den Server haben, muss die oben stehende Zeile mittels Raute auskommentiert werden.
#bind-address 127.0.0.1
Aber Achtung! Ohne weitere Sicherheitsvorkehrungen ist es gefährlich, den MySQL Dienst so weiter offen stehen zu lassen. Daher empfiehlt es sich, dem Benutzer Root keinen Remote Zugriff zu gestatten. Ebenfalls sollte man Remote Benutzern so wenig Rechte wie es nur möglich ist vergeben. Ebenfalls sollte auch nicht der MySQL Benutzername der Seite entsprechen. (z.B. unterhaltungsbox, unterhaltungsbox.com oder webseite etc.)
Ich hoffe, dieser Artikel konnte euch helfen, den Server gegen Eindringlinge etc. abzusichern. Bei Fragen zögert nicht, diese per Kommentar zu stellen.
Wie immer der rechtliche Teil des Artikels: Ich hafte für keinerlei Beschädigungen am System oder Gerät, die im Zuge der Verwendung dieser Erklärung auftreten können.
Wieder was gelernt.
Sehr gut erklärt! Danke!
Super erklärt, von Dir konnte ich viel lernen.
Dankeeeeeeeee!!!!
Gut erklärt! Danke!
Ich würde an eurer Stelle den Login mit Passwort zu verbieten und dafür einen SSH Key zu verwenden. Das ist noch mal sicherer. Denkt daran: jede noch so kleine Sicherheitslücke ist eine Sicherheitslücke zuviel. Lieber ein paar Stunden mehr einen Server absichern als irgendwann unter Zeitstress einen gehackten Server zu bereinigen…