Uso un tunnel SSH dal lavoro per aggirare vari firewall idotici (è ok con il mio capo :)). Il problema è che dopo un po 'la connessione ssh di solito si blocca e il tunnel è rotto.
Se potessi almeno monitorare automaticamente il tunnel, potrei riavviare il tunnel quando si blocca, ma non ho nemmeno immaginato un modo per farlo.
Punti bonus per chi può dirmi come impedire che la mia connessione SSH appaia, ovviamente!
Tutti i firewall stateful dimenticano una connessione dopo non aver visto un pacchetto per quella connessione per un po 'di tempo (per evitare che le tabelle di stato si riempiano di connessioni dove 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 essere ascoltato dall'altra parte (2 ore è un valore comune). Se, tuttavia, esiste un firewall di stato che si dimentica della connessione prima che i pacchetti keepalive possano essere inviati, una connessione inattiva ma prolungata morirà.
In questo caso, la soluzione è impedire che la connessione diventi inattiva. OpenSSH ha un'opzione chiamata ServerAliveInterval che può essere usata per impedire che la connessione rimanga inattiva troppo a lungo (come bonus, rileverà quando il peer è morto prima, anche se la connessione è inattiva).
Sulla tua mac o linux machine configura il tuo ssh tieni il server ssh vivo ogni 3 minuti. Apri un terminale e porta il tuo invisibile .ssh nella tua casa:
cd ~/.ssh/
quindi creare un file di configurazione a 1 riga con:
echo "ServerAliveInterval 180" >> config
dovresti anche aggiungere:
ServerAliveCountMax xxxx (high number)
il valore predefinito è 3, quindi ServerAliveInterval 180 interromperà l'invio dopo 9 minuti (3 dell'intervallo di 3 minuti specificato da ServerAliveInterval).
Ho usato il seguente script Bash per continuare a generare nuovi tunnel ssh quando il precedente muore. L'utilizzo di uno script è utile quando non si desidera o non è possibile installare pacchetti aggiuntivi o utilizzare il compilatore.
while true
do
ssh <ssh_options> [[email protected]]hostname
sleep 15
done
Si noti che questo richiede un file di chiavi per stabilire automaticamente la connessione, ma è il caso anche di autossh.
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 [email protected]
[Install]
WantedBy=multi-user.target
(Modifica il comando ssh per adattarlo)
sshtunnel
quindi assicurati che l'utente esista per primosystemctl enable sshtunnel
per impostarlo per l'avvio al momento dell'avviosystemctl start sshtunnel
per iniziare immediatamenteAggiornamento gennaio 2018 : alcune distribuzioni (ad 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.
Mi sembra che tu stia interpretando erroneamente ServerAliveCountMax. Come ho capito i documenti, è il numero di messaggi server alive che possono rimanere senza risposta senza che la connessione venga interrotta. Quindi, in casi come quello di cui stiamo discutendo qui, impostarlo su un valore elevato si limiterà a garantire che una connessione sospesa non venga rilevata e terminata!
La semplice impostazione di ServerAliveInterval dovrebbe essere sufficiente per risolvere il problema con un firewall che dimentica la connessione e lasciare basso ServerAliveCountMax consentirà al terminale di origine di notare l'errore e terminare se la connessione fallisce comunque.
Quello che vuoi è, 1) che la connessione rimanga aperta in modo permanente in circostanze normali, 2) che la connessione non venga rilevata e che il lato originario esca in caso di errore, e 3) che il comando ssh venga nuovamente emesso ogni volta che uscite (il modo in cui lo fai è molto dipendente dalla piattaforma, lo script "while true" suggerito da Jawa è unidirezionale, su OS XI è in realtà impostato un oggetto launchd).
Usa sempre l'opzione SSH ServerAliveInterval
nel caso in cui i problemi del tunnel siano generati dalle sessioni NAT scadute.
Usa sempre un metodo di rigenerazione nel caso in cui la connettività vada giù completamente, hai almeno tre opzioni qui:
while true do ssh ...; sleep 5; done
) non rimuove il comando sleep, ssh
potrebbe fallire rapidamente e rigenererai troppi processi/etc/inittab
, per avere accesso a una scatola spedita e installata in un altro paese, dietro NAT, senza il port forwarding alla casella, è possibile configurarla per creare un tunnel ssh:
tun1:2345:respawn:/usr/bin/ssh -i /path/to/rsaKey -f -N -o "ServerAliveInterval 180" -R 55002:localhost:22 [email protected] 'sleep 365d'
script upstart su Ubuntu, dove /etc/inittab
non è disponibile:
start on net-device-up IFACE=eth0
stop on runlevel [01S6]
respawn
respawn limit 180 900
exec ssh -i /path/to/rsaKey -N -o "ServerAliveInterval 180" -R 55002:localhost:22 [email protected]
post-stop script
sleep 5
end script
o utilizzare sempre entrambi i metodi.
Ho risolto questo problema con questo:
Modificare
~/.ssh/config
E aggiungi
ServerAliveInterval 15
ServerAliveCountMax 4
Secondo 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.
ExitOnForwardFailure yes
è un buon complemento agli altri suggerimenti. Se si connette ma non riesce a stabilire il port forwarding, è altrettanto inutile per te come se non fosse affatto connesso.
Un po 'un trucco, ma mi piace usare lo schermo per mantenere questo. Al momento ho un inoltro remoto che è stato in esecuzione per settimane.
Esempio, iniziando localmente:
screen
ssh -R ......
Quando viene applicato l'inoltro remoto e si dispone di una shell sul computer remoto:
screen
Ctrl + a + d
Ora hai un avanzamento remoto ininterrotto. Il trucco è quello di eseguire schermo su entrambe le estremità
Recentemente ho avuto questo problema da solo, perché queste soluzioni richiedono di reinserire la password ogni volta se si utilizza una password di accesso Ho usato sshpass in un loop con un prompt del testo per evitare di avere la password nel file batch.
Ho pensato di condividere la mia soluzione su questo punto nel caso in cui qualcun altro abbia lo stesso problema:
#!/bin/bash
read -s -p "Password: " pass
while true
do
sshpass -p "$pass" ssh [email protected] -p port
sleep 1
done
Ho avuto bisogno 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 respawn ssh usando l'autenticazione basata su chiave.
Non sono sicuro riguardo l'impiccagione, ma ho perso i tunnel a causa dei timeout.
Mi piacerebbe fornire il codice per il respawner, ma non riesco a trovarlo in questo momento.
mentre ci sono strumenti come autossh che aiutano a riavviare la sessione ssh ... quello che trovo veramente utile è eseguire il comando 'screen'. Ti permette di RIPRENDERE le tue sessioni ssh anche dopo che ti sei disconnesso. Particolarmente utile se la tua connessione non è affidabile come dovrebbe essere.
... non dimenticare di segnare questa è la risposta 'corretta' se ti aiuta k! ;-)
Poiché autossh
non soddisfa le nostre esigenze (esiste un errore se non riesce a connettersi al server al primo tentativo), abbiamo scritto una pura applicazione bash: https://github.com/aktos-io/link-con-server
Per impostazione predefinita, crea un tunnel inverso per la porta sshd del NODE (22) sul server. Se è necessario eseguire altre azioni (come l'inoltro di porte aggiuntive, l'invio di messaggi di posta elettronica sulla connessione, ecc.) È possibile inserire le cartelle di script on-connect
e on-disconnect
.
Ho avuto problemi simili con il mio ISP precedente. Per me è stato 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. Quindi puoi eseguire qualsiasi servizio tramite questa connessione.
Potrebbero esserci ancora problemi con la connessione, ma dal momento che il tunnel sarà più tollerante, qualsiasi sessione ssh sentirà un breve rallentamento invece di essere disconnessa.
Per fare ciò avrai bisogno di un servizio VPN online che puoi configurare sul tuo server.