Pages

PHP gegen Attacken absichern

Grob geschätzt 80 Prozent aller erfolgreichen Angriffe von außen auf einen Server passieren über das PHP-Modul des Webservers. Lese hier, wie du PHP sicherer machen kannst.

PHP kann Dateien auf den Server schreiben, ausführbaren Code von Webadressen nachladen oder Linux-Systemkommandos mit den Rechten des Webservers ausführen. Meist sind diese Möglichkeiten nützlich und notwendig. Doch viel zu oft lässt sich, dank Fehlern, eine Funktion von außen missbrauchen, um Schädlingsprogramme auf dem Webserver zu installieren.

Deshalb sollte sich jeder Webserver-Administrator dringend mit den Konfigurationsmöglichkeiten von PHP4 beziehungsweise PHP5 vertraut machen, und nur so viele Funktionen zulassen, wie auf dem Server auch tatsächlich benötigt werden. Die dafür zuständige Datei heißt php.ini und liegt, je nach Version von Webserver und PHP, in einem der folgenden Verzeichnisse:

/etc/php4/apache/

/etc/php4/apache2/

/etc/php5/apache/

/etc/php5/apache2/


Nach jeder Änderung empfiehlt sich ein

apachectl restart

oder
apache2ctl restart


Erst mit dem Neustart werden die Änderungen wirksam. Das graceful-Kommando des Skripts apachectl reicht dazu nicht immer aus.

Gehe die folgenden Anweisungen Schritt für Schritt durch und setze den vorgeschlagenen Wert in deine php.ini. Setze den Wert auch, wenn er die Voreinstellung (default) ist. Denn die jeweils gültigen Voreinstellungen ändern sich des öfteren von PHP-Version zu PHP-Version. Angegeben sind die Defaults für PHP5, bei PHP4 sind sie sehr versionsabhängig.

Und das sind die Befehle:

register_globals = off ;(php5-default: off)

verhindert, dass beliebige Variable im PHP-Code durch GET- oder POST-Parameter überschrieben werden können. Beim Aufruf der URL http://server/page.php?login=true ist beispielsweise der Wert in der Variablen $_GET["login"] abgelegt. Mit

register_globals=on


wird zusätzlich alleine über den URL-Parameter die PHP-Variable $login gesetzt. Dieser Parameter sollte darum heutzutage unter keinen Umständen mehr auf on gesetzt werden.

memory_limit = 12M ;(default: 8M)

begrenzt den Speicher (in Megabyte), der bei jedem einzelnen Aufruf eines Skripts verbraucht werden darf. So wird beispielsweise verhindert, dass eine versehentlich programmierte Endlosschleife den kompletten verfügbaren Speicher belegt. Viele PHP-Anwendungen sind recht speicherhungrig, so dass der Wert eventuell höher gewählt werden muss. Das CMS Typo3 benötigt beispielsweise eine Grenze von mindestens 16MB.

max_execution_time = 60 ;(default: 30)

begrenzt die Zeit, die ein Script für die Ausführung bekommt. Auch das verhindert Probleme mit versehentlichen Endlosschleifen. Allerdings darf der Wert nicht zu niedrig sein - schließlich soll auch bei voller Serverlast etwa eine aufwendige Datenbankabfrage ohne Fehlermeldung bearbeitet werden.

max_input_time = 60 ;(default: 60)

begrenzt die Zeit, die ein Script mit dem Einlesen der übergebenen Parameter verbringen darf.

default_socket_timeout = 60 ;(default: 60)

begrenzt die Zeit, die PHP bei der Übertragung von Streams auf die Gegenseite wartet.

allow_url_fopen = off ;(default: on)

Defaultmäßig erlaubt es PHP, bei allen Befehlen, die Dateien öffnen, statt eines lokalen Dateinamen auch eine URL anzugeben. Das betrifft beispielsweise die Befehle require, include oder fopen. Setze diesen Wert nur auf on, wenn du diese Funktionalität unbedingt benötigst. Denn schon ein include($_GET["filename"]) stellt ein erstklassiges Sicherheitsrisiko dar. Hier sind allerdings auch die PHP-Programmierer gefragt. Denn solche Konstruktionen sind leichtsinnig.

