Server bei inaktivität im Netz schlafen legen
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.
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.
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 ;)