Feb 12 2010

Skript: Netzwerkinterface neustarten

Ich hatte eine Debian etch Maschine, virtualisiert mit KVM, bei der brach unter Last immer die Netzwerkverbindung zusammen. Reproduzierbar. Das Update auf Lenny brachte nix. Ich habe die Maschine gestern mit Lenny neu aufgesetzt und die Probleme existieren nicht mehr. Hier nun das Skript was ueberprueft ob eine Verbindung nach aussen moeglich ist und ggfs. das Interface neustartet, ich brauche es nicht mehr, aber bevor ich es loesche hier noch einmal dokumentiert:

#!/bin/bash
##
#  check if network is available and if not restart
#  the network interface
##
 
if ping -c 1 -w 1 -q www.google.de &>/dev/null; then
#  echo "Network is up, no further action required"
  echo ""&>/dev/null
else
  echo "Network is down, restarting the interface..."
  ifdown eth0 && ifup eth0
 fi

Nov 8 2009

Wann is noch der naechste routinemaessige fsck?

Einige von euch kennen sicherlich das Problem: Ein wichtiges Kernelupdate zwingt zum Reboot der Serverinfrastruktur. Per SSH wird das Update eingespielt und ein Reboot abgesetzt, aber nicht alle Server koennen ueber DRAC-Karten oder Web-KVM ueberwacht werden. Von Zeit zu Zeit bleibt einem das Herz dann stehen wenn ein Server nicht wiederkommt, die Pings kommen zurueck mit einem “Destiniation or Host unreachable” oder vergleichbar…
Waerend man seine Jacke anzieht, Schuhe zubindet und parallel dazu fieberhaft ueberlegt was das Problem sein koennte und was da schiefgelaufen ist, schweift auf dem Weg zur Wohnungstuer noch ein letzter Blick zum Monitor und genau in dem Moment geht dann doch gerade der so herbeigesehnte erste Ping durch. Man rennt an den Rechner zurueck, loggt sich per SSH ein, ueberprueft das alles laeuft und waerend der Adrenalinspiegel sinkt kommt einem in den Sinn, dass das nur ein routinemaessiger Dateisystemcheck gewesen sein wird…

Wann der naechste check ausgefuehrt wird, kann man leicht mit dumpe2fs herausfinden. Bin ich aber ehrlich gesagt zu faul zu und vergesse ich auch jedes mal. Darum habe ich mir (nach einem entsprechenden Herzstillstand) ein kleines Skript geschrieben mit dem Namen nextfscheck, was ich unter /usr/local/sbin/ abgelegt habe und das ich vor einem Reboot aufrufen kann um zu wissen ob es einen fsck geben wird oder nicht. Das Skript ist simpel, das Skript ist billig. Als Parameter wird ein gueltiges gemountetes Device angegeben und dann bekomme ich die Info wieviele remounts noch zum naechsten fsck sind, bzw. an welchem Datum der naechste routinemaessige Dateisystemcheck durchgefuehrt wird. Fuer alle die die ebenfalls Interesse an dem Skript haben, hier:

#!/bin/bash
#
# Give information about the next filesystem check 
#
# 2009-11-08:	initial Version   / Jan Toenjes <mail@jan-toenjes.de>
# 2009-11-09:    changed dumpe2fs to "tune2fs -l" as suggested by kero / Jan Toenjes <mail@jan-toenjes.de>
 
 
# check if skript is run as root for tune2fs 
if [ `id -u` != "0" ] ; then 
  echo ""
  echo "     Usage: $0 /dev/disk"
  echo ""
  echo "     Error: You need to be root to run this skript"
  echo ""
  exit 3
fi
 
 
# check if needed programs are installed
which bc 1>/dev/null 
if [ $? -ne 0 ]; then
  echo "    ERROR: Cant find bc"
  exit 3        
fi        
 
 
# check if we got a parameter 
if [ "$1" == "" ] ; then
  echo ""
  echo "     Usage: $0 /dev/disk"
  echo ""
  echo "     Error: You need to give a valid mounted device as parameter i.e. /dev/sda1" 
  echo ""
  exit 3
fi
 
 
 
 
# check if the device given as a parameter exists
DEVEXIST=`mount | grep -ir "$1" | grep "/dev/" | wc | awk {'print $1'}`
if [ "$DEVEXIST" == "0" ] ; then
  echo ""
  echo "     Usage: $0 /dev/disk/"
  echo ""
  echo "     Error: The given parameter  \"$1\"  is not a valid mounted device."
  echo ""
  exit 3
fi
 
 
 
# get remaining mounts
MOUNTCOUNT=`tune2fs -l $1 2>&1 | grep "Mount count:" | awk {'print $3'}`
MAXIMUMMOUNTCOUNT=` tune2fs -l $1 2>&1 | grep "Maximum mount count:" | awk {'print $4'}`
REMAININGMOUNTS=`echo $MAXIMUMMOUNTCOUNT-$MOUNTCOUNT|bc`
 
 
 
# check if we have a fsck after a specific time value and give wanted information
TIMECHECK=`tune2fs -l $1 2>&1 | grep "Check interval:" | awk {'print $3'}`
if [ "$TIMECHECK" == "0" ] ; then
  echo "The next filesystem check of $1 will be after another $REMAININGMOUNTS mounts."
 
else
  NEXTCHECKAFTER=`tune2fs -l $1 2>&1 | grep "Next check after:" | sed 's/Next check after:[ \t]*$//g'`
  echo "The next filesystem check of $1 will be on $NEXTCHECKAFTER or after another $REMAININGMOUNTS mounts."
 