open_basedir = /var/www/:/usr/share/pear/ ;(default:nicht gesetzt)

Dieser Parameter schränkt das Öffnen von Dateien weiter ein. PHP läßt nur noch den Zugriff auf solche Dateien zu, die in oder unterhalb der angegebenen Pfade gespeichert sind. Allerdings solltest du hier nicht zu restriktiv sein: Liegt ein PHP-Programmpaket, wie etwa phpMyAdmin, in einem Pfad außerhalb des üblichen www-Verzeichnisses, muss dieser Pfad mit aufgeführt werden, sonst wird das Programmpaket nicht mehr funktionieren.

session.save_path = /var/tmp/www ;(default: nicht gesetzt)

gibt das Verzeichnis an, in dem PHP seine Session-Informationen ablegt.

Aus Sicherheitsgründen sollte dafür nicht das Standard-Tempverzeichnis genutzt werden.

upload_tmp_dir = /var/tmp/www ;(default: nicht gesetzt)

gibt das Verzeichnis an, in dem PHP hochgeladene Dateien ablegt. Auch dafür sollte keinesfalls das Standard-Tempverzeichnis verwendet werden.

upload_max_filesitze = 2M ;(default: 2M)

begrenzt die Größe der Dateien in Megabyte, die via PHP-Funktionen hochgeladen werden können. Der ideale Wert hängt davon ab, für welche Anwendungen PHP eingesetzt wird. Du kannst auch einen größeren Wert, etwa 20M wählen, nur unbegrenzt sollte die Dateigröße nicht sein.

enable_dl = off ;(default: on)

Die Standardeinstellung aktiviert den PHP-Befehl dl(), der PHP-Extensions im Programmcode nachlädt. So verlierst du aber die Kontrolle, welche Extensions auf deinem Webserver verwendet werden. Stelle diesen Parameter also besser auf off und lade Extensions über die php.ini, etwa

extension=mysql.so


PHP-Parameter individuell einstellen

Aufwendiger wird die Einstellung, wenn nicht für den Webserver einheitliche Werte gelten sollen, etwa, weil der Server unter verschiedenen URLs verschiedene PHP-Anwendungen anbietet. Doch auch dann ist es möglich, sichere Einstellungen zu erreichen. Dazu setzt man zunächst in der php.ini alle global geltenden Werte. Alles Weitere passiert dann in den Config-Dateien des Apache-Werbservers. Dafür gibt es zwei Config-Befehle:

php_admin_flag

php_admin_value


Diese beiden Befehle können auch innerhalb eines



Blocks verwendet werden, so dass sie für einen virtuellen Server gelten.
Beispiel:



(...)

php_admin_flag allow_url_fopen off

php_admin_value memory_limit 10M

php_admin_value open_basedir /home/ vserver1/:/usr/share/ pear/



Beachte die Schreibweise ohne =-Zeichen.

Wenn auf Apache mehrere virtuelle Server laufen, solltest du open_basedir, session.save_path und upload_tmp_dir für jeden Host getrennt setzen.

Achtung, Fußangel

Nicht alle Beschränkungen, die du in der php.ini setzt, können in der Apache-Config wieder aufgehoben werden. Ist in der php.ini etwa allow_url_fopen auf off gesetzt, bleibt es auf off, was auch immer du in Apache einstellst.

Verwende in diesem Fall folgenden Trick:

allow_url_fopen = on

in der php.ini.

php_admin_flag allow_url_fopen off

in der globalen Apache-Konfiguration. Und dann wiederum

php_admin_flag allow_url_fopen = on


innerhalb des Virtualhosts, der diese Funktion benötigt. Um zu überprüfen, welche Einstellungen innerhalb eines Hosts tatsächlich gelten, verwende ein kurzes Skript mit dem Befehl phpinfo().

Noch mehr Sicherheit für PHP

