Automatically Shutdown Idle Server
howto idle shutdown
Premice
Imagine you started a server and stopped using the service on it (e.g. some gameserver, openvpn, …) but you can just not now shut it down manually?
Let’s setup a quick bash script that monitors network connections to that service and shutdown the server when it is idle for some time.
Idea
We can run a script via cronjob (every e.g. 5 minutes)
If the script does not find any connected clients the first time, it will save the current time (in seconds since epoch) to a file in /tmp. The next calls to the script it will check if
- a) still no clients are connected. If there are clients connected, it will remove the file again.
- b) the idle timeout is reached. If the idle timeout is reached, it will poweroff the server
The script
- check_poweroff.sh (in this example I put it into “/home/user/auto_poweroff”)
#!/bin/bash
#this script checks how long {whatever} server is idle, and after 30 minutes will power off the machine
DEBUG="True"
PORT=1234 # TCP port number your server is listening to
#file that tracks since when server is idle, gets removed after reboot (cron entry)
# add cron entry: '@reboot /usr/bin/rm -f /tmp/myServer_idle_time'
track_idle_time=/tmp/myServer_idle_time
max_idle_time=1800 # idle time in seconds, 1800 is 30 minutes, 3600 is 1 hour
#if connected_clients is empty there are no clients connected
connected_clients=$(sudo netstat -an | grep "$PORT" | grep ESTABLISHED)
if [[ -n "$connected_clients" ]]; then
if [[ $DEBUG == "True" ]]; then echo "there are still users connected to the server. removing $track_idle_time"; fi
rm -fv $track_idle_time
else
# idle file does not exist yet? create it and put seconds since 1970-01-01 00:00:00 UTC into it
if [[ ! -f "$track_idle_time" ]]; then
/usr/bin/date "+%s" > $track_idle_time
else
time_idle_since=$(grep -Eo '([0-9]+)' $track_idle_time)
time_idle=$(expr $time_idle_since + $max_idle_time)
now=$(/usr/bin/date "+%s")
if [[ $now -gt $time_idle ]];then
if [[ $DEBUG == "True" ]]; then echo "We are idle more than $max_idle_time. powering off machine"; fi
sudo /usr/sbin/shutdown -h now
fi
fi
fi
Cron entries
Add the following cron entries:
(do “crontab -e” if unsure)
(the first removes the file we keep track at boot and the other is our script that runs every 5 minutes)
@reboot /usr/bin/rm -f /tmp/myServer_idle_time
*/5 * * * * /bin/bash /home/user/auto_poweroff/check_poweroff.sh >> /home/user/auto_poweroff/auto_poweroff.log
Variants
openvpn
For an openvpn server you can look at the actual clients that are connected (instead of using netstat). Change line 14 to
connected_clients=$(sudo /bin/grep "^CLIENT_LIST" /etc/openvpn/server/openvpn-status.log)
(change the path to the location of your openvpn status log)