{{tag> }} ====== Weitere Linbo-Skripte ====== ==== Welche Clients sind online? ==== Um festzustlelen, welche Clients derzeit noch online sind, kann man das tool **fping** benutzen. Dafür nehme ich die workstations-Datei, filtere mit **grep** alle Zeilen heraus, die auf **0** oder **0;** enden, schneide mit **cut** die IP-Spalte heraus und gebe das Ergebnis an **fping** weiter. Der Paramter **-a** zeigt nur die IPs der Rechner, die derzeit erreichbar sind. cat /etc/linuxmuster/workstations | grep -v '0;$\|0$' | cut -d ";" -f 5 | fping -a 2> /dev/null # IP-basiert cat /etc/linuxmuster/workstations | grep -v '0;$\|0$' | cut -d ";" -f 2 | fping -a 2> /dev/null # hostbasiert ==== Feststellen des Betriebssystems ==== Man kann über das Testen offener Ports versuchen, das laufende Betriebssystems festzustellen. Das ist im allgemeinen zwar keine sichere Methode, da ich aber im Schulnetz die Dienste kenne und gezielt ein- und ausschalten kann, sollte das in der Regel eine solide Erkennung ermöglichen. Um das für das eigene Netz zu planen, kann man mit nmap $hostname verschiedene Clients auf offene bzw. geschlossene Ports untersuchen. Dies sollte relativ schnell einen geeigneten Port-Test-Plan ergeben, der zuverlässig zwischen Windows und Linux unterscheidet. Geeignete Ports sind z.B.: |**Port**|**Dienst**|**OS**| |2222|SSH|Linbo| |135|RPC-Dienst|Windows| |631|Cups|Linux| Der Befehl zum gezielten Testen eines Ports mit nmap lautet nmap 10.16.1.2 -p 22 | sed -n 6p bzw nmap hostname -p 22 | sed -n 7p **sed** filtert hier die Zeile heraus, die die Rückmeldung über den abgefragten Port enthält. Wenn man mit Hostnamen arbeitet, gibt es eine zusätzliche Zeile mit dem DNS-Eintrag, daher das **7p**. Daraus kann man nun eine einfache Bedingung bauen: nmap 10.16.1.5 -p 22 | sed -n 6p | grep -c "open" > /dev/null && echo OFFEN || echo GESCHLOSSEN Es wird also einfach gezählt (**grep -c**), wie oft das Wort "open" vorkommt - das Ergebnis ist **0** oder **1**. **&&** (und bzw. wenn) **||** (oder bzw. wenn nicht) verknüpfen den Test mit Befehlen. ==== Liste aller Räume ==== Für manche Skripte kann es hilfreich sein, sich die Liste aller Räume ausgeben zu lassen - das ist mit folgender Zeile möglich: cat /etc/linuxmuster/workstations | grep -v "0$\|0;$\" | cut -d ";" -f 1 | sed '$!N; /^\(.*\)\n\1$/!P; D' **sed** ist ein wirkliches Wunderwerkzeug - der letzte Befehl entfernt Duplikate aus der Liste. In den **grep**-Befehl kann man weitere auszuschließende Räume packen: cat /etc/linuxmuster/workstations | grep -v "0$\|0;$\|^raum1\|^raum2\|^raum7" | cut -d ";" -f 1 | sed '$!N; /^\(.*\)\n\1$/!P; D' Um diese Räume in einem Skript abzuarbeiten, kann man das Ergebnis auch in einem **Array** speichern: rooms=( $(cat /etc/linuxmuster/workstations | grep -v "0$\|0;$\|^raum1\|^raum2\|^raum7" | cut -d ";" -f 1 | sed '$!N; /^\(.*\)\n\1$/!P; D') ) echo ${rooms[@]} zeigt nun alle Räume, ein for room in $rooms ... arbeitet die Räume ab. ==== Herunterfahren von Rechnern ==== Wenn ein Rechner per ssh erreichbar ist, kann man direkt per **ssh** einen Befehl übergeben. ssh administrator@$host shutdown /t 0 /s Falls man keinen passwortlosen Zugang zu den Clients eingerichtet hat, kann man **sshpass** nutzen, um ein Passwort zu übergeben. Die Option **StrictHostKeyChecking no** verhindert bei neuen Clients den Abbruch wegen unbekanntem Hosts. Ein kompletter Befehl könnte also heißen: sshpass -p "" ssh -o "StrictHostKeyChecking no" administrator@$host shutdown /t 0 /s && echo "shutdown windows/linux on $host" Bei passwortlosem Zugang (hier z.B. Linbo) lautet der Befehl: ssh -o "StrictHostKeyChecking no" -p 2222 $host poweroff && echo "shutdown linbo on $host" Dies klappt sogar, wenn wie derzeit unter Linbo kein Login auf der Shell möglich ist. ==== linbo-remote-Probleme ==== Manchmal geht beim längeren **linbo-remote**-Aufgaben etwas schief. Da linbo-remote die **start.conf**-Dateien verändert, bleiben dann evtl. die falschen Dateien zurück und der Benutzer sieht nur ausgegraute Linbo-Buttons und kann nichts tun. Das folgende Skript behebt diese fehlerhaften Verlinkungen #/bin/bash # Zurückschreiben etwaiger Linbo-Remote-Verknüpfungen test linbo-remote -l | wc-l && exit 0 # Sicherstellen, dass kein linbo-remote mehr läuft cd /var/linbo for f in $(ls start.conf-* 2>/dev/null); do if ! [[ $(echo $f | cut -d "." -f "6") -eq "" ]]; then echo "Setze $f zurück auf $(echo $f | cut -d "." -f "1-5")" mv -f $f $(echo $f | cut -d "." -f "1-5") fi done ==== Kleine feine Einzeiler ==== Die bisherigen Überleungen lassen sich zu einem Einzeiler zusammenfassen, der alle eingeschalteten Rechner samt Betriebssystem ausgibg: for host in $(cat /etc/linuxmuster/workstations | grep -v '0;$\|0$' | cut -d ";" -f 2 | fping -a 2> /dev/null); do nmap $host -p 2222 | sed -n 7p | grep -c "open" > /dev/null && echo "Auf $host läuft LINBO" || nmap $host -p 135 | sed -n 7p | grep -c "open" > /dev/null && echo "Auf $host läuft WINDOWS" || echo "Auf $host läuft LINUX"; done; Damit lässt sich das Herunterfahren aller Rechner als Einzeiler realisieren (z.B. als abendlicher **cron-job**): for host in $(cat /etc/linuxmuster/workstations | grep -v '0;$\|0$' | cut -d ";" -f 2 | fping -a 2> /dev/null); do nmap $host -p 2222 | sed -n 7p | grep -c "open" > /dev/null && || nmap $host -p 135 | sed -n 7p | grep -c "open" > /dev/null && || ; done; Möchte man einzelne Rechner auslassen, kann man sie in den ersten grep-Befehl einbauen (z.B. **grep -v '0;$\|0$\|admin01\|backupserver'** - hier werden die Rechner **admin01** und **backupserver** ausgelassen, **\|** ist das **oder** von **grep**). Danach kann dann Raum für Raum synchronisiert werden (hier 2 Betriebssysteme): for room in ( raum1 raum2 raum3 ) do linbo-remote -r $room -w 45 -c partition,initcache,sync:1,sync:2,halt sleep 1h done ==== Ein vollständiges Synchronisations-Skript ==== Das folgende Skript lässt einzelne oder alle Räume synchronisieren und verbindet das mit ein wenig Logging - dann hat man am Morgen gleich eine Liste der Rechner, von man "nachhelfen" bzw. nachforschen muss. Für die Einschränkung auf einzelne Räume wird ein zusätzliches **grep** eingefügt, welches nach dem Raumnamen am Anfang der Zeile sucht (**grep "^"**). #!/bin/bash # Dieses Skript fährt Rechner einer Gruppe per ssh herunter, # synchronisiert danach und loggt fehlerhafte Rechner log=yosync.log logfail=yosyncfail.log echo "Log-Datei: groupsync $1 ( $(date) )" | tee $log if [ "$1" == "all" ]; then rooms=( $(cat /etc/linuxmuster/workstations | grep -v "0$\|0;$" | cut -d ";" -f 1 | sed '$!N; /^\(.*\)\n\1$/!P; D') ) else rooms=$1 fi for room in ${rooms[@]}; do echo "Shutdown $room" | tee -a $log for host in $(cat /etc/linuxmuster/workstations | grep -v '0;$\|0$' | grep "^$room" | cut -d ";" -f 2 | fping -a 2> /dev/null); do nmap $host -p 2222 | sed -n 7p | grep -c "open" > /dev/null && ssh -o "StrictHostKeyChecking no" -p 2222 $host poweroff || nmap $host -p 135 | sed -n 7p | grep -c "open" > /dev/null && sshpass -p "" ssh -o "StrictHostKeyChecking no" @$host shutdown /t 0 /s || sshpass -p "" ssh -o "StrictHostKeyChecking no" @$host shutdown /t 0 /s; done; echo "Sync $room" | tee -a $log linbo-remote -r $room -w 45 -c partition,initcache,sync:1,sync:2,halt | tee -a $log echo "--- fertig - warte eine Stunde" | tee -a $log sleep 1h done echo "ListFailCliens -> FailLog" | tee -a $log while read line; do grep $(echo $line | cut -d " " -f 1) /etc/linuxmuster/workstations | cut -d ";" -f 1-3,5) > $logfail done < <(grep "Failed" $log)