Ein MCP namens SystemD

Bunte Linien kreisen vor meinen Augen und bilden bunte Muster. Die Augen schmerzen. Der Kopf schmerzt und auch das Gehirn hat Schaden genommen. Die Welt ist dunkel, aber bunt.  Ich öffne die Augen. Ein rötlich strahlender Wächter stößt mich mit einer Energielanze an: „Aufstehen, Programm!“ Er will, daß ich mit ihm komme. Wir beschreiten Wege aus Energie… bunter Energie, seltsam neonfarbend und doch schwarz, wie die Nacht. Unterwegs treffen wir andere „Programme“ mit Ihren „Wächtern“. Bald stehe ich vor einem Kopf aus Licht: Der MCP, es gibt ihn wirklich!!!!!!

Verstört wache ich auf. Ein Computeradminalptraum, mitten am Tag, vermutlich am Keyboard eingenickt. Aber was könnte mir so einen Schrecken eingejagt haben, daß ich davon einen Tron .. ähm… traum hatte ?

Es fällt mir wieder ein, ich war grade dabei den Beitrag „Revenge of MariaDB“ Part II zu schreiben. Ja, MariaDB, was war doch gleich … achja.. ging mal wieder nicht nach dem Wechsel von F23 auf F24. Einer unserer Datenbankserver  macht merkwürdige Dinge. Die Webanwendung produzierte sporadisch „Kann nicht in die Datenbank verbinden“ Fehlermeldungen und brachte damit die QA vom Kunden an den Rand des Nervenzusammenbruchs.

Die Analyse geschaltete sich schwierig, weil die Admins immer erst nach einem Vorfall gerufen wurden, aber da ging es wieder. Erst eine zeitnahe Analyse des Netzwerkverkehrs bracht dann den ersten Hinweis: „Can’t create a new Thread. If you have enough free memory, check if … “

Damit konnte man etwas anfangen, ein Blick in eine spezielle Überwachungsdatei brachte dann den Hinweis, daß statt 40.000 Datenbankprozessen, nur wenige Hundert liefen. Also half nur ein Testlauf, mit einer Software, die Verbindungen in die Datenbank aufbaut und offen hält. Sowas kann man schnell in PHP, Perl oder Java schreiben:

import ordb.*;

public class Test {

    public static void main(String[] args) {

        Httpd[] liste = new Httpd[100000];
        for(int i=0;i< Integer.parseInt( args[0] );i++) {
            System.out.println("i="+i);
            liste[i] = new Httpd();
        }
        try {
            Thread.sleep(30000);
        } catch(Exception e) {

            e.printStackTrace();
            System.out.println(e);
        }

    }

}

In einer zweiten Konsole, kann man dann den Datenbankserver überwachen :

strace -e send,read,write -s 1024 -f -p `pidof mysqld`

Damit hat man alle Datenbankserverinstanzen im Blick, was die so Lesen und Schreiben und tatsächlich bestätigte dies den Anfangsverdacht, daß der Datenbankserver nicht genug Prozesse spawnen kann. Er setzte bei 512 Prozessen aus, viel zu wenig für unsere Anwendung.

Der schwierige Teil : Limits prüfen

Als erstes denkt man natürlich, daß sich bei den Limits aus Systemd und die Limits : The Revenge of Mariadb etwas geändert hätte, hatte es aber nicht. Wenn man das OS updatet können aber noch ganz andere Dinge passieren, also muß man hier nach „neuen“ Limits suchen.  Um überhaupt die Limits eines Prozesses Live einsehen zu können, muß man ins /proc/ eintauchen:  cat /proc/`pidof mysqld`/limits

Das kann dann so aussehen:

Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            unlimited            unlimited            bytes     
Max core file size        unlimited            unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             unlimited            unlimited            processes 
Max open files            65536                65536                files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       32195                32195                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

Dummerweise sagt dies genau, was man nicht hören will: Alles ok, es gibt keine Limits bei den Prozessen.

Und jetzt steht man da, wo zum Geier kommt dieses 512 Prozesse Limit her?

Es gibt eine Datei namens:  /etc/security/limits.conf

In der könnte man Limits für User eintragen, was aber nicht der Fall war. Außerdem wäre das in der Auflistung genau dieser Limits aufgefallen. Wo kommt dann das Limit her ?

An der Stelle muß man dann praktisch zu Denken anfangen, weil Docs lesen bringt einen fast nicht weiter, weil man gar nicht damit rechnet, daß es noch mehr Limitmöglichkeiten gibt, also auch nicht weiß in welcher Richtung man suchen sollte. Ein gesunder Pragmatismus ist jetzt hilfreich, vielleicht wars auch eine Verzweiflungstat :  grep -r 512 /etc/ /proc/sys/

