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 -N
por 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
.