Darüber hinaus gibt es weitere Parameter, um PHP noch stärker abzusichern, etwa

safe_mode =

disable_functions =


Setzt man allerdings diese Parameter auf sichere Werte, schränkt man die Funktionalität von PHP so stark ein, dass viele Anwendungen nicht mehr oder nur noch eingeschränkt funktionieren. Wer diese Parameter ändert, sollte deshalb danach seine Anwendungen ausführlich testen.

IP-Adressen vom Zugriff sperren

Beim Betrachten deiner Log-Dateien ist dir aufgefallen, dass von einer bestimmten IP-Adresse, besonders viele Seiten abgerufen werden? Dann sperren wir die IP einfach. Falls du ein Apache benutzt und rooot oder der Administrator dir die passenden Rechte eingeräumt hat, geht das am einfachsten über die Datei .htaccess.

Schreib dort zunächst die Zeile
order allow,deny

hinein. Das bedeutet: Zunächst einmal ist der Zugriff auf deine Seite allen erlaubt. IP-Adressen, die nicht zugreifen dürfen, müssen explizit ausgeschlossen werden.

Trage danach die IP-Adressen ein, die du ausschließen willst,

Beispiel:

deny 123.255.1.2

deny 251.10.28.148

und so weiter.


Achte aber darauf, das du nicht versehentlich Suchmaschinen auszusperrest.

SSH - Daemon gegen Attacken sichern

Immer wieder sehr beliebt bei pubertären Script-Kiddies scheinen Attacken auf den Secure-Shell-Daemon sshd zu sein. Dabei werden innerhalb von Sekunden hunderte von Login-Versuchen mit Standard-Usernamen wie root, ftp, admin etc. und Passworten aus dem Wörterbuch ausprobiert - frei nach dem Motto: Irgendwo wird's schon klappen.

Solche Attacken sind nicht nur lästig, sie kosten durch die schiere Menge der Anfragen auch Netzwerk-Bandbreite und Rechenkapazitäten. Mit einfachen Mitteln kann man die eigene Secure Shell gegen solchen und ähnlichen Unfug sichern. Alle Einstellungen gehören in das sshd-Configfile, das normalerweise sshd_config heißt und im Verzeichnis /etc/ssh liegt.

Wir müssen bevor wir loslegen ein neuen User anlegen, bevor wir es losgeht.

adduser zwerg


Wir öffnen die Config Datei und bearbeiten sie.

nano /etc/sshd_config


1. Das ursprüngliche SSH-Protokoll Version 1 ist veraltet und hat einige bekannte Sicherheitsmängel. Deswegen sollte Ihr Server nur Protokoll-Version 2 zulassen. Die Zeile

Protocol 2


sorgt dafür.

2. Lange nicht alle Benutzer eines Servers müssen sich per SSH anmelden können. Der Parameter AllowUsers definiert, welche Nutzer erlaubt sind. Alle nicht genannten bleiben ausgesperrt. Beispiel:

AllowUsers root zwerg crew


Ob man den root-Login per SSH überhaupt zulässt, ist Glaubensfrage. Meiner Meinung nach spricht nichts dagegen, solange man ein solides Passwort für root definiert hat.

3. Kein Benutzer braucht ewig, um sich einzuloggen, also Benutzername und Passwort einzugeben. Jeder gestartete sshd-Task braucht aber Speicher und Rechenzeit. Also gibt man mit

LoginGraceTime 60


eine Minute Timeout vor. Hat sich 60 Sekunden nach Verbindungsstart noch niemand korrekt eingeloggt, wird der Task beendet.

Vorsicht: Natürlich ist hier auch ein noch kürzerer Wert möglich. Aber berücksichtigen Sie immer, daß Ihr Server auch einmal überlastet sein kann und die Kommunikation mit dem sshd deshalb verzögert wird. Da kann es äußerst lästig werden, wenn der Timeout zu schnell zuschlägt.

4. Um zu verhindern, daß durch einen Hackversuch hunderte sshd-Tasks gleichzeitig gestartet werden, gibt es einen sehr nützlichen Parameter. Fügen Sie dazu die Zeile

