Como configurar um atalho para uma conexão SSH por meio de um túnel SSH

22

Os servidores de produção da minha empresa (FOO, BAR ...) estão localizados atrás de dois servidores de gateway (A, B). Para conectar-me ao servidor FOO, tenho que abrir uma conexão ssh com o servidor A ou B com meu nome de usuário JOHNDOE e, em A (ou B), posso acessar qualquer servidor de produção que abra uma conexão SSH com um nome de usuário padrão (vamos chamá-lo WEBBY).

Então, cada vez que tenho que fazer algo como:

ssh johndoe@a
...
ssh webby@foo
...
# now I can work on the server

Como você pode imaginar, esse é um problema quando preciso usar scpou se preciso abrir rapidamente várias conexões.

Eu configurei uma chave ssh e também estou usando .ssh / config para alguns atalhos.

Eu queria saber se posso criar algum tipo de configuração ssh para digitar

ssh foo

e deixe o SSH abrir / encaminhar todas as conexões para mim. É possível?

Editar

A resposta do womble é exatamente o que eu estava procurando, mas parece que agora não posso usar o netcat porque ele não está instalado no servidor de gateway.

weppos:~ weppos$ ssh foo -vv
OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/xyz/.ssh/config
debug1: Applying options for foo
debug1: Reading configuration data /etc/ssh_config
debug2: ssh_connect: needpriv 0
debug1: Executing proxy command: exec ssh a nc -w 3 foo 22
debug1: permanently_drop_suid: 501
debug1: identity file /Users/xyz/.ssh/identity type -1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_rsa type 1
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug2: key_type_from_name: unknown key type 'Proc-Type:'
debug2: key_type_from_name: unknown key type 'DEK-Info:'
debug2: key_type_from_name: unknown key type '-----END'
debug1: identity file /Users/xyz/.ssh/id_dsa type 2
bash: nc: command not found
ssh_exchange_identification: Connection closed by remote host
Simone Carletti
fonte

Respostas:

36

Como uma versão mais concreta da resposta de Kyle, o que você deseja colocar no seu ~/.ssh/configarquivo é:

host foo
  User webby
  ProxyCommand ssh a nc -w 3 %h %p

host a
  User johndoe

Então, quando você executa "ssh foo", o SSH tenta johndoe@aexecutar o SSH , execute netcat( nc) e, em seguida, executa um SSH webby@fooatravés deste túnel. Magia!

Obviamente, para fazer isso, o netcat precisa estar instalado no servidor de gateway; este pacote está disponível para todas as principais distribuições e sistemas operacionais.

mulher
fonte
Excelente! Eu estava tentando descobrir isso, eu nunca tinha entrado nessa situação exata antes. Manterei minha resposta lá, caso isso possa ajudar alguém com uma situação menos específica no futuro.
Kyle Brandt
Atualizei minha pergunta original, incluindo a saída detalhada da minha conexão. Parece que não posso usar o netcat. Deve estar disponível por padrão?
Simone Carletti
Nem sempre, você tem o poder de instalá-lo? Você pode ser capaz de fazer isso com telnet também, eu nunca tentei isso ...
Kyle Brandt
Você também pode fazer o download do netcat para o diretório inicial e compilá-lo lá. Você poderia, então, basta usar o caminho completo no comando proxy, ou seja, / home / usuário / bin / nc
Kyle Brandt
Acabei de verificar as configurações do sistema. No Ubuntu, o netcat parece estar disponível por padrão, infelizmente os servidores de gateway são equipados com o OpenSUSE. Também vou considerar instalar o netcat nos servidores de gateway.
Simone Carletti
7

Você pode usar a diretiva ProxyCommand no seu arquivo ~ / .ssh / config, por exemplo, para usar o netcat como o relé:

host server2
    ProxyCommand ssh server1 nc server2 22

Você usaria apenas 'ssh server2'. As informações da página de manual desta diretiva são encontradas em 'man ssh_config'

Kyle Brandt
fonte
5

Prefiro uma abordagem diferente que mantenha um túnel pré-autenticado no servidor de gateway. Em ~/.ssh/config:

Host a
    ControlMaster auto
    ControlPath ~/.ssh/control-master/%r@%h:%p

Então em .bashrc:

s () {
        if ( ssh -O check a 2>&1 > /dev/null 2>&1 )
        then
                ssh -t a ssh $1
        else
                if [[ -S ~/.ssh/control-master/insyte@a:22 ]]
                then
                        echo "Deleting stale socket..."
                        rm ~/.ssh/control-master/insyte@a:22
                fi
                echo "Opening master session..."
                if ssh -Nf a
                then
                         ssh -t a ssh $1
                fi
        fi
 }

Então, para se conectar ao foo:

s foo

A primeira vez que você o conectar, o autenticará em "a" e abrirá um túnel ssh persistente e em segundo plano. Chamadas subsequentes para "s" serão abertas quase instantaneamente através do túnel pré-autenticado.

Funciona bem.

Insyte
fonte
2

Esse tipo de funcionalidade existe nas versões mais recentes do OpenSSH e pode ser usado fazendo

ssh -W server2 server1

Onde server2está o seu destino pretendido e server1é o seu host proxy. Você pode facilitar isso usando a ProxyCommandopção na sua configuração ssh, algo como:

host = *.example.com
user = packs
port = 22
ProxyCommand ssh -W %h:%p server1
Scott Pack
fonte
Parece que, para que isso funcione, você precisa do OpenSSH 5.4+ nos três locais: desktop, intermediário, destino. (Bem, o primeiro e o último, certamente).
Steve Bennett
@ SteveBennett: Estou usando esse método há algum tempo, funciona muito bem. Eu tive que voltar ao método netcat em alguns sistemas RHEL5, o que era irritante.
Scott pacote de
2

Quando netcatnão estiver disponível no proxy, tente este truque:

host foo
  User webby      
  ProxyCommand ssh a 'exec 3<>/dev/tcp/foo/22; cat <&3 & cat >&3;kill $!'

host a
  User johndoe

Então você deve ser capaz ssh foo.

Além disso, se você possui uma versão recente do ssh em a (por exemplo, com o -Wcomando para encaminhar entrada e saída padrão), poderá usar:

host foo
  User webby
  ProxyCommand ssh -W foo:%p a

host a
  User johndoe

Finalmente, só porque achei legal (e não porque funcionará no seu caso em particular, devido a diferenças de nome de usuário), a postagem de blog de um amigo mostra como tornar esse tipo de coisa dinâmica e encadear proxies SSH recursivamente em cadeia (junto com algumas coisas que não funcionam bem):

host */*
  ProxyCommand ssh ${$(dirname %h)/\%%/@} nc ${$(basename %h)#*%%} %p

E então ssh machine1/machine2deve lhe dar uma concha machine2, encapsulada machine1.

Gostaria de saber se o uso de sedcomandos personalizados em vez de dirnamee basenamepode não resolver o problema com diferentes nomes de usuário?

Paul Price
fonte
2

Isso pode ser conseguido fazendo ssh -At johndoe@a ssh webby@foo. O -Acomando encaminha seu agente ssh (para que você não precise se autenticar novamente no proxy), enquanto -tgarante que exista um terminal no proxy. A seguinte função bash pode ser útil:

ssh-bounce () {
    local cmd=""
    for i in "$@"; do
        cmd+="ssh -At $i "
    done
    $cmd
}
Marcin
fonte
Esta é de longe a solução mais simples. Agora, ele só precisa de mais 35 votos positivos. (Btw o -A não faz nada para mim.)
Steve Bennett
0
weppos:~ weppos$ ssh foo -vv
[..]
bash: nc: command not found

O Netcat não está instalado a. Quando você executa ssh host "command arg", commandé executado host, não na máquina local.

markdrayton
fonte
Sim eu conheço. Foi exatamente isso que relatei em um comentário à resposta de womble. :)
Simone Carletti
0

Desde o OpenSSH 7.3 (01/08/2016), a ProxyJumpopção e o -Jsinalizador da linha de comando correspondentes estão disponíveis para permitir uma indireção mais simples através de um ou mais bastiões do SSH ou "jump hosts".

Isso remove a dependência do nccomando externo, conforme encontrado na solução da Womble .

ssh -J johndoe@a webby@foo 

estabelecerá uma conexão SSH da estação de trabalho para o servidor gateway acomo usuário johndoe e encapsulará a sessão SSH para hospedar o usuário da Web por meio disso.

Para simplificar a criação de definições de host para você ~/.ssh/confige sua, você pode simplesmente executarssh foo

Host a
    User johndoe

Host foo
    User Webby 
    ProxyJump a
HBruijn
fonte