Johannes Truschnigg - SRE & DevOps


Zur Suche ▼Zum Archiv ▼

Eintrag von 2011-09-26

GNU screen als Systemmonitor für ungenutzte ttys


Fast jeder GNU/Linux-Anwender hat schon einmal mit einem Linux VT (Virtual Terminal) zu tun gehabt: das sind jene durch den Kernel emulierten Terminals, die man durch Drücken von [CTRL]+[ALT]+[F1]...[F12] erreichen kann. Auf manchen dieser auch ttys genannten Bildschirme kann man sich in eine Shell einloggen, auf anderen ist Debug- und Log-Output zu sehen, und auf wieder anderen läuft (zumindest auf Desktop-Maschinen) zumeist das lokale Display eines X-Servers. Die Details sind, wie so oft, distributionsspezifisch.

Unter Debian GNU/Linux werden diese ttys (und was in ihnen direkt nach dem Hochfahren läuft) durch /sbin/init (aus dem Paket sysvinit) verwaltet. In der Standardkonfiguration ist das Setup wenig abwechslungsreich: die ttys 1 bis 6 starten das Programm getty(8), das - sofern man es nicht per Startparameter anders anweist - /bin/login startet. Um den Rest (den konkreten Anmeldevorgang am System unter der Nutzeridentität XY) kuemmert sich dann das PAM-Subsystem.

Meiner Erfahrung nach ist diese Vorbelegung der Linux-VTs reichlich sinnlos: auf Desktops braucht man sie vorwiegend dann, wenn der X-Server des lokalen Displays abstuerzt, und auf Servern arbeitet man im Regelfall ohnehin via ssh(1). In virtualisierten Umgebungen kommt man manchmal in die Verlegenheit, direkt mit einem VT eines Gastsystems zu interagieren, wenn der Gast (vielleicht durch eine irrtümliche Fehlkonfiguration) selbst vom Netzwerk getrennt ist, der Hypervisor-Host (der auch Input- und Output-Geräte für die Gastsysteme emuliert) aber sowohl auf das Netzwerk, als auch auf die virtuelle Tastatur und den virtuellen VGA-Ausgang des Gastsystem Zugriff nehmen kann.

Gründe also, die vielleicht einen oder zwei derart belegte und auf Login-Versuche wartende VTs in Multiuser-Runlevels rechtfertigen, aber wohl nicht gleich sechs an der Zahl. Vor allem der nach dem Bootvorgang sichtbare VT kann meines Erachtens sinnvoller genutzt werden: als Systemmonitor. Zur übersichtlichen Aufteilung des durch Linux emulierten Terminals kann man auf das mächtige GNU screen(1) zurückgreifen: dieser Terminal-Multiplexer ermöglicht es unter anderem, den Anzeigebereich vertikal und hortizontal zu splitten, und in die resultierenden Partitionen einzelne CLI- oder TUI-Programme zu packen - eine Art Tiling Window Manager für Terminals, auch wenn sich eben diese Familie von Fensterverwaltungsprogrammen fuer X11 das Konzept von screen abgeschaut hat, und nicht etwa umgekehrt.

GNU screen kann diese Aufteilungstricks sowohl interaktiv (zur Laufzeit) als auch durch eine Konfigurationsdatei, die screenrc, vorbestimmen lassen. Um den verfügbaren Platz im Terminal in vier Panele (eine 2x2-Konfiguration) aufzuteilen und darin einige nützliche Informationen über den Systemstatus anzuzeigen, kann man sich folgender screenrc behelfen:

shell /bin/true
autodetach on
defutf8 on
startup_message off
caption string "%{= kg}=/\\= %t =/\\="
defwrap off

screen /usr/bin/top
title "CPU, Memory"

split
split -v
focus down

screen /usr/bin/iotop
title "I/O Throughput"

focus down

screen /usr/bin/watch -t -d -n5 "/bin/df"
title "Filesystem Status"

split -v
focus down

screen /usr/bin/watch -t "dmesg | nl | tail -n15"
title "Kernel Messages"

Ausprobieren kann man diese Konfiguration, indem man sie unter einem (beliebigen) Dateinamen speichert, und den Pfad zu dieser als Argument zur Option "-c" von screen anführt, z. B. also so: `screen -c /usr/local/etc/screenrc_sysmon`. Zu beachten ist dabei, dass die durch die Konfiguration referenzierten, zu startenden Programme im System unter den jeweiligen Pfaden installiert sein müssen, da es sonst zu (harmlosen) Fehlern kommt.

Die oben notierte Konfiguration hat noch einen Schönheitsfehler: Sie kann zur Laufzeit verändert bzw. beschädigt werden. Um dies zu verhindern, kann man sich zweier Kniffe behelfen:

  1. Abschalten der Escape-Sequenz
  2. Setzen restriktiver screen-ACLs

