Linux – ich habe keinen RAM mehr

Da ich in den letzten Jahren immer wieder Diskussionen darum hatte, daß Linux den „gesamten“ RAM auffrisst, habe ich mir gedacht, da ich mein Wissen eh ins Blog schreiben wollte, wäre jetzt ein guter Zeitpunkt den Sachverhalt nochmal eindeutig in einem Artikel zu veröffentlichen.

Worum geht es ?

Ich mach das Problem am sinnvollsten an einem Bild deutlich:

Das ist einer meiner Linux Server, der laut top unschwer behauptet 12.414 GB RAM von 32 GB RAM zu verwenden.
Da nur ein paar kleinere Java-Applikationen und ein DB-Server auf der Büchse laufen, sieht das natürlich erstmal imposant aus.

Wow, die eine JAVA-App zieht 12GB virtuell – das ist übrigens mein BitBucket (6GB) mit ElasticSearch (6GB) – MySql zieht auch schon 3GB RAM.

Aber halt, ist das wirklich so ?

Schauen wir uns doch einfach mal den Prozess 10676 an, der angeblich 6706,7MB verbrät.
– Sorry, daß werden jetzt knappe 1000 Zeilen 🙂 –

Also laut pmap verbraucht dieser Java-Prozess tatsächlich nur ca. 1,6 GB RAM und keine 6,8GB.

Was zeigt denn also top da bei VIRT an ?
Das ist schlicht alles, was die Applikation gerade im Zugriff hat, also Files und RAM.
Wie man am pmap sehr schön sehen kann, hat die eine JVM tatsächlich irgendwo knappe 6 GB insgesamt im Zugriff, also Logfiles, Klassen und halt auch nebenbei noch RAM (1,5GB).

Warum sagt mir mein Top, daß ich 12GB von 32GB RAM gerade verbrauche ?

Hier kommt Linux ins Spiel. Schauen wir uns einfach einmal an, was da in dem Bildchen unter „cached Mem“ steht, kommen wir der Sache auf die Spur

Laut top haben wir also 7,5GB an „cached Mem“.

Machen wir mal die Gegenkontrolle mit free

Und wie man bei free sehr schön sehen kann, haben wir in der Zeile „-/+ buffers/cache“ unter „free“ auf einmal 26GB RAM stehen.
Meine laufenden Applikationen ziehen also tatsächlich nur irgendwas um 6GB RAM, inklusive OS.

Aber was ist das denn nun mit dem „cached Mem“ ?

Linux nimmt sich die Freiheit für schnellere Zugriffe auf Files diese schlicht im RAM zu cachen.
Damit also das Linux auf meinem Server den Zugriff auf die physikalischen Festplatten so gering wie möglich halten kann, cached es halt die Dateien, die oft im Zugriff sind, schlicht im RAM.

Und wenn meine Apps jetzt mehr tatsächlichen RAM brauchen ?

Die Frage ist recht simpel zu beantworten: in dem Moment, wo der tatsächliche RAM-Bedarf seitens der installierten Applikationen höher wird, wird der cached-Memory automatisch vom OS wieder freigegeben an die Applikationen.
Wenn man nun recht langsame Festplatten in seinem System hat, könnte daß ein Moment sein, wo man auf einmal Leistungseinbrüche auf dem System feststellen kann.

 

Fazit

Wenn ihr meint, daß Euer Speicher vom Linux „aufgefressen wird“ schaut einfach mit free nach, was in der Zeile „-/+ buffers/cache“ unter „free“ steht, dann wisst Ihr, was Ihr noch an Reserven habt. 🙂

 

 

Debian und Initscripte

Unter Debian gibt es für init Scripte eigentlich eine recht gute Vorlage, die man unter /etc/init.d/skeleton findet.

OK, war ein Scherz 🙂
Die Vorlage ist mehr als rudimentär und nicht wirklich nutzbar.

