rsync hackear para devolver arquivos entre dois servidores não conectados

8

Aqui está a conexão:

[Server1] <---> [my desktop] <---> [Server2]

Servidor1 e servidor2 não têm permissão para falar diretamente um com o outro (não pergunte). Meu desktop, no entanto, é capaz de acessar os dois servidores via ssh.

Eu preciso copiar os arquivos do server1 para o server2.

Por tradição, tenho usado um hack ssh + tar, como tal:

ssh -q root@Server1 'tar -vzc /path/to/files ' | ssh -q root@Server2 'tar -vzx -C /'

E isso funciona muito bem, mas eu gostaria de dar um passo além e fazer o rsync funcionar entre os dois servidores através do meu desktop.

Agora eu sei que eu poderia iniciar um túnel de redirecionamento de porta ssh em um terminal e depois rsync sobre esse túnel em outra janela, mas eu não quero mexer com um segundo terminal ou fazer e quebrar uma porta separada túnel. o que eu quero é:

  • Um comando de linha para arquivos rsync de Server1 para server2 VIA my desktop
  • tudo em uma linha de comando, uma janela de terminal
  • Eu quero que o túnel de encaminhamento de porta exista apenas durante a vida do comando rsync.
  • Eu não quero scp, quero rsync.

Alguém tem um truque para fazer isso?

EDIT: Aqui está o comando de trabalho! Ótimo trabalho a todos: 1. Para o caminho da chave rsa, não pode usar tildae, teve que usar "/ root /". 2. Aqui está a linha de comando final:

ssh -R 2200:SERVER2:22 root@SERVER1 "rsync -e 'ssh -p 2200 -i /root/.ssh/id_rsa_ROOT_ON_SERVER2' --stats --progress -vaz /path/to/big/files root@localhost:/destination/path"

Boom continua a dinamite.

    
por regulatre 23.08.2010 / 14:28

3 respostas

5

Se você deseja manter uma cópia dos dados na máquina intermediária, pode simplesmente escrever um script que atualizou a cópia local usando o servidor1 como referência e, em seguida, atualizou o backup no servidor2 usando a cópia local como referência:

#!/bin/sh
rsync user@server1:/path/to/stuff /path/to/loca/copy -a --delete --compress
rsync /path/to/loca/copy user@server2:/path/to/where/stuff/should/go -a --delete --compress

Usar um script simples significa que você deseja um único comando para fazer tudo. Isso, obviamente, pode ser um não-segurança se os dados forem confidenciais (você ou outras pessoas da sua empresa podem não querer uma cópia flutuando em seu laptop). Se server1 é local para você, então você pode simplesmente deletar a cópia local depois (já que será rápido para reconstruir através da LAN local na próxima vez).

A construção de um túnel para que os servidores possam efetivamente conversar entre si mais diretamente deve ser possível assim:

  1. No servidor 2, faça uma cópia de / bin / sh como / usr / local / bin / shforkeepalive. Use um link simbólico ao invés de uma cópia, então você não precisa atualizá-lo após as atualizações de segurança que o patch / bin / sh.
  2. No servidor 2, crie um script que não faça nada além de repetir a suspensão por alguns segundos e, em seguida, fazer eco de uma pequena quantidade de texto, e usar essa agora "cópia" de sh:

    #!/usr/local/bin/shforkeepalive
    while [ "1" != "0" ]; do
            echo Beep!
            sleep 5
    done
    

    (o echo provavelmente não é necessário, pois a sessão não ficará inativa por tempo suficiente para expirar, mesmo que o SSHd esteja configurado para ignorar os pacotes de manutenção do cliente ssh)

  3. Agora você pode escrever um script no seu laptop que inicia seu túnel reverso em segundo plano, diz ao server1 para usar o rsync para executar a operação de cópia e, em seguida, mata o túnel reverso matando o script de loop (que fechará a sessão SSH) :

    #!/bin/sh
    ssh user@server2 -L2222:127.0.0.1:22 /usr/local/bin/keepalivesctipt &
    ssh user@server1 -R2222:127.0.0.1:2222 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'
    ssh user@server2 killall shforkeepalive
    