GNU screen verwendet eine sogenannte "Escape-Sequenz" - eine spezielle Tastenfolge mit besonderer Bedeutung - um das Verhalten des Programms zur Laufzeit steuern zu können. Indem man diese auf den leeren String "" setzt und damit abschaltet, verhindert man, dass Benutzer auf die durch die Konfigurationsdatei definierten screen-Session-Parameter Einfluss nehmen können. Dies erreicht man durch das folgende (zusätzliche) Statement in der Konfigurationsdatei:

escape ""

Nun gilt es noch, dem Benutzer die Einflussnahme auf in der screen-Session laufende Programme zu verwehren. Der Prozess- und CPU-Last-Monitor `top` z. B. könnte durch Drücken der Taste [Q] beendet werden, was es zu verhindern gilt. GNU screen beherrscht (aus vielerlei Gründen, aber einer der wichtigsten und treibendsten für die Umsetzung dieses Features war wohl die verlockende Vision von Mehrspieler-Nethack-Sessions!) einen Mehrnutzer-Modus, in dem sich zeitgleich mehr als ein Nutzer auf eine screen-Session verbinden können. Ein derartiger Mechanismus schreit natürlich förmlich nach einem Berechtigungssystem (sodass z. B. User A auf Screen 1 vollzugriff hat, User B aber nur lesen darf), welches GNU screen selbstverständlich in Form von Access Control Lists (ACLs) bietet. DIe folgenden drei zusätzlichen Konfigurationszeilen aktivieren den Multi-User-Modus, und entfernen die "write" und "execute"-Berechtigungen für alle Screens in dieser Session von allen Usern:

multiuser on
aclchg * -w "#"
aclchg * -x "#"

Seitens screen ist das schon alles - möchte man aber tatsächlich einen VT als Anzeige für einen derart konfigurierten screen gebrauchen, fehlt noch ein Puzzlestein: Linux VTs haben die (für diesen konkreten Anwendungsfall) unangenehme Angewohnheit, DPMS zu aktivieren, und angebundene Anzeigegeräte nach einigen Minuten in den Standby-Modus zu schicken. Vor allem in virtualisierten Umgebungen ist das (in Abwesenheit eines physischen Monitors) eher schädlich als hilfreich, da man so ohne den Einsatz einer seriellen Konsole nach Ablauf des Standby-Zeitlimits nicht mehr an potenziell hilfreiche Fehlermeldungen im Falle eines Kernel Panics kommt. Auch für unseren GNU screen-Systemmonitor ist dieses Verhalten mehr lästig als nützlich, weswegen wir - gemeinsam mit dem Start der vorkonfigurierten screen-Session - in ein kleines Hilfsprogramm packen:

#!/bin/sh
export TERM=linux
/bin/echo -ne "\033[9;0]"
/usr/bin/setterm -powerdown 0
/usr/bin/screen -c /usr/local/etc/screenrc_sysmon

Das obige Beispiel impliziert natürlich, dass die vorhin erstellte screenrc unter dem Pfadnamen "/usr/local/etc/screenrc_sysmon" abgespeichert wurde. Das Shellscript oben speichert man z. B. unter "/usr/local/bin/sysmon-screen" und setzt die Executable-Permissions darauf. Nun kann man sich daran machen, die konfigurierte Instanz von getty auf dem ersten Linux-VT durch dieses kleine Shellscript zu ersetzen. Dazu muss man unter Debian die Datei "/etc/inittab" ändern, konkret mindestens einen jener Einträge, die den regulären Ausdruck /^[0-6]:/ matchen. Die Änderungen im Detail zu beschreiben ist etwas länglich, weswegen ich einfach einen kleinen patch(1) hier anhänge, aus dem man die notwendigen Eingriffe ableiten kann:

--- a/inittab
+++ b/inittab
@@ -53,5 +53,6 @@
 #
 -1:2345:respawn:/sbin/getty 38400 tty1
 -2:23:respawn:/sbin/getty 38400 tty2
 -3:23:respawn:/sbin/getty 38400 tty3
 +
 +#1:2345:respawn:/sbin/getty 38400 tty1
 +2:23:respawn:/usr/local/bin/sysmon-screen
 +3:2345:respawn:/sbin/getty 38400 tty3
  4:23:respawn:/sbin/getty 38400 tty4

Wer die Konfigurationsdateien aus den obigen Ausführungen lieber herunterlädt anstatt sie selbst händisch zusammenzukopieren, der findet Kopien davon hier:

direkter Link ▲

© 2007-2019 Johannes Truschnigg | valid xhmtl & css