fi

Jun 3 2009

/usr/bin/mail

Es ist immer mal wieder sinnvoll von der Bash aus Skripten Emails zu verschicken. Ich vergesse immer wieder einige nuetzliche Schalter deswegen zum festhalten:

  • mail -s “Betreff” empfaenger@example.net (EMail mit Betreff)
  • mail -s “Betreff” empfaenger@example.net < /tmp/meinbrief (Email mit Betreff und meinbrief als Text)
  • cat /tmp/meinbrief | mail -e -s “Betreff” empfaenger@example.net (Email wird nur verschickt wenn der body nicht leer ist)
  • mail -a “From: Sender <sender@example.net>” -s “Betreff” empfaenger@example.net (Schreibt den From-Header um)
  • uuencode /tmp/meinbild.png /tmp/meinbild.png | mail -s “Betreff” empfaenger@example.net (Versendet meinbild.png als Anlage)

Apr 15 2009

An welchem Port befindet sich der Host?

Diese Frage muss natuerlich beantwortet sein, wenn ich Rechner die einen Virus haben automatisch in ein VLAN packen moechte. Gestern habe ich geschrieben, wie man auf den FSM726v2 einen Port via SNMP automatisch in ein VLAN setzt. Heute geht es nun darum, basierend auf einer MAC-Adresse, in unserem Wohnheim herauszufinden, auf welchem Switch und an welchem Port darauf ein Rechner sitzt, bzw. DER vireninfizierte Rechner sitzt. Es gab dafuer bei uns im Tutorium ein perl-Skript, das fuer diese Aufgabe gute 4 1/2 Minuten benoetigte.  Wir haben so um die 45 Switche bei uns im Wohnheim.

Meine erste Loesung in bash dauerte ca. doppelt so lange wie das perl Skript, aber nachdem ich das ganze noch einmal ueberdacht hatte bekomme ich die gewuenschte Information nun in Sekunden. Das Skript in dieser Form funktioniert fuer FSM726v2 und FSM7328 Switche, sollte aber ohne Probleme wenn man die OIDs anpasst auch fuer alle anderen Switchtypen funktionieren.  Hier das Skript:

#!/bin/bash
 
##
# sucht nach mac-adressen auf den switchen und
# gibt den port aus, auf dem sie zu finden ist
#
# syntax: ./mac-port.sh 00:11:22:33:44:55
#
# 04/2009 - Jan Toenjes - jan@atw.goe.net
##
 
# Ueberpruefen ob uns eine gueltige MAC-Adresse uebergeben wurde
VALID=$( echo $1 | sed -n "/^\([0-9A-Z][0-9A-Z]:\)\{5\}[0-9A-Z][0-9A-Z]$/p" )
 
if [ -z $VALID ]; then
  echo ""
  echo " syntax: $0 00:11:22:33:44:55"
  echo ""
  echo ""
  echo " Dem Skript muss eine gueltige MAC-Adresse als Parameter uebergeben werden."
  echo ""
  echo " Version: 0.1 von Jan Toenjes - jan@atw.goe.net "
  echo ""
 
else
 
# SWITCHE1 = FSM726v2 ; SWITCHE2 = FSM7328
SWITCHE1="1.1.1.1 1.1.1.2 1.1.1.3 "
SWITCHE2="1.1.2.1 1.1.2.2"
 
# Zeugs
OID1=".1.3.6.1.2.1.17.4.3.1.2"
OID2="SNMPv2-SMI::mib-2.17.7.1.2.2.1.2.1"
MACDEC=""
 
# Doppelpunkte aus MAC-Adresse entfernen
MACSPLIT=`echo $1 | sed 's/:/ /g'`
 
# MAC-Adresse von HEX in DEC konvertieren
for i in $MACSPLIT ; do
  MACDEC=$MACDEC.$(echo "ibase=16; $i"| bc) ;
done
 
# Gucken ob die MAC-Adresse auf dem Switch FSM726v2 vorhanden ist und wenn ja welcher Port
for i in $SWITCHE1 ; do
  RESULT1=`snmpget -v1 -c tutrw $i $OID1$MACDEC 2&gt;&amp;1 | head -1 | grep INTEGER`;
  # Port extrahieren
  RESULT2=`echo $RESULT1 | sed 's/.*INTEGER: //g'` ;
  # Wenn kein Uplink-Port dann Info ausgeben
  if ([ "$RESULT2" != "25" ] &amp;&amp; [ "$RESULT2" != "26" ]  &amp;&amp; [ -n "$RESULT2" ]); then
    echo Mac-Adresse: $1 gefunden auf Switch $i und Port $RESULT2
  fi
done
 
# und das gleiche auch noch einmal fuer die FSM7328
for i in $SWITCHE2 ; do
  RESULT1=`snmpget -v1 -c tutrw $i $OID2$MACDEC 2&gt;&amp;1 | head -1 | grep INTEGER`;
  RESULT2=`echo $RESULT1 | sed 's/.*INTEGER: //g'` ;
 
  if ([ "$RESULT2" != "25" ] &amp;&amp; [ "$RESULT2" != "26" ] &amp;&amp; [ "$RESULT2" != "27" ] &amp;&amp; [ "$RESULT2" != "28" ] &amp;&amp; [ -n "$RESULT2" ]); then
    echo Mac-Adresse: $1 gefunden auf Switch $i und Port $RESULT2
  fi
done
 
fi