Server bei inaktivität im Netz schlafen legen

Aus wiki.archlinux.de

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
   
   ###
   # CONFIG
   ###
   
   # Filename of the statusfile
   STATUSFILE="/tmp/auto-hibernate"
   
   # 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.1/24"
   
   # how many clients are always on (other servers, routers, etc)
   MINCLIENTS=5
   
   # shutdown after how many retries?
   RETRIES=2
   
   ###
   # END CONFIG
   ###
   
   NUMCLIENTS=`nmap -sP $RANGE -oG - | grep "^Host" | wc -l`
   
   # Next line for DEBUG only, comment out for productive use
   #echo $NUMCLIENTS
   
   if [ $NUMCLIENTS -le $MINCLIENTS ]; then
       if [ ! -f "$STATUSFILE" ]; then
           echo "COUNT=$RETRIES" > $STATUSFILE
       fi
       . $STATUSFILE
       if [ $COUNT -le $MINCLIENTS ]; then
   # I don't think we need this echo on an headless system.
   # Comment in if you like.
   #        echo "Shutdown, my dear..."
   	   echo $(date) >> /var/log/auto-hibernate.log
           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 und RETRIES.

  • 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.

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 ;)