Da ich auch kleinere Webservices/Server geschrieben habe, die irgendwo laufen, hab ich mir mal ein simples init-Script geschrieben, daß ich nun überall unter Debian/Ubuntu nutze.

Simpel deswegen, weil ich nur ein paar Zeilen anpassen muß, damit ich das für jedes Projekt verwenden kann.

Das Script baut auf dem LSBInit-Framework auf.

Hier einfach ein Beispiel für meinen GPRS-Server, Scriptname gprsserver, der ein laufendes mysql benötigt:

Sieht zwar kompliziert aus, ist es aber nicht wirklich.
Alles was man einstellen muß, hört mit dem „END OF CONFIG-SECTION“ auf.

Das fertig angepasste Script, gefolgt von einem chmod 755, kopiert man dann einfach nach /etc/init.d/gprrserver

Anschließend teilt man dem System noch über ein

mit, das es bitte in /etc/rcX.d die entsprechenden Links setzen möge.

Was tun bei DoS/DDoS-Angriffen ?

Ich beobachte nebenbei gerne die neuesten Entwicklungen im Bereich DDoS (DistributedDenialofService).

NEIN, nicht weil ich es selbst nutzen möchte, sondern schlicht um Kunden besser schützen zu können.

In den letzten Tagen hatte schon Akamai die Segel gestrichen, als ein illustrer Traffic von 620GBit/s das Blog von Brian Krebs lahmlegte (übrigens eine mehr als imposante Zugriffsrate für ein Blog 🙂 ).
Heute lese ich nun auf Heise, daß der französische Hoster OVH von einem DDoS mit 1,1TB/s minimal überrascht wurde.

Das sind mal UpStream-Raten 🙂

Und nu ?

Da nun nicht jeder Webseitenbetreiber von einem DDoS in diesen Außmaßen getroffen wird, empfiehlt es sich zum Beispiel beim Apache httpd etwas wie mod_evasive einzusetzen.
Es wird ganz sicher nicht dem Anfangs genannten Traffic von 620GB/1,1TB standhalten – da ist der Speicher schneller voll, als man Papp sagen kann – aber es hilft doch gegen Script-Kids und wirklich einfach gestrickte DoS/DDoS-Versuche.

Zusätzlich könnte man natürlich auch noch eine Strategie wählen die ich in diesem Beitrag beschrieben hatte und diese Methode auf Port 80 ausdehnen.

 

Toll 🙁

Ich werde mal am Wochenende versuchen einen etwas detaillierten Beitrag zu mod_evasive zu schreiben 🙂

Welche Gegenmaßnahmen man sonst noch treffen kann, darf ich, nach gründlicher rechtlicher Recherche, hier leider nicht posten 🙁

Ein Lockfile im Shell-Script

Gute Vorschläge und Ideen um Lock-Files in einem Shell-Script zu verwenden, gibt es wie Sand am Meer.

Es gehen – mittlerweile seit Jahren – tiefgreifenden Diskussionen einher, welche Variante nun die Sicherste ist und welche Scripts Race-Conditions haben.

Meine persönliche Variante, die sicherlich nicht im Millisekunden-Bereich stabil ist, ist die folgende:

Über die erste Zeile hole ich mir einen Lockfilenamen in /tmp der den Namen des Scripts+“.lock“ hat.

Das kill -0 prüft schlicht, ob der Prozess der das „Lock“ hat, auch tatsächlich noch läuft.

Trap sichert noch ab, daß, außer bei einem kill -9, das Lockfile auch gelöscht wird 🙂

SSL Einstellungen auf dem Apache (Drown)

Das Thema SSL mit Let’s Encrypt werde ich zwar erst in einem später Blogeintrag thematisieren, aber durch die aktuelle Problematik wegen DROWN, schreibe hier doch mal etwas zum Thema SSL.

