[Tip] SSH: Entfernten Prozess beenden wenn die SSH-Sitzung beendet wird

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

[Tip] SSH: Entfernten Prozess beenden wenn die SSH-Sitzung beendet wird

Beitrag von heisenberg » 01.12.2023 16:15:10

Kurzbeschreibung

Hallo zusammen,

ich habe gerade versucht zu erreichen, dass ein per SSH laufender Prozess auf einem Remote-System sich beendet, sobald die SSH-Verbindung aus irgend einem Grund zusammenbricht. Der Normalfall ist bei mir, dass mein Shellscript sich nicht beendet und deswegen spätere, erneute Aufrufe stört, bzw. blockiert.

Letztlich wird in dem Fall dem aufgerufenen Prozess ein Signal geschickt, auf das dass Script reagieren kann.

Die Stolperfallen

Folgende Stolperfallen hatte ich dabei zu lösen:
  • Das Signal wird in Abhängigkeit davon gesendet, ob das Programm auf dem Zielrechner mit einem Terminal/Pseudoterminal verbunden ist oder nicht. Ist ein Terminal verbunden, bekomme ich ein SIGHUP (1) in dem entfernt laufenden Programm. Ist kein Terminal verbunden bekomme ich nach einer gewissen Zeit ein SIGPIPE (13).
  • Normalerweise ist kein Terminal beim SSH-Aufruf vorhanden, es sei denn, ich starte meinen SSH-Aufruf mit -o RequestTty=force
  • Alternative dazu ist vermutlich, dass ich im systemd-unit-file StandardInput=tty angebe.
  • Der Aufruf von trap (=bash-Funktion) ist recht empfindlich, was da alles drin sein darf. Auf jeden Fall nicht alle Bash-Syntaxkonstrukte.
Das aktuell Skript sieht bei mir dann so aus:

Code: Alles auswählen

#!/bin/bash

REMOTE_PORT="$1"
LAN_IP="$2"

touch /tmp/signal.log

# Debug received signals:
#
# for((sig=0;sig<=30;sig++));do
#        trap "echo \"'$$': got signal '$sig'\" >>/tmp/signal.log" $sig
# done

trap "echo \"'$LAN_IP' '$$': got signal '1'  (SIGHUP),  exiting\" >>/tmp/signal.log && exit" 1
trap "echo \"'$LAN_IP' '$$': got signal '13' (SIGPIPE), exiting\" >>/tmp/signal.log && exit" 13

while :;do
        echo "$REMOTE_PORT" >$HOME/forwarded_ports/$LAN_IP
        echo -n .
        sleep 5
done
Das Script, dass die SSH-Verbindung auf der anderen Seite initiiert ist das:

Code: Alles auswählen

#!/bin/bash

declare -rx PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin
declare -rx LC_ALL=C

. /etc/default/su-remote-access

# get the ipv4 address of the first network lan device
LAN_IP="$(get-first-lan-ip)"

# get only the number characters of an md5 hash of the the ip address
HASH="$(echo -n "$LAN_IP" | md5sum | awk '{print $1}' | tr -d 'a-f' )"

# sample down a part of the hash to a fixed ipv4-derived number between 2000 - 65000
REMOTE_PORT=$(( ( ${HASH:1:10} % 63000 ) + 2000 ))

/usr/bin/autossh                -i ${PORT_FORWARDING_PRIVATE_KEY}                       \
                                -o UserKnownHostsFile=${PORT_FORWARDING_KNOWN_HOSTS}    \
                                -l ${PORT_FORWARDING_REMOTE_USER}                       \
                                -R 127.0.0.1:${REMOTE_PORT}:localhost:22                \
                                -o ExitOnForwardFailure=yes -p 22                       \
                                ${PORT_FORWARDING_REMOTE_SERVER} /usr/local/bin/remote-keepalive $REMOTE_PORT $LAN_IP
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
heisenberg
Beiträge: 3567
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: [Tip] SSH: Entfernten Prozess beenden wenn die SSH-Sitzung beendet wird

Beitrag von heisenberg » 01.12.2023 19:33:11

Hmm. So sauber funktioniert das noch nicht. Bei Variante 2) mit TTY und SIGHUP kommt das Signal aber erst, wenn der absendende Host mit der gleichen IP wieder da ist. Funktional reicht das für mich, auch wenn ganz sauber schöner wäre.

Bei Variante 1) mit SIGPIPE scheint das genauso zu sein.

Ich habe jetzt nochmal das Programm so eingestellt, dass es sich nach 5 Stunden spätestens beendet. Es wird ja ggf. direkt wieder neu gestartet.

Nachtrag:

Es dauert wohl einfach länger. Aktuell teilweise 20 Minuten, bis da ein Signal kommt. Mal beobachten.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Antworten