MaxStartups 3:30:10


in das Configfile ein.

Diese Beschränkung ist äußerst effektiv, aber etwas kompliziert zu verstehen: Die Werte im Beispiel bedeuten, daß 2 (= 1. Wert minus 1) "unauthenticated" (also im Login-Stadium befindliche) sshd-Verbindungen immer erlaubt sind. Ab der 3. (= 1. Wert) Verbindung wird mit einer Wahrscheinlichkeit von 30% (2. Wert) die Verbindung abgelehnt. Diese Wahrscheinlichkeit steigt linear an, bis bei 10 (3. Wert) offenen Verbindungen jeder weitere Verbindungsversuch zu 100% abgelehnt wird.

Achtung: Bereits eingeloggte Nutzer zählen nicht zu diesen Werten! Die angegebenen Beispielwerte sollten also für jeden kleineren bis mittleren Server ausreichend sein. Haben Sie sehr viele SSH-Nutzer, können höhere Werte angebracht sein, etwa

MaxStartups 10:30:50


Jenseits dieser Config-Parameter ist das A und O der Server-Sicherheit natürlich ein sicheres Passwort.

Linux - Befehle - Basic - 8 - Benutzerverwaltung

Benutzerverwaltung

id

gibt deinen Benutzernamen und die Gruppenmitgliedschaften aus

whoami

Wer bin ich? Ausgabe des Benutzernamens

who

Wer ist alles eingeloggt? Ausgabe der Benutzernamen, des Terminals und der Login-Zeit.

passwd

ändert das Passwort des aktuellen Benutzers

useradd -m [USERNAME]

legt den neuen Benutzer [USERNAME] an und erzeugt ein Homeverzeichnis

passwd [USERNAME]

ändert das Passwort des Benutzers [USERNAME] (nur als root)

userdel -r [USERNAME]

löscht den Benutzer [USERNAME] und sein Homeverzeichnis

groupadd [GRUPPE]

erzeugt eine neue Gruppe [GRUPPE]

groupdel [GRUPPE]

löscht die Gruppe [GRUPPE]

Linux - Befehle - Basic - 7 - Systeminformationen

Systeminformationen

mount

Ausgabe aller gemounteter Partitionen/Geräte

df

Ausgabe der Nutzung der gemounteten Geräte

date

Anzeige von Datum und Uhrzeit

free

gibt die Nutzung des Arbeitsspeichers aus

uptime

zeigt die Prozessorauslastung und -laufzeit an

top

zeigt die höchsten Ressourcenverbraucher an

ps ax

zeigt Informationen über laufende Prozesse an

kill [PID]

beendet den Prozess mit der Prozess-ID [PID]

killall [PROZESSNAME]

beendet alle Prozesse mit dem Namen [PROZESSNAME] (z. B. mozilla)

uname -a

gibt Kernel-Informationen aus

arch

zeigt die Prozessorfamilie an

Linux - Befehle - Basic - 6 - Zugriffsrechte

Zugriffsrechte

chmod [OPTIONEN] [DATEI]

ändert die Zugriffsrechte der Datei [DATEI]

chgrp [GRUPPE] [DATEI]

ändert die Gruppe der Datei [DATEI] in [GRUPPE]

chown [OWNER] [DATEI]

ändert den Eigentümer der Datei [DATEI] in [OWNER]

Linux - Befehle - Basic - 9 - Geräte partitionieren, formatieren, überprüfen, mounten

Geräte partitionieren, formatieren, überprüfen, mounten

fdisk [DEVICE]

Partitionierung der Festplatte [DEVICE]

mke2fs [DEVICE]

Anlegen eines ext2-Dateisystems auf dem Gerät [DEVICE]

mkfs.ext3

Anlegen eines ext3-Dateisystems auf dem Gerät

mkfs.ext4

Anlegen eines ext4-Dateisystems auf dem Gerät

fsck [DEVICE]

Gerät [DEVICE] auf Fehler überprüfen

