Debian: string Verarbeitung

0

Die richtige Verarbeitung von Zeichenketten die Auswertungen sehr einfach machen und einem so eine Menge Arbeit ersparen. Den Befehl cat kennt denke ich jeder. cat gibt den Inhalt einer Datei aus. Um nun alle Verbindungen aus der /var/log/mail heruaszufiltern baut sich der Befehl wiefolgt auf

cat /var/log/mail | grep connect | egrep -v '(disconnect|NOQUEUE|lost|statistics|AMAVIS)'
...
Dec 30 09:40:35 postfix/smtpd[24538]: connect from mail.starneslaw.com[66.182.161.98]
Dec 30 09:40:39 postfix/smtpd[25691]: connect from unknown[125.134.78.108]
Dec 30 09:40:50 postfix/smtpd[27354]: connect from unknown[211.201.226.142]
Dec 30 09:40:55 postfix/smtpd[24538]: connect from kcin02.prserv.net[12.154.55.42]
Dec 30 09:41:00 postfix/smtpd[24538]: connect from unknown[121.156.13.143]
Dec 30 09:41:00 postfix/smtpd[27354]: connect from unknown[58.230.121.191]
Dec 30 09:41:00 postfix/smtpd[25691]: connect from unknown[121.142.100.162]
Dec 30 09:41:04 postfix/smtpd[24538]: connect from unknown[211.201.226.142]
...

Als erstes werden alle Zeilen entfernt, die kein connect enthalten. Anschließend beschränken wir das Ergebniss auf alle unknwon Verbindungen. Danach werden alle Zeilen ausgeschlossen (egrep -v) die ein disconnect, NOQUEUE, lost, statistics oder AMAVIS enthalten. Dafür nutzt man am besten egrep. Es ermöglicht einem mehrere Ausdrücke gleichzeitig zu filtern.

Nun brauche wir für eine spätere Verarbeitung Dec 30 12:12:07 postfix/smtpd[7355]: connect from  ja nicht. Also schmeißen wir das auch noch raus:

cat /var/log/mail | grep connect | egrep -v '(disconnect|NOQUEUE|lost|statistics|AMAVIS)' | awk '{print $8}'
...
segment-210-214-208-27.maa.sify.net[210.214.208.27]
unknown[218.156.133.82]
unknown[125.135.163.139]
unknown[211.53.153.229]
kcin04.prserv.net[12.154.55.44]
segment-210-214-208-27.maa.sify.net[210.214.208.27]
bzq-84-110-234-48.red.bezeqint.net[84.110.234.48]
70-241-254-162.ded.swbell.net[70.241.254.162]
nat-tar.aster.pl[212.76.37.138]
...

Um evtl. Leerzeilen zu entfernen kann der Befehl um sed erweitert werden:

cat /var/log/mail | grep connect | egrep -v '(disconnect|NOQUEUE|lost|statistics|AMAVIS)' | awk '{print $8}' | sed '/^$/d'

Nun trennen wir Hostname und IP voneinander. Dazu nutzen wir als erstes das Zeichen „]“ als Trenner und geben vom Ergebniss das erste Feld aus. Anshließend splitten wir den String und nutzen als Trenner „[“ und drehen die daraus resultierenden Felder um. Somit erhalten wir zuerst die IP und anschließend den Hostnamen:

cat /var/log/mail | grep connect | egrep -v '(disconnect|NOQUEUE|lost|statistics|AMAVIS)' | awk '{print $8}' | sed '/^$/d' | cut -d "]" -f 1 | awk '{split($0, feld,"[");print (feld[2], feld[1])}'
...
83.10.101.155 ackz155.neoplus.adsl.tpnet.pl
190.42.160.111 unknown
217.97.0.138 unknown
76.65.207.228 TOROON63-1279381476.sdsl.bell.ca
190.42.160.111 unknown
125.142.21.109 unknown
81.215.129.76 unknown
209.85.132.190 an-out-0910.google.com
117.6.43.47 unknown
63.199.244.21 adsl-63-199-244-21.dsl.sndg02.pacbell.net
123.23.213.103 unknown
190.42.160.111 unknown
125.142.21.109 unknown
...

Jetzt das ganze noch zusammen fassen, welche IP wie oft eine Verbindung aufgebaut hat. Dazu fassen wir die Auflistung der IP Adressen zusammen (uniq -c) und sortieren das Ergebniss anschließend Nummerisch (-n) und drehen das Ergebniss um, damit die größere Zahl an Treffern ob steht (-r):

cat /var/log/mail | grep connect | egrep -v '(disconnect|NOQUEUE|lost|statistics|AMAVIS)' | awk '{print $8}' | sed '/^$/d' | cut -d "]" -f 1 | awk '{split($0, feld,"[");print (feld[2], feld[1])}' |uniq -c | sort -nr
...
     16 200.104.157.159 pc-159-157-104-200.cm.vtr.net
     14 83.29.113.172 brt172.neoplus.adsl.tpnet.pl
     14 83.23.109.85 def85.neoplus.adsl.tpnet.pl
     14 190.48.225.8 unknown
     11 203.130.67.59 unknown
     10 124.91.67.238 unknown
      9 84.55.207.195 unknown
      9 72.79.178.212 pool-72-79-178-212.sctnpa.east.verizon.net
...

Datei Zeilenweise verarbeiten

Was auch noch ganz interessant ist, ist Zeilenweise Verarbeitung einer Datei. Dazu wird in folgendem Beispiel eine Datei mit IP Adressen von Hosts erstellt, die sich über SMTP mit dem Server verbunden haben. Anschließend wird für jede IP Adresse in dieser Datei der PTR über dig abgefragt. Sollten mehr als 1 PTR zurück gegeben werden, wird nur der erste ausgegeben.

#/bin/bash
connect_ip=$(cat /var/log/mail | grep connect | egrep -v '(disconnect|lost|client|NOQUEUE)' | awk '{print $8}' |cut -d "[" -f 2 | cut -d "]" -f 1)
cat $connect_ip |while read line
do
   mail_PTR=$(dig +short -x $mail_IP | tr "n" " " |awk '{print $1}');
   sleep 0.25
done;
Teilen.

Über den Autor

Seit der Ausbildung zum Fachinformatiker Systemintegration (2002-2005) bei der DaimlerChrysler AG, beruflich im Bereich der E-Mail Kommunikation (Exchange, Linux) sowie des ActiveDirectory, mit entsprechenden Zertifizierungen (MCSE 2003, MCITP Ent.-Admin 2008, MCSE 2012, LPIC 1-3) tätig. Abgeschlossenes Studium zum Master of Science der IT-Management an der FOM sowie zertifizierter Datenschutzbeauftragter. Aktuell im Projektmanagement tätig.

Antworten