Múltiplas sessões ssh no comando único

5

Estou tentando copiar um banco de dados de um servidor para outro. Eu tentei usar o seguinte comando e está ficando preso ao digitar as senhas ssh. Se eu colocar a senha de um servidor, ele reclama do outro e vice-versa.

ssh root@server1 mysqldump --databases db | ssh root@server2 mysql

Eu consegui fazer a transferência mantendo os lixões temporariamente no meu computador, apenas me perguntando se há uma maneira de fazer isso funcionar.

    
por Drew 28.02.2012 / 21:13

6 respostas

5

Prompts de senha são incômodos. A maneira de tornar o ssh mais utilizável é usar chaves para autenticação e executar um agente de chave ( ssh-agent ) onde você pode registrar uma chave uma vez por sessão (com um tempo limite opcional). Então você pode executar diretamente

ssh root@server1 mysqldump --databases db | ssh root@server2 mysql

Se você puder efetuar login do server1 para o server2, deverá transferir os dados diretamente entre os dois servidores.

ssh root@server1 'mysqldump --databases db | ssh root@server2 mysql'

(ou o contrário, se você puder efetuar login do server2 para o server1). Novamente, tenha uma chave SSH para autenticação. Em sua máquina local, registre uma chave privada SSH que forneça acesso ao servidor1 e outra que lhe dê acesso ao servidor2; Certifique-se de que o encaminhamento de agentes esteja ativado ( AgentForwarding yes in ~/.ssh/config ).

Se você realmente não pode evitar digitar uma senha, seu melhor recurso é primeiro estabelecer a conexão, depois ir e transferir os dados. Com versões recentes suficientes do OpenSSH, você pode abrir uma conexão principal e, em seguida, rotear conexões escravas através dela. As conexões escravas não requerem autenticação extra. No seu ~/.ssh/config :

ControlMaster auto
ControlPath ~/.ssh/control:%h:%p:%r

Iniciar uma conexão mestre para os dois servidores:

ssh -N -M root@server1 &
ssh -N -M root@server2 &

Depois faça a cópia:

ssh root@server1 mysqldump --databases db | ssh root@server2 mysql

Depois disso, você pode matar as conexões principais se não precisar mais delas.

ssh -O exit root@server1
ssh -O exit root@server2
    
por 29.02.2012 / 03:37
4

A maneira mais eficiente de fazer isso seria canalizar do mysqldump server. Mais ou menos como esta lista de comandos ...

ssh root@server1 'mysqldump --databases db | ssh root@server2 mysql'

Se você não puder canalizar da máquina remota, por alguma razão relacionada à configuração, você poderia fazer esta lista de comandos ...

ssh root@server1 'mysqldump db' | ssh root@server2 'mysql db'

Se eu fosse forçado a fazer o último, eu consideraria gziping o mysqldump . Acredito que isso me salvou algum tempo de transferência, independentemente de isso não ser a primeira escolha.

ssh root@server1 'mysqldump db | gzip -f' | ssh root@server2 'gzip -d | mysql db'

Este último exemplo, pode não ser 100% correto, estou supondo que deve funcionar.

    
por 28.02.2012 / 21:38
2

No caso de você ser forçado a passar de A para B com uma máquina semelhante a um proxy, não há mágica: você terá que usar o proxy, sendo seu computador ou um servidor intermediário.

Pode ser muito irritante, mas o ssh é tão flexível que pode ser transparente. Se você instalar o programa nc no proxy, poderá adicioná-lo ao seu ~/.ssh/config de A :

Host B
  ProxyCommand ssh -q my_proxy nc -q0 B 22

E depois disso, você poderá, de A , fazer comandos clássicos de ssh / scp para B como se não houvesse nenhum proxy.

Portanto, com essa configuração, você poderá usar sshfs .

sshfs B: /mnt/B_fs

E com sshfs, seu comando dump pode finalmente ter esta aparência:

 mysqldump --databases db ... > /mnt/B_fs/db.dump

Infelizmente, isso não acelera a largura de banda do proxy. O melhor que você pode fazer com o ssh é ativar Compression e aumentar CompressionLevel .

Veja este post para obter uma explicação mais detalhada sobre o multi-hop do ssh.

    
por 28.02.2012 / 22:57
2

Pelo que entendi, a principal dificuldade que você encontra é que você precisa digitar duas senhas: uma para a primeira conexão ssh (escrita para o pipe) e outra para a segunda conexão ssh (leitura do pipe).

Uma maneira razoável de lidar com esse problema (pouco razoável) é configurar uma chave temporária sem senha para autenticar de sua conta local para as contas raiz remotas. Desde que a configuração do daemon do ssh de remoção já suporte a autenticação baseada em chave, você pode configurar o login sem senha sem alterar a configuração do sshd. Com este método, no entanto, você precisa editar a lista authorized_keys para o usuário remoto.

Aqui está um script que gera uma chave sem senha, faz um login interativo em cada controle remoto para adicionar autorização de chave, não interativamente faz sua cópia do mysql, remove a autorização de forma não interativa e, finalmente, remove a chave gerada arquivos.

#!/bin/bash
set -e  # bail out if anything fails

verbose=
rmthosts="server1 server2"
rmtuser=root

# generate key with empty passphrase
keyfn=~/.ssh/tmpid_rsa
keycomment="tmpid_$USER@$HOSTNAME"
rm -f $keyfn*
ssh-keygen -t rsa -N '' -C $keycomment -f $keyfn

# add key to remote accounts
authfn=.ssh/authorized_keys
for rmthost in $rmthosts
do
    [ "$verbose" ] && echo "Adding key to $rmtuser@$rmthost:$authfn"
    < $keyfn.pub ssh $rmtuser@$rmthost "cat >>$authfn"
done


# perform your mysql copy
[ "$verbose" ] && echo "Performing operation"
ssh -i $keyfn rcp@gromit hostname | \
    ssh -i $keyfn rcp@gromit "cat >/tmp/prog.out"


# remove the temporary key
[ "$verbose" ] && echo "Removing temporary keys"
for rmthost in $rmthosts
do
    ssh -i $keyfn $rmtuser@$rmthost "sed -i '/$keycomment/d' $authfn"
done
ssh-add -d $keyfn
rm -f $keyfn*
    
por 29.02.2012 / 05:28
2

As principais soluções são as melhores. Mas se você, por algum motivo, não puder fazer isso, poderá modificar seu cmdline para

ssh root@server1 mysqldump --databases db | {sleep 5; ssh root@server2 mysql; }

para que o segundo comando aguarde. Ajuste o 5 de acordo com a rapidez com que você digita na primeira senha.

Esteja ciente de que esta é apenas uma solução alternativa e que as principais soluções são de longe melhores.

    
por 29.02.2012 / 08:41
0

Embora as soluções de gerenciamento de chaves sejam ótimas e o caminho a ser seguido, eu tenho outra maneira de fazê-lo sem: Use pipes nomeados e dois shells.

No primeiro tipo de shell

mkfifo ~/db_dump
cat db_dumb | ssh root@server2 mysql

e digite a segunda senha.

No outro tipo de shell

ssh root@server1 mysqldump --databases db >~/db_dump

e digite a primeira senha.

Quando o despejo é feito:

rm ~/db_dump

em qualquer shell.

Acho que você poderia começar o despejo primeiro e restaurar o segundo. Não deve fazer muita diferença.

    
por 15.02.2017 / 10:15