mount /mnt/cdrom

bindet eine eingelegte CD-ROM in das Dateisystem ein

umount /mnt/cdrom

entfernt eine CD-ROM aus dem Dateisystem

Linux - Befehle - Basic - 5 - Dateien

Dateien

cat [DATEI]

zeigt den Inhalt der Datei [DATEI] auf dem Bildschirm an

more [DATEI]

zeigt den Inhalt der Datei [DATEI] seitenweise an

less [DATEI]

wie more, man kann aber auch nach oben blättern

cp [DATEI1] [DATEI2]

kopiert Datei [DATEI1] in Datei [DATEI2]

mv [DATEI1] [DATEI2]

benennt Datei [DATEI1] in [DATEI2] um

mv [DATEI] [VERZ]

verschiebt Datei [DATEI] ins Verzeichnis [VERZ]

rm [DATEI]

löscht die Datei [DATEI]


touch [DATEI]

erzeugt die leere Datei [DATEI]

Linux - Befehle - Basic - 4 - Navigation im Dateisystem

Navigation im Dateisystem

pwd

gibt das aktuelle Verzeichnis aus

cd /

wechselt ins Hauptverzeichnis

cd ..

wechselt in das übergeordnete Verzeichnis

cd [VERZ]

wechselt ins Verzeichnis [VERZ]

cd -

wechselt in das vorherige Verzeichnis

cd

wechselt ins Home-Verzeichnis des Benutzers

Linux - Befehle - Basic - 3 - Programme Starten

Programme starten

[PROG]

Programm [PROG], welches sich im Pfad befindet, starten

./[PROG]

Programm [PROG], welches sich im aktuellen Verzeichnis befindet, starten

[PFAD]/[PROG]

Programm [PROG], welches sich im Verzeichnis [PFAD] befindet, starten

Linux - Befehle - Basic - 2 - Suchen

Suchen

whereis [PROGRAMM]

sucht in den Verzeichnissen der Umgebungsvariablen PATH nach [PROGRAMM]

find . | grep [DATEI]

sucht ausgehend vom aktuellen Verzeichnis nach [DATEI]

grep [SUCHSTRING] [DATEI]

durchsucht DATEI nach dem Suchbegriff [SUCHSTRING]

locate [DATEI]

durchsucht die Locate-Datenbank nach [DATEI]

Linux - Befehle - 1 - Basic

Anfänger - Linux - Befehle - Basic 1

Basics

startx

startet das X-Window-System und eine grafische Benutzeroberfläche

logout

ordnungsgemäßes Abmelden von der Konsole

[BEFEHL] --help

gibt einen kurzen Hilfetext zum [BEFEHL] aus

man [BEFEHL]

zeigt die Manual-Page zum [BEFEHL] an

info [BEFEHL]

zeigt Dokument zu [BEFEHL] im Info-System an

shutdown -r now

Rechner neustarten

shutdown -h now

Rechner herunterfahren

Pakete nach der Installation - Deinstallation aufräumen

Damit die Anwendung sauber entfernt / deinstalliert wird.

Weitere Befehle von APT

sudo apt-get install paketname

damit wird ein Paket mit all seinen Abhängigkeiten installiert

sudo apt-get upgrade

bringt alle Pakete auf den neuesten Stand, installiert jedoch keine
neuen Pakete (was evtl. nötig ist um das System aktuell zu halten,
falls sich Abhängigkeiten geändert haben)


sudo apt-get dist-upgrade

bringt alle Pakete auf den neuesten Stand

sudo apt-get update

holt die neuesten Informationen über Pakete vom Ubuntu-Server

sudo apt-cache search suchwort

liefert eine Liste der verfügbaren (installiert oder nicht) Pakete,
in deren Namen oder Beschreibung "suchwort" vorkommt


sudo apt-cache show paketname

liefert eine Paketbeschreibung

sudo apt-cache showpkg paketname

zeigt Abhängigkeiten zum Paket an


sudo apt-cache stats

liefert eine Liste der installierten und verfügbaren Pakete