#!/bin/bash
#-------------------------------------------------------------------------------
# fetch-dsl-ip.sh                                (C) 2003 T.Birnthaler OSTC GmbH
#-------------------------------------------------------------------------------
# IP-Adressen der DSL-Anschlüsse aus Access-Logdatei extrahieren und im privaten
# Web-Server-Verzeichnis "staff" ablegen.
#-------------------------------------------------------------------------------
# Aus Sicherheitsgründen
PATH=/bin:/usr/bin                              # Programme nur hier suchen
IFS=" \t\n"                                     # Standard-Shell-Trennzeichen
LS_OPTIONS=                                     # "ls"-Optionen aus
umask 057                                       # Gruppe/Andere einschränken

# Konstanten
SEARCH='"GET /dslcheck.html HTTP/1.0" 200'      # Exakter Suchtext
SEARCH='dslcheck.html'                          # Grober Suchtext
 USERS="office10 client01 client02"             # Gesuchte Benutzerverbindungen
 GROUP="wwwrun"                                 # Besitzer-Gruppe (ANPASSEN!)
  MODE="644"                                    # Zugriffsrechte
   TMP=$(mktemp /tmp/dslXXXXXXX) || exit 1      # Temporäre Datei (sicher!)
 INPUT="/var/www/logs/access.log"               # Eingabe-Datei (ANPASSEN!)
OUTPUT="/var/www/htdocs/staff/dsl-ip.txt"       # Ausgabe-Datei (ANPASSEN!)
 TAILS="10 50 100 500 1000 5000 10000"          # Längen ab Dateiende
   DBG=                                         # Debugmodus Aus

# Signale abfangen
trap 1 2 3 13 15 "exit 2"       # -> Signal 0 = Skript-Ende auslösen

# Temporäre Zwischen-Dateien bei Skriptende (Signal 0) automatisch löschen
trap '[ $TMP ] && rm -rf "$TMP" > /dev/null 2>&1' 0

# Debugging an?
[ "$1" = "-d" ] && DBG=1

# Test oder Produktion?
if [ "$DBG" ]
then
       TMP="/tmp/dsl-ip.txt.$$"                    # Zwischendatei
	 INPUT="./var_log_messages"                    # Eingabe-Datei
	OUTPUT="./dsl-ip.txt"                          # Ausgabe-Datei
	 TAILS="100 1000 10000 100000"                 # Längen ab Dateiende
fi

# Temp. Ausgabedatei leeren und gewünschter Benutzer(-Gruppe) zuordnen
> $TMP
chgrp $GROUP $TMP

#-------------------------------------------------------------------------------
# Über alle Namen USERS die letzten Zeilen TAILS von Logfile INPUT nach dem
# Schlüssel SEARCH durchsuchen und Datum + Uhrzeit + IP-Adresse + Loginnamen
# extrahieren. Dies für immer längere Enden von Logfile INPUT wiederholen,
# bis etwas gefunden wurde oder im max. Bereich nichts gefunden wurde.
# Ergebnis umformen und nach TMP speichern. Eingabeformat (Common Log Format):
#   212.114.236.193 - user10 [13/Oct/2004:14:42:34 +0200] "GET /dslcheck.html HTTP/1.0" 200 51
#   ^^^^^^^^^^^^^^^   ^^^^^^  ^^ ^^^ ^^^^ ^^^^^^^^
#   \1              \2     \3 \4  \5   \6
# umformen in Zwischenformat:
#   Sep 13 2004 14:42:34 212.114.236.193 user10
#   \4  \3 \5   \6       \1              \2
#-------------------------------------------------------------------------------
for USR in $USERS
do
	for TAIL in $TAILS
	do
		[ "$DBG" ] && echo "checking $USR $TAIL..."
		INFO=$(tail -$TAIL $INPUT |
			grep "$SEARCH" |
			grep "$USR" |
			sed 's@^\([0-9.]*\) - \([^ ]*\) \[\([0-9]*\)/\([A-Za-z]*\)/\([0-9]*\):\([0-9:]*\) .*$@\4 \3 \5 \6 \1 \2@' |
			tail -1)
		[ "$INFO" ] && break
	done
	if [ -z "$INFO" ]
	then
		echo "NOTFOUND $USR" >> $TMP
	else
		[ "$DBG" ] && echo "INFO=<$INFO>"
#-------------------------------------------------------------------------------
# Zwischenformat:
#   Sep 13 2004 14:42:34 212.114.236.193 user10
#   $1  $2 $3   $4       $5              $6
# umformen in Endformat:
#   20030913 14:42:34 212.114.236.193 user10
#   $3  $1$2 $4       $5              $6
#-------------------------------------------------------------------------------
		echo $INFO | awk 'BEGIN {
			# Abbildung Monatsnamen => Nummer
			mon["Jan"] = 1; mon["Feb"] =  2; mon["Mar"] =  3; mon["Apr"] =  4
			mon["May"] = 5; mon["Jun"] =  6; mon["Jul"] =  7; mon["Aug"] =  8
			mon["Sep"] = 9; mon["Oct"] = 10; mon["Nov"] = 11; mon["Dec"] = 12
		}
		{
			printf("%4d%02d%02d %s %s %s\n",
				$3, mon[$1], $2, $4, $5, $6);
		}' >> $TMP
	fi
done

# Datei OUTPUT "atomar" erzeugen
[ ! "$DBG" ] && chmod $MODE $TMP && mv $TMP $OUTPUT
[ "$DBG" ] && cat $TMP && ls -l $TMP && rm $TMP
