VM nach SSH-Inaktivität automatisch herunterfahren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
paedubucher
Beiträge: 931
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von paedubucher » 23.11.2024 15:38:52

Ich manage ein Setup mit einer grösseren Zahl von Debian-VMs in der Cloud. Die VMs dienen nur zur Ausbildung; auf ihnen läuft nichts Kritisches.

Gerne würde ich diese VMs automatisch herunterfahren, wenn sie eine Zeit lang (z.B. zwei Stunden) nicht verwendet worden sind. Die VMs werden dabei per SSH verwendet; Zugriff auf darauf eingerichtete Services (Web-Server, Datenbanken usw.) sind nicht relevant. Besteht keine SSH-Verbindung, kann die VM nach zwei Stunden heruntergefahren werden.

Ich habe folgende Idee:
  • Eine SSH-Verbindung wird automatisch unterbrochen, wenn sie eine Stunde inaktiv war.
  • Eine VM wird automatisch heruntergefahren, wenn die letzte SSH-Verbindung vor über einer Stunde beendet worden ist.
Für das erste Problem habe ich zwei Konfigurationsdirektiven für sshd(8) gefunden:
  • ChannelTimeout: Nach dieser Zeit wird ein nicht verwendeter Kanal geschlossen.
  • UnusedConnectionTimeout: Nach dieser Zeit wird eine Verbindung geschlossen, die keinen offenen Kanal hat.
Zur Unterscheidung zwischen Kanal und Verbindung werde ich mich noch etwas schlau machen müssen, aber ich bin zuversichtlich, dass ich inaktive SSH-Verbindungen zuverlässig loswerden kann.

Für das zweite Problem habe ich noch keinerlei Vorstellungen, wie ich es lösen könnte. Irgendwie müsste ich herausfinden können, dass eine SSH-Verbindung geschlossen worden ist. Oder ich müsste die Anzahl offener SSH-Verbindungen live monitoren. Ist keine offen, startet ein Timer. Sobald wieder eine geöffnet wird, wird der Timer zurückgesetzt. Solche Sachen lassen sich wunderbar in Go mit Channels und Timern umsetzen. Die Frage ist nur, was ich genau monitoren soll. Gibt es da passende APIs dazu? Oder soll ich Logdaten bzw. das Journal auslesen?

Evtl. könnte man auch irgend eine Art Hook definieren beim Beenden einer Shell-Session. Aber dann müsste ich auch beim Öffnen mitzählen.

Das Monitoring aktiver Login-Shells über Prozesse wäre auch eine Möglichkeit, aber ich müsste dann schon wissen, welche Shells zum Einsatz kommen. So richtig weit komme ich mit keinem Ansatz.

Ich wäre froh um Anregungen! :THX:
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

rodney
Beiträge: 370
Registriert: 09.12.2016 04:15:59

Re: VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von rodney » 23.11.2024 16:32:41

Ungetestet, muesste aber mit kleinen Anpassungen funktionieren: Per cron regelmaessig testen ob es aktive SSH-Verbindungen gibt...

Benutzeravatar
paedubucher
Beiträge: 931
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von paedubucher » 23.11.2024 17:27:47

rodney hat geschrieben: ↑ zum Beitrag ↑
23.11.2024 16:32:41
Ungetestet, muesste aber mit kleinen Anpassungen funktionieren: Per cron regelmaessig testen ob es aktive SSH-Verbindungen gibt...
Danke! Das könnte man mit gewissen Modifikationen so gut ausrollen. Ich versuche das gerne im Zusammenspiel mit den anderen beiden SSH-Einstellungen! :THX:
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
paedubucher
Beiträge: 931
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von paedubucher » 23.11.2024 19:36:56

Ich habe das Skript nun auf meine Anforderungen angepasst:

Code: Alles auswählen

#!/bin/bash
#
# Shuts down the host on inactivity.
#
# Designed to be executed as root from a cron job. It will power off on the 2nd
# consecutive run without an active ssh session. That prevents an undesirable
# shutdown when the machine was just started, or on a brief disconnect.
#
# Setup as a cron job:
#
# */5 * * * * /usr/local/sbin/idlebuster
#
# Source: https://serverfault.com/a/1061792

systemd-cat -t idlebuster -p info echo 'running idlebuster'

set -o nounset -o errexit -o pipefail

IDLE_FILE='/tmp/idlebuster'

ss | grep ssh | grep -q ESTAB
STATE=$?
systemd-cat -t idlebuster -p info echo "idlebuster state: ${STATE}"

if [ $STATE -eq 0 ]
then
        systemd-cat -t idlebuster -p debug echo 'poweroff prevented due to activity (open ssh session)'
        rm -f "${IDLE_FILE}"
        exit 0
fi

if [ -f "${IDLE_FILE}" ]
then
        systemd-cat -t idlebuster -p alert echo 'poweroff due to inactivity (no open ssh session)'
        /usr/sbin/poweroff
else
        systemd-cat -t idlebuster -p warning echo 'inactivity detected (no open ssh session)'
        touch "${IDLE_FILE}"
fi
Selbst wenn keine SSH-Verbindung mehr offen ist – die SSH-Konfiguration macht, was sie soll – wird der Server nicht heruntergefahren.

Das Journal sagt folgendes:

Code: Alles auswählen

$ sudo journalctl -f -t idlebuster
Nov 23 17:42:01 patrick-bucher idlebuster[60266]: running idlebuster
Nov 23 17:43:01 patrick-bucher idlebuster[60281]: running idlebuster
Nov 23 17:44:01 patrick-bucher idlebuster[60296]: running idlebuster
Nov 23 17:45:01 patrick-bucher idlebuster[60312]: running idlebuster
Nov 23 17:46:01 patrick-bucher idlebuster[60334]: running idlebuster
Nov 23 17:47:01 patrick-bucher idlebuster[60349]: running idlebuster
Nov 23 17:48:01 patrick-bucher idlebuster[60364]: running idlebuster
Nov 23 17:49:01 patrick-bucher idlebuster[60379]: running idlebuster
Irgend etwas mache ich in meinem Skript falsch :?
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

rodney
Beiträge: 370
Registriert: 09.12.2016 04:15:59

Re: VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von rodney » 23.11.2024 19:51:03

Edit: "Lass mal das exit 0 weg" war ein undurchdachter Schnellschuss. Sorry

Benutzeravatar
paedubucher
Beiträge: 931
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: VM nach SSH-Inaktivität automatisch herunterfahren

Beitrag von paedubucher » 23.11.2024 20:29:14

rodney hat geschrieben: ↑ zum Beitrag ↑
23.11.2024 19:51:03
Edit: "Lass mal das exit 0 weg" war ein undurchdachter Schnellschuss. Sorry
Das Problem lag hier:

Code: Alles auswählen

set -o nounset -o errexit -o pipefail
Wahrscheinlich war es das pipefail. Die Zeile ss | grep ssh | grep -q ESTAB produziert ja einen Fehler, wenn grep ssh fehlschlägt. Und das war meine Modifikation gegenüber dem ursprünglichen Skript.

Aber diese Lösung funktioniert nun offenbar. Ich werde das demnächst deployen. Eine heruntergefahrene Instanz kostet nur einen Bruchteil von einer laufenden, zumal man bei ersterer nur den Storage und nicht noch das Compute bezahlen muss.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Antworten