Serversicherheit LAMP, Tuning, BadBots
In diesem kleinen Artikel werde ich auf die Auswahl eines Servers, das Einrichten des Servers sowie der später verwendeten Applikation eingehen,
sehr viel über die Absicherung schreiben, das Tuning behandeln, darauf eingehen, wie bad Bots behandelt werden können (und sollten) und zum Schluß rechtliche Hinweise für den Betrieb einer eigenen Webseite geben.
Ich möchte auf die Schnelle Erfahrungen von mehreren Jahren Serverbetrieb weitergeben.
Ich versuche, diesen Artikel möglichst universell zu halten. Die genauen Konfigurationen sind von System zu System unterschiedlich, abhangig von den Anforderungen und der eingesetzten Software. Oftmals sind die Übergänge fließend.
Hinweis: Ein eigener Server im Internet ist kein Spielzeug! Sicherheit steht an erster Stelle, zu schnell ist es passiert, daß ein Server einem Botnetzwerk angeschlossen wird.
Man muß sich darüber im Klaren sein, daß man jeden Tag mindestens eine Stunde mit dem Lesen von Logfiles, dem Ausführen von Updates und kleineren Optimierungsarbeiten aufwenden muß.
Niemand sonstiges sollte jemals Zugangsdaten erhalten. Wenn ein Problem besteht, sollte es nicht der eine oder andere Experte machen, auch wenn man ihnen sehr vertraut. Ein gewollter, ungewollter oder versehentlicher Mißbrauch dieser Daten kann fatale Folgen haben. Es ist nicht schlimm, den Server kurz vom Netz zu trennen.
Fremde Inhalte sollten nur nach strenster Kontrolle, möglicht auf einem lokalen Rechner, auf den Server gebracht werden.
Die Verantwortung trägt derjenige, der den Server gekauft oder gemietet hat, kein anderer. Und Unwissenheit schützt nicht vor Strafe.
Ist schon die Idee für einen Webauftritt vorhanden und soll möglichst schnell umgesetzt werden: Es gibt fertige CMS, für jeden Einsatzzweck flexibel konfigurier- und erweiterbar. Aber, sofern diese Systeme massenhaft "verteilt" werden, sind Sicherheitslücken bekannt und werden auch ausgenutzt. Oftmals werden bekannte Sicherheitslücken als unwichtig eingestuft, die Problembehebung hinausgeschoben.
Bei http://www.cvedetails.com/ kann man sich schon informieren.
Die Entwicklung eines eigenen CMS benötigt sehr viel Zeit, dies steht dem schnellen Auftritt gegenüber.
Serverauswahl:
Ein Root-Server ist natürlich das Beste, was man nehmen kann. Man ist Herr seines Systems, man ist allein auf diesem System. Aber solche Server kosten entsprechend. Auch die Ersatzteilbeschaffung bei einem Defekt ist oftmals nicht kostenfrei. Man kann einen Server auch lokal in sein eigenes Heimnetzwerk stellen. Sofern dieser auch unter einer festen Adresse von außen erreichbar sein soll, ist ein DynDNS-Eintrag nötig (ist schon seit einigen Jahren nicht mehr kostenlos) und der Server sollte 24/7 angestellt bleiben und verursacht nicht zu unterschätzende Stromkosten. Auch sollte man weitere Sicherheitsmaßnahmen ergreifen, da nun von außen in das eigene lokale Netzwerk geroutet wird.
V-Root sind günstiger. Es gibt zwei Varianten. Der "echte" v-root bekommt "fest verdrahtete" Hardware zugewiesen, ähnlich richtiger Hardware. Auch ist man vollständig Herr über das System, meist wird nur eine Liste von verfügbaren Betriebssystemen vorgegeben. Der "unechte" v-root besitzt garantierte Hardwareeigenschaften, die auf ein Maximum kurzzeitig erweitert werden können, es wird oft eine Anzahl von Datenbanken und/oder Scriptsprachen vorgegeben. Das ist nichts weiter als ein vHost, ein Ordner auf einem bestehenden Webserver. Alle daraufliegenden Hosts teilen sich die Rechenleistung des Masters, wie beim "echten" v-root, jedoch sind diese untereinander abhängig. Zieht ein Host 100% Leistung, liegen alle anderen Host brach. Beim "echten" v-root sind Hardwaregrenzen für jeden Host gesetzt, so daß diese sich untereinander beeinflussen können.
Ein managed-Server wäre eine Alternative für Leute, die sich nicht mit Sicherheit und Updates beschäftigen wollen oder können. Das übernimmt dann der Provider. Aber: Haftbar ist der Webseitenbetreiber, der Provider ist fast immer fein raus, auch wenn er etwas verschlampt hat. Weiterhin kann es Probleme geben, wenn man spezielle Software einsetzt. Bei Unstimmigkeiten schiebt der Provider zuerst immer die Schuld auf die Software, auch wenn es am Server liegt.
Webspace ist billig, man kann kaum etwas selbst einstellen, ist ein Host nebenan infiziert, sind alle infiziert.
Zusammenfassung:
-Sicherheit steht an erster Stelle!
-CMS und weitere Software sorgfältig aussuchen!
Rootserver:
Vorteile: Leistung
muß nicht geteilt werden
man ist der Herr im Haus
als lokaler Rechner schnell vom Netzwerk trennbar
Nachteil: sehr teuer
"echter" v-root:
Vorteile: wird nicht geteilt
man ist der Herr im Haus
oftmals recht billig
Nachteil: etwas weniger Leistung als root
einige Sachen vorgegeben (z.B. Betriebssystem)
"falscher" v-root:
Nachteil: fast alles wird vorgegeben
wird geteilt
Leistung abhängig von den anderen Hosts
teilweise teurer als "echter" v-root
managed Server:
Vorteil: man muß sich nicht mehr so oft um die Sicherheit kümmern
oftmals gute Leistung
Nachteil: manchmal zickiger Support
oftmals teurer als v-root
Webspace:
Vorteil: billig, teilweise kostenlos
man braucht (und kann) sich nicht mehr um die Sicherheit auf Serverebene kümmern
Nachteil: Leistung abhängig von anderen Hosts
Infektionsrisiko durch Serverebene
oftmals alles, auch das CMS, vorgegeben
Server und Software installieren, Sicherheitsmaßnahmen
Ich selbst verwende eine Suse auf einem "echten" v-root, benutze bequemerweise zypper und dränge zur weiteren Bequemlichkeit in Richtung webmin.
Sobald das Betriebssystem aufgespielt wurde, benötigt root sofort (möglichst schnell) ein neues Paßwort.
Der Server ist sofort aus dem Internet erreichbar und ohne jegliche Schutzmaßnahmen. Sofort hängen verschiedene Bots an Port 22 (SSH) und versuchen, einen Zugang zum Server zu erhalten. Egal, welches Betriebssystem verwendet wird: Ein Nutzer ist immer bekannt. Unter Microsoft Windows ist es der Administrator, unter Unix der root. Man kann also 24/7 einen Bruteforce auf das Paßwort starten, soweit, wie es die Netzwerkanbindung hergibt. Im Zweifelsfall sollte das System neu aufgesetzt werden.
root bekommt also ein neues Paßwort. Man sollte sich einen Satz ausdenken, der ein wichtiges Ereignis in seinem Leben beschreibt, incl. Datum und Uhrzeit. Zum Paßwort werden dann die Anfangsbuchstaben der Wörter, die Zahlen und Sonderzeichen.
Unter https://review.datenschutz.ch/passwortcheck/check.php kann man ein ähnliches Paßwort auf Sicherheit testen.
root legt gleich einen anderen Nutzer mit einem ähnlich langem Paßwort an. Unter Webmin geht das recht bequem unter "System -> Users and Groups", unter "Webmin -> Webmin Users -> Convert Unix to Webmin Users" ist dieser Nutzer auch unter Webmin nutzbar.
Nun können root und andere (well known) Nutzer deaktiviert werden (System -> Users and Groups -> Nutzer auswählen), d.h. er wird auf "no login allowed" gesetzt, wird temporär deaktiviert oder bekommt die Shell /bin/false bzw. /sbin/nologin.
Bei jedem neu installierten Programm wird eventuell ein neuer Nutzer angelegt, daher hier immer überprüfen!
Noch immer hängen verschiedene Bots auf Port 22. Oftmals ist zu lesen, man könne den Port ein oder zwei Nummern "Umlegen". Das wissen auch mittlerweile die Betreiber der Bots.
Auf http://de.wikipedia.org/wiki/Liste_d...2.80.931023.29 kann man sich einen Port aussuchen, der nicht vom eigenen System genutzt wird und möglichst nicht auf das Betriebssystem verweist (Port zur Analyse vom Blätterrauschen des Jupiter der NASA wird wohl eher nicht das Ziel von Angriffen sein). Einen Portscan hält das nicht auf, es wird immer das passende Serverbanner mitgegeben, man hält sich dafür die "dummen" Bots, die nur wenige Ports kennen, vom Hals.
In /etc/ssh/sshd_config und /etc/ssh/ssh_config wird der neue Port eingetragen. SSH neu starten (webmin "Bootup und Shutdown -> SSH -> Restart").
Mittels zypper (Konsole, wie z.B. putty) als root können nun die Paketquellen installiert werden. Zypper ist ein Installationsmanager, der Paketabhängigkeiten von selbst auflöst und notfalls zusätzliche Software mitinstalliert.
Die URL des Depots ist einfach so einzutragen, den Aliasnamen kann man sich aussuchen, wie man möchte.
Folgende Depots sind wichtig (bitte selbst die Depots suchen!):
Diese Adressen stehen nur als Beispiel, man kann recht schnell die Repositories für das eigene System finden.
dient dazu, den Inhalt der Repositories neu einzulesen, wenn es Updates gibt,
startet die Updates. Bei einem neuen System kommen hier einige Updates zusammen.
zypper ref und zypper up sollte man in Zukunft mindestens einmal wöchentlich ausführen, jedoch spätestens dann, wenn für installierte Software wichtige Sicherheitsupdates verkündet werden.
sucht nach Software mit dem Namen Name. Dort kommen einige Einträge je nach Software zusammen. In der Regel reicht
zum installieren der Software aus. Möchte man eine spezielle Version der Software installieren, sollte man direkt diesen (oftmals langen) Namen angeben.
Somit wird fail2ban installiert. Fail2ban ist eine kleine Software, die Logfiles pro Sekunde analysiert und unangenehme Einträge an die Firewall weiterreicht.
Man kann selbst einstellen, welches Logfile in welchem Zeitraum analysiert werden soll, wie viele fehlerhafte Einträge (Login-Versuche, Hack-Versuche usw.) in diesem Zeitrahmen möglich sein dürfen und wie lange die entsprechende IP gesperrt werden soll.
Zypper wird möglicherweise iptables (eine mögliche Firewall) mitinstallieren, sowie einige zusätzliche Bibliotheken.
Fail2ban kann leider oftmals nicht schnell genug reagieren oder bereits mehrere geöffnete und gehaltene Verbindungen trennen. Es ist alles in Ordnung, dazu später mehr. Fail2ban schützt dennoch das System.
In /etc/fail2ban/jail.conf werden nun die SSH-Jails aktiviert (je nachdem, welche man möchte).
Ich selbst verwende u.a.
Standard ist eigentlich der Pfad des Log-Files für SSH /var/log/messages. Gegebenenfalls anpassen! Man kann
hinzufügen, wenn man von den Standardeinstellungen abweichen möchte. Das Beispiel bedeutet, daß von jetzt bis 60 Sekunden in die Vergangenheit geschaut wird, ob mehr als zwei Einträge vorhanden sind und somit sämtliche Paktete dieser IP für eine Woche als "drop" behandelt werden.
Wer Webmin verwendet, fügt (sofern nicht schon vorhanden, je nach Aktualisierung von fail2ban unterschiedlich) z.B.
hinzu. Wer mag, kann auch schon das jail [recidive] aktivieren, es sperrt Wiederholungstäter länger aus. Jail.conf speichern und schließen.
In /etc/fail2ban/filter.d liegen die ganzen Filterdateien mit den regulären Ausdrücken, mit denen die Jails funktionieren. Falls nicht vorhanden, müssen diese erstellt werden (644, root,root). Diese Dateien werden in der jail.conf in filter= genannt.
Syntax ist immer [Definition] failregex ignoreregex
Man kann die Regexen anpassen, notfalls "Proben" sammeln.
Fail2ban kann jetzt gestartet werden (start at boot-time).
Später wird noch ein Jail für den Apache eingerichtet.
Mit zypper kann nun mysql (es wird bei SuSe garantiert eine MariaDB), Apache (möglichst die neueste Version, aktuell 2.4, darauf achten, daß einige Einstellungen für 2.2 nicht mit 2.4 kompatibel sind!) und PHP (möglichst die letzte Version für längeren Support), ich verwende mod_php, installiert werden.
Unter /usr/share/mysql gibt es Hinweise zur my.cnf (diese ist in /etc) für verschiedene Systeme. Das ist Tuning, dazu später mehr.
Ich rate vom Einsatz von phpmyadmin ab. Nach dieser Software wird sehr oft gesucht, man muß diese also richtig gut verstecken. Die Statements kann man auch in die Konsole eingeben, notfalls vorher in einem Textdokument speichern. Das Datenbankdesign kann keine Software erledigen, dazu ist immer noch der Mensch da. Und was nicht installiert ist, verschwendet keinen Platz und kann nicht angegriffen werden.
Zum Konfigurieren von MySQL ist kein Netzwerkzugriff erforderlich, wer ohnehin keine Datenbankverbindung von außen zulassen möchte, kann folgende Einstellung in /etc/my.cnf beibehalten
Weiteres im Tuning.
MySQL kann jetzt gestartet werden. Mittels Konsole wird nun (mySQL nicht als root ausführen, man kann es erzwingen, aber trotzdem nicht machen, dazu hat man den Unix-Nutzer mit root-Rechten) dem mySQL-root ein recht gutes Passwort vergeben, ein zusätzlicher Nutzer mit eingeschränkten Rechten auf die neu zu erstellende Datenbank angelegt (wer ein fertiges CMS verwendet, hat jetzt sehr viel zu tun, wer selbst geschrieben hat, kennt seine DB-Struktur), er sollte kein DROP und möglichst wenig DELETE dürfen und sämtliche Nutzer mit % werden entfernt oder zumindest die Rechte entzogen. Diese %-Nutzer sind Verbindungen nach außen. Sollte bei einem Update das bind 127.0.0.1 verloren gehen, sind so zwar Verbindungen nach außen möglich, jedoch kein Login. Die benötigte Datenbank kann nun, eventuell nach Anpassen der my.cnf (z.B. File per table für InnoDB) eingefügt werden.
SuSe verteilt die Konfigurationsdateien vom Apache im ganzen System. Mittels Webmin kann man unter "Servers -> Apache Webserver -> Edit Config Files" einigermaßen einige Dateien einstellen, jedoch nicht alle.
Man bearbeitet die /etc/sysconfig/apache2. Wichtig sind hier:
APACHE_SERVERTOKENS="ProductOnly" oder noch weniger. Ein "Hallo, ich bin ein Apache-Server" reicht aus. Je mehr ein Server aussagt, umso eher hat der potenzielle Angreifer einen passenden Exploit parat.
APACHE_SERVERSIGNATURE="off"
APACHE_SERVERNAME="www.domain.tld"
Weiterhin werden die Module hinzugefügt und/oder entfernt. Man sollte sich fragen, welche Module man wirklich benötigt. Jeder Request durchläuft jedes Modul, damit das Modul feststellen kann, ob es zuständig ist, oder nicht. Das ist ein Geschwindigkeitsvorteil und verbraucht weniger RAM.
Sind die Module nicht in der Liste der standardmäßig installierten Module aufgeführt, so kann man die schnell mittels zypper nachinstallieren.
Als Beispiel:
Für ein kleines Forum ist dies ausreichend. Die auth-Module sind notwendig, verschiedene andere dienen dem Tuning und anderen Zwecken, dazu später mehr.
Wie man sieht, ist PHP als Modul eingebunden, mod_cgi wird nicht benötigt.
Sobald der Server läuft, beherrscht er PHP und muß nicht den Request an das CGI-Modul übergeben und auf Antwort warten. Zudem gibt es bösartige Requests, die versuchen, die php.ini im cgi-bin-Ordner zu überschreiben, zum Leidwesen aller Serverbetreiber auch oft erfolgreich.
Ich möchte hier keine Anleitung geben, es gab eine Welle von solchen (bereits decodiert, um Mißbrauch zu verhindern)
Wer seine Logfiles regelmäßig liest, wird diese codierten 5-Zeiler kennen.
Mod_php hat den Vorteil, daß www/wwwrun nicht auf die php.ini zugreifen kann, da diese in einem rootbereich liegt.
Die etc/php5/apache2 und cli/php.ini kann nun bearbeitet werden.
Wichtig sind vorerst:
exposephp off
safe_mode on
register_globals (sofern verfügbar) off
display_errors off (Fehler werden in /var/log/apache2/error_log gespeichert)
expose_php off (ok, man erkennt php schon in der URL, sofern man das nicht mit mod_rewrite umschreibt)
Datenverarbeitung einschränken (Ausführungszeiten, input_vars, nesting_level, Übergebene var-Mengen und -Größen beim Upload)
die php.ini in cli stärker beschränken
nicht benötigte Erweiterungen in etc/php5/conf.d auskommentieren
Es gibt noch weitere Kleinigkeiten, die ich hier vergessen habe, die lassen sich aber sehr schnell finden, spätestens beim Durchlesen aller Funktionalitäten in der php.ini.
disabled_functions ist ein wichtiges Thema. Man sollte danach im Netz suchen und sämtliche zusammengetragenen Funktionen bereinigen, auf Sinnfreiheit überprüfen (da gab es mal jemanden, der inject_code verboten hat) und nachschauen, ob diese vom eigenen CMS genutzt werden.
Ich werde hier nicht meine ganze php.ini zur Schau stellen. U.a. gehören jedoch
zu den verbotenen Funktionen.
Kleiner Tipp: mysql sollte man nicht mehr benutzen, stattdessen das neuere und schnellere mysqli. Wurde php mit sqlnd anstelle der Treiber von Oracle kompiliert, kann man noch zusätzliche Performance gewinnen.
Die http.conf vom Apache erhält noch
Schauen, was passt.
Die Webseite kann nun nach /srv/www/htdocs geschoben werden. Nach einem Start von Apache sollte nun alles mehr oder weniger funktionieren. Aber bitte Apache sofort wieder beenden. Kleiner Probleme können nun behoben werden, ich möchte darauf nicht eingehen.
Ab sofort, wenn der Server läuft, erhalten wir unschöne Requests von infizierten Servern und Botnetzwerken. Ich möchte es den Anfängern und em einen oder anderen Profi ersparen, selbst alles zusammenzusammeln. Hier eine Liste der häufigsten Angriffe, die mir untergekommen sind.
Dies sind Teile von reinen Requests. SQL-Injections, Exploits für bekannte CMS oder andere Software, Referrer-Spammer und HTTP-Methoden. Sollte man die eine oder andere Datei, den Pfad oder Methode nutzen, so sollte man diese entfernen. Diese Liste gilt für reines PHP. Jeder wird natürlich nah und nach eigene "Wörter" hinzufügen.
Damit erstellen wir ein neues Jail und .conf in fail2ban. Leider sind die Regexen von fail2ban nicht ganz PCRE-kompatibel (sorry, das waren andere Ausdrücke, ich komme jetzt gerade nicht drauf), es gibt keine Möglichkeit, Groß- und Kleinschreibung gleichzeitig zu behandeln (das war das i-Flag) und es gibt Gruppierungsprobleme. Es nimmt nichts von der Serverperformance weg, da fail2ban nebenbei läuft.
In /etc/fail2ban/filter.d wird eine neue Datei (nennen wir sie apache-dreck.conf) erstellt.
Der Googlebot-Handler ist dabei, da sich google recht gut zum Hacken eignet. Ich werde darauf später genauer eingehen.
Nein, das läßt sich leider nicht gruppieren und zusammenfassen. Bitte für das eigene System anpassen (WP-Nutzer sollten die wp-Ausdrücke entfernen, englischsprachige CMS benutzen die kleine index.php usw.)
Einen Ordner höher bekommt die jail.conf noch
Fail2ban neu starten.
Zusammenfassung:
Betriebssystem aufsetzen, updaten und absichern
fail2ban einrichten
mySQL, Apache, PHP installieren, konfigurieren und grundlegend absichern
eventuell weitere benötigte Module für Apache und PHP nachinstallieren
Weiterhin sollte man nun übergebene Variablen an die PHP-Scripte bereinigen.
ist ein Minimum. Man kann zusätzliche Bereichsprüfungen (bei Zahlenwerten) durchführen und eigene reguläre Ausdrücke verwenden.
Zuerst werden unnötige Leerzeichen vor und nach der Variable entfernt. Mit htmlentities und des passenden Flags kann man gewisse HTML-Tags von vorn herein escapen, womit z.B. Spambots keine Links mehr als HTML-Tag erstellen können. Ein Nicht-UTF8-Schriftsatz wäre interessant, wenn man nur lateinische Schriftzeichen handhaben möchte. Man ist für die Beiträge anderer auf der eigenen Seite haftbar, man möchte keinen Brief vom Staatsanwalt bekommen, weil jemand etwas böses eingetragen hat, was man nicht lesen kann. Danach sorgt mysqli für einen sauberen String. Ein Cast ist nur für nicht-Strings sinnvoll, da PHP Inhalte von Variablen erst als String ansieht. Es wird mit dem Cast versucht, eine Zahl aus dem String zu interpretieren. Wenn es nicht geht, dann eben gar nichts. So vermeidet man SQL-Injections.
Mit dieser neuenVar wird nun weitergearbeitet, da diese nun einigermaßen sauber ist.
@ für Variablen sollte vermieden werden. Es wird die Fehlermeldung unterdrückt, die diese Variable erzeugt. Leider aber auch Fehlermeldungen aller Konstrukte, die mit dieser Variable in Kontakt gekommen sind. Das ist bei kleinen Scripten, die man im Netz findet, sehr oft der Fall. Man erfährt nie, daß irgend etwas stattgefunden hat.
Als PHP-Wrapper eignet sich ZB Block von Zaphod B. von www.spambotsecurity.com.
Es wird vor jeglicher Aktivität in die PHP-Scripte eingehängt, die immer geladen werden (main.php, login.php, abhängig vom CMS).
Es überprüft den Request, den UA, den Referer und die Hostadresse mittels Signaturen, die ständig von einer weltweiten Community aktualisiert und verbessert werden. Der bösartige Host bekommt ein 403 und/oder 503, das jeweilige Script ein "die". Ein weiteres bösartiges Vorgehen wird effektiv verhindert.
Mittlerweile sind über 1700 Signaturen bekannt, die einem PHP-Script und/oder einer PHP-Webseite schaden können. Auch werden bekannte bad Hosts und Ranges von vornherein ausgesperrt. Es ist schneller und systemschonender als mod_security und erzeugt weniger false-positives. Weiterhin arbeitet es mit der Liste auf www.stopforumspam.com zusammen, als api oder lokales file. ZB Block sollte hier für den Sicherheitsgedanken erwähnt werden. Es ist mit sehr vielen CMS, die auf PHP basieren, kompatibel. Zusätzlich kann ein tarbaby eingerichtet werden, dazu später mehr.
Servertuning und Bad Bots
RAM ist durch nichts zu ersetzen, nur durch mehr RAM. Ebenso CPU. Das läßt sich oftmals nicht ändern.
Die Verarbeitung eines Requests und die Ausgabe an den Client können aber oft beschleunigt werden.
Caching ist eines der Zauberworte. Hier gibt es oft keine festen Regeln, es ist alles abhängig vom eigenen System und dem Einsatzzweck. Bitte die Werte nicht ungeprüft einfach so übernehmen!
Die Dateien in /usr/share/mysql für mySQL geben einige Hinweise für verschiedene Systeme. Möglichst viele Verbindungen zulassen, möglichst große Cache-Bereiche. Aber nicht übertreiben. Es wäre eine Verschwendung, einer Datenbank von 3 MB 3 GB Cache zuzuordnen.
Hier ein Auszug aus meiner cnf. MySQL werden so 2,5 GB zugewiesen (aber nicht benutzt, nur im Notfall). Ich verwende InnoDB.
Man sollte darauf achten, daß die Tabellen einen Index besitzen. Zudem sollten die Datentypen so klein wie möglich gehalten werden. Wenn nur 4 Zahlenwerte möglich sind, ist ein bool zu klein, ein Integer zu groß. Tinyint und smallint bieten sich hier an. Ob nun zwei oder 4 Byte je Datensatz für ein Feld verschwendet werden, macht sich erst bemerkbar, wenn tausende Datensätze vorhanden sind. Kleinere Tabellen belegen weniger Platz und können schneller abgearbeitet werden.
Dem Apache kann man auch sehr auf die Sprünge helfen. Erforderlich ist allerdings oftmals ein Zugriff auf die Serversteuerung, wohl dem, der einen (v)root-Server hat oder einen guten Kontakt zum Support bei einem managed Server.
Die Verwendung von htaccess-files lehnt die Apache-Foundation aus Performansgründen ab.
http://httpd.apache.org/docs/current.../htaccess.html
Für jeden Request (HTML, CSS, JS, Bilder...) muß der Server in dem entsprechenden Ordner nachschauen, ob eine .htaccess vorhanden ist und die Regeln anwenden. Danach muß er in den Unterordner schauen, usw. Das ist sehr zeitintensiv. Im <directory> sind die Regeln schon beim Start des Servers bekannt.
Die Inhalte der .htaccess werden in <directory> eingetragen und mit
<Directory />
Options None
AllowOverride None
Require all denied
</Directory>
.htaccess deaktiviert. Bitte beachten, daß das Serverdirectory (htdocs) angegeben ist. Die Syntax von Apache 2.4 hat sich geändert, wie man sieht.
hostnames_lookup off, keep_alive on, maxkeepaliverequests und -timeout vernünftig begrenzen, Anzahl und Fähigkeiten der Worker/Childs sinnvoll einstellen.
Was im RAM liegt, muß nicht von der langsamen Festplatte geholt werden. Dies gilt hier nur für statische Dateien, wie Bilder, CSS, JS. Hier ist der vollständige Pfad anzugeben.
Ein Haltbarkeitsdatum für die Ressourcen wird erstellt und nur ausgeliefert, wenn der Client sie noch nicht hat, ansonsten ein 304
Zusätzlich komprimieren wir die Daten, wenn es geht. Nicht alle Browser unterstützen dies. Höhere Kompressionsraten sind möglich, aber nicht sinnvoll, da mit jedem weiteren Level nur noch wenige Byte eingespart werden. Werte sind hardwareabhängig.
Generell gilt, was nicht oder weniger übertragen werden muß, ist auch schneller beim Kunden. Suchmaschinen belohnen diese Einstellung, der Client freut sich auch über ein schnelleres Internet.
In der php.ini steckt weiteres Optimierungspotential.
Ich möchte hier nicht auf die einzelnen Werte eigehen, jeder kann sich diese selbst aus der php.ini herauslesen.
Man sollte recht viele Verpindungen, auch persistente, zulassen und die Timeouts relativ hoch halten. Ein Requests kann somit eine bestehende Verbindung nutzen, es muß keine neue aufgebaut werden.
mysqli kann den Cache von mysqlnd nutzen, welches wiederrum (als Treiber) auf den Querycache von mySQL zugreift.
PHP5.5 besitzt schon den eigebauten Zend Opcache und Optimizer. Möglichst alle Scripte sollten in den Cache passen, von der Anzahl und der Größe her. Die Bitmask vom Optimizer sollte man aktivieren und das System testen, es kann vorkommen, daß der Optimizer nicht wie vorgesehen arbeitet.
Die prozedurale Programmierung ist näher am Echzeitverhalten als OOP, bei geringerem Speicherverbrauch.
OOP besteht aus Datenkapselung, Vererbung und Polymorphie.
Datenkapselung ist eine recht gut handhabbare Sache für denjenigen, der eine Instanz einer Klasse erstellt. Er muß nicht wissen, was wie funktioniert. Die Instanz wird nach den Regeln des Konstruktors erstellt und beherrscht alles. Ob nun ein echo "Hallo Welt"; oder berechne die Mondumlaufbahn anhand der Gravitationsverzerrungen am Jupiter; echo "Hallo Welt"; ausgegeben wird, macht schon einen Unterschied. Es funktioniert ja.
Da die erzeugte Instanz aufgrund der Vererbung alles das kann, was die übergeordneten Klassen können (unter C# ist das bis hoch zum obersten Object object), wird recht viel Speicher benötigt. Dies auch noch so lange, bis die Instanz zerstört wurde und vom Garbage-Collector eingesammelt wurde.
Garbage-Collector: Es ist schon ein Unterschied, ob er bei jedem Request, alle 100 oder alle 10000 losläuft.
Includes sollten vermieden werden. Der Parser muß an einem include seine Arbeit einstellen, alles in den RAM zurückschaufeln, das includefile suchen, abarbeiten und mit dem Ergebnis zum alten Script zurückkehren. Ohne include vervielfacht man seine Quelltexte, sie werden recht unleserlich (besonders bei prozeduraler Programmierung), dafür schneller abgearbeitet.
Wer mag, kann sich auch noch mit der Microoptimierung beschäftigen.
Da nun die oben erwähnten bad Requests auf den Server einprasseln und fail2ban die Hosts an iptables weiterleitet, könnte man doch dafür sorgen, daß diese Bots ein wenig festgehalten werden und dem ahnungslosen Administrator eine Meldung hinterlassen wird. Zusätzlich kann dem Bot auch noch Müll mitgegeben werden. Der Betreiber des Bots wird sich sicherlich sehr freuen, wenn sein doch so schneller Bot recht langsam geworden ist und sinnlose Daten zur Auswertung speichert oder sendet.
Im Moment erzeugen diese Requests ein 404 - not found.
Mit ZB Block hat man die Möglichkeit, ein tarbaby einzusetzen. Zudem wird alles gefahrlos mitgeloggt, so daß man gegebenenfalls weitere Maßnahmen ergreifen kann.
Grob übersetzt: Hier werden 1000 zufällige Zeichen erzeugt, nacheinander ausgegeben und bei jedem Zeichen eine kleine Pause eingelegt.
Damit dies auch funktioniert, wird mod_rewrite bemüht. Warnung: Sobald sich etwas in dem Statement befindet, was man selbst nutzen muß, bitte entfernen.
Dies ist auch eine Geschwindigkeitsoptimierung.
Viele Seiten nutzen die Syntax
RewriteCond dies [OR]
RewriteCond das [OR]
RewriteCond jenes [OR]
...
Obwohl es sich um ODER-Verknüpfungen handelt, muß der Parser, auch bei einem Match, jede Condition ablaufen.
In der Zusammenfassung wird nun überprüft: Befindet sich ein c im Request? Wenn nein, dann überspringe die komplette Gruppe. Es ist eine Zeitersparnis, die wirklich etwas bringt. Auch für andere Rewriterules.
Hier können wir also Gruppierungen und den NC-Flag nutzen, in dem Fall wird auch noch die klein geschriebene index.php als bad request angesehen.
Nun wird alles umgeleitet auf das tarbaby. Eine normale Umleitung erzeugt einen 301/302, was die Bots nicht interessiert. Sie möchten nur eine 200 oder einen 400er sehen. Mit [PT] wird intern umgeleitet, ohne daß sich die URL (im Browser, Bots verwenden nun keinen) ändert, sie werden direkt an das Tarbaby geschickt. [L] ist nicht zwingend notwendig, da [PT] diesen schon bedingt. Aber sicher ist sicher, weitere Rules werden nun nicht mehr ausgeführt. Mod_rewrite verarbeitet aber nun diesen neuen Request zum Tarbaby. Diesen müssen wir vorher abbrechen. Also wird vor diesem Block ein
gesetzt und eine weitere Abarbeitung von Regeln beendet.
In den Logfiles von ZB Block kann man genau sehen, was eigentlich gesendet wurde. Das ist sehr oft sehr bedenklich. Das harmloseste waren Veruche, die Startseite einer WP-Installation zu ändern. Oftmals wird man den Versuch sehen, ein "hochgeladenes" Bild (food, fish, lobex21, usw.) in eine .php umzubenennen. Dies erstellt eine Shell.
Leider müssen wir jetzt den Google-Bot Beachtung schenken. Er führt das aus, was er (es muß noch nicht einmal als Link deklariert sein) in die Finger bekommt. Es gibt die Geschichten mit google.translate und weiter Sachen, die ich hier nicht erklären möchte. Der Google-Bot führt dann ahnungslos den Angriff aus.
Wir kopieren den Block der bad Requests und fügen ihn zwischen die beiden eben erstellten Blöcke ein.
Bei einem solchen Request bekommt der Bot eine 404. Zusätzlich wird dem Bot verboten, die IP und den Servernamen abzulaufen. Ich habe festgestellt, daß Google der einzige gute Bot ist, der www.domain.tld, domain.tld, IP und Servername (also Name des Rechners im DNS-Eintrag) abläuft. Das wäre gutartiges Cloaking. Sollte jemand mit einem gefälschtem UA und einer solchen Anfrage dort hineinlaufen, bekommt dieser dann auch einen not found.
Damit sieht die Struktur wie folgt aus:
wenn tarbaby -> beenden
bad Google-request -> 404
bad requests -> tarbaby
Mit dieser Methode "vergifte" ich verschiedenen Keyword-Searchern die Datenbanken. Zusätzlich werden die auch noch von fail2ban behandelt.
Rechtliches
Hier muß man sich leider auch kümmern.
Urheberrecht
Urheberrecht dürfte klar sein. Nicht alles, was im Netz zu finden ist, kann man so nutzen. Man fragt den Urheber nach den Bedingungen oder erstellt selbst etwas. Frei Nutzbar sind nur Sachen, die auch so gekennzeichnet sind (dort gibt es eventuell auch Bedingungen), der Urheber ist seit 70 Jahren verstorben oder absolut nicht auffindbar.
Impressum
Jedes Telemedium, welches geschäftsmäßig etwas anbietet, unterliegt dem Telemediengesetz und der Anbieter muß sich darauf verewigen. Geschäftsmäßig bedeutet nicht, daß etwas verdient wird, sondern nur, daß etwas dauerhaft angeboten wird. Wenn der Server im Ausland steht, unterliegt er genauso dieser Pflicht, wenn er hauptsächlich an deutsche Kunden ausliefert. Der Grund liegt darin, daß der Verbraucher sofort einen Verantwortlichen hat, ohne sich durch Whois-Daten und Registrare wühlen zu müssen.
Ausgenommen sind reine Testseiten und private angebote, die paßwortgeschützt sind. Leicht zugänglich, also keine Klick-Marathons, leicht zu lesen, also keine Bilder. Sicher ist sicher, Abwahnungen sind teuer. Macht man das Erwerbsmäßig, wird es noch teurer.
Datenschutzerklärung
Das reicht nicht aus. Datenschutz bedeutet nicht, daß Kundendaten in einem Tresor untergebracht werden. Datenschutz ist der Schutz des Bürgers vor dem Mißbrauch seiner Daten. Die Daten liegen zwar im Tresor, jemand hat aber einen Schlüssel und gibt sie an Dritte weiter, und der Kunde wundert sich, daß er unnötige Werbung bekommt. Die Datenschutzerklärung vernünftig formulieren und an das eigene Angebot anpassen.
Jugendschutz
Bisher gibt es noch kein wirksames Mittel, Jugendliche und Kinder von jugendgefährdenden Medien fernzuhalten. Viele Methoden wurden als unzureichend eingestuft, andere sind unbezahlbar bzw. für den Kunden unzumutbar. Man sollte sich selbst fragen, ob man jugendgefährdende Inhalte anbietet.
Informationen dazu gibt es unter http://www.age-label.de/basis und http://www.online-management-kontor....fizierung.html
Im Streitfall ist eine vorhandene age_de.xml sehr günstig, wenn sie vernünftig ausgestellt wurde.
Dieser Artikel hilft "Neulingen" zu einer schnelleren und sicheren Einrichtung und Betrieb eines Servers und gibt den "Alten" hoffentlich noch einige weitere Ideen mit auf dem Weg. Gern kann eine Diskussion hier fortgesetzt und die Einträge ergänzt werden, für weitere Fragen stehe ich gern nicht mehr zur Verfügung.
Vielen Dank für die Aufmerksamkeit.
In diesem kleinen Artikel werde ich auf die Auswahl eines Servers, das Einrichten des Servers sowie der später verwendeten Applikation eingehen,
sehr viel über die Absicherung schreiben, das Tuning behandeln, darauf eingehen, wie bad Bots behandelt werden können (und sollten) und zum Schluß rechtliche Hinweise für den Betrieb einer eigenen Webseite geben.
Ich möchte auf die Schnelle Erfahrungen von mehreren Jahren Serverbetrieb weitergeben.
Ich versuche, diesen Artikel möglichst universell zu halten. Die genauen Konfigurationen sind von System zu System unterschiedlich, abhangig von den Anforderungen und der eingesetzten Software. Oftmals sind die Übergänge fließend.
Hinweis: Ein eigener Server im Internet ist kein Spielzeug! Sicherheit steht an erster Stelle, zu schnell ist es passiert, daß ein Server einem Botnetzwerk angeschlossen wird.
Man muß sich darüber im Klaren sein, daß man jeden Tag mindestens eine Stunde mit dem Lesen von Logfiles, dem Ausführen von Updates und kleineren Optimierungsarbeiten aufwenden muß.
Niemand sonstiges sollte jemals Zugangsdaten erhalten. Wenn ein Problem besteht, sollte es nicht der eine oder andere Experte machen, auch wenn man ihnen sehr vertraut. Ein gewollter, ungewollter oder versehentlicher Mißbrauch dieser Daten kann fatale Folgen haben. Es ist nicht schlimm, den Server kurz vom Netz zu trennen.
Fremde Inhalte sollten nur nach strenster Kontrolle, möglicht auf einem lokalen Rechner, auf den Server gebracht werden.
Die Verantwortung trägt derjenige, der den Server gekauft oder gemietet hat, kein anderer. Und Unwissenheit schützt nicht vor Strafe.
Ist schon die Idee für einen Webauftritt vorhanden und soll möglichst schnell umgesetzt werden: Es gibt fertige CMS, für jeden Einsatzzweck flexibel konfigurier- und erweiterbar. Aber, sofern diese Systeme massenhaft "verteilt" werden, sind Sicherheitslücken bekannt und werden auch ausgenutzt. Oftmals werden bekannte Sicherheitslücken als unwichtig eingestuft, die Problembehebung hinausgeschoben.
Bei http://www.cvedetails.com/ kann man sich schon informieren.
Die Entwicklung eines eigenen CMS benötigt sehr viel Zeit, dies steht dem schnellen Auftritt gegenüber.
Serverauswahl:
Ein Root-Server ist natürlich das Beste, was man nehmen kann. Man ist Herr seines Systems, man ist allein auf diesem System. Aber solche Server kosten entsprechend. Auch die Ersatzteilbeschaffung bei einem Defekt ist oftmals nicht kostenfrei. Man kann einen Server auch lokal in sein eigenes Heimnetzwerk stellen. Sofern dieser auch unter einer festen Adresse von außen erreichbar sein soll, ist ein DynDNS-Eintrag nötig (ist schon seit einigen Jahren nicht mehr kostenlos) und der Server sollte 24/7 angestellt bleiben und verursacht nicht zu unterschätzende Stromkosten. Auch sollte man weitere Sicherheitsmaßnahmen ergreifen, da nun von außen in das eigene lokale Netzwerk geroutet wird.
V-Root sind günstiger. Es gibt zwei Varianten. Der "echte" v-root bekommt "fest verdrahtete" Hardware zugewiesen, ähnlich richtiger Hardware. Auch ist man vollständig Herr über das System, meist wird nur eine Liste von verfügbaren Betriebssystemen vorgegeben. Der "unechte" v-root besitzt garantierte Hardwareeigenschaften, die auf ein Maximum kurzzeitig erweitert werden können, es wird oft eine Anzahl von Datenbanken und/oder Scriptsprachen vorgegeben. Das ist nichts weiter als ein vHost, ein Ordner auf einem bestehenden Webserver. Alle daraufliegenden Hosts teilen sich die Rechenleistung des Masters, wie beim "echten" v-root, jedoch sind diese untereinander abhängig. Zieht ein Host 100% Leistung, liegen alle anderen Host brach. Beim "echten" v-root sind Hardwaregrenzen für jeden Host gesetzt, so daß diese sich untereinander beeinflussen können.
Ein managed-Server wäre eine Alternative für Leute, die sich nicht mit Sicherheit und Updates beschäftigen wollen oder können. Das übernimmt dann der Provider. Aber: Haftbar ist der Webseitenbetreiber, der Provider ist fast immer fein raus, auch wenn er etwas verschlampt hat. Weiterhin kann es Probleme geben, wenn man spezielle Software einsetzt. Bei Unstimmigkeiten schiebt der Provider zuerst immer die Schuld auf die Software, auch wenn es am Server liegt.
Webspace ist billig, man kann kaum etwas selbst einstellen, ist ein Host nebenan infiziert, sind alle infiziert.
Zusammenfassung:
-Sicherheit steht an erster Stelle!
-CMS und weitere Software sorgfältig aussuchen!
Rootserver:
Vorteile: Leistung
muß nicht geteilt werden
man ist der Herr im Haus
als lokaler Rechner schnell vom Netzwerk trennbar
Nachteil: sehr teuer
"echter" v-root:
Vorteile: wird nicht geteilt
man ist der Herr im Haus
oftmals recht billig
Nachteil: etwas weniger Leistung als root
einige Sachen vorgegeben (z.B. Betriebssystem)
"falscher" v-root:
Nachteil: fast alles wird vorgegeben
wird geteilt
Leistung abhängig von den anderen Hosts
teilweise teurer als "echter" v-root
managed Server:
Vorteil: man muß sich nicht mehr so oft um die Sicherheit kümmern
oftmals gute Leistung
Nachteil: manchmal zickiger Support
oftmals teurer als v-root
Webspace:
Vorteil: billig, teilweise kostenlos
man braucht (und kann) sich nicht mehr um die Sicherheit auf Serverebene kümmern
Nachteil: Leistung abhängig von anderen Hosts
Infektionsrisiko durch Serverebene
oftmals alles, auch das CMS, vorgegeben
Server und Software installieren, Sicherheitsmaßnahmen
Ich selbst verwende eine Suse auf einem "echten" v-root, benutze bequemerweise zypper und dränge zur weiteren Bequemlichkeit in Richtung webmin.
Sobald das Betriebssystem aufgespielt wurde, benötigt root sofort (möglichst schnell) ein neues Paßwort.
Der Server ist sofort aus dem Internet erreichbar und ohne jegliche Schutzmaßnahmen. Sofort hängen verschiedene Bots an Port 22 (SSH) und versuchen, einen Zugang zum Server zu erhalten. Egal, welches Betriebssystem verwendet wird: Ein Nutzer ist immer bekannt. Unter Microsoft Windows ist es der Administrator, unter Unix der root. Man kann also 24/7 einen Bruteforce auf das Paßwort starten, soweit, wie es die Netzwerkanbindung hergibt. Im Zweifelsfall sollte das System neu aufgesetzt werden.
root bekommt also ein neues Paßwort. Man sollte sich einen Satz ausdenken, der ein wichtiges Ereignis in seinem Leben beschreibt, incl. Datum und Uhrzeit. Zum Paßwort werden dann die Anfangsbuchstaben der Wörter, die Zahlen und Sonderzeichen.
Code:
Bsp: Der Willi hat den Hans am 32.13. bei einer Kneipenschlägerei derart in den Hintern getreten, daß der Rettungsdienst Willi's Schuh erst um 25:61 aus Hans extrahieren konnte. DWhdHa32.13.beKdidHg,ddRWSeu25:61aHek.
root legt gleich einen anderen Nutzer mit einem ähnlich langem Paßwort an. Unter Webmin geht das recht bequem unter "System -> Users and Groups", unter "Webmin -> Webmin Users -> Convert Unix to Webmin Users" ist dieser Nutzer auch unter Webmin nutzbar.
Nun können root und andere (well known) Nutzer deaktiviert werden (System -> Users and Groups -> Nutzer auswählen), d.h. er wird auf "no login allowed" gesetzt, wird temporär deaktiviert oder bekommt die Shell /bin/false bzw. /sbin/nologin.
Bei jedem neu installierten Programm wird eventuell ein neuer Nutzer angelegt, daher hier immer überprüfen!
Noch immer hängen verschiedene Bots auf Port 22. Oftmals ist zu lesen, man könne den Port ein oder zwei Nummern "Umlegen". Das wissen auch mittlerweile die Betreiber der Bots.
Auf http://de.wikipedia.org/wiki/Liste_d...2.80.931023.29 kann man sich einen Port aussuchen, der nicht vom eigenen System genutzt wird und möglichst nicht auf das Betriebssystem verweist (Port zur Analyse vom Blätterrauschen des Jupiter der NASA wird wohl eher nicht das Ziel von Angriffen sein). Einen Portscan hält das nicht auf, es wird immer das passende Serverbanner mitgegeben, man hält sich dafür die "dummen" Bots, die nur wenige Ports kennen, vom Hals.
In /etc/ssh/sshd_config und /etc/ssh/ssh_config wird der neue Port eingetragen. SSH neu starten (webmin "Bootup und Shutdown -> SSH -> Restart").
Mittels zypper (Konsole, wie z.B. putty) als root können nun die Paketquellen installiert werden. Zypper ist ein Installationsmanager, der Paketabhängigkeiten von selbst auflöst und notfalls zusätzliche Software mitinstalliert.
Code:
zypper ar URL_des_Depots Aliasname
Folgende Depots sind wichtig (bitte selbst die Depots suchen!):
Code:
http://download.opensuse.org/distribution/XXX/repo/oss/ http://download.opensuse.org/distribution/XXX/repo/non-oss/ http://download.opensuse.org/update/XXX/ http://download.opensuse.org/update/XXX-non-oss/ http://download.opensuse.org/repositories/Apache/openSUSE_XXX/ http://download.opensuse.org/repositories/Apache:/Modules/Apache_openSUSE_XXX/ http://download.opensuse.org/repositories/server:/php/openSUSE_XXX/ http://download.opensuse.org/repositories/server:/php:/extensions/server_php_openSUSE_XXX/
Code:
zypper ref
Code:
zypper up
zypper ref und zypper up sollte man in Zukunft mindestens einmal wöchentlich ausführen, jedoch spätestens dann, wenn für installierte Software wichtige Sicherheitsupdates verkündet werden.
Code:
zypper se Name
Code:
zypper in Name
Somit wird fail2ban installiert. Fail2ban ist eine kleine Software, die Logfiles pro Sekunde analysiert und unangenehme Einträge an die Firewall weiterreicht.
Man kann selbst einstellen, welches Logfile in welchem Zeitraum analysiert werden soll, wie viele fehlerhafte Einträge (Login-Versuche, Hack-Versuche usw.) in diesem Zeitrahmen möglich sein dürfen und wie lange die entsprechende IP gesperrt werden soll.
Zypper wird möglicherweise iptables (eine mögliche Firewall) mitinstallieren, sowie einige zusätzliche Bibliotheken.
Fail2ban kann leider oftmals nicht schnell genug reagieren oder bereits mehrere geöffnete und gehaltene Verbindungen trennen. Es ist alles in Ordnung, dazu später mehr. Fail2ban schützt dennoch das System.
In /etc/fail2ban/jail.conf werden nun die SSH-Jails aktiviert (je nachdem, welche man möchte).
Ich selbst verwende u.a.
Code:
[ssh-tcpwrapper] enabled = true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] # sendmail-whois[name=SSH, dest=you@example.com] ignoreregex = for myuser from logpath = /path/to/log
Code:
maxretry = 2 bantime = 604800 findtime = 60
Wer Webmin verwendet, fügt (sofern nicht schon vorhanden, je nach Aktualisierung von fail2ban unterschiedlich) z.B.
Code:
[webmin-iptables] enabled = true filter = webmin action = iptables[name=webmin, port=10000, protocol=tcp] # sendmail-whois[name=ProFTPD, dest=you@example.com] logpath = /var/webmin/miniserv.log maxretry = 2 bantime = 86400 findtime = 600
In /etc/fail2ban/filter.d liegen die ganzen Filterdateien mit den regulären Ausdrücken, mit denen die Jails funktionieren. Falls nicht vorhanden, müssen diese erstellt werden (644, root,root). Diese Dateien werden in der jail.conf in filter= genannt.
Syntax ist immer [Definition] failregex ignoreregex
Code:
# Fail2Ban configuration file [Definition] # Option: failregex # Notes.: regex to match the password failure messages in the logfile. The # host must be matched by a group named "host". The tag "<HOST>" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?P<host>\S+) # Values: TEXT # failregex = <HOST>.*"POST /session_login\.cgi.*401 # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
Fail2ban kann jetzt gestartet werden (start at boot-time).
Später wird noch ein Jail für den Apache eingerichtet.
Mit zypper kann nun mysql (es wird bei SuSe garantiert eine MariaDB), Apache (möglichst die neueste Version, aktuell 2.4, darauf achten, daß einige Einstellungen für 2.2 nicht mit 2.4 kompatibel sind!) und PHP (möglichst die letzte Version für längeren Support), ich verwende mod_php, installiert werden.
Unter /usr/share/mysql gibt es Hinweise zur my.cnf (diese ist in /etc) für verschiedene Systeme. Das ist Tuning, dazu später mehr.
Ich rate vom Einsatz von phpmyadmin ab. Nach dieser Software wird sehr oft gesucht, man muß diese also richtig gut verstecken. Die Statements kann man auch in die Konsole eingeben, notfalls vorher in einem Textdokument speichern. Das Datenbankdesign kann keine Software erledigen, dazu ist immer noch der Mensch da. Und was nicht installiert ist, verschwendet keinen Platz und kann nicht angegriffen werden.
Zum Konfigurieren von MySQL ist kein Netzwerkzugriff erforderlich, wer ohnehin keine Datenbankverbindung von außen zulassen möchte, kann folgende Einstellung in /etc/my.cnf beibehalten
Code:
skip-networking bind-address = 127.0.0.1
MySQL kann jetzt gestartet werden. Mittels Konsole wird nun (mySQL nicht als root ausführen, man kann es erzwingen, aber trotzdem nicht machen, dazu hat man den Unix-Nutzer mit root-Rechten) dem mySQL-root ein recht gutes Passwort vergeben, ein zusätzlicher Nutzer mit eingeschränkten Rechten auf die neu zu erstellende Datenbank angelegt (wer ein fertiges CMS verwendet, hat jetzt sehr viel zu tun, wer selbst geschrieben hat, kennt seine DB-Struktur), er sollte kein DROP und möglichst wenig DELETE dürfen und sämtliche Nutzer mit % werden entfernt oder zumindest die Rechte entzogen. Diese %-Nutzer sind Verbindungen nach außen. Sollte bei einem Update das bind 127.0.0.1 verloren gehen, sind so zwar Verbindungen nach außen möglich, jedoch kein Login. Die benötigte Datenbank kann nun, eventuell nach Anpassen der my.cnf (z.B. File per table für InnoDB) eingefügt werden.
SuSe verteilt die Konfigurationsdateien vom Apache im ganzen System. Mittels Webmin kann man unter "Servers -> Apache Webserver -> Edit Config Files" einigermaßen einige Dateien einstellen, jedoch nicht alle.
Man bearbeitet die /etc/sysconfig/apache2. Wichtig sind hier:
APACHE_SERVERTOKENS="ProductOnly" oder noch weniger. Ein "Hallo, ich bin ein Apache-Server" reicht aus. Je mehr ein Server aussagt, umso eher hat der potenzielle Angreifer einen passenden Exploit parat.
APACHE_SERVERSIGNATURE="off"
APACHE_SERVERNAME="www.domain.tld"
Weiterhin werden die Module hinzugefügt und/oder entfernt. Man sollte sich fragen, welche Module man wirklich benötigt. Jeder Request durchläuft jedes Modul, damit das Modul feststellen kann, ob es zuständig ist, oder nicht. Das ist ein Geschwindigkeitsvorteil und verbraucht weniger RAM.
Sind die Module nicht in der Liste der standardmäßig installierten Module aufgeführt, so kann man die schnell mittels zypper nachinstallieren.
Als Beispiel:
Code:
APACHE_MODULES="alias auth_basic authz_host dir expires include log_config mime negotiation setenvif php5 reqtimeout authn_core authz_core rewrite deflate filter file_cache"
Wie man sieht, ist PHP als Modul eingebunden, mod_cgi wird nicht benötigt.
Sobald der Server läuft, beherrscht er PHP und muß nicht den Request an das CGI-Modul übergeben und auf Antwort warten. Zudem gibt es bösartige Requests, die versuchen, die php.ini im cgi-bin-Ordner zu überschreiben, zum Leidwesen aller Serverbetreiber auch oft erfolgreich.
Ich möchte hier keine Anleitung geben, es gab eine Welle von solchen (bereits decodiert, um Mißbrauch zu verhindern)
Code:
POST /phppath/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=""+-d+open_basedir=none+-d+auto_prepend_file=php://input+-n
Mod_php hat den Vorteil, daß www/wwwrun nicht auf die php.ini zugreifen kann, da diese in einem rootbereich liegt.
Die etc/php5/apache2 und cli/php.ini kann nun bearbeitet werden.
Wichtig sind vorerst:
exposephp off
safe_mode on
register_globals (sofern verfügbar) off
display_errors off (Fehler werden in /var/log/apache2/error_log gespeichert)
expose_php off (ok, man erkennt php schon in der URL, sofern man das nicht mit mod_rewrite umschreibt)
Datenverarbeitung einschränken (Ausführungszeiten, input_vars, nesting_level, Übergebene var-Mengen und -Größen beim Upload)
die php.ini in cli stärker beschränken
nicht benötigte Erweiterungen in etc/php5/conf.d auskommentieren
Es gibt noch weitere Kleinigkeiten, die ich hier vergessen habe, die lassen sich aber sehr schnell finden, spätestens beim Durchlesen aller Funktionalitäten in der php.ini.
disabled_functions ist ein wichtiges Thema. Man sollte danach im Netz suchen und sämtliche zusammengetragenen Funktionen bereinigen, auf Sinnfreiheit überprüfen (da gab es mal jemanden, der inject_code verboten hat) und nachschauen, ob diese vom eigenen CMS genutzt werden.
Ich werde hier nicht meine ganze php.ini zur Schau stellen. U.a. gehören jedoch
Code:
phpinfo, chmod, allow_url_fopen, allow_url_include, escapeshellcmd, exec, eval, escapeshellarg, getenv, ini_alter, ini_restore, ini_get_all, ini_get, passthru, proc_nice, popen, proc_open, pclose, proc_terminate, proc_get_status, proc_close, pfsockopen, putenv, shell_exec, show_source, symlink, system, set_time_limit, syslog, openlog, readfile, open_base, openlog, restore_include_path, set_include_path, set_magic_quotes_runtime, fpassthru, fputcsv, fputs, fread, fscanf, sscanf, fseek, ftruncate
Kleiner Tipp: mysql sollte man nicht mehr benutzen, stattdessen das neuere und schnellere mysqli. Wurde php mit sqlnd anstelle der Treiber von Oracle kompiliert, kann man noch zusätzliche Performance gewinnen.
Die http.conf vom Apache erhält noch
Code:
<IfModule mod_php5.c> AddType application/x-httpd-php .php # AddType application/x-httpd-php .php5 # AddType application/x-httpd-php-source .phps AddHandler application/x-httpd-php .php </IfModule> #AddType application/x-httpd-php .php
Die Webseite kann nun nach /srv/www/htdocs geschoben werden. Nach einem Start von Apache sollte nun alles mehr oder weniger funktionieren. Aber bitte Apache sofort wieder beenden. Kleiner Probleme können nun behoben werden, ich möchte darauf nicht eingehen.
Ab sofort, wenn der Server läuft, erhalten wir unschöne Requests von infizierten Servern und Botnetzwerken. Ich möchte es den Anfängern und em einen oder anderen Profi ersparen, selbst alles zusammenzusammeln. Hier eine Liste der häufigsten Angriffe, die mir untergekommen sind.
Code:
admin,axa.php,azenv,api,sql,soapCaller,script,status,server_new,sqlite,sleep,SQL,pma,phppath, phpmy,w00tw00t,wp-login,wp-content,wp-register,wpcron,webmail,webdav,ofc,openflashchart, cgi-bin,calendar,components,cmd,count,concat,com_jnews,CFIDE,CMD,COUNT,CONCAT,remote,roundcube, httpmon,hudson,xmlrpc,x0x0x0,invoker,information_schema,install,include,HNAP1,manager, database,typo3,nice,gameframe,json,%6C%6C,%27,main.php,library,UNION,index.php, OPTIONS,TRACE,TRACK,PROPFIND,CONNECT
Damit erstellen wir ein neues Jail und .conf in fail2ban. Leider sind die Regexen von fail2ban nicht ganz PCRE-kompatibel (sorry, das waren andere Ausdrücke, ich komme jetzt gerade nicht drauf), es gibt keine Möglichkeit, Groß- und Kleinschreibung gleichzeitig zu behandeln (das war das i-Flag) und es gibt Gruppierungsprobleme. Es nimmt nichts von der Serverperformance weg, da fail2ban nebenbei läuft.
In /etc/fail2ban/filter.d wird eine neue Datei (nennen wir sie apache-dreck.conf) erstellt.
Code:
[Definition] failregex = ^<HOST>.*"(GET|HEAD|POST).*(admin) ^<HOST>.*"(GET|HEAD|POST).*(axa\.php) ^<HOST>.*"(GET|HEAD|POST).*(azenv) ^<HOST>.*"(GET|HEAD|POST).*(api) ^<HOST>.*"(GET|HEAD|POST).*(ADMIN) ^<HOST>.*"(GET|HEAD|POST).*(Admin) ^<HOST>.*"(GET|HEAD|POST).*(sql) ^<HOST>.*"(GET|HEAD|POST).*(soapCaller) ^<HOST>.*"(GET|HEAD|POST).*(script) ^<HOST>.*"(GET|HEAD|POST).*(status) ^<HOST>.*"(GET|HEAD|POST).*(server_new) ^<HOST>.*"(GET|HEAD|POST).*(sqlite) ^<HOST>.*"(GET|HEAD|POST).*(sleep) ^<HOST>.*"(GET|HEAD|POST).*(SQL) ^<HOST>.*"(GET|HEAD|POST).*(Sql) ^<HOST>.*"(GET|HEAD|POST).*(pma) ^<HOST>.*"(GET|HEAD|POST).*(phppath) ^<HOST>.*"(GET|HEAD|POST).*(phpmy) ^<HOST>.*"(GET|HEAD|POST).*(w00tw00t) ^<HOST>.*"(GET|HEAD|POST).*(wp\-login) ^<HOST>.*"(GET|HEAD|POST).*(wp\-content) ^<HOST>.*"(GET|HEAD|POST).*(wp\-register) ^<HOST>.*"(GET|HEAD|POST).*(wpcron) ^<HOST>.*"(GET|HEAD|POST).*(webmail) ^<HOST>.*"(GET|HEAD|POST).*(webdav) ^<HOST>.*"(GET|HEAD|POST).*(ofc) ^<HOST>.*"(GET|HEAD|POST).*(openflashchart) ^<HOST>.*"(GET|HEAD|POST).*(cgi\-bin) ^<HOST>.*"(GET|HEAD|POST).*(calendar) ^<HOST>.*"(GET|HEAD|POST).*(components) ^<HOST>.*"(GET|HEAD|POST).*(cmd) ^<HOST>.*"(GET|HEAD|POST).*(count) ^<HOST>.*"(GET|HEAD|POST).*(concat) ^<HOST>.*"(GET|HEAD|POST).*(com_jnews) ^<HOST>.*"(GET|HEAD|POST).*(CFIDE) ^<HOST>.*"(GET|HEAD|POST).*(CMD) ^<HOST>.*"(GET|HEAD|POST).*(COUNT) ^<HOST>.*"(GET|HEAD|POST).*(CONCAT) ^<HOST>.*"(GET|HEAD|POST).*(remote) ^<HOST>.*"(GET|HEAD|POST).*(roundcube) ^<HOST>.*"(GET|HEAD|POST).*(httpmon) ^<HOST>.*"(GET|HEAD|POST).*(hudson) ^<HOST>.*"(GET|HEAD|POST).*(xmlrpc) ^<HOST>.*"(GET|HEAD|POST).*(x0x0x0) ^<HOST>.*"(GET|HEAD|POST).*(invoker) ^<HOST>.*"(GET|HEAD|POST).*(information_schema) ^<HOST>.*"(GET|HEAD|POST).*(install) ^<HOST>.*"(GET|HEAD|POST).*(include) ^<HOST>.*"(GET|HEAD|POST).*(PMA) ^<HOST>.*"(GET|HEAD|POST).*(HNAP1) ^<HOST>.*"(GET|HEAD|POST).*(manager) ^<HOST>.*"(GET|HEAD|POST).*(database) ^<HOST>.*"(GET|HEAD|POST).*(typo3) ^<HOST>.*"(GET|HEAD|POST).*(nice) ^<HOST>.*"(GET|HEAD|POST).*(gameframe) ^<HOST>.*"(GET|HEAD|POST).*(json) ^<HOST>.*"(GET|HEAD|POST).*(%%6C%%6C) ^<HOST>.*"(GET|HEAD|POST).*(%%27) ^<HOST>.*"(GET|HEAD|POST).*(main\.php) ^<HOST>.*"(GET|HEAD|POST).*(library) ^<HOST>.*"(GET|HEAD|POST).*(UNION) ^<HOST>.*"(GET|HEAD|POST).*(union) ^<HOST>.*"(GET|HEAD|POST).*(bench) ^<HOST>.*"(GET|HEAD|POST).*(BENCH) ^<HOST>.*"(GET|HEAD|POST).*(index\.php) ^<HOST>.*"(OPTIONS) ^<HOST>.*"(TRACE) ^<HOST>.*"(TRACK) ^<HOST>.*"(PROPFIND) ^<HOST>.*"(CONNECT) ignoreregex = ^<HOST>.*(compatible; Googlebot|google) ^<HOST>.*(internal dummy connection)
Nein, das läßt sich leider nicht gruppieren und zusammenfassen. Bitte für das eigene System anpassen (WP-Nutzer sollten die wp-Ausdrücke entfernen, englischsprachige CMS benutzen die kleine index.php usw.)
Einen Ordner höher bekommt die jail.conf noch
Code:
[apache-dreck] enabled = true filter = apache-dreck action = iptables-multiport[name=apache-dreck, port="80"] logpath = /var/log/apache2/access_log maxretry = 0 bantime = 86400 findtime = 600
Zusammenfassung:
Betriebssystem aufsetzen, updaten und absichern
fail2ban einrichten
mySQL, Apache, PHP installieren, konfigurieren und grundlegend absichern
eventuell weitere benötigte Module für Apache und PHP nachinstallieren
Weiterhin sollte man nun übergebene Variablen an die PHP-Scripte bereinigen.
Code:
$_neueVar = (ggf. cast) (mysqli_real_escape_string($con, htmlentities(trim($_POST/GET/SESSION/COOKIE...['var']), FLAGs)));
Zuerst werden unnötige Leerzeichen vor und nach der Variable entfernt. Mit htmlentities und des passenden Flags kann man gewisse HTML-Tags von vorn herein escapen, womit z.B. Spambots keine Links mehr als HTML-Tag erstellen können. Ein Nicht-UTF8-Schriftsatz wäre interessant, wenn man nur lateinische Schriftzeichen handhaben möchte. Man ist für die Beiträge anderer auf der eigenen Seite haftbar, man möchte keinen Brief vom Staatsanwalt bekommen, weil jemand etwas böses eingetragen hat, was man nicht lesen kann. Danach sorgt mysqli für einen sauberen String. Ein Cast ist nur für nicht-Strings sinnvoll, da PHP Inhalte von Variablen erst als String ansieht. Es wird mit dem Cast versucht, eine Zahl aus dem String zu interpretieren. Wenn es nicht geht, dann eben gar nichts. So vermeidet man SQL-Injections.
Mit dieser neuenVar wird nun weitergearbeitet, da diese nun einigermaßen sauber ist.
@ für Variablen sollte vermieden werden. Es wird die Fehlermeldung unterdrückt, die diese Variable erzeugt. Leider aber auch Fehlermeldungen aller Konstrukte, die mit dieser Variable in Kontakt gekommen sind. Das ist bei kleinen Scripten, die man im Netz findet, sehr oft der Fall. Man erfährt nie, daß irgend etwas stattgefunden hat.
Als PHP-Wrapper eignet sich ZB Block von Zaphod B. von www.spambotsecurity.com.
Es wird vor jeglicher Aktivität in die PHP-Scripte eingehängt, die immer geladen werden (main.php, login.php, abhängig vom CMS).
Es überprüft den Request, den UA, den Referer und die Hostadresse mittels Signaturen, die ständig von einer weltweiten Community aktualisiert und verbessert werden. Der bösartige Host bekommt ein 403 und/oder 503, das jeweilige Script ein "die". Ein weiteres bösartiges Vorgehen wird effektiv verhindert.
Mittlerweile sind über 1700 Signaturen bekannt, die einem PHP-Script und/oder einer PHP-Webseite schaden können. Auch werden bekannte bad Hosts und Ranges von vornherein ausgesperrt. Es ist schneller und systemschonender als mod_security und erzeugt weniger false-positives. Weiterhin arbeitet es mit der Liste auf www.stopforumspam.com zusammen, als api oder lokales file. ZB Block sollte hier für den Sicherheitsgedanken erwähnt werden. Es ist mit sehr vielen CMS, die auf PHP basieren, kompatibel. Zusätzlich kann ein tarbaby eingerichtet werden, dazu später mehr.
Servertuning und Bad Bots
RAM ist durch nichts zu ersetzen, nur durch mehr RAM. Ebenso CPU. Das läßt sich oftmals nicht ändern.
Die Verarbeitung eines Requests und die Ausgabe an den Client können aber oft beschleunigt werden.
Caching ist eines der Zauberworte. Hier gibt es oft keine festen Regeln, es ist alles abhängig vom eigenen System und dem Einsatzzweck. Bitte die Werte nicht ungeprüft einfach so übernehmen!
Die Dateien in /usr/share/mysql für mySQL geben einige Hinweise für verschiedene Systeme. Möglichst viele Verbindungen zulassen, möglichst große Cache-Bereiche. Aber nicht übertreiben. Es wäre eine Verschwendung, einer Datenbank von 3 MB 3 GB Cache zuzuordnen.
Hier ein Auszug aus meiner cnf. MySQL werden so 2,5 GB zugewiesen (aber nicht benutzt, nur im Notfall). Ich verwende InnoDB.
Code:
key_buffer_size = 384M max_allowed_packet = 1M table_open_cache = 600 sort_buffer_size = 4M read_buffer_size = 4M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 48M join_buffer_size = 128M thread_cache_size = 16 thread_concurrency = 8 innodb_data_home_dir = /var/lib/mysql innodb_log_group_home_dir = /var/lib/mysql innodb_buffer_pool_size = 768M innodb_additional_mem_pool_size = 32M innodb_log_buffer_size = 8M innodb_file_format=Barracuda innodb_file_per_table=ON #query_cache query_cache_limit = 128M query_cache_size = 768M query_cache_type = 1 query_cache_min_res_unit = 64k
Dem Apache kann man auch sehr auf die Sprünge helfen. Erforderlich ist allerdings oftmals ein Zugriff auf die Serversteuerung, wohl dem, der einen (v)root-Server hat oder einen guten Kontakt zum Support bei einem managed Server.
Die Verwendung von htaccess-files lehnt die Apache-Foundation aus Performansgründen ab.
http://httpd.apache.org/docs/current.../htaccess.html
You should avoid using .htaccess files completely if you have access to httpd main server config file. Using .htaccess files slows down your Apache http server. Any directive that you can include in a .htaccess file is better set in a Directory block, as it will have the same effect with better performance.
Die Inhalte der .htaccess werden in <directory> eingetragen und mit
<Directory />
Options None
AllowOverride None
Require all denied
</Directory>
.htaccess deaktiviert. Bitte beachten, daß das Serverdirectory (htdocs) angegeben ist. Die Syntax von Apache 2.4 hat sich geändert, wie man sieht.
hostnames_lookup off, keep_alive on, maxkeepaliverequests und -timeout vernünftig begrenzen, Anzahl und Fähigkeiten der Worker/Childs sinnvoll einstellen.
Was im RAM liegt, muß nicht von der langsamen Festplatte geholt werden. Dies gilt hier nur für statische Dateien, wie Bilder, CSS, JS. Hier ist der vollständige Pfad anzugeben.
Code:
<IfModule mod_file_cache.c> MMapFile /Pfad/zu/Ressource.xxx /Pfad/zu/Ressource2.xxx /Pfad/zu/Ressource3.xxx </IfModule>
Code:
<IfModule mod_expires.c> ExpiresActive on ExpiresDefault "access plus 1 months" ExpiresByType image/jpg "access plus 1 months" ExpiresByType image/gif "access plus 1 months" ExpiresByType image/jpeg "access plus 1 months" ExpiresByType image/png "access plus 1 months" ExpiresByType text/css "access plus 1 months" ExpiresByType image/x-icon "access plus 1 months" </IfModule>
Code:
<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/css text/x-component text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon DeflateBufferSize 102400 DeflateWindowSize 15 DeflateMemLevel 9 DeflateCompressionLevel 2 <IfModule mod_setenvif.c> BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html </IfModule> <IfModule mod_headers.c> Header append Vary User-Agent env=!dont-vary </IfModule> </IfModule>
In der php.ini steckt weiteres Optimierungspotential.
Ich möchte hier nicht auf die einzelnen Werte eigehen, jeder kann sich diese selbst aus der php.ini herauslesen.
Man sollte recht viele Verpindungen, auch persistente, zulassen und die Timeouts relativ hoch halten. Ein Requests kann somit eine bestehende Verbindung nutzen, es muß keine neue aufgebaut werden.
mysqli kann den Cache von mysqlnd nutzen, welches wiederrum (als Treiber) auf den Querycache von mySQL zugreift.
PHP5.5 besitzt schon den eigebauten Zend Opcache und Optimizer. Möglichst alle Scripte sollten in den Cache passen, von der Anzahl und der Größe her. Die Bitmask vom Optimizer sollte man aktivieren und das System testen, es kann vorkommen, daß der Optimizer nicht wie vorgesehen arbeitet.
Die prozedurale Programmierung ist näher am Echzeitverhalten als OOP, bei geringerem Speicherverbrauch.
OOP besteht aus Datenkapselung, Vererbung und Polymorphie.
Datenkapselung ist eine recht gut handhabbare Sache für denjenigen, der eine Instanz einer Klasse erstellt. Er muß nicht wissen, was wie funktioniert. Die Instanz wird nach den Regeln des Konstruktors erstellt und beherrscht alles. Ob nun ein echo "Hallo Welt"; oder berechne die Mondumlaufbahn anhand der Gravitationsverzerrungen am Jupiter; echo "Hallo Welt"; ausgegeben wird, macht schon einen Unterschied. Es funktioniert ja.
Da die erzeugte Instanz aufgrund der Vererbung alles das kann, was die übergeordneten Klassen können (unter C# ist das bis hoch zum obersten Object object), wird recht viel Speicher benötigt. Dies auch noch so lange, bis die Instanz zerstört wurde und vom Garbage-Collector eingesammelt wurde.
Garbage-Collector: Es ist schon ein Unterschied, ob er bei jedem Request, alle 100 oder alle 10000 losläuft.
Includes sollten vermieden werden. Der Parser muß an einem include seine Arbeit einstellen, alles in den RAM zurückschaufeln, das includefile suchen, abarbeiten und mit dem Ergebnis zum alten Script zurückkehren. Ohne include vervielfacht man seine Quelltexte, sie werden recht unleserlich (besonders bei prozeduraler Programmierung), dafür schneller abgearbeitet.
Wer mag, kann sich auch noch mit der Microoptimierung beschäftigen.
Da nun die oben erwähnten bad Requests auf den Server einprasseln und fail2ban die Hosts an iptables weiterleitet, könnte man doch dafür sorgen, daß diese Bots ein wenig festgehalten werden und dem ahnungslosen Administrator eine Meldung hinterlassen wird. Zusätzlich kann dem Bot auch noch Müll mitgegeben werden. Der Betreiber des Bots wird sich sicherlich sehr freuen, wenn sein doch so schneller Bot recht langsam geworden ist und sinnlose Daten zur Auswertung speichert oder sendet.
Im Moment erzeugen diese Requests ein 404 - not found.
Mit ZB Block hat man die Möglichkeit, ein tarbaby einzusetzen. Zudem wird alles gefahrlos mitgeloggt, so daß man gegebenenfalls weitere Maßnahmen ergreifen kann.
PHP-Code:
<?php
require("/Pfad/zu/zbblock/zblog.php");
require("/Pfad/zu//zbblock/zbblock.php");
// Dribbler tarbaby.
// Copyright 2014 GNU/GPL Mike (zaphod a.t. spambotsecurity.com)
if (ob_get_level() == 0) ob_start();
echo(str_pad('',1024));
for ($i = 0; $i<1000; $i++){
for ($j = 0; $j<rand(1,2); $j++){
echo chr(rand(0,255));
}
ob_flush();
flush();
$x=rand(1,5);
sleep($x);
}
echo "<br><br>You triggered this tarbaby due your bad behavior.<br>";
ob_end_flush();
?>
Damit dies auch funktioniert, wird mod_rewrite bemüht. Warnung: Sobald sich etwas in dem Statement befindet, was man selbst nutzen muß, bitte entfernen.
Code:
RewriteCond %{REQUEST_URI} (c(?:gi\-bin|omponents|ontent|hangelog\.php)|a(?:dministrator|xa\.php)|p(?:hppath|lugin|hpmyadmin|ma|asswd)|o(?:ption=com_jce|penflashchart|fc\-library|fc_upload)|w(?:p\-login\.php|p\-content|ebdav|00tw00t|pcron\.php)|s(?:oapCaller\.bs|id=|etup\.php)|i(?:mages/stories|mgmanager)|myadmin|\?action|login\.php|editor|xmlrpc)(.*)$ [NC,OR] RewriteCond %{REQUEST_URI} index\.php(.*)$ RewriteRule ^(.*)$ /Pfad/zu/tarbaby\.php [PT,L]
Viele Seiten nutzen die Syntax
RewriteCond dies [OR]
RewriteCond das [OR]
RewriteCond jenes [OR]
...
Obwohl es sich um ODER-Verknüpfungen handelt, muß der Parser, auch bei einem Match, jede Condition ablaufen.
In der Zusammenfassung wird nun überprüft: Befindet sich ein c im Request? Wenn nein, dann überspringe die komplette Gruppe. Es ist eine Zeitersparnis, die wirklich etwas bringt. Auch für andere Rewriterules.
Hier können wir also Gruppierungen und den NC-Flag nutzen, in dem Fall wird auch noch die klein geschriebene index.php als bad request angesehen.
Nun wird alles umgeleitet auf das tarbaby. Eine normale Umleitung erzeugt einen 301/302, was die Bots nicht interessiert. Sie möchten nur eine 200 oder einen 400er sehen. Mit [PT] wird intern umgeleitet, ohne daß sich die URL (im Browser, Bots verwenden nun keinen) ändert, sie werden direkt an das Tarbaby geschickt. [L] ist nicht zwingend notwendig, da [PT] diesen schon bedingt. Aber sicher ist sicher, weitere Rules werden nun nicht mehr ausgeführt. Mod_rewrite verarbeitet aber nun diesen neuen Request zum Tarbaby. Diesen müssen wir vorher abbrechen. Also wird vor diesem Block ein
Code:
RewriteCond %{REQUEST_URI} /(Pfad/zu/tarbaby\.php) [NC] RewriteRule .* - [L]
In den Logfiles von ZB Block kann man genau sehen, was eigentlich gesendet wurde. Das ist sehr oft sehr bedenklich. Das harmloseste waren Veruche, die Startseite einer WP-Installation zu ändern. Oftmals wird man den Versuch sehen, ein "hochgeladenes" Bild (food, fish, lobex21, usw.) in eine .php umzubenennen. Dies erstellt eine Shell.
Leider müssen wir jetzt den Google-Bot Beachtung schenken. Er führt das aus, was er (es muß noch nicht einmal als Link deklariert sein) in die Finger bekommt. Es gibt die Geschichten mit google.translate und weiter Sachen, die ich hier nicht erklären möchte. Der Google-Bot führt dann ahnungslos den Angriff aus.
Wir kopieren den Block der bad Requests und fügen ihn zwischen die beiden eben erstellten Blöcke ein.
Code:
RewriteCond %{HTTP_USER_AGENT} Googlebot.* [NC] RewriteCond %{HTTP_HOST} (Servername|IP) [NC,OR] RewriteCond %{REQUEST_URI} (c(?:gi\-bin|omponents|ontent|hangelog\.php) ... |xmlrpc)(.*)$ [NC,OR] RewriteCond %{REQUEST_URI} index\.php(.*)$ RewriteRule .* - [R=404,L]
Damit sieht die Struktur wie folgt aus:
wenn tarbaby -> beenden
bad Google-request -> 404
bad requests -> tarbaby
Mit dieser Methode "vergifte" ich verschiedenen Keyword-Searchern die Datenbanken. Zusätzlich werden die auch noch von fail2ban behandelt.
Rechtliches
Hier muß man sich leider auch kümmern.
Urheberrecht
Urheberrecht dürfte klar sein. Nicht alles, was im Netz zu finden ist, kann man so nutzen. Man fragt den Urheber nach den Bedingungen oder erstellt selbst etwas. Frei Nutzbar sind nur Sachen, die auch so gekennzeichnet sind (dort gibt es eventuell auch Bedingungen), der Urheber ist seit 70 Jahren verstorben oder absolut nicht auffindbar.
Impressum
Jedes Telemedium, welches geschäftsmäßig etwas anbietet, unterliegt dem Telemediengesetz und der Anbieter muß sich darauf verewigen. Geschäftsmäßig bedeutet nicht, daß etwas verdient wird, sondern nur, daß etwas dauerhaft angeboten wird. Wenn der Server im Ausland steht, unterliegt er genauso dieser Pflicht, wenn er hauptsächlich an deutsche Kunden ausliefert. Der Grund liegt darin, daß der Verbraucher sofort einen Verantwortlichen hat, ohne sich durch Whois-Daten und Registrare wühlen zu müssen.
Ausgenommen sind reine Testseiten und private angebote, die paßwortgeschützt sind. Leicht zugänglich, also keine Klick-Marathons, leicht zu lesen, also keine Bilder. Sicher ist sicher, Abwahnungen sind teuer. Macht man das Erwerbsmäßig, wird es noch teurer.
Datenschutzerklärung
Wir nehmen den Schutz Ihrer Daten sehr ernst.
Jugendschutz
Bisher gibt es noch kein wirksames Mittel, Jugendliche und Kinder von jugendgefährdenden Medien fernzuhalten. Viele Methoden wurden als unzureichend eingestuft, andere sind unbezahlbar bzw. für den Kunden unzumutbar. Man sollte sich selbst fragen, ob man jugendgefährdende Inhalte anbietet.
Informationen dazu gibt es unter http://www.age-label.de/basis und http://www.online-management-kontor....fizierung.html
Im Streitfall ist eine vorhandene age_de.xml sehr günstig, wenn sie vernünftig ausgestellt wurde.
Dieser Artikel hilft "Neulingen" zu einer schnelleren und sicheren Einrichtung und Betrieb eines Servers und gibt den "Alten" hoffentlich noch einige weitere Ideen mit auf dem Weg. Gern kann eine Diskussion hier fortgesetzt und die Einträge ergänzt werden, für weitere Fragen stehe ich gern nicht mehr zur Verfügung.
Vielen Dank für die Aufmerksamkeit.
Kommentar