Dalai
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Hallo Leute, ich brauche mal wieder die Hilfe der Experten. Ich hätte gerne eine Auswertung der Samba-Logs, genauer gesagt die der Loginversuche. Mit entsprechendem Loglevel schreibt Samba diese folgendermaßen in die Logs, für jedes System (mindestens) ein Log: [2019/11/11 01:22:08.349596, 2] ../source3/auth/auth.c:305(auth_check_ntlm_password)
check_ntlm_password: authentication for user [administrator] -> [administrator] -> [administrator] succeeded
[2019/11/11 01:29:14.875027, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [administrator] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 01:47:16.628853, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [administrator] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 01:54:22.130610, 2] ../source3/auth/auth.c:305(auth_check_ntlm_password)
check_ntlm_password: authentication for user [admin] -> [administrator] -> [administrator] succeeded
[2019/11/11 01:54:48.207200, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [admin] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 17:07:52.265313, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [hans] -> [hans] FAILED with error NT_STATUS_NO_SUCH_USER (Die Leerzeilen hab ich nur wegen besserer Lesbarkeit eingefügt.) Ziel ist es, das besser lesbar zu machen, in einer Zeile nach dem Schema: [Logfile] [Zeitstempel] user [hans] -> [hans] NT_STATUS_NO_SUCH_USER , z.B. also [log.<rechnername_oder_IP>] [2019/11/11 00:00:00] user [hans] -> [hans] NT_STATUS_NO_SUCH_USER Nun dachte ich zuerst an sed , aber ich sehe keine offensichtliche Möglichkeit, nach einem Pattern - in diesem Fall 'Authentication for user.*FAILED' - zu suchen und dann die vorherige Zeile zu holen. Nur nach 'auth_check_ntlm_password' zu suchen, findet auch die erfolgreichen Logins, die aber (vorerst) nicht benötigt werden. Kann man das mit sed und/oder awk erledigen? Wenn ja, wie genau (und in verständlich 😉)? PS: System ist Ubuntu Server 14.04 (jaja, ich weiß, dass das bereits aus dem Support ist), aber das Forum ließ nur die Auswahl unterstützter Versionen zu. Grüße
Dalai
Bearbeitet von sebix: Falsche Versionsangabe entfernt und Betriebssystem im Titel ergänzt.
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4391
Wohnort: Göttingen
|
Hm, hilft Dir -b bei grep vielleicht weiter?
egrep -B 1 'Authentication for user.*FAILED' test.log
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Klar, an grep hab ich auch gedacht (mit genau diesem Weg), und zum Rausholen der Zeilen aus allen Logs ist das sicherlich als erster Schritt brauchbar, aber wie dann weiter? Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
Das geht sehr gut mit awk , aber mir fehlt gerade die Zeit konkreter zu werden.
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4391
Wohnort: Göttingen
|
Hm, wie wäre es mit so etwas?
awk '/Authentication for user.*FAILED/ { if (a && a !~/Authentication for user.*FAILED/) print a;} {a=$0;}' test.log
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
rklm schrieb: Das geht sehr gut mit awk , aber mir fehlt gerade die Zeit konkreter zu werden.
Ah, gut zu wissen, danke. Wenn du die Zeit findest, wäre es klasse, wenn du einen Ansatz posten könntest. Doc_Symbiosis schrieb: Hm, wie wäre es mit so etwas?
awk '/Authentication for user.*FAILED/ { if (a && a !~/Authentication for user.*FAILED/) print a;} {a=$0;}' test.log
Das gibt nur die jeweils erste Zeile mit dem Zeitstempel zurück. Ist auch logisch, denn wenn ich das richtig verstehe, sagt die if-Bedingung, dass er alles ausgeben soll, was nicht dem RegEx entspricht. Grüße
Dalai
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4391
Wohnort: Göttingen
|
Hm, dann verstehe ich noch nicht, was Du möchtest. Also, wenn ich den Befehl auf das von Dir angegebene Log anweden, bekomme ich folgende Ausgabe:
2019/11/11 01:29:14.875027, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
[2019/11/11 01:47:16.628853, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
[2019/11/11 01:54:48.207200, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
[2019/11/11 17:07:52.265313, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password) Das ist das jeweils genau die Zeile vor derjenigen, wo Authentication for user.*FAILED vorkommt.
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
Doc_Symbiosis schrieb: Hm, dann verstehe ich noch nicht, was Du möchtest.
Dann wiederhole ich nochmal das Wesentliche (mit Hervorhebung): Ziel ist es, das besser lesbar zu machen, in einer Zeile nach dem Schema: [Logfile] [Zeitstempel] user [hans] -> [hans] NT_STATUS_NO_SUCH_USER , z.B. also [log.<rechnername_oder_IP>] [2019/11/11 00:00:00] user [hans] -> [hans] NT_STATUS_NO_SUCH_USER
Kurz: Zusammenfassen der beiden zu einem Event gehörenden Zeilen zu einer einzelnen Zeile, nach dem oben genannten Schema. Sozusagen die Essenz der Logeinträge rausholen: Logfile, Zeitstempel und welche Nutzer probiert wurden mit welchem Ergebnis. Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
Dalai schrieb: rklm schrieb: Das geht sehr gut mit awk , aber mir fehlt gerade die Zeit konkreter zu werden.
Ah, gut zu wissen, danke. Wenn du die Zeit findest, wäre es klasse, wenn du einen Ansatz posten könntest.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | $ cat log
[2019/11/11 01:22:08.349596, 2] ../source3/auth/auth.c:305(auth_check_ntlm_password)
check_ntlm_password: authentication for user [administrator] -> [administrator] -> [administrator] succeeded
[2019/11/11 01:29:14.875027, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [administrator] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 01:47:16.628853, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [administrator] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 01:54:22.130610, 2] ../source3/auth/auth.c:305(auth_check_ntlm_password)
check_ntlm_password: authentication for user [admin] -> [administrator] -> [administrator] succeeded
[2019/11/11 01:54:48.207200, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [admin] -> [administrator] FAILED with error NT_STATUS_WRONG_PASSWORD
[2019/11/11 17:07:52.265313, 2] ../source3/auth/auth.c:315(auth_check_ntlm_password)
check_ntlm_password: Authentication for user [hans] -> [hans] FAILED with error NT_STATUS_NO_SUCH_USER
$ awk '/^\[/ {if (match($0, /^\[([0-9]{4}(\/[0-9]{2}){2} ([0-9]{2}:){2}[0-9]{2})/, matches)) time=matches[1]} /^ / {if (match($0, /[aA]uthentication for (user \[[^]]+\] -> \[[^]]+\]) (FAILED with error ([a-zA-Z_]+))?/, matches)) print "[" ARGV[ARGIND] "] [" time "] " matches[1] " " matches[3]}' log
[log] [2019/11/11 01:22:08] user [administrator] -> [administrator]
[log] [2019/11/11 01:29:14] user [administrator] -> [administrator] NT_STATUS_WRONG_PASSWORD
[log] [2019/11/11 01:47:16] user [administrator] -> [administrator] NT_STATUS_WRONG_PASSWORD
[log] [2019/11/11 01:54:22] user [admin] -> [administrator]
[log] [2019/11/11 01:54:48] user [admin] -> [administrator] NT_STATUS_WRONG_PASSWORD
[log] [2019/11/11 17:07:52] user [hans] -> [hans] NT_STATUS_NO_SUCH_USER
|
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4391
Wohnort: Göttingen
|
Also eher so etwas (den Rest des Zeitstempels müsstest Du Dir noch hinbauen, aber das hat rklm ja schön gemacht):
$egrep -B 1 'Authentication for user.*FAILED' test.log | awk '/[0-9][0-9][0-9][0-9]\/[0-9][0-9]\// {printf $1" "; next} {print $4" "$5" "$6" "$7" "$11}'
[2019/11/11 user [administrator] -> [administrator] NT_STATUS_WRONG_PASSWORD
[2019/11/11 user [administrator] -> [administrator] NT_STATUS_WRONG_PASSWORD
[2019/11/11 user [admin] -> [administrator] NT_STATUS_WRONG_PASSWORD
[2019/11/11 user [hans] -> [hans] NT_STATUS_NO_SUCH_USER Ist allerdings ganz schön hingefriggelt...
Un den Hostname müsstest Du Dir noch reinbauen...
|
Doc_Symbiosis
Anmeldungsdatum: 11. Oktober 2006
Beiträge: 4391
Wohnort: Göttingen
|
Wenn Du den Hostname noch davor haben möchtest, ginge so etwas in der Richtung:
for i in log.*; do egrep -B 1 'Authentication for user.*FAILED' $i| awk -v hostname="$i" '/[0-9][0-9][0-9][0-9]\/[0-9][0-9]\// {printf hostname" "$1" "; next} {print $4" "$5" "$6" "$7" "$11}'; done
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
rklm Was ein Monstrum von String 😮. Aber ich habe den Inhalt sogar nachvollziehen können und verstanden (auch wenn ich im ersten Moment beim RegEx fürs Datum gestutzt habe). Sogar eine Anpassung, dass nur fehlgeschlagene Logins ausgegeben werden, ist sehr einfach machbar. Dankeschön! 👍 Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
Dalai schrieb: rklm Was ein Monstrum von String 😮.
Man kann das in einem Skript natürlich schöner formatieren über mehrere Zeilen.
Aber ich habe den Inhalt sogar nachvollziehen können und verstanden (auch wenn ich im ersten Moment beim RegEx fürs Datum gestutzt habe).
Prima!
Sogar eine Anpassung, dass nur fehlgeschlagene Logins ausgegeben werden, ist sehr einfach machbar. Dankeschön! 👍
Noch besser. ☺ Ein Punkt, den ich weggelassen habe, ist die Fehlerbehandlung, also wenn z.B. der Regex für die erste Zeile nicht matched.
|
Dalai
(Themenstarter)
Anmeldungsdatum: 16. Juni 2008
Beiträge: 2316
Wohnort: Meiningen
|
rklm schrieb: Man kann das in einem Skript natürlich schöner formatieren über mehrere Zeilen.
Da das sowieso in ein Bash-Skript gepackt wurde, ist es dort über drei Zeilen verteilt. Aber ich weiß schon, dass awk-Code, insbesondere awk-Skripte, noch länger sein können (kürzlich in einem Munin-Plugin sowas gesehen).
Ein Punkt, den ich weggelassen habe, ist die Fehlerbehandlung, also wenn z.B. der Regex für die erste Zeile nicht matched.
Was meinst du genau? Die if-Bedingung prüft doch, ob es matcht, und wenn nicht, wird nach meinem Verständnis der folgende Code (mit der zweiten if-Bedingung) gar nicht weiter ausgeführt. Oder übersehe ich etwas? Ich habe den RegEx noch etwas optimiert und verändert: awk '/^\[/ {if (match($0, /^\[([0-9]{4}(\/[0-9]{2}){2} ([0-9]{2}:){2}[0-9]{2}).*auth_check_ntlm_password/, matches)) time=matches[1]}
/^ / {if (match($0, /Authentication for (user .*) FAILED with error ([a-zA-Z_]+)/, matches))
print "[" ARGV[ARGIND] "] [" time "] " matches[1] " " matches[2]}' logfiles Die Angabe auth_check_ntlm_passwort in der ersten Zeile hat die Ausführungszeit um ca. 40% reduziert (von ~8,5 auf ~5 Sekunden bei um die 400 Logdateien), weil nicht mehr jede zweite Logzeile matcht sondern nur noch die mit Loginereignissen (erfolgreich oder nicht). Und die detailierte Angabe des Usernamens habe ich verallgemeinert, sowie die Optionalität des FAILED entfernt. Danke nochmal! Das hat mir viel Kopfzerbrechen erspart, bei dem bislang nichts außer dem simplen grep-Befehl rauskam. Grüße
Dalai
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
Dalai schrieb: rklm schrieb:
Ein Punkt, den ich weggelassen habe, ist die Fehlerbehandlung, also wenn z.B. der Regex für die erste Zeile nicht matched.
Was meinst du genau? Die if-Bedingung prüft doch, ob es matcht,
Ja, aber time wird dann z.B. nicht auf einen Leerstring gesetzt.
und wenn nicht, wird nach meinem Verständnis der folgende Code (mit der zweiten if-Bedingung) gar nicht weiter ausgeführt. Oder übersehe ich etwas?
Beide if -Bedingungen sind unabhängig voneinander - also ja, Du übersiehst etwas.
Danke nochmal! Das hat mir viel Kopfzerbrechen erspart, bei dem bislang nichts außer dem simplen grep-Befehl rauskam.
Bitte.
|