두 개의 연결되지 않은 서버간에 파일을 반송하는 rsync 핵


8

연결은 다음과 같습니다.

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

서버 1과 서버 2는 서로 직접 대화 할 수 없습니다 (요청하지 마십시오). 그러나 내 데스크탑은 ssh를 통해 두 서버 모두에 액세스 할 수 있습니다.

server1에서 server2로 파일을 복사해야합니다.

전통적으로 나는 ssh + tar 핵을 사용하고있다 :

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

그리고 그것은 훌륭하게 작동하지만 한 걸음 더 나아가서 내 데스크탑을 통해 두 서버 사이에서 rsync 작업을하고 싶습니다.

이제는 한 터미널에서 ssh 포트 전달 터널을 시작한 다음 다른 창에서 해당 터널을 재 동기화 할 수 있다는 것을 알고 있지만 두 번째 터미널로 혼란을 겪거나 별도의 포트 포워드 터널을 만들고 끊고 싶지 않습니다. 내가 원하는 것은 :

  • 데스크탑 1에서 서버 1에서 서버 2로 파일을 재 동기화하는 하나의 라이너 명령
  • 하나의 명령 행에서 하나의 터미널 창
  • 포트 전달 터널이 rsync 명령 수명 동안 만 존재하기를 원합니다.
  • 나는 scp하고 싶지 않고 rsync하고 싶다.

아무도 그 일을하는 데 트릭이 있습니까?

편집 : 다음은 작업 명령입니다! 모두가 대단한 일 : 1. rsa 키 경로의 경우 틸대를 사용할 수 없으며 "/ root /"를 사용해야했습니다. 2. 최종 명령 줄은 다음과 같습니다.

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"

붐은 다이너마이트를 간다.


정말 훌륭합니다. 변경해야 할 한 가지는 호스트 키 확인을 비활성화하는 것입니다. TTYless 인증을위한 SSH 키가 있지만 서버가 서로 대화 한 적이 없으므로 호스트 키를 확인할 수 없습니다. -p 또는 -i 플래그 다음에 -o StrictHostKeyChecking = no를 비활성화하는 것이 가장 좋습니다.
Amala

답변:


5

중간 머신에 데이터 사본을 유지하려면 server1을 참조로 사용하여 로컬 사본을 업데이트 한 다음 로컬 사본을 참조로 사용하여 server2에서 백업을 업데이트 한 스크립트를 작성하면됩니다.

#!/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

간단한 스크립트를 사용한다는 것은 모든 것을하기 위해 단일 명령을 원한다는 것을 의미합니다. 데이터가 민감한 경우에는 물론 보안상의 문제가되지 않을 수 있습니다 (귀하 또는 회사의 다른 사람이 랩톱에서 복사본을 띄우고 싶지 않을 수 있음). server1이 로컬 인 경우 다음에 로컬 사본을 신속하게 재구성하므로 나중에 로컬 사본을 삭제할 수 있습니다.