Also in allen Dateien von ETC und PROC nach einer EIntragung mit 512 zu suchen. Und genau das hat zum Erfolg geführt, so daß ich jetzt eine Anklage wegen Ruhestörung und einen Abdruck meiner Hand an der Stirn habe 😀

Der SystemD macht mehr als er sollte

Im SystemD gibt es eine Konfigurationsdatei : /etc/systemd/system.conf

Der Auslieferungszustand bei Fedora ist, daß dort alle Werte auskommentiert sind, also ungültig sind. Dort fand sich eine 512 Eintragung und der Name der Option war … DefaultTasksMax=512 !

Aber die Option war abgeschaltet, also ist doch die erste Annahme, daß es kein Limit gibt, oder? Tja, Pech gehabt! Der Wert ist nur Deko, weil als Default in den SystemD einkompiliert 🙁

Zum Glück kann man den Wert in dieser Config ändern, den SystemD + MariaDB neustarten und dann wird der neue, unlimitierte Wert auch übernommen. Er taucht in keiner ( mir bekannten ) Procdatei auf. (Hinweise willkommen)

Alles in allem eine Änderung die wohl zu einer heftigen Reaktion seitens der Betroffenen geführt hat, weil die Systemd Entwickler das in einer neueren Version auf 15% der möglichen Prozesse eines Systems limitiert haben. In  unserem Fall wäre das noch schlimmer gewesen, weil wir so noch schlechter hätten Debuggen können, weil es sehr viel seltener passiert wäre.

Warum gibt es das Limit überhaupt ? Ja, weil es Bomben gibt. Das sind z.b. Bashscripte die sich selbst starten und dabei von der Shell abforken, so daß nach kurzer Zeit alle Resourcen eines Systems aufgebraucht sind. Hackt man also einen Server, könnte man den so intern dosen. Damit das nicht geht, gibt wenigstens ein Limit 😉 Das mal jemand Fedora als Server benutzt und dann auch noch als High Performance, damit hatte wohl niemand gerechnet 😀

Meiner Meinung nach, sollte sich der SystemD auf das Starten von Programmen konzentrieren, denn da ist er bedingt besser als SystemV. Aber die ganzen anderen Anmaßungen die das Teil so vornimmt, sind nicht so schön. Der SystemD kann einen echt fertig machen 😉

Ich bin mal gespannt, was beim nächsten OS Upgrade auf uns wartet 😉

PHP-CGI verbraucht zuviel Speicher

Dieser Beitrag ist aus der Kategorie:

„Was kann da schon schief gehen“

Speicher ist billig, aber doch endlich und nicht beliebig nachrüstbar.  Es kann also Situationen geben, wo man Speicher einsparen muß, weil andere der irrigen Meinung, waren, das mit dem Speicherverbrauch  wäre kein Problem.

Aber der Reihe nach:  Was ist überhaupt das Problem ?

PHP als CGI ausgeführt, verbraucht pro Start > 400 MB Speicher fürs Nichtstun.

Beispiel:  „php-cgi -a“ startet PHP ohne irgend was zu machen.

In einer zweiten Konsole läßt man sich mit pmap anzeigen, wer in dem Prozess was an Speicher belegt:

pmap {pid of process}

Beispielausgabe ( gekürzt : Warum kommt später )

[root@xxx]# pmap 5408
5408:   php-cgi -a
0000560d00b44000   3724K r-x– php-cgi
0000560d010e6000    536K r—- php-cgi
0000560d0116c000     16K rw— php-cgi

00007fce773f8000     28K r-x– libcrypt-2.23.so
00007fce773ff000   2044K —– libcrypt-2.23.so
00007fce775fe000      4K r—- libcrypt-2.23.so
00007fce775ff000      4K rw— libcrypt-2.23.so

total           420372K

Genau, 410 MB und nicht eine Anweisung ausgeführt. 3.7 MB gehen für den PHP-Interpretercode selbst drauf, ok. 2 MB gehen alleine für die libcrypt drauf.

Und jetzt der Grund wieso die Ausgabe gekürzt ist: PHP benutzt 75 Libs => ~ 160 MB Speicherverbrauch … bei jedem Script!

Bei der Analyse ist aber aufgefallen, daß auch eine Locale eingebunden wird:

-rw-r–r– 1 root root 110562112 22. Dez 12:01 /usr/lib/locale/locale-archive
-rw-r–r– 1 root root         0 22. Dez 12:01 /usr/lib/locale/locale-archive.tmpl

