• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

"ssh"-Tool gesucht

monade

Newbie
Hi,

ich suche schon seit längerem ein Skript/Programm, dass mir eine Meldung aufpopt, wenn sich ein User auf meinem Rechner per ssh eingeloggt hat. Also explizit nicht sowas wie "who", bei dem ich ja selbst aktiv überprüfen kann, wer gerade online ist.

Kennt jemand etwas in die Richtung?

Merci,

monade
 

gaw

Hacker
Als schnelle Lösung ohne Programmierung eines eigenen TCP-Servers oder Wrappers lässt sich das im Polling Modus über ein Bashskript realisieren.

Ich habe mir einmal die Zeit genommmen ein bash skript zu schreiben, das als Warnmelder dient und sich meldet sobald sich Fremde auf den Rechner einloggen, ganz gleich ob über die alten rlogin-Befehle oder über ssh. Genutzt werden dabei die Befehle who, xterm. sleep und der dialog Befehl. Das ganze ist so angelegt das sich das Fenster öffnet und nach einer Weile wieder verabschiedet um zu vermeiden das der Desktop mit Warnmeldungen überschwemmt wird, falls man den Rechner für kurze Zeit verlässt. Daher wiederholen sich die Nachrichten solange wie Fremde eingeloggt sind und enden erst wenn das Programm gestoppt wird oder die Verbindung gestoppt wird beispielsweise mir rcsshd stop.

Es gibt sicher elegantere Möglichkeiten mit perl und tk. Dieses Skript soll aber gleichzeitig didaktischen Zwecken genügen und dient als Beispiel für den Umgang mit xterm, dialog, sleep und who. Es zeigt, wie sich das Problem mit klassischen bash-Befehlen lösen lässt.

foreignguard:
Code:
#!/bin/sh
# Copyright (c) 2004 gaw
#
# script using dialog, who and xterm to popup a alert box if foreign client login
if [ "$1" = "--help" -o "$1" = "-h" ]; then
        cat<<EOT

usage $0 [KEEPING_TIME] [POLLING_TIME]

$0 using "dialog", "who", "sleep" and "xterm" to pop up a alert box when a foreign client log in. It is recommandable to start this script in the background (&).

KEEPING_TIME: period (sec) the messagebox stay on the desktop 
POLLING_TIME: period (sec) after $0 is looking for foreign access

EOT
        exit
fi

if test -n "$2" ; then
        POLLING_TIME=$2
else
        POLLING_TIME=12
fi

if test -n "$1" ; then
        KEEPING_TIME=$1
else
        KEEPING_TIME=5
fi


while test 1; do
        ACCESS=`who | grep -v "\(console\)" | tr -s " " ":" | grep "(" | tr -d ")" | tr -d "("`
        for i in $ACCESS;
        do
                if test -n $i ; then
                        USER=`echo $i | cut -d ":" -f1`
                        TERMINAL=`echo $i | cut -d ":" -f2`
                        MONTH=`echo $i | cut -d ":" -f3`
                        DAY=`echo $i | cut -d ":" -f4`
                        HOUR=`echo $i | cut -d ":" -f5`
                        MINUTE=`echo $i | cut -d ":" -f6`
                        HOST=`echo $i | cut -d ":" -f7`
                        TIME="$MONTH $DAY $HOUR:$MINUTE"
                        MESSAGE="\Zb\Z1ALERT! \Zn At $TIME user $USER log in from $HOST"
                        xterm +sb -geometry 65x7 -title ALERT! -e dialog --colors --no-shadow --sleep $KEEPING_TIME --infobox "$MESSAGE" 100 100 &
                        fi
        done
        sleep $POLLING_TIME
done

Die Benutzung ist frei, jede Benutzung erfolgt aber ausdrücklich auf eigenes Risiko, für unmittelbare oder mittelbare Schäden wird jegliche Haftung auch Dritten gegenüber ausgeschlossen.

Unter Linux mit der Maus kopieren, in einen Editor kopieren und als foreignguard abspeichern.
Mit
>chmod 755 foreignguard
die entsprechenden Rechte setzen und im Hintergrund starten
>./foreignguard &

wenn einem die Verweildauer der Warnmeldung auf dem Desktop zu kurz oder zu lang erscheint oder die Abstände verändern will in denen das Skript überprüft ob sich jemand einloggt, kann er das durch die Parameter keeping time und polling time verändern.
Beispiel für 4 Sekundenwarnmeldung und erneutes Nachfragen nach 2 Sekunden:
./foreignguard 4 2


Viel Spaß beim Testen.

