Aufzeichnen von Administratortätigkeiten

Nahezu jeder Admin ist heute mit dem Problem der “Kontrollen” und “Nachweispflicht” konfrontiert. Dabei sind Changes / Changemanagement der Anfang und das komplette “Monitoring der Administratortätigkeiten” die logische Konsequenz. Dazu werden beispielsweise auf einem Terminalserver alle Sitzungen per Video aufgezeichnet. Was ich nun suchte war eine Möglichkeit die kompletten Bildschirmausgaben einer SSH Sitzung aufzuzeichnen. Damit könnten dann sämtliche Befehle … recht einfach nachvollzogen werden, bzw. sogar zur Fehlerfindung genutzt werden wenn der Admin Unsinn gemacht hat und selbst nachvollziehen möchte was er eigentlich gemacht hat.

Ob das ganze sinnvoll oder nicht ist, das soll an dieser Stelle nicht diskutiert werden. Es geht darum eine Lösung für diese Anforderung zu finden.

Ich habe lange nach einer Lösung gesucht. Die gibt es auch. Es sind die Boxen zweier Hersteller, die den kompletten ssh Traffic, teilweise sogar inklusive X11 und auch anderer Protokolle aufzeichnen. Schaut man sich jedoch die Preise für eine solche Lösung an, dann überlegt man sich doch zweimal, ob man wirklich so viel Geld dafür ausgeben möchte / muss. Eines vorweg: Die Boxen wurden von mir nicht getestet, da das ganze preislich völlig uninteressant war.

Also wurde Dr. Google bemüht und auch diverse Kollegen wurden gefragt – leider nirgendwo eine wirkliche Lösung.

Naja, wie man es so aus der Community gewöhnt ist wird sich dann eben selbst hingesetzt und versucht etwas zu “bauen”. Ganz neu erfinden musste ich das ganze nicht. Es gab – wie so schön unter Linux – schon diverse Möglichkeiten und Tools. Dabei ist eines das zentrale und wichtigste: script. Mit Hilfe von script ist es möglich z.B. Befehlsfolgen aufzuzeichnen inkl. der Ausgabe. Wobei die Ausgabe ebenfalls alls Steuerzeichen für die Ausgabe enthällt. Im Endeffekt entsteht ein “Video” der Ausgabe, welches man beispielsweise zum Support schicken kann.

Das Programm um die Aufnahmen zu erstellen und abzuspielen war also gefunden. Als nächstes musste eine Lösung gefunden werden um die Aufzeichung automatisch und auch sicher zu starten. Es bringt nur relativ wenig wenn ich von einem Benutzer erwarte einen Befehl zu starten wenn er sich anmeldet, bzw. wäre es auch ein wenig albern das ganze als bsp. SOX konformes Monitoring zu deklarieren, wenn ich einfach den Prozess beenden kann und dem entsprechend dann machen kann was ich möchte ohne dass das ganze aufgezeichnet wird. Dazu wurden diverse Schritte nötig die im folgenden Howto enthalten sind.

Prerequisites

  • jumphost (Server, über den alle ssh Zugriffe auf Server gestartet werden; dieser Host sollte der einzige sein, der Zugriff auf die Server hat (iptables, …))
  • script (normalerweise in den linux-utils Paketen enthalten)
  • das wars schon

Technische anpassungen

Anpassen der /etc/bashrc

Um den Benutzern nach der Umstellung weiterhin zu erlauben eigene alias Definitionen, bzw. Funktionen zu setzen, wird in der /etc/bashrc eine Kleinigkeit hinzugefügt:

# additional aliases to be set by the user
if [ -e /home/$USER/.bashrc_user ]; then
 . /home/$USER/.bashrc_user
fi

Dadurch kann jeder Benutzer sich in der Datei ~/.bashrc_user seine eigenen Definitionen hinterlegen.

Anpassen der ~/.bashrc

Meldet ein Benutzer sich am Jumphost an, so muss das Programm “script” automatisch gestartet werden. Dies wird über die ~/.bashrc realisiert. Diese sieht aus wie folgt:

# jumphost configuration
#
# If you want to set own alias definitions, please
# create a file .bashrc_user in your homedirectory !!
#
script -c "/bin/bash --rcfile /etc/bashrc" -f -q -t 2>/adminmon/timing/`date +%Y%m%d_%H%M%S`-$$-$USER.timing /adminmon/output/`date +%Y%m%d_%H%M%S`-$$-$USER.script
wait
exit

Verzeichnisse

Die Daten (.script, .timing) werden in eigenen Verzeichnissen gesammelt. .script in einem Verzeichnis, welches nur von root gelesen und beschrieben werden darf, und eines für die .timing Dateien auf die der Benutzer kompletten Zugriff hat. Eigentlich könnte man sagen, dass doch beide Dateien in einem Verzeichnis liegen könnten, auf die der Benutzer selbst keinen Zugriff hat – richtig. Leider funktioniert das nicht mit script. script schreibt die Bildschirmausgaben per Parameter in eine Datei – also mit den Rechten des Benutzerkontextes unter dem script gestartet wird. Die Timing Informationen werden jedoch als Ausgabe auf STDERR von script ausgegeben und umgelenkt (s. Befehl in der .bashrc) – die .timing Datei wird also mit den Rechten des Benutzers geschrieben. script wird während der Konfiguration (s.u.) die setuid root Rechte bekommen. Dadurch wird das Programm zwar vom Benutzer gestartet, allerdings mit root Rechten. Das gilt wie eben beschrieben für die Ausgabedatei der Bildschirmdaten, jedoch nicht für die Umleitung der Timing Informationen. Daher die Verzeichnisse mit den verschiedenen Rechten.

