mac - ssh: comprueba si un túnel está vivo
ssh tunnel putty (9)
He escrito un pequeño script bash que necesita un túnel ssh para extraer datos de un servidor remoto, por lo que solicita al usuario:
echo "Please open an ssh tunnel using ''ssh -L 6000:localhost:5432 example.com''"
Me gustaría comprobar si el usuario abrió este túnel y salir con un mensaje de error si no existe un túnel. ¿Hay alguna forma de consultar el túnel ssh
, es decir, verificar si el puerto local 6000 está realmente en túnel hacia ese servidor?
Autossh es la mejor opción: el proceso de comprobación no funciona en todos los casos (por ejemplo, proceso zombie, problemas relacionados con la red)
ejemplo:
autossh -M 2323 -c arcfour -f -N -L 8088:localhost:80 host2
Esta es mi prueba. Espero que sea útil.
# $COMMAND is the command used to create the reverse ssh tunnel
COMMAND="ssh -p $SSH_PORT -q -N -R $REMOTE_HOST:$REMOTE_HTTP_PORT:localhost:80 $USER_NAME@$REMOTE_HOST"
# Is the tunnel up? Perform two tests:
# 1. Check for relevant process ($COMMAND)
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND
# 2. Test tunnel by looking at "netstat" output on $REMOTE_HOST
ssh -p $SSH_PORT $USER_NAME@$REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_HTTP_PORT.*LISTEN" /
> /dev/null 2>&1
if [ $? -ne 0 ] ; then
pkill -f -x "$COMMAND"
$COMMAND
fi
Esto es más una pregunta tipo serverfault, pero puede usar netstat.
algo como:
# netstat -lpnt | grep 6000 | grep ssh
Esto le dirá si hay un proceso ssh escuchando en el puerto especificado. también le informará el PID del proceso.
Si realmente desea verificar que el proceso ssh se inició con las opciones correctas, puede buscar el proceso por PID en algo como
# ps aux | grep PID
Estos son pasos más detallados para probar o solucionar problemas en un túnel SSH. Puede usar algunos de ellos en un script. Estoy agregando esta respuesta porque tuve que solucionar el vínculo entre dos aplicaciones después de que dejaron de funcionar. Simplemente desgranar para el proceso de ssh no fue suficiente, ya que todavía estaba allí. Y no pude usar nc -z
porque esa opción no estaba disponible en mi conjuro de netcat.
Vamos a empezar desde el principio. Supongamos que hay una máquina, que se llamará local con dirección IP 10.0.0.1 y otra, llamada remota , en 10.0.3.12. Precederé estos nombres de host, a los comandos a continuación, por lo que es obvio dónde se ejecutan.
El objetivo es crear un túnel que reenvíe el tráfico TCP desde la dirección de bucle invertido en la máquina remota en el puerto 123 a la máquina local en el puerto 456. Esto se puede hacer con el siguiente comando, en la máquina local:
local:~# ssh -N -R 123:127.0.0.1:456 10.0.3.12
Para verificar que el proceso se está ejecutando, podemos hacer:
local:~# ps aux | grep ssh
Si ve el comando en la salida, podemos continuar. De lo contrario, verifique que la clave SSH esté instalada en el control remoto. Tenga en cuenta que excluyendo el nombre de usuario antes de la IP remota, hace que ssh use el nombre de usuario actual.
A continuación, queremos verificar que el túnel esté abierto en el control remoto:
remote:~# netstat | grep 10.0.0.1
Deberíamos obtener un resultado similar a esto:
tcp 0 0 10.0.3.12:ssh 10.0.0.1:45988 ESTABLISHED
Sería bueno ver algunos datos desde el control remoto al host. Aquí es donde entra netcat . En CentOS se puede instalar con yum install nc
.
Primero, abra un puerto de escucha en la máquina local:
local:~# nc -l 127.0.0.1:456
Luego haz una conexión en el control remoto:
remote:~# nc 127.0.0.1 123
Si abre una segunda terminal en la máquina local, puede ver la conexión. Algo como esto:
local:~# netstat | grep 456
tcp 0 0 localhost.localdom:456 localhost.localdo:33826 ESTABLISHED
tcp 0 0 localhost.localdo:33826 localhost.localdom:456 ESTABLISHED
Mejor aún, sigue y escribe algo en el control remoto:
remote:~# nc 127.0.0.1 8888
Hallo?
anyone there?
Debería ver esto reflejado en la terminal local:
local:~# nc -l 127.0.0.1:456
Hallo?
anyone there?
¡El túnel está funcionando! Pero, ¿qué ocurre si tiene una aplicación, llamada appname , que se supone que escucha en el puerto 456 de la máquina local? Termina nc en ambos lados y luego ejecuta tu aplicación. Puede verificar que está escuchando en el puerto correcto con this :
local:~# netstat -tulpn | grep LISTEN | grep appname
tcp 0 0 127.0.0.1:456 0.0.0.0:* LISTEN 2964/appname
Por cierto, ejecutar el mismo comando en el control remoto debería mostrar sshd escuchando en el puerto 127.0.0.1:123.
Netcat es tu amigo:
nc -z localhost 6000 || echo ''no tunnel open''; exit 1
Podemos verificar usando el comando ps
# ps -aux | grep ssh
Mostrará todo el servicio shh ejecutándose y podremos encontrar el servicio de túnel listado
Use autossh . Es la herramienta que está destinada a monitorear la conexión ssh.
stunnel es una buena herramienta para hacer conexiones semipermanentes entre hosts.
#!/bin/bash
# Check do we have tunnel to example.com server
lsof -i tcp@localhost:6000 > /dev/null
# If exit code wasn''t 0 then tunnel doesn''t exist.
if [ $? -eq 1 ]
then
echo '' > You missing ssh tunnel. Creating one..''
ssh -L 6000:localhost:5432 example.com
fi
echo '' > DO YOUR STUFF < ''