Viele Webserver die im Netz verfügbar sind, sind leider mehr als suboptimal konfiguriert, was nun gerade durch das beeindruckende DROWN-Problem und dem Anbieter Server4You mehr als deutlich wird.

Laut BSI (Bundesamt für Sicherheit in der Informationstechnik) sind alleine in Deutschland 245.000 IPs betroffen.

Wenn man nun eine Seite mit SSL betreibt, sollte man sie zumindest einmal prüfen lassen, ob der Webserver wirklich richtig konfiguriert ist.
Einen kostenlosen und mehr als umfangreichen Test gibt es bei: Qualys SSL Labs

Aber zunächst einmal frisch ans Werk 🙂

Um das Drown-Problem zu lösen, ändert man in seiner ssl.conf im Apachen die Zeile mit dem SSLProtocol wie folgt ab:

Dazu noch in der selben Datei die default Zeile SSLCipherSuite wie folgt

abändern und schon hat man mit dieser kleinen Änderung, gefolgt von einem

das Drown-Problem gelöst.

 

Wem nun noch seine CypherSuites wichtig sind, weil Qualys SSL Labs, die Seite nur als A- einstuft, kann mit der folgenden Änderung in der ssl.conf

seine Probleme lösen.

 

Mehr zum Thema Zertifikate kommt demnächst, wenn ich über Let’s Encrypt schreibe. 🙂

Oracle DB GUI Installation

Da ich auf meinem MAC zu Test-/Entwicklungszwecken immer eine Menge VMs am laufen habe, kam ich die Tage in die Situation, daß ich in einer VM eine Oracle DB 12c installieren mußte.

Bis zur Version 10, die ich auch noch in irgendeiner VM installiert habe, ging das ganze Setup ja noch per Console.

Aber mit der 12c geht das nur noch über eine GUI oder Responsefile Installation 🙁

Ich weiß nicht, was sich die Jungs und Mädels da bei Oracle denken, aber gelinde ausgedrückt ist das mehr als Suboptimal.
Warum muß ich zur Installation einer Server-Version einer Datenbank jetzt eine „klickie-buntie“ GUI benutzen oder ein Responsefile ?

Aber egal. Also die GUI.

Das Problem: wie bekomme ich aus einer Linux VM, auf die ich mich nur per ssh connecte, diese komische GUI auf meinem MAC per X-Forwarding angezeigt ?

Nach etwas längerer Bastelei war die Lösung eigentlich recht einfach:

Die GUI wurde dann auch brav auf meinem MAC angezeigt.

Das X enabled das X-Forwarding und das C schaltet noch die Compression der Datenpakete ein 🙂

 

IPTables Alias für das .profile

Das Arbeiten unter Unix/Linux kann mitunter nervig sein, wenn man Befehle immer wiederholen muß.
Daher bieten sich alias an, die man einfach in sein .profle, oder unter bash halt ins .bash_profile, schreibt.

Bei der täglichen Spielerei mit meinen geliebten chinesischen Hackern, also der Entwicklung des Scripts aus Teil 2, waren drei alias Befehle mehr als hilfreich, die ich hier auch nicht vorenthalten möchte.

 

Anzeige welche IPs jetzt in der Blockliste stehen

Da mein Script alle 5 Minuten recht rigoros IPs auf die dynamische Blockliste setzt hab ich mich für den alias iptl entschieden, der mir sämtliche IPs anzeigt, die auf der Blockliste stehen:

Das ist nun kein Hexenwerk, erleichert die Arbeit aber ungemein 🙂

Für den Anfang recht cool, aber, daß muß ich zu meiner Schande gestehen, ab einer gewissen Anzahl von Einträgen in der dynamisch geblockten Liste, wird es schnell unübersichtlich.

Also hab ich mir gedacht, daß es doch noch recht schick wäre, wenn man nur die IPs angezeigt, die auch tatsächlich aktiv Pakete schicken.
Der Alias dafür ist iptld :