Auch bekannt als 107 MB und diese Datei wird in jeden PHP Prozess geladen,  der läuft. Keine Gnade.

Locale  – was sind das ?

„Locals“ sind keine Eingeborenen, sondern nur die Informationen über jene, also Zahlensysteme, Schreibrichtung, Datumsformat, Gewichte, Längen usw. . Wer mal sehen will, welche auf seinem Linux installiert sind, gibt das ein : locale -a

Da kommen Sachen von Sprachen, wo man nicht mal sagen kann, wo die passenden Länder sind 😉

Irgendwann hat Red Hat mal entschieden, daß die einfach alle Sprachen des Planeten ausliefern, weil dann der User nicht mehr machen muß. Stimmt.

Auf einem Desktopsystem ok. Aber auf einem Server ist das nicht ok und deswegen muß das auf ein gesundes Maß gedrückt werden. Das macht man mit  : /usr/sbin/build-locale-archive -v -l „de:en:ru:jp“

„Oh… geht ja gar nicht“ ????

Doch geht, aber nur mit Trick Siebzehn aus der „Erschiesst den Trottel Ecke“.

Die obige Locale-Archiv-Datei kommt mit dem Paket „glibc-all-langpacks“ auf den Server. Damit kommt aber auch ein TEMPLATE File mit, aus dem man sich genau das Archiv selbst bauen kann, wenn man eben nicht alles haben will.

Ihr habt’s erfaßt, das wäre zu einfach gewesen 🙁

Die Templatedatei ist nämlich LEER und damit nicht zu gebrauchen. Ihr Fragt Euch jetzt : „Wie bekommt man so ein Template?“ hmm.. Tja.. aus dem Repo jedenfalls nicht und doch, bekommt man. Jetzt wird es lustig, wir kopieren das vorhandene Archiv als Template für sich selbst ! Ja, richtig, mit der Faust durchs Auge: In your Face Red Hat!

Also eingegeben:

cp locale-archive locale-archive.tmpl
/usr/sbin/build-locale-archive -v -l „de:en:ru:jp“
locale -a

und schon ist das File keine 107 MB  mehr sondern nur noch 7 MB und auch das halte ich für extrem viel Schrott für 4 Sprachen. Aber jetzt lädt das php nur noch 7 MB rein. Das macht in der Endabrechnung dann 25% weniger RAM Verbrauch.

Als nächstes muß man rausfinden, wieso die Libs jeweils 2 MB verbrennen, wenn die nur 70k groß sind. Aber das ist eine andere Geschichte aus dem |-: La-La-La-Land 😐 .

 

 

Selten eindeutiger krimineller Spam

Spams unterliegen ja wie alles andere einer Mode. Heute flatterte ein richtig eindeutiger Spam ins Haus, der sich nicht eindeutiger als Spam outen lies. Besonders war nur, was damit wirklich geplant war.

Ich hatte eigentlich bei dem Betreff „for CV“ ein Bild oder ein WordDoc erwartet, daß einen Exploit enthält, aber tatsächlich kam das hier:

Dear info,

We are looking for employees working remotely.

My name is Rich, I am the personnel manager of a large International company.
Most of the work you can do from home, that is, at a distance.

Salary is $2300-$5300.

If you are interested in this offer, please visit Our Site

http://www.buildmypodcast.com/wp-content/themes/twentyfifteen/{GEHACKTEURL}.html

d_healthHave a nice day!

Spamassassin hat die Mail  extrem eindeutig als Spam erkannt. Eine Regel sticht besonders ins Auge :

 Inhaltsanalyse im Detail:   (27.5 Punkte, 5.0 benötigt) 
 Pkte Regelname              Beschreibung
 ---- ---------------------- --------------------------------------------------
...
  3.0 URI_WP_HACKED          URI for compromised WordPress site, possible malware
...
Subject: for CV

Was meint, daß die URL in der Email eine WordPress Installation ist, die vermutlich gehackt wurde.

Spamassassin lernt also auch immer dazu, und das ist gut so 😉

Der Sinn der Sache war übrigens, den Empfänger als Finanzagent für Geldwäsche anzuwerben.  Wenn Sie also sowas sehen, wie immer, aber in die Tonne damit.

Kleine Anekdote am Rande: Für eine fiktive Deutsche Firma hat mich so ein Spam auch schon erreicht. Da in dem Fall allerdings nachvollziehbare Login, Adressen usw. vorhanden waren, ging das ausnahmsweise an die Staatsanwaltschaft, statt direkt in der Tonne zu landen.