A maneira como isso funciona:

  • Linha 1: padrão "comando para usar para interpretar este script" marcador
  • Linha 2: inicie uma conexão SSH com o túnel reverso e execute o script keepalive por meio dele para mantê-lo aberto. O trailing & diz ao bash para executar isso em segundo plano, para que as próximas linhas possam ser executadas sem esperar que ele termine
  • Linha 3: inicie um túnel que se conectará ao túnel acima para que server1 possa ver o server2 e execute o rsync para executar a cópia / atualização sobre essa disposição
  • Linha 4: elimina o script de manutenção de atividade assim que a operação de rsync é concluída (e, assim, a segunda chamada de SSH retorna), o que ocorrerá e a primeira sessão de ssh.

Isso não parece particularmente limpo, mas deve funcionar. Eu não testei o acima, então você pode precisar ajustá-lo. Tornar o comando rsync um script de linha única no server1 pode ajudar reduzindo qualquer necessidade de escapar de caracteres como o comando 'on the calling ssh.

BTW: você diz "não pergunte" por que os dois servidores não podem ver um ao outro diretamente, mas geralmente há boas razões para isso. Meu servidor doméstico e o servidor em que seus backups on-line são mantidos não podem fazer login entre si (e ter senhas e chaves diferentes para todos os usuários) - isso significa que se um dos dois for hackeado, ele não pode ser usado como um caminho fácil para hackear o outro para que meus backups on-line sejam mais seguros (alguém que deletar meus dados do live não pode usar sua capacidade de atualizar os backups para excluir os backups, pois não tem capacidade direta de tocar no site de backup principal). Ambos os servidores podem se conectar a um servidor intermediário em outro lugar - o servidor ativo é configurado para enviar seus backups (via rsync) para a máquina intermediária no início da manhã e o servidor de backup é configurado (um pouco mais tarde para concluir a etapa 1) e coletar as atualizações (novamente via rsyc seguido por uma etapa de snapshot para manter várias idades de backup). Essa técnica também pode ser usada em sua situação e, se for o caso, eu a recomendaria como uma maneira muito mais limpa de fazer as coisas.

Editar: Mesclando meu hack com o Aaron's para evitar todo o trabalho com cópias de / bin / sh e um script keep-alive separado no server2, esse script no seu laptop deve fazer todo o trabalho :

#!/bin/sh
ssh user@server2 -L2222:127.0.0.1:22 sleep 60 &
pid=$!
trap "kill $pid" EXIT 
ssh user@server1 -R2222:127.0.0.1:2222 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'

Como no caso acima, o rsync está se conectando ao localhost: 2222, que encaminha o túnel para o localhost do seu laptop: 2222, que é encaminhado através do outro túnel para o localhost do servidor2: 22.

Editar 2: Se você não se importa com o servidor1 ter uma chave que permite autenticar diretamente com o servidor2 (mesmo que não possa ver o servidor2 sem um túnel), você pode simplificar ainda mais com:

#!/bin/sh
ssh user@server1 -R2222:123.123.123:22 rsync /path/to/stuff [email protected]:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'

onde 123.123.123.123 é um endereço público para o server2, que pode ser usado como uma cópia + colar uma linha em vez de um script.

    
por 23.08.2010 / 15:33
2

Aqui estão alguns métodos que tornam a sincronização simples, mas requerem algum trabalho de configuração.

  • Configure um túnel ssh reverso do server1 para a sua área de trabalho (desculpe, eu não posso dizer o .ssh/config de incantation fora do topo da minha cabeça). Encadeie-o com uma conexão da sua área de trabalho para o server2. Execute o rsync do server1.

  • Configure um proxy de meias (ou um proxy http que aceite CONNECT) em sua área de trabalho. Use-o para estabelecer uma conexão ssh de server1 para server2. Execute o rsync do servidor2.

  • Use uníssono em vez de rsync. Mas o fluxo de trabalho é diferente.

  • Monte os diretórios de um ou de ambos os servidores em sua área de trabalho usando sshfs .

por 23.08.2010 / 23:39
1

Por que uma linha? Use um script de shell pequeno:

#!/bin/bash
# Run me on server1

# Create the port forward server1 -> desktop -> server2 (i.e.
# the first forward creates a second tunnel running on the desktop)
ssh -L/-R ... desktop "ssh -L/-R ... server2 sleep 1h" &    
pid=$!

# Kill port forward process on exit and any error
trap "kill $pid" EXIT 

rsync -e ssh /path/to/files/ root@localhost:/path/to/files/on/server2

IIRC, você pode definir o tempo de sono mais baixo; o primeiro ssh não terminará enquanto alguém usar o canal.

    
por 23.08.2010 / 15:34