Redhat patcht 6 Monate nach Fedora

Wer heute die Patchnotes der CERTs verfolgt hat, wird dort eine Warnung für BASH finden, die vom Redhat Security Team stammt.

Betroffene Software:

  Bash
  

Betroffene Plattformen:

  Red Hat Enterprise Linux Desktop 6
  Red Hat Enterprise Linux HPC Node 6
  Red Hat Enterprise Linux Server 6
  Red Hat Enterprise Linux Workstation 6
  
Mehrere Schwachstellen in GNU Bash ermöglichen einem lokalen, nicht
authentisierten Angreifer die Ausführung beliebigen Programmcodes, auch mit
Administratorrechten, sowie das Umgehen von Sicherheitsvorkehrungen u.a. mit
der Folge eines Denial-of-Service (DoS)-Zustandes.

Red Hat stellt für die Red Hat Enterprise Linux 6 Produkte Server, Desktop,
Workstation und HPC Node Sicherheitsupdates bereit.

Patch:

  Red Hat Security Advisory RHSA-2017:0725

  <http://rhn.redhat.com/errata/RHSA-2017-0725.html>

Da es sich hier um eine aus meiner Sicht problematische Sicherheitslücke handelt, ist es unverständlich, wieso RedHat 6 Monate gewartet hat. Fedora, daß ja im Prinzip vom selben Team mit betreut wird, hatte den Patch bereits im September 2016 eingepflegt:

* Fr Sep 30 2016 Siteshwar Vashisht <svashisht@redhat.com> - 4.3.42-7
- CVE-2016-7543: Fix for arbitrary code execution via SHELLOPTS+PS4 variables
  Resolves: #1379634