Und schon werden via iptld nur noch die „aktiven IPs“ angezeigt 🙂

 

Ein kleiner IPTables Echtzeitmonitor

IPTables in Echtzeit via alias zu monitoren ist auch eine nette Möglichkeit seinen Server im Auge zu behalten.
Daher nun ein kleiner IPTables-Monitor als alias:

IPTables SSH Brute Force blockieren – Teil 2

Im ersten Teil hatte ich ja eine recht simple Methode beschrieben, wie man BruteForce-SSH-Attacken recht simpel mit IPTables blockieren kann, ohne sich weiter um das Thema kümmern zu müßen.

In diesem Artikel wird es jetzt etwas kniffliger. Es ist zwar schön, wenn man BFAs (Brute Force Attacke) abwenden kann, die innerhalb kurzer Zeitspannen reinkommen, aber was passiert denn nun, wenn jemand gezielt dieses Zeitfenster umgeht und trotzdem zig tausende von Anfragen über einen bestimmten Zeitraum schickt ?
Meine IP-Tables config in /etc sieht zunächst einmal so aus:

Also nichts weltbewegendes. 🙂 Ich lasse SSH, HTTP, HTTPS und SMTP zu, der Rest wird gedropped.
Wie man unschwer erkennen kann, ist der BFA-Blocker aus dem ersten Teil ebenfalls Bestandteil der Basiskonfiguration von IP-Tables.

Bei einem meiner Server fiel mir nach recht kurzer Zeit auf, daß von einem chinesischen IP-Block aus versucht wurde einen verzögerten BFA über mehrere IPs und mit variablen Zeitabständen zu versuchen. Mal waren die Abstände zunächst innerhalb einer Minute, weswegen der Trick aus dem ersten Teil half. Dann hörten diese Versuche „innerhalb einer Minute“ für den gesamten IP-Block auf einmal auf. Die Chinesen schienen gemerkt zu haben, daß sie so nicht weiterkamen.

Danach kamen neue Versuche aus dem selben chinesischen IP-Block, mit variablen Zeitverzögerungen, die nun nicht mehr in den 60-Sekunden-Trick fielen.

Da mein root-Passwort größer 30 Zeichen ist und aus einer illustren Kombination aus Groß-/Kleinschreibung, Zahlen und Sonderzeichen besteht, zudem noch eine 2-Wege-Authentifizierung stattfindet, habe ich mir um das „Knacken“ meines PWs keine wirklichen Sorgen gemacht 🙂
Aber es nervt halt schon, wenn einem die Logs zugemüllt werden.

Es stand zunächst die Idee im Raum, eines von den vielen auf dem Markt verfügbaren Tools zu nutzen, aber ich vertraue auf Unix-Ebene zunächst grundsätzlich keinem Code den ich nicht selbst geschrieben habe oder innerhalb 15 Minuten verstehe. (Alte Admin-/Hacker-Krankheit).

Also was eigenes Schreiben.
Herausgekommen sind 98 Zeilen Shell-Script, die IP-Tables dynamisch, über cron gesteuert, konfigurieren 🙂
Ob diese 98 Zeilen jeder sofort innerhalb 15 Minuten versteht, kann ich nicht beurteilen, aber ich werde hier jetzt einfach zeigen wie ich vorgegangen bin und am Ende das fertige Script zum Download zur Verfügung stellen.

Mein betroffener Server läuft auf Debian GNU/Linux 7 (wheezy) und sollte daher, mal von einigen File-Locations abgesehen, als Referenz herhalten können.

Der erste Ansatz, um herauszufinden, wie man das Ganze nun dynamisch macht, ist ersteinmal herauszufinden, was man denn nicht blocken möchte ^^
Sämtliche Informationen die wir zum blocken oder nicht-blocken brauchen, finden wir unter Debian in dem File „/var/log/auth.log“.
Wenn man sich die Datei genauer anschaut, findet man darin auch Zeilen wie diese: