Server bei inaktivität im Netz schlafen legen: Unterschied zwischen den Versionen

Aus wiki.archlinux.de
Chepaz (Diskussion | Beiträge)
K Verschiebung community -> extra
 
(Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt)
Zeile 21: Zeile 21:
'''Client-Seitig'''
'''Client-Seitig'''


Um den Server per WoL zu wecken braucht man das Paket community/wol. Es wird per
Um den Server per WoL zu wecken braucht man das Paket extra/wol. Es wird per
     pacman -S wol
     pacman -S wol
installiert.
installiert.
Zeile 32: Zeile 32:


Folgendes Script wird nun unter /root/scripts/auto-hibernate.sh gespeichert und ausführbar gemacht:
Folgendes Script wird nun unter /root/scripts/auto-hibernate.sh gespeichert und ausführbar gemacht:
     #!/bin/sh
     #!/bin/sh
    #
     # (cc:by-sa) 2007 Marco Gabriel, http://www.marcogabriel.com/
     # (cc:by-sa) 2007 Marco Gabriel, http://www.marcogabriel.com/
    #
     # Powersaver.sh
     # Powersaver.sh
     #
     #
     # Modified 2015 by chepaz --> auto-hibernate.sh
     # Modified 2015 by chepaz --> auto-hibernate.sh
    # mx-bounce(at)gmx.de
      
      
     ###
     ### CONFIG START
    # CONFIG
     ##
     ###
     #
      
     # Filename of the statusfile
     # Filename of the statusfile
     STATUSFILE="/tmp/auto-hibernate"
     STATUSFILE="/tmp/auto-hibernate"
      
     #
    # Filename of the logfile
    LOGFILE="/var/log/auto-hibernate.log"
    #
     # which ip range should be checked?
     # which ip range should be checked?
     # this example looks in "192.168.1.10 to 192.168.1.30"  
     # this example looks in "192.168.1.10 to 192.168.1.30"  
     # and "192.168.178.10 to 192.168.178.30"
     # and "192.168.178.10 to 192.168.178.30"
     #RANGE="192.168.1,178.10-30"
     #RANGE="192.168.1,178.10-30"
     RANGE="10.10.10.1/24"
     RANGE="10.10.10.0/24"
      
     #
     # how many clients are always on (other servers, routers, etc)
     # how many clients are always on (other servers, routers, etc)
     MINCLIENTS=5
     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
      
      
     # shutdown after how many retries?
     NUMCLIENTS=`nmap -sP $RANGE -oG - | grep "^Host" | wc -l`
    RETRIES=2
      
      
     ###
     # write the scanresult to file
     # END CONFIG
     echo "Time clientscan: $(date), Clients seen: $NUMCLIENTS" >> $LOGFILE
    ###
      
      
     NUMCLIENTS=`nmap -sP $RANGE -oG - | grep "^Host" | wc -l`
     # check if clients up that should prevent action
    for i in ${PREVCLIENTS[@]}
        do
        ping -c1 $i &>/dev/null
            pingstatus=$?
      
      
    # Next line for DEBUG only, comment out for productive use
            if [ $pingstatus -eq "0" ]; then
    #echo "Time clientscan: $(date), Clients seen: $NUMCLIENTS" >> /var/log/auto-hibernate.log
                echo "$i reachable, no action triggered!" >> $LOGFILE
                exit 0
            fi
        done
      
      
    # check the results, take action if applicable
     if [ $NUMCLIENTS -le $MINCLIENTS ]; then
     if [ $NUMCLIENTS -le $MINCLIENTS ]; then
         if [ ! -f "$STATUSFILE" ]; then
         if [ ! -f "$STATUSFILE" ]; then
Zeile 74: Zeile 92:
         . $STATUSFILE
         . $STATUSFILE
         if [ $COUNT -le 0 ]; then
         if [ $COUNT -le 0 ]; then
    # I don't think we need this echo on an headless system.
        echo "Hibernate at: $(date)" >> $LOGFILE
    # Comment in if you like.
            rm $STATUSFILE
    #        echo "Shutdown, my dear..."
            systemctl hibernate;
      echo $(date) >> /var/log/auto-hibernate.log
          rm $STATUSFILE
          systemctl hibernate;
         else
         else
             let COUNT=$COUNT-1
             let COUNT=$COUNT-1
Zeile 89: Zeile 104:
         fi
         fi
     fi
     fi


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


Das Script ist leicht zu lesen, abgepasst werden müssen die Variablen '''RANGE''', '''MINCLIENTS''' und '''RETRIES'''.
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 ;) )
* 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)
* 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.
* 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.


[[Benutzer:Chepaz|Chepaz]] ([[Benutzer Diskussion:Chepaz|Diskussion]])
[[Benutzer:Chepaz|Chepaz]] ([[Benutzer Diskussion:Chepaz|Diskussion]])

Aktuelle Version vom 24. Mai 2023, 18:32 Uhr

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