2009-09-08 13:04:22 +0000 2009-09-08 13:04:22 +0000
244
244

Come mantenere aperto in modo affidabile un tunnel SSH?

Uso un tunnel SSH dal lavoro per aggirare vari firewall idotici (va bene per il mio capo :)). Il problema è che dopo un po’ la connessione ssh di solito si blocca, e il tunnel si interrompe.

Se potessi almeno monitorare il tunnel automaticamente, potrei riavviare il tunnel quando si blocca, ma non ho ancora trovato un modo per farlo.

Punti bonus per chi sa dirmi come evitare che la mia connessione ssh si blocchi, ovviamente!

Risposte (16)

296
296
296
2009-09-08 13:43:51 +0000

Sembra che tu abbia bisogno di autossh . Questo monitorerà un tunnel ssh e lo riavvierà quando necessario. Lo abbiamo usato per un paio d'anni e sembra funzionare bene.

autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C

Maggiori dettagli sul parametro -M qui

40
40
40
2009-09-28 13:47:26 +0000

Tutti i firewall statici dimenticano una connessione dopo non aver visto un pacchetto per quella connessione per un certo tempo (per evitare che le tabelle di stato si riempiano di connessioni in cui entrambe le estremità sono morte senza chiudere la connessione). La maggior parte delle implementazioni TCP invierà un pacchetto keepalive dopo un lungo periodo di tempo senza avere notizie dall'altra parte (2 ore è un valore comune). Se, tuttavia, c'è un firewall stateful che si dimentica della connessione prima che i pacchetti keepalive possano essere inviati, una connessione longeva ma inattiva morirà.

Se questo è il caso, la soluzione è impedire che la connessione diventi inattiva. OpenSSH ha un'opzione chiamata ServerAliveInterval che può essere usata per evitare che la connessione rimanga inattiva per troppo tempo (come bonus, rileverà quando il peer è morto prima anche se la connessione è inattiva).

24
24
24
2010-05-29 13:45:08 +0000

Sul vostro mac o macchina linux configurate il vostro ssh mantenendo il server ssh vivo ogni 3 minuti. Aprite un terminale e andate nel vostro invisibile .ssh nella vostra casa:

cd ~/.ssh/

poi create un file di configurazione di 1 linea con:

echo "ServerAliveInterval 180" >> config

dovreste anche aggiungere:

ServerAliveCountMax xxxx (high number)

il default è 3 quindi ServerAliveInterval 180 smetterà di inviare dopo 9 minuti (3 dell'intervallo di 3 minuti specificato da ServerAliveInterval).

23
23
23
2009-09-22 14:58:15 +0000

Ho usato il seguente script Bash per continuare a generare nuovi tunnel ssh quando il precedente muore. Usare uno script è comodo quando non si vuole o non si può installare pacchetti aggiuntivi o usare il compilatore.

while true
do
  ssh <ssh_options> [user@]hostname
  sleep 15
done

Notate che questo richiede un keyfile per stabilire la connessione automaticamente, ma questo è il caso anche di autossh.

21
21
21
2016-07-28 06:10:14 +0000

Systemd è l'ideale per questo.

Creare un file di servizio /etc/systemd/system/sshtunnel.service contenente:

[Unit]
Description=SSH Tunnel
After=network.target

[Service]
Restart=always
RestartSec=20
User=sshtunnel
ExecStart=/bin/ssh -NT -o ServerAliveInterval=60 -L 5900:localhost:5900 user@otherserver

[Install]
WantedBy=multi-user.target

(Modificare il comando ssh per adattarlo)

  • questo verrà eseguito come utente sshtunnel quindi assicurarsi che l'utente esista prima
  • emettere systemctl enable sshtunnel per impostare l'avvio all'avvio
  • emettere systemctl start sshtunnel per avviare immediatamente

Update Jan 2018 : alcune distro (e. Es. Fedora 27) possono utilizzare la politica SELinux per impedire l'uso di SSH da systemd init, nel qual caso sarà necessario creare una politica personalizzata per fornire le esenzioni necessarie.

11
11
11
2013-11-28 01:04:34 +0000

Mi sembra che stiate tutti interpretando male ServerAliveCountMax. Da quanto ho capito dai documenti, è il numero di messaggi server alive che possono rimanere senza risposta senza che la connessione venga terminata. Quindi, in casi come quello di cui stiamo discutendo qui, impostarlo ad un valore alto assicurerà solo che una connessione bloccata non venga rilevata e terminata!

Impostare semplicemente ServerAliveInterval dovrebbe essere sufficiente a risolvere il problema di un firewall che si dimentica della connessione, e lasciare ServerAliveCountMax basso permetterà all'estremità originaria di notare il fallimento e terminare se la connessione fallisce comunque.

Quello che volete è, 1) che la connessione rimanga aperta permanentemente in circostanze normali, 2) che il fallimento della connessione venga rilevato e la parte originaria esca in caso di fallimento, e 3) che il comando ssh venga riemesso ogni volta che esce (come lo fate dipende molto dalla piattaforma, lo script “while true” suggerito da Jawa è un modo, su OS X ho effettivamente impostato un elemento launchd).

9
9
9
2014-03-08 21:30:40 +0000

Usare sempre l'opzione ServerAliveInterval SSH nel caso in cui i problemi del tunnel siano generati da sessioni NAT scadute.

Usare sempre un metodo di respawning nel caso in cui la connettività vada giù del tutto, avete almeno tre opzioni qui:

  • programma autossh
  • script bash (while true do ssh ...; sleep 5; done) non rimuovere il comando sleep, ssh può fallire rapidamente e si respawneranno troppi processi
  • /etc/inittab, per avere accesso a una scatola spedita e installata in un altro paese, dietro NAT, senza port forwarding alla scatola, è possibile configurarla per creare un tunnel ssh verso di voi:

  • script upstart su Ubuntu, dove /etc/inittab non è disponibile:

o usare sempre entrambi i metodi.

6
6
6
2013-05-30 13:32:05 +0000

Ho risolto il problema con questo:

Modifica

~/.ssh/config

E aggiungi

ServerAliveInterval 15
ServerAliveCountMax 4

Secondo la man page per ssh\config:

ServerAliveCountMax
         Sets the number of server alive messages (see below) which may be
         sent without ssh(1) receiving any messages back from the server.
         If this threshold is reached while server alive messages are
         being sent, ssh will disconnect from the server, terminating the
         session. It is important to note that the use of server alive
         messages is very different from TCPKeepAlive (below). The server
         alive messages are sent through the encrypted channel and there‐
         fore will not be spoofable. The TCP keepalive option enabled by
         TCPKeepAlive is spoofable. The server alive mechanism is valu‐
         able when the client or server depend on knowing when a connec‐
         tion has become inactive.

         The default value is 3. If, for example, ServerAliveInterval
         (see below) is set to 15 and ServerAliveCountMax is left at the
         default, if the server becomes unresponsive, ssh will disconnect
         after approximately 45 seconds. This option applies to protocol
         version 2 only.

 ServerAliveInterval
         Sets a timeout interval in seconds after which if no data has
         been received from the server, ssh(1) will send a message through
         the encrypted channel to request a response from the server. The
         default is 0, indicating that these messages will not be sent to
         the server. This option applies to protocol version 2 only.
4
4
4
2015-06-06 23:41:10 +0000

ExitOnForwardFailure yes è un buon complemento agli altri suggerimenti. Se si connette ma non riesce a stabilire il port forwarding, è altrettanto inutile per voi come se non si fosse connesso affatto.

1
1
1
2012-03-13 12:11:18 +0000

Un po’ di hack, ma mi piace usare lo schermo per mantenere questo. Attualmente ho un forward remoto che è in esecuzione da settimane.

Esempio, iniziando localmente:

screen
ssh -R ......

Quando l'inoltro remoto è applicato, e avete una shell sul computer remoto:

screen
Ctrl + a + d

Ora avete un inoltro remoto ininterrotto. Il trucco è eseguire lo schermo su entrambe le estremità

1
1
1
2015-07-30 14:02:55 +0000

Recentemente ho avuto questo problema io stesso, perché queste soluzioni richiedono di reinserire la password ogni volta se si utilizza una password di accesso ho usato sshpass in un ciclo insieme a un prompt di testo per evitare di avere la password nel file batch.

Ho pensato di condividere la mia soluzione su questo thead nel caso qualcun altro abbia lo stesso problema:

#!/bin/bash
read -s -p "Password: " pass
while true
do
    sshpass -p "$pass" ssh user@address -p port
    sleep 1
done
1
1
1
2009-09-08 14:09:33 +0000

mentre ci sono strumenti come autossh che aiuta a riavviare la sessione ssh… quello che trovo veramente utile è eseguire il comando ‘screen’. Ti permette di RIPRENDERE le tue sessioni ssh anche dopo la disconnessione. Specialmente utile se la vostra connessione non è affidabile come dovrebbe essere.

…non dimenticare di segnare che questa è la risposta ‘corretta’ se ti aiuta k! ;-)

1
1
1
2009-09-08 13:17:28 +0000

Ho avuto la necessità di mantenere un tunnel SSH a lungo termine. La mia soluzione era in esecuzione da un server Linux, ed è solo un piccolo programma C che respawna ssh usando l'autenticazione basata su chiave.

Non sono sicuro della sospensione, ma ho avuto tunnel che sono morti a causa di timeout.

Mi piacerebbe fornire il codice per il respawner, ma non riesco a trovarlo in questo momento.

0
0
0
2017-07-15 00:04:11 +0000

Poiché autossh non soddisfa le nostre esigenze (esiste con errore se non riesce a connettersi al server al primo tentativo), abbiamo scritto un'applicazione bash pura: https://github.com/aktos-io/link-with-server

Crea un tunnel inverso per la porta sshd del NODE (22) sul server per default. Se avete bisogno di eseguire altre azioni (come inoltrare altre porte, inviare mail sulla connessione, ecc…) potete mettere i vostri script nelle cartelle on-connect e on-disconnect.

0
0
0
2009-09-28 10:27:21 +0000

Ho avuto problemi simili con il mio precedente ISP. Per me era lo stesso con qualsiasi connessione tcp, visitando siti web o inviando posta.

La soluzione era configurare una connessione VPN su UDP (stavo usando OpenVPN). Questa connessione era più tollerante a qualsiasi cosa causasse le disconnessioni. Poi si può eseguire qualsiasi servizio attraverso questa connessione.

Ci possono ancora essere problemi con la connessione, ma poiché il tunnel sarà più tollerante, qualsiasi sessione ssh subirà un breve ritardo piuttosto che essere disconnessa.

Per fare questo avrete bisogno di un servizio VPN online che potete impostare sul vostro server.

0
0
0
2020-02-20 15:09:46 +0000

Potreste semplicemente usare il comando tmux sul vostro server remoto. Vi permette di aprire una “sessione” sulla macchina remota dove eseguirete il vostro codice remoto.

Poi potete uscire (o perdere la connessione nel vostro caso) dalla macchina remota senza preoccuparvi, dato che il vostro codice è al sicuro nella vostra sessione tmux.

Infine, quando vi riconnettete sul server remoto, avete solo bisogno di tmux attach per tornare alla sessione che avevate precedentemente aperto e questo è tutto.