Server bei inaktivität im Netz schlafen legen

Aus wiki.archlinux.de
Version vom 29. November 2015, 18:37 Uhr von Chepaz (Diskussion | Beiträge) (Script geändert.)

Server bei inaktivität im Netz schlafen legen

Einleitung

Einen Server daheim 24/7 zu betreiben ist sicherlich die angenehmste Variante um jederzeit darauf zugreifen zu können. Allerdings braucht so ein Gerät natürlich Strom und die wenigsten Heimserver werden tatsächlich non-stop benötigt. Der Gedanke ist also so ein Gerät nur in Betrieb zu haben wenn man es benötigt, bzw. solange bestimmte Rechner im Netz aktiv sind.

Aufbauend auf diesem Script soll nun erläutert werden wie man das bewerkstelligen kann.

Das Prinzip ist sehr einfach: Der Server soll das Netz auf $n+x Rechner scannen, ist nur eine Mindestmenge an Rechnern zu erreichen legt er sich schlafen.

Achtung: Für dieses Beispiel ist anzunehmen das sich alle Rechner im selben Netz befinden. Wenn das nicht der Fall ist muss man das folgende Script an seine eigene Infrastruktur anpassen!

Konfiguration/Installation

Vorbereitungen

  • Es muss sichergestellt sein das der Server hibernation zuverlässig beherrscht. (Alternativ kann man natürlich auch suspend benutzen, dann muss das Script angepasst werden.)
  • Die MAC-Adresse des Servers muss bekannt sein.
  • Der Server muss per Wake-on-Lan aufwachen.

Client-Seitig

Um den Server per WoL zu wecken braucht man das Paket community/wol. Es wird per

   pacman -S wol

installiert.

Man kann den Server dann aufwecken in dem man wol seine MAC-Adresse mitgibt:

   wol aa:bb:cc:dd:ee:ff

Nach absetzen des Befehls sollte der Server aufwachen und nach einigen Sekunden erreichbar sein. Den Aufruf von wol kann man natürlich nach Belieben automatisieren.

Server-Seitig

Folgendes Script wird nun unter /root/scripts/auto-hibernate.sh gespeichert und ausführbar gemacht:

   #!/bin/sh
   # (cc:by-sa) 2007 Marco Gabriel, http://www.marcogabriel.com/
   # Powersaver.sh
   #
   # Modified 2015 by chepaz --> auto-hibernate.sh
   # mx-bounce(at)gmx.de
   
   ### CONFIG START
   ##
   #
   # Filename of the statusfile
   STATUSFILE="/tmp/auto-hibernate"
   #
   # Filename of the logfile
   LOGFILE="/var/log/auto-hibernate.log"
   #
   # which ip range should be checked?
   # this example looks in "192.168.1.10 to 192.168.1.30" 
   # and "192.168.178.10 to 192.168.178.30"
   #RANGE="192.168.1,178.10-30"
   RANGE="10.10.10.0/24"
   #
   # how many clients are always on (other servers, routers, etc)
   MINCLIENTS=11
   #
   # clients which prevent system _always_ to hibernate if online 
   # set to non-existing hostname if not needed, e.g. PREVCLIENTS=( none )
   PREVCLIENTS=( computer1 computer2...computer3 )
   #
   # shutdown after how many retries?
   RETRIES=3
   #
   ##
   ### CONFIG END
   
   NUMCLIENTS=`nmap -sP $RANGE -oG - | grep "^Host" | wc -l`
   
   # write the scanresult to file
   echo "Time clientscan: $(date), Clients seen: $NUMCLIENTS" >> $LOGFILE
   
   # check if clients up that should prevent action
   for i in ${PREVCLIENTS[@]}
       do
   	    ping -c1 $i &>/dev/null
           pingstatus=$?
   
           if [ $pingstatus -eq "0" ]; then
               echo "$i reachable, no action triggered!" >> $LOGFILE
               exit 0
           fi
       done 
   
   # check the results, take action if applicable
   if [ $NUMCLIENTS -le $MINCLIENTS ]; then
       if [ ! -f "$STATUSFILE" ]; then
           echo "COUNT=$RETRIES" > $STATUSFILE
       fi
       . $STATUSFILE
       if [ $COUNT -le 0 ]; then
   	    echo "Hibernate at: $(date)" >> $LOGFILE
           rm $STATUSFILE
           systemctl hibernate;
       else
           let COUNT=$COUNT-1
           echo "COUNT=$COUNT" > $STATUSFILE
       fi;
   else
       if [ -f "$STATUSFILE" ]; then
           rm $STATUSFILE
       fi
   fi


   chmod +x /root/scripts/auto-hibernate.sh

Das Script ist leicht zu lesen, abgepasst werden müssen die Variablen RANGE, MINCLIENTS, RETRIES und PREVCLIENTS.

  • RANGE beinhaltet einen IP-Adressbereich der gescannt werden soll (in der Regel das gesammte lokale Netz, wenn man nicht gerade etwas exklusives daheim hat ;) )
  • MINCLIENTS beinhaltet die Anzahl Clients die immer aktiv sind (z.B. 5 für: Router, DNS/DHCP-Server, 3x Drucker)
  • RETRIES beinhaltet nach welchem Durchlauf ohne "Funde" im Netzwerk der Server in den hibernate gehen soll.
  • PREVCLIENTS sind Hostnamen die den Server hindern in den hibernate zu gehen wenn sie pingbar sind.

Chepaz (Diskussion)

Achtung:

Die in diesem Artikel vorgestellte Technik benötigt einen laufenden Cron-Service. Standardmäßig nutzt Arch Linux systemd-Timer. Der Periodische Start muss entwerder über diese Timer umgesetzt werden – oder es muss ein Cron-Service (siehe dort) installiert werden.

Chepaz (Diskussion)

Damit das Script nun periodisch aufgerufen wird legt man einen Cronjob an mit

   crontab -e

Die crontab befüllt man dann beispielsweise so

   # Example of job definition:
   # .---------------- minute (0 - 59)
   # |  .------------- hour (0 - 23)
   # |  |  .---------- day of month (1 - 31)
   # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
   # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
   # |  |  |  |  |
   # *  *  *  *  * user-name command to be executed
   */10 *  *  *  * /root/scripts/auto-hibernate.sh

Das Script wird nun alle 10 Minuten aufgerufen, scannt das Netz und dekrementiert den Zähler (RETRIES) wenn keine Clients mehr zu finden sind. Ist der Zähler bei 0 wird der Timestamp in ein Logfile geschrieben und systemctl hibernate aufgerufen.

Wenn man alles richtig gemacht hat sollte sich der Server nun nach 50 Minuten ohne Clients im Netz schlafen legen ;)