[root@machine adm32]# ls -la /adminmon/
total 20
drwxrwxrwx  4 root root 4096 Sep 25 11:05 .
drwxr-xr-x 25 root root 4096 Sep 25 11:05 ..
drwx------  2 root root 4096 Sep 25 14:22 output
drwxrwxrwx  2 root root 4096 Sep 25 14:22 timing

script setuid root

Aus oben genanntem Grund muss /usr/bin/script das setuid root Bit bekommen.

[root@machine adm32]# chmod u+s /usr/bin/script

Überwachungsscript

Das Überwachungsscript ist für die Überwachung der angemeldeten Benutzer verantwortlich. Überwachung in dem Sinne, als dass jeder Benutzer einen laufenden script Prozess besitzen muss – ansonsten wird er automatisch abgemeldet.

#!/bin/bash

# Security Script to check if all users are
# monitored by script to get typescripts of
# their doing.
#
# If a user runs a session without this, the
# user session will be terminated.
#
# Ronny Becker, 09.2009

#set -x

NOT="root bin daemon adm shutdown halt mail uucp operator ftp nobody dbus avahi mailnull smmsp nscd ntp vcsa rpc rpcuser nfsnobody sshd pcap haldaemon rpm xfs gdm"

# do a dumb loop
while [ 0 == 0 ]; do
 # get processlist
 PSDATA=`ps a -o user,tname,pid,command | sed 's/  *//'`

 # users online ?
 # to get unique users, set username = username(p)tty;
 for ACTUSER in `who | awk '{print $1$2}'`; do
  # if the user is in NOT list - continue
  if [[ $NOT =~ ${ACTUSER%pts*} ]]; then
   continue
  else
   # get proc information
   DATA=`echo "$PSDATA" | grep "pts${ACTUSER#*pts}"`
   if [[ $DATA =~ script\ -c\ /bin/bash\ --rcfile\ /etc/bashrc\ -f ]]; then
    # delete /dev/null if you want to have more logging
    echo "$ACTUSER: Proc found" > /dev/null
   else
    echo "$DATA" | while read PROCDATA; do
     if [[ $PROCDATA =~ \-bash ]]; then
      PID2KILL=`echo "$PROCDATA" | awk '{print $2}'`
      # check if proc ist running > 10 secs
      TIMEDIFF=$((`date +%s` - `stat --format=%Z /proc/${PID2KILL}`))
      if [ $TIMEDIFF -lt 5 ]; then logger -t script_security -p local0.notice "User: ${ACTUSER%pts*} Msg: lt 5 secs without"; continue; fi
      echo "Diese Session wird nun geschlossen, da die Protokollierung nicht mehr sichergestellt ist." | write ${ACTUSER%pts*}
      sleep 3
      kill -9 $PID2KILL
      logger -t script_security -p local0.warning "User: $ACTUSER Msg: User killed PID: $PID2KILL"
     fi
    done
    # delete /dev/null if you want to have more logging
    echo "$ACTUSER: No proc found" > /dev/null
   fi
  fi
 done
 sleep 5;
done

Das Script überprüft alle 5 Sekunden den Status der Benutzer und loggt eventuelle “Zwischenfälle” per syslog. Zusätzlich müssen Benutzer mind. 5 Sekunden lang im System angemeldet sein, bevor die Session geschlossen wird. Das kommt daher, dass ein Benutzer den script Befehl erst während der Anmeldung startet und ansonsten die Session beendet werden könnte bevor er wirklich angemeldet ist.

Dieses Script muss quasi immer im Hintergrund laufen (als root). Als Daemon überwacht es dann jede Session.

Hilfe von cfengine

Bei einigen der “tasks” kann cfengine gute Dienste leisten. z.B. wenn es darum geht die ~/.bashrc eines jeden Benutzers zu prüfen oder die Verzeichnissrechte unterhalb von /adminmon. Desweiteren kann cfengine prüfen ob das Überwachungsskript läuft.

Abspielen einer Aufnahme

Aufnahmen werden mit Hilfe von “scriptreplay” abgespielt.

scriptreplay 20090925_142228-8287-adm31.timing 20090925_142228-8287-adm31.script

Um eine Aufnahme während der Wiedergabe anzuhalten, genügt der Shortcut STRG+S (Pause); zum Fortfahren STRG-Q.

Noch offen

  • Cleanup Script erstellen (die zusammengehörigen .script / .timing Dateien sollten in ein .tar gepackt werden)
  • Script erstellen um größere Wartezeiten in denen nichts passiert zu minimieren. Dazu werden einfach alle Werte (z.B.) > 5 innerhalb der .timing Datei auf 5 gesetzt.

2 Responses to Aufzeichnen von Administratortätigkeiten

  1. Severin Wiedemann

    Besteht hier nicht eine gravierende Sicherheitslücke, da mittels Aufruf von /usr/bin/script (wenn dieses setuid-Rechte hat) seitens eines Benutzers ein beliebiger Befehl unter Root-Rechten ausgeführt werden kann.

    Beim Nachstellen dieser Konstellation ist mir z.B. aufgefallen, dass sich unter dem normalen Benutzer-Kontext durch den Aufruf von /usr/bin/script -c”/bin/bash” -f /etc/passwd z.B. die Datei /etc/passwd mit dem typescript überschreiben lässt und somit das System z.B. unbrauchbar gemacht werden kann…
    Vielleicht sollte man um Script einen Wrapper schreiben, der derartige Dinge unterbindet…

    • Ronny

      Hi und Uppps!

      Da hast Du Recht. Das müssen wir uns mal genauer anschauen. Solltest Du eine Idee haben, so sind wir natürlich für jeden Hinweis dankbar.
      (Hätte nicht gedacht, dass jemand in unseren Scripten auch Sicherheitslücken findet :-) )

      Gruß
      Ronny

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>