서버가 서로 직접 통신 할 수 있도록 터널을 구성하면 다음과 같이 가능합니다.

  1. 서버 2에서 / bin / sh를 / usr / local / bin / shforkeepalive로 복사하십시오. 복사본 대신 기호 링크를 사용하면 / bin / sh를 패치하는 보안 업데이트 후에 업데이트 할 필요가 없습니다.
  2. 서버 2에서 몇 초 동안 루프 절전 모드를 수행 한 다음 소량의 텍스트를 출력하는 스크립트를 작성하고 이제 sh의 "복사"를 사용하십시오.

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

    echoSSHd가 ssh 클라이언트의 keep-alive 패킷을 무시하도록 구성되어 있어도 세션이 시간 초과 될 정도로 오랫동안 유휴 상태가 아니기 때문에 아마도 필요하지 않습니다.

  3. 이제 랩톱에서 백그라운드에서 역방향 터널을 시작하고 rsync를 사용하여 복사 작업을 수행하도록 지시 한 다음 루핑 스크립트를 종료하여 역방향 터널을 종료하는 스크립트를 작성할 수 있습니다 (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 user@127.0.0.1:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'
    ssh user@server2 killall shforkeepalive
    

이것이 작동하는 방식 :

  • 1 행 : 표준 "이 스크립트를 해석하는 데 사용하는 명령"마커
  • 2 행 : 리버스 터널로 SSH 연결을 시작하고이를 통해 keepalive 스크립트를 실행하여 열어 둡니다. 후행은 bash가 백그라운드에서 이것을 실행하도록 지시하므로 다음 줄이 끝나기를 기다리지 않고 실행할 수 있습니다.
  • 3 행 : server1이 server2를 볼 수 있도록 위의 터널에 연결할 터널을 시작하고 rsync를 실행하여이 배열을 통해 복사 / 업데이트를 수행하십시오.
  • 4 행 : rsync 작업이 완료되면 두 번째 SSH 호출이 반환되고 첫 번째 ssh 세션 인 keep-alive 스크립트를 종료합니다.

이것은 특별히 깨끗하지는 않지만 작동합니다. 위의 테스트를 수행하지 않았으므로 조정해야 할 수도 있습니다. rsync 명령을 server1에서 단일 행 스크립트로 만들면 호출하는 ssh 명령에서 '와 같은 문자를 이스케이프 처리해야하는 필요성을 줄일 수 있습니다.

BTW : 두 서버가 서로를 직접 볼 수없는 이유에 대해 "조회하지 마십시오"라고 말하지만 그 이유는 종종 있습니다. 온라인 백업이 유지되는 내 홈 서버와 서버는 서로 로그인 할 수 없으며 모든 사용자에 대해 다른 암호 + 키를 갖습니다. 즉, 두 서버 중 하나가 해킹되면 쉽게 액세스 할 수 없습니다. 온라인 백업이 더 안전 해 지도록 다른 시스템을 해킹하십시오 (실시간에서 내 데이터를 악의적으로 삭제하는 사람은 백업을 업데이트하여 해당 백업을 삭제하는 기능을 사용할 수 없으므로 기본 백업 사이트를 직접 만질 수는 없습니다). 두 서버 모두 다른 곳의 중간 서버에 연결할 수 있습니다. 라이브 서버는 아침 일찍 rsync를 통해 백업을 중간 머신으로 푸시하도록 설정되고 백업 서버는 연결을 위해 (나중에 1 단계를 완료하기 위해 잠시 후에) 설정됩니다 업데이트를 수집합니다 (rsyc를 통해 여러 백업 기간을 유지하기 위해 스냅 샷 단계). 이 기술은 귀하의 상황에서도 사용할 수 있으며, 그렇다면 훨씬 더 깨끗한 방식으로 작업하는 것이 좋습니다.

편집 : server2의 / bin / sh 사본과 별도의 keep-alive 스크립트로 인해 발생하는 모든 문제를 피하기 위해 Aaron의 해킹을 병합하면 랩톱 의이 스크립트가 전체 작업을 수행해야합니다.

#!/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 user@127.0.0.1:/destination/path/to/update -a --delete --compress -e 'ssh -p 2222'

위와 같이 rsync는 localhost : 2222에 연결하여 터널을 노트북의 localhost : 2222로 전달하고 다른 터널을 통해 다른 터널을 통해 server2의 localhost : 22로 전달합니다.

편집 2 : server1이 server2로 직접 인증 할 수있는 키를 가지고 있지 않다면 (터널없이 server2를 볼 수는 없지만) 다음과 같이 단순화 할 수 있습니다.

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

여기서 123.123.123.123은 server2의 공개 주소이며 스크립트 대신 copy + paste one-liner로 사용할 수 있습니다.


대량의 데이터 (20 + 기가 바이트)이며 로컬에 저장하는 대신 동시에 입출력하는 것이 좋습니다. 아무것도 저장하지 않고 PC를 통해 데이터를 스트리밍하고 싶습니다. 당신은 "묻지 마라"에 대해 옳습니다. 비록 피타에도 불구하고 좋은 이유입니다.
regulatre

Plesae는 원래 질문에 대한 새로운 편집을 봅니다
regulatre

내 마지막 편집 (타임 스탬프에 따라 주석이 게시되기 몇 초 전에 게시되어 아마 동시에 입력했을 수 있음)은 찾고있는 한 줄짜리 줄 것입니다.
David Spillett

안녕하세요 !!! 효과가있다! 1. rsa 키의 경우 틸대를 사용할 수 없으며 "/ root /"를 사용해야했습니다. 2. 최종 명령 줄은 다음과 같습니다.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"
regulatre

안녕하세요 @David,이 멋진 해킹에 감사드립니다. 그러나 제대로 작동하려면 두 솔루션 (첫 번째 및 두 번째 편집 모두)을 사용하여 서버 1에서 서버 2의 키가 필요합니다. 나는 그것이 정상이라고 생각합니다 (포트 전달, server1이 여전히 server2에 인증하려고합니다) If you don't mind server1 having a key .... server1에 server2의 키가없는 것을 실제로 피할 수 있는지 말해 줄 수 있습니까?
ssssteffff 2014

2

동기화를 단순한 원 라이너로 만드는 몇 가지 방법이 있지만 설정 작업이 필요합니다.

  • server1에서 데스크탑으로 역방향 ssh 터널을 설정하십시오 (죄송합니다, .ssh/config머리 꼭대기 에서 주문을 말할 수는 없습니다 ). 데스크탑에서 서버로 연결하여 연결하십시오 2. server1에서 rsync를 실행하십시오.

  • 데스크탑에서 socks 프록시 (또는 CONNECT를 허용하는 http 프록시)를 설정하십시오. 이를 사용하여 server1에서 server2로 ssh 연결을 설정하십시오. server2에서 rsync를 실행하십시오.

  • rsync 대신 unison 을 사용하십시오 . 그러나 워크 플로우는 다릅니다.

  • sshfs를 사용하여 데스크탑의 하나 또는 두 서버에서 디렉토리를 마운트하십시오 .


1

왜 한 줄? 작은 쉘 스크립트를 사용하십시오.

#!/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, 수면 시간을 더 낮게 설정할 수 있습니다. ssh누군가가 채널을 사용하는 한 첫 번째 는 종료되지 않습니다.


나는 확신 rsync를가 SSH를 통해 두 개의 원격 서버간에 작동하지 않을 수있어 그런 식으로 (단지 로컬 -> 원격 또는 remote-> 로컬) -의 사용 불구 sleep하고 trap내 대답 방법을 "살아 유지하고 죽이기"보다 깔끔한 모양이다 .
David Spillett

원래 질문에 대한 수정 사항을 참조하십시오.
regulatre

젠장, 네 말이 맞아 명령 링에서 두 개의 호스트를 인수로 지정할 수 없습니다. ... hmmm ..
Aaron Digulla

좋아, 나는 해결책을 향상시켰다. server1의 ssh 서비스를 server1에 표시하려면 두 개의 포트 전달을 작성해야합니다.
Aaron Digulla

";"몇 개 추가 그것을 하나의 라이너로 바꾸십시오. 아이디어를 스크립트로 이해하기가 더 쉽습니다.
Aaron Digulla
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.