Ich habe ein Skript, das einen Reverse-Tunnel auf einem Endpunkt aufbaut HostB
. Es sieht folgendermaßen aus:
cat tun.sh
#!/usr/bin/env bash
# Test code
/usr/bin/ssh -V 1> /home/userA/bin/tun.stdout 2> /home/userA/bin/tun.stderr
# Establish tunnel
createTunnel() {
/usr/bin/ssh -R *:19999:localhost:22 userB@hostB
}
# Do nothing if tunnel is already established
/usr/bin/ssh -p 19999 userA@hostB true
if [[ $? -ne 0 ]]; then
createTunnel
fi
Wenn ich es manuell ausführe ./tun.sh
, funktioniert es, und ich kann auf HostB sehen, dass BenutzerA angemeldet ist. Wenn ich es erneut auf HostA ausführe, aber von einer anderen Konsole aus, funktioniert es wie erwartet – es wird kein zweiter Tunnel gestartet.
Alles soweit ist gut.
Ich bearbeite jetzt meine Crontab, sodass sie folgendermaßen aussieht:
crontab -l
# m h dom mon dow command
*/1 * * * * /home/userA/bin/tun.sh
Das Skript wird jede Minute ausgeführt. Das sollte kein Problem sein, da das Skript beendet wird, wenn der Tunnel bereits eingerichtet ist.
Allerdings wird BenutzerA jetzt nicht angemeldet, als wenn ich es manuell von der Konsole aus ausführe.
Der Testcode oben im Skript bestätigt, dass das Skript aufgerufen wird und über die Ausführungsberechtigung verfügt /usr/bin/ssh
:
~/bin$ ls
tun.sh tun.stderr tun.stdout
~/bin$ cat tun.stderr
OpenSSH_5.3p1 Debian-3ubuntu7, OpenSSL 0.9.8k 25 Mar 2009
~/bin$ cat tun.stdout
[empty]
Aus irgendeinem Grund -V
schreibt es in stderr
und nicht stdout
in , aber das ist ein Detail. Der Hauptpunkt ist hier, dass das Skript jede Minute ausgeführt wird.
Meine Frage ist:warum wird der SSH-Tunnel nicht hergestellt?
Antwort1
Vielen Dank an @Andrew für den Hinweis ssh-agent
. Soweit ich sehe, muss das Passwort gespeichert oder entfernt werden, wenn man den Tunnel einrichten möchte, ohne jedes Mal ein Passwort eingeben zu müssen. Ich habe mich für die Entfernung entschieden. Der Vollständigkeit halber sind hier einige Bereinigungsmaßnahmen basierend auf den Kommentaren, die ich erhalten habe:
#!/usr/bin/env bash
# Establish tunnel
createTunnel() {
/usr/bin/ssh -i /home/laptopuser/.ssh/id_rsa_tunnel -R 2200:localhost:22 [email protected]
}
# Do nothing if tunnel is already established
/usr/bin/ssh -i /home/user/laptopuser/.ssh/id_rsa_tunnel -p 2200 [email protected] true
if [[ $? -ne 0 ]]; then
createTunnel
fi
crontab:
# m h dom mon dow command
*/1 * * * * /home/laptopuser/bin/establishTunnel.sh
Kopieren Sie Ihre Tunnel-ID in den VPS:
ssh-copy-id -i /home/user/laptopuser/.ssh/id_rsa_tunnel vps.com
warte bis der Tunnel läuft (siehe sudo watch grep CRON /var/log/syslog
) und kopiere deine normale ID, falls du sie noch nicht hast~/.ssh/authorized_keys
ssh-copy-id vps.com -p 2200
Idealerweise würde der Tunnel sowohl auf dem VPS als auch auf dem Laptop als dedizierter Benutzer ausgeführt.
Antwort2
Ich hatte ein ähnliches Problem – der SSH-Tunnel funktioniert, wenn er von einem Skript ausgeführt wird, aber nicht von Crontab. SSH sucht nach Schlüsseln und bekannten Hosts in $HOME/.ssh. Wenn Sie das Skript von Bash unter dem Benutzer Tom ausführen, ist $HOME /home/tom. Wenn das Skript von Crontab ausgeführt wird, ist der Benutzer root und $HOME ist /home/root (oder undefiniert).
Lösung: Definieren Sie HOME in Ihrem Skript für den Benutzer, der über die Schlüssel verfügt.
HOME=/home/tom