mfG
gaw
 
OP
M

monade

Newbie
Wow, ich bin echt baff :eek:
Toll, welche Mühe du dir gemacht hast. Leider läuft das Programm bei mir noch nicht:
~> ./foreignguard
./foreignguard: line 51: syntax error: unexpected end of file

Trotzdem besten Dank!

monade

edit: der fehler muss irgendwo beim copy und paste in der zeile mit "cat<<EOT" passieren, jedenfalls scheint es jetzt zu funktionieren. Muss nu mal testen.
 

gaw

Hacker
Probiers noch mal, es hatten sich nur zwei kleine Fehler eingeschlichen, die sind korrigiert. Das here-Dokument ist schon korrekt, es fehlten lediglich die Quotes in den Argumenten von test bei den folgenden zwei if-Abfragen. Ich hatte sie per Hand nachgetragen hatte, weil ich keine Lust hatte das gesamte Skript noch mal zu kopieren. Mal sollte es halt nicht machen. :) Das Skript habe ich nach der Korrektur noch einmal zur Kontrolle per Maus aus dem Forum in den vi fallen lassen ohne etwas zu ändern. Es sollte nun nichts mehrs schiefgehen, viel Spaß beim Testen.

gaw
 
OP
M

monade

Newbie
mmh, ok, also ich glaub das was das Programm tun soll, tut es :)
Ausnahme: es wird nicht nur angezeigt, wenn Fremde sich einloggen, sondern auch mein eigener Login wird immer aufgepoppt...

Schön wäre es natürlich noch, wenn auch angezeigt würde, wann sich jemand wieder ausgeloggt hat. Dazu müsste man aber vermutlich zwischenspeichern, wer zuletzt eingeloggt _war_ und dann abgleichen, wer nun im Moment eingeloggt ist.
Und ein letztes: wichtig wäre die Option, dass nur dann eine Anzeige aufpoppt, sobald jemand "neues" eingeloggt ist. Wenn ich das richtig sehe, popt das Fenster ja nun alle $PollingTime auf, selbst wenn niemand neues dazu gekommen ist.

Ansonsten großes Lob und dickes Dankeschön :)

monade
 

gaw

Hacker
Das war auch nur ein einfaches Beispiel wie sich dein Problem ohne allzu großen Programmieraufwand realisieren läßt. Sicher lassen sich noch unzählige Varianten diskutieren, aber schließlich ist das nur ein Forum und meine Zeit auch begrenzt. Du kannst das Skript aber gerne erweitern, wenn du möchtest. Wenn du nicht alle Verbindungen sondern nur die neuen angezeigt haben willst musst du tatsächlich zwischenspeichern und die Logik geringfügig verändern. Zum Beispiel indem du die eigentliche Arbeit in eine Funktion packst, einen Zähler mit einbaust der dann 2,3 oder 5 mal das Skript aufruft und anschließend wichtige Identifikationsmerkmale des Zugriffes in einen String oder in eine temporäre Datei ablegt. Vor Aufruf dieser Funktion überprüfst du halt ob dieser Zugriff schon abgespeichert ist. Wenn du wenig Erfahrung im Scripting besitzt empfehle ich dir vorher ein Struktogramm oder ein Flussdiagramm zu erstellen um die Logik richtig zu erfassen.

Was richtig ist dieses Skript zeigt alle login Versuche über ssh an, weil der Befehl who das in Klammern hinter dem Aufruf anzeigt. Aus Sicht von who gilt auch der ssh-Zugang vom eigenen Host als Fremdzugriff, weil dieser über eine IP 127.0.0.1 des loopback erfolgt. Allerdings ist es unüblich sich über ssh auf dem Rechner einzuloggen auf dem man sich befindet, es sei denn zu Testzwecken. Und dann ist es ebenso ganz sinnvoll das zu testen.

Es gibt natürlich noch andere Möglichkeiten, zum Beispiel mit Perl. Das geht dann aber schon in die Socketprogrammierung hinein und ist etwas aufwendiger, wenn man es vernünftig programmieren will. Dafür läßt sich das Polling aber auf Prozeßebene mit Timer wesentlich professioneller ausführen und mit TK-Widgets lassen sich die Boxen grafisch besser gestalten. Im Moment arbeite ich an verschiedenen anderen Projekten und habe leider keine Zeit dafür.


mfG
gaw
 

gaw

Hacker
ps: was mir noch einfällt. Wenn es dich stört dass das Login vom eigenen Rechner mit angezeigt wird kannst du das Skript auch erweitern indem du vorher mit Hostname und Hostname -d Rechner und Domainnamen ermittelst in Variable packst (mit backticks) und anschließend mit einer If-Abfrage überprüfst. Das ist nicht allzu schwierig und als Start in die bash-Programmierung geeignet.