* Mi Sep 21 2016 David Kaspar [Dee'Kej] <dkaspar@redhat.com> - 4.3.42-6
- CVE-2016-0634 - Fix for arbitrary code execution via malicious hostname
  Resolves: #1377614

Für mich erschreckend daran, daß die Lücke auch nur als Moderate geführt wird, obwohl man mit Hilfe eines DHCP Servers Code auf einem Computer ausführen kann. Einen Rouge DHCP Server in ein Netz zu bringen ist nachdem man einen Computer übernommen hat, nicht mehr so schwer. Da die meisten Netze via DHCP gemanaged werden, reagieren natürlich auch praktische alle Rechner im Netz auf so einen Angriff. Um so mehr ist es unverständlich, wie es sechs Monate gedauert hat, bis der Patch endlich erstellt wurde.

Und dabei hatte ich vor, die Linux Distributionen für Ihre zügigen Updates zu loben, was zumindest bei Fedora stimmt.

Wie man rausbekommt, wer ausgeswappt wurde

Wir kennen es alle, Zig GB Ram in Hardware verbaut und die Kiste swappt trotzdem. Da will man irgendwann wissen, wer/welcher Prozess dafür verantwortlich ist. Aber der Reihe nach:

Was ist „Swappen“ ?

Dazu müssen wir erstmal wissen, was virtuelles Ram ist. Physikalisches Ram kann sich sicher jeder vorstellen, das kann man als Baustein in die Hand nehmen 😉 Selbiges ist z.b. 10 GB groß ( siehe unten / nicht fragen ist ne VM )

top - 16:26:05 up 17:16,  1 user,  load average: 0,75, 0,56, 0,53
Tasks: 413 total,   1 running, 411 sleeping,   0 stopped,   1 zombie
%Cpu(s):  8,3 us,  4,0 sy,  0,0 ni, 86,5 id,  0,4 wa,  0,4 hi,  0,1 si,  0,2 st
KiB Mem : 10264728 total,   563348 free,  3256528 used,  6444852 buff/cache
KiB Swap:  1048572 total,   739584 free,   308988 used.  6788296 avail Mem

d.b. „physikalisch“ stehen allen Programmen zusammen maximal 10 GB Hauptspeicher zur Verfügung, mit dem sie auskommen müssen. Wenn alle RAM Speicherzellen benutzt werden und jemand will mehr Speicher haben, gibt es einen OOM Error : Out Of Memory! und die Aktion schlägt fehl, was Programme üblicherweise übel nehmen und die weitere Zusammenarbeit verweigern. Soweit, so klar.

Jetzt gibt es aber Programmierer, die mehr Speicher anfordern, als ihre Anwendung braucht. Der RAM wird „nutzlos“ belegt und steht anderen Programmen nicht zur Verfügung. Entweder müßte man GB weise Ram nachrüsten, oder man tut nur so als wenn man Speicher hätte 🙂

Virtueller Speicher

Auch VMEM genannt, ist nichts anderes als die Illusion, daß man mehr Speicher hat, als man hat. Technisch gesehen ist, das einfach: Bevor ein Programm nichts in den Speicher, den es anforderte, geschrieben hat, muß es den Speicher nicht wirklich geben. Man kann dem Programm einfach sagen, daß seine Anforderung nach 10 TB Ram erfolgreich war. Solange es die 10 TB nie benutzt, ist alles ok.

Wird von dem Programm etwas in seinen Speicherbereich geschrieben, so merkt dies das OS und kann den Speicherblock tatsächlich physikalisch machen. Eine MMU ( Memory Management Unit ) in der CPU macht das. Die mapped nämlich den echten Physikalischen Speicherbereich in den Virtuellen Speicherbereich, so daß die Schreibzugriffe an Adressen gehen, die es nicht wirklich gibt, aber so umgebogen werden, daß sie an der richtigen Stelle landen, alles hardwaremäßig.

Das klappt solange, wie der real genutzte Speicher kleiner ist, als die Menge verbauten Hauptspeichers.

Der Notfall: Einen OOM verhindern.

Kurz vor dem Punkt, wo das System keinen Speicher mehr hätte, wird geprüft, wann einzelne Speicherbereiche das letzte mal gelesen oder geschrieben wurden. Wenig verwundernd stellt man dann fest, daß es Speicherblöcke gibt, die in letzter Zeit nicht benutzt wurden.

Idee: Die könnte ich doch irgendwo in einem langsamen Speichermedium mit viel Platz auslagern, oder ? Gedacht, getan: Das Swappen wurde aktiviert und meint, daß bei Speichermangel ungenutzte Teile auf die Festplatte geschrieben werden und andere Teile, die dort schon lagen, wieder eingelesen werden. Man tauscht(swap) also die aktiven und inaktiven Speicherbereiche mit Hilfe der Platte aus.

Swappen

Dieser Vorgang heißt „swappen“. Es wird also ständig auf die Platte geschrieben und davon gelesen. Das hört sich erstmal nicht nach einem Problem an. Ist es aber, weil wenn soviel verschiedenes RAM ständig geswappt wird, wird das System langsam, schliesslich muß man warten bis dieser Vorgang vorbei ist. Wenn es langsam wird, stauen sich die Prozess: Die Load/Last steigt.

Die Idee beim Swapspeicher ist, daß man lange ungenutzte Speicherblöcke auslagert und die auch nicht gleich wieder benutzt werden. Auf einem Desktoprechner ist der Klassiker, daß der Speicher frei ist, bis Photoshop ein 50MP Bild lädt. Das geht vielleicht noch ins RAM, aber Browser, Mailprogramm, Kalender usw. nicht mehr. Da man aber gerade mit Photoshop arbeitet, ist das auch nicht schlimm, denn es ist nicht zu erwarten, daß ich vor Beendigung der aktiven Aufgabe von Photoshop eins der anderen Programme brauche. I.d.R. klappt das auch. Das führt zur irrigen Annahme, daß viel Swapspeicher = „total geile Sache“ ist.

Auf einem Server ist das etwas anderes. Da kann man nicht wirklich vorhersehen, wann ein Dienst gebraucht wird und da ist swappen zu vermeiden. Weil wenn viel Swapspeicher vorhanden ist, dauert es auch entsprechend lange, bis der voll beschrieben oder gelesen ist. d.h. der Rechner steht praktisch, nur weil er Speicher auf die Platte schreibt.

Auf einem Server ist es deutlich cleverer, wenig Swapspeicher zu haben, damit tatsächlich ein OOM entsteht, wenn es nötig ist. Kleinere temporäre Swaps sollten aber möglich bleiben. Deswegen ist der Swapspeicher im Beispiel oben auch nur 1 GB groß. Die Regel, daß der Swap 50% vom Hauptspeicher groß sein sollte, war im MB Bereich charmant, mit GB aber nicht mehr ganz so gut.

Wie verhindert man das Swappen ?

Mal davon abgesehen, daß man das Abschalten und auch das Verhalten des Swappens im Kernel beeinflussen kann, wäre es viel cleverer den Grund für das Swappen zu finden und das geht nur, wenn man weiß wer gerade geswappt wird.

Bevor die Kommentare losgehen: Das Programm, dessen Speicher auf dem Swapspeicher landet, muß nicht jenes sein, daß zuviel RAM wollte. Aber es ist das Programm auf das man am ehesten verzichten kann 😉 Das es überhaupt im Swap gelandet ist, beweist, daß es nicht aktiv war/ist und deswegen müßte man mal nachdenken, ob man es überhaupt braucht. Dazu muß man aber erstmal wissen, wer da gelandet ist.

SMEM – die Speicheranzeige

SMEM ist ein Tool, daß man sich per DNF nachinstallieren muß. Es produziert so eine Map :

  PID User     Command                         Swap      USS      PSS      RSS 
  557 root     /sbin/rngd -f                    156        4        7     1292 
  752 root     /sbin/agetty --noclear tty1      128        4       12     1692 
  753 root     /sbin/agetty --keep-baud 11      152        4       35     2184 
 1690 mailman  /usr/bin/python /usr/lib/ma    30000        4       51     1676 
  614 root     /usr/sbin/atd -f                 180       52       66     2104 
18675 root     sleep 60                           0       80       97     1312 
19506 root     sleep 30s                          0       84      126     1736 
 1467 samba    /usr/sbin/smbd                  2048       16      323     2868 
 9514 50779    dovecot/imap                       0      312      340     3828 
 1659 nobody   proftpd: (accepting connect     2076      144      349     2148 
12494 root     dovecot/log                        0      348      355     2544

In der Liste kann man schön sehen, daß Mailman schön hervor sticht. Mailman ist ein Mailinglistenmanager. Den braucht man nur ganz selten. Da müßte man mal über einen Umzug nachdenken. Die Liste oben ist natürlich nur ein Auszug und wenig aussagekräftig. Im weiteren Verlauf tauchte Mailman dann entsprechend oft auf.

Hinweis: DAS ein Programm mal den einen oder anderen Block ausgelagert bekommen hat, ist nicht weiter dramatisch. Das gibts öfter und ist auch kein Problem, weil diese Teile üblicherweise nur beim Start wichtig waren und später einfach nicht mehr benutzt werden.

Wenn man den Verursacher des Speicherverbrauchs sucht, geht man anders vor:

watch -n 1 „top -c -b -n >> /tmp/memory.log“  oder watch -n 1 „smem >> /tmp/memory.log“

Wobei im Einzelfall „-n 1“ vielleicht ein bisschen zu oft ist und man jede Menge ungewollte IO generiert. Da müßt Ihr etwas auf Eure Bedürfnisse achten.

Aus der Ausgabe kann man dann mit AWK den Namen des Programms, den Speicherverbrauch und den Zeitpunkt ermitteln. Ein bisschen Bashmagie und man bekommt schnell mit, wer der Verursacher ist.

Kleines Beispiel auf dem Weg zum eigenen Terminal :

# smem | grep -E " [0-9]{6,} "
3983 root     spamd chil                         0    42344    47397   104600
8016 root     spamd chil                         0    44636    49667   106744
3937 root     spamd chil                         0    44924    49907   106584
4158 root     spamd chil                         0    45352    50354   107176
2033 exim     /usr/sbin/clamd -c /etc/cla      772   497848   498045   501436
14335 mysql   /usr/libexec/mysqld --based        0   853144   853421   858820
4269 nobody   java server/Server                 0  1175172  1175819  1179580

Das gibt einem nur die Zeilen aus, in denen mehr als fünfstellige Zahlen vorkommen, weil den Kleinkram suchen wir ja nicht.

In dem Beispiel oben lohnt sich der Blick auf den Clam AntiVirusprozess clamd. Der verbraucht mittlerweile 750MB RAM nur durch den Start und der größte Block davon ist meistens unbenutzt. Clamd bietet sich als Ziel der Aktion auch deswegen an, weil er netzwerkfähig ist. Man kann also leicht einen zweiten Server aufbauen, der nur Clamd laufen hat und zu dem alle anderen Server hingehen und Ihre Mails auf Viren checken lassen.

So bräuchte man die 750 MB nicht mehr auf jedem Mailserver verbraten, sondern nur einmal. Natürlich setzt das voraus, daß der Server mit dem Clamd auch schnell etwaige Anfragen beantwortet. Aber das ist ein anderes Thema.

RPM: wie man zusätzliche alte/neue Kernels installiert

Wer Linux benutzt, wird früher oder später mal einen alten Kernel benutzen müssen. Sei es, weil im neuen ein Treiber fehlt, oder obskure Dinge passieren, wo man den Stand von letzter Woche nochmal austesten muß, z.b. als Vergleichsbasis.

Normalerweise behält Fedora die letzten 3 Kernels auf der Platte, besonders der laufende Kernel wird nie gelöscht. Nur, wenn so ein Problem erst Tage später bemerkt wird, kann es sein, daß der alte Kernel weg ist.

Wenn man dann einen alten Kernel gefunden hat, dazu gibt es diverse Möglichkeiten, und man installiert das Paket mit DNF, dann geht das nicht, weil es veraltet ist. Die meisten greifen dann auf RPM direkt zurück, was richtig ist. Wenn man das allerdings als Update einspielt, sind plötzlich alle neueren Kernels weg 🙂

Der richtige Befehl dazu lautet: rpm -ivh –oldpackage …/kernel-der-wahl-*rpm

Falls man es doch schon verbockt hatte, einfach mit DNF den neuesten Kernel wieder installieren 😉