como executar um túnel em segundo plano como parte de um script de shell

como executar um túnel em segundo plano como parte de um script de shell

Eu corro estesdois comandoso tempo todo para me conectar à minha instância rds no aws que está protegida por um firewall (então eu faço um túnel através da instância ec2) assim:

comando 1: abra o túnel (executado em segundo plano)

ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &

comando 2: conecte-se ao banco de dados através da porta do túnel:

PGPASSWORD=password psql dbname -U user -h ip_address -p port;

o que é incrível, mas eu gostaria de colocar ambos em uma única função. Mas nada funcionou comigo:

tentativa 1: executar sem material de fundo:

function db()
{
    ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub &
    PGPASSWORD=password psql dbname -U user -h ip_address -p port;
}

simplesmente me diz isso:

$proddb
[1] 62924
psql: could not connect to server: Connection refused
    Is the server running on host "127.0.0.1" and accepting
    TCP/IP connections on port 6666?

embora o comando inicial esteja sendo executado em segundo plano:

ps aux | grep host
(standard input):435:abdullah         62924   0.0  0.0  4315660   5828 s006  S     3:06PM   0:00.03 ssh -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub

e se eu executar imediatamente o próximo comando depois dele .. eu me conecto ao banco de dados perfeitamente!

PGPASSWORD=password psql dbname -U user -h ip_address -p port;
user=>

como faço para que isso funcione?

Responder1

O primeiro comando não teve tempo de estabelecer um túnel quando o segundo comando foi executado, dando assim uma "Conexão recusada".

Apenas não use &, mas use a opção-f:

-f
Solicita que o ssh vá para segundo plano antes da execução do comando. Isso é útil se o ssh solicitar senhas ou frases secretas, mas o usuário quiser isso em segundo plano. Isso implica -n. A maneira recomendada de iniciar programas X11 em um local remoto é com algo como ssh -f host xterm.
Se a opção de configuração ExitOnForwardFailure estiver definida como “sim”, então um cliente iniciado com -f aguardará que todos os encaminhamentos de porta remota sejam estabelecidos com sucesso antes de se colocar em segundo plano.

Juntando tudo isso, substitua a linha ssh na função por:

ssh -o ExitOnForwardFailure=yes -f -N -L port:host:5432 user@$ip -i ~/.ssh/key.pub

dessa forma, executar a função várias vezes não deixará (múltiplo-1) ssh inútil em execução.

Também é possível substituir -Npor um curto comando de suspensão remota. Dessa forma, não haverá um comando ssh ocioso de longa duração que precisará ser pesquisado se precisar ser eliminado. O Ssh ainda aguardará o fim do uso do túnel antes de terminar, portanto o pequeno atraso não é um problema:

ssh -o ExitOnForwardFailure=yes -f -L port:host:5432 user@$ip -i ~/.ssh/key.pub sleep 15

Responder2

Esta solução da @AB também pode ser usada para criar um "servidor de salto" entre dmz (internet ou endpoints de borda) e mz (backend) com túnel de encaminhamento de porta ssh para hosts backend, por exemplo:

(todas as respectivas portas devem ser abertas usando firewall-cmd)

desthost_ip é o ip de destino para o serviço que está sendo acessado, ele deve ter um processo de resposta vinculado a ele, ou seja, tomcat, webapp, etc.

Na borda do DMZ:

ssh -o ExitOnForwardFailure=yes -f -L localhost_ip:port:desthost_ip:port user@dest_ip -i xyz.key sleep 15

Então, se localhost também tiver um ip público; supondo que desthost tenha um serviço baseado em https em execução, algo assim pode funcionar:

https://public_ip_of_localhost:port

Isso deve abrir a página do serviço desthost_ip:port.

ssh -o ExitOnForwardFailure=yes -f -L 192.168.1.199:8001:192.168.2.10:8081 [email protected] -i xyz.key sleep 15

E

https://192.168.1.199:8001 

ou

https://public_ip_for_192.168.1.199:8001

abrirá a página de serviço em 192.168.2.10:8081.

informação relacionada