mfG
gaw
 
OP
M

monade

Newbie
Das war keine Aufforderung an dich, sondern eine Bemerkung, was mir zum Einsatz dieses Programmes noch fehlen würde. :)
Ich finde es sowieso schon klasse, dass du dich hingesetzt hast um dieses "Lehrstück" zu coden.

Btw: ich meinte nicht, das mein "ssh-Zugang vom eigenen Host als Fremdzugriff" angezeigt wird. Es reicht schon, dass ich foreignguard in der konsole öffne, dann wird mir alle $PollingTime angezeigt:

Alert! At $Datum user $user log in from console

Also selbst wenn noch kein ssh im Spiel ist.

monade
 

gaw

Hacker
Das ist seltsam, bei mir nicht. Vielleicht benutzt du ein anderes who oder hast dich irgendwo vertippt. Bei mir (Suse 9.1) funktioniert es einwandfrei. Was gibt den der Befehl who aus?

mfg
gaw
 
OP
M

monade

Newbie
Folgendes gibt Who aus, wenn ich als User 1mal die Konsole öffne und dabei auch nur einen Tab offen habe:

user@meinrechner:~> who
user :0 Dec 1 00:38 (console)
user pts/0 Dec 1 00:39
user pts/1 Dec 1 00:53

ich nehme an, daran könnte es liegen...
 

gaw

Hacker
Yo, daran liegt es. Wahrscheinlich loggst du dich über einen Displaymanager ein.

Füge in die Zeile

ACCESS=`who | tr -s " " ":" | grep "(" | tr -d ")" | tr -d "("`

eine weiteres grep hinzu, so dass die Zeile so aussieht:
ACCESS=`who | grep -v \(console\) | tr -s " " ":" | grep "(" | tr -d ")" | tr -d "("`

Mein Script läuft damit. Ich kann aber leider bei mir im Augenblick nicht testen, ob deine Ausgabe gefiltert wird, weil ich dazu einen xdm einrichten müsste und ein anderes Programm im Hintergrund läuft, aber es müsste eigentlich klappen.Wenn es funktioniert melde dich, damit ich das Script oben korrigieren kann.

Ein schönes Beispiel übrigens, worin die Tücken bestehen können wenn man mit rapid shell scripting die Ausgaben von Programmen auswertet.

mfg
gaw
 

gaw

Hacker
Eine sehr einfache aber effiziente Methode sich anzeigen zu lassen wer sich wann über die ssh anmeldet, allerdings ohne popup-Fenster besteht darin den syslog für sich arbeiten zu lassen. Ändere die syslog Datei dahingehend, dass (fast) nur die ssh Aufrufe in eine spezielle Datei umgeleitet werden. Das geht so:
1. Ändern der sshd_config
Code:
# Logging
#obsoletes QuietMode and FascistLogging
SyslogFacility USER
LogLevel VERBOSE

Der LogLevel VERBOSE des ssh-Daemon zeigt etwas mehr an als der standardmäßig eingestellte LogLevel INFO. Mit SyslogFacility USER beeinflussen wir die Art der Systemmeldung. Anschließend lenken wir alle Ausgaben die USER produzieren um.

Füge diese Zeile in die /etc/syslog.conf ein
Code:
user, user.*            -/var/log/usrmessages

Anschließend starte den syslog-Daemon und den sshd neu:
deinrechner:/irgendwo # rcsyslog restart
deinrechner:/irgendwo # rcsshd restart

Jetzt kannst du ein xterm öffnen und
user@deinrechner:~>tail -f /var/log/usrmessages
eingeben. der Cursor bleibt am Ende stehen (Option -f) und wartet auf neue Einträge. Wenn du dich jetzt einloggst siehst du das sofort, viel schneller und professioneller als das ein einfaches bashscript kann, weil der syslog im Zusammenarbeit mit dem sshd sofort reagiert. Und weil der sshd im verbose Modus arbeitet sendet er auch ein Signal wenn die ssh Verbindung beendet ist.

mfG
gaw
 
OP
M

monade

Newbie
Wunderbar! Die Ausgabe wird nun tatsächlich gefiltert. Im Grunde kann ich das Skript jetzt schon einsetzten. Nochmal wirklich vielen Dank!

Dein syslog-Ansatz ist ebenfalls interessant, vielleicht probiere ich ihn mal bei Gelegenheit aus :)
 
Oben