두 리모컨 사이에서 파일을 재 동기화하는 방법은 무엇입니까?


54

로컬 쉘을 사용하여 두 개의 원격 호스트간에 파일을 전송하고 싶지만 두 개의 원격이 다음과 같이 지정된 경우 rsync가 동기화를 지원하지 않는 것 같습니다.

$ rsync -vuar host1:/var/www host2:/var/www
The source and destination cannot both be remote.

비슷한 결과를 얻기 위해 사용할 수있는 다른 해결 방법 / 명령은 무엇입니까?



1
실제로 세 번째 호스트에서 sshfs를 활용하여 두 개의 원격 호스트간에 재 동기화 할 수 있습니다. 그냥 그런 다음 호스트 3.이 host1 및 host2의 마운트 SSHFS을 사용 rsync를 1 ~ 2
윌리엄 레그

@WilliamLegg 사용의 단점 은 소스 및 대상 파일 시스템을 모두 로컬 sshfsrsync보고 델타 알고리즘을 비활성화한다는 것입니다. 그 시점에서 당신은 거의 사용할 수도 있습니다 cp -p. 이것 과 그에 대한 주석 을 제안하는 답변을 참조하십시오 .
roaima

답변:


50

알다시피, 원격 소스 및 원격 대상에서 rsync를 사용할 수 없습니다. 두 서버가 서로 직접 통신 할 수 없다고 가정하면 ssh를 사용하여 로컬 컴퓨터를 통해 터널링 할 수 있습니다.

대신에

rsync -vuar host1:/var/www host2:/var/www

이것을 사용할 수 있습니다

ssh -R localhost:50000:host2:22 host1 'rsync -e "ssh -p 50000" -vuar /var/www localhost:/var/www'

궁금한 점이 있으면이 -R옵션은 host1의 포트 50000에서 (로컬 컴퓨터를 통해) host2의 포트 22로 매핑되는 역방향 채널을 설정합니다. host1에서 host2로 직접 연결되지 않았습니다.


1
@roaima의 솔루션이 마음에 들지만 여러 가지 이유로 인해 작동하지 못했습니다. 결국 sshfs두 원격 디렉토리를 로컬로 마운트 한 다음 로컬로 마운트 된 두 디렉토리에서 사용했습니다 rsync.
aidan

키가 사용되는 예를 볼 수 있습니까? -issh 명령에 필요한 키를 지정하는 방법을 알아내는 데 어려움이 있습니다 .
onassar

@onassar -i key...ssh명령 뒤에 따옴표 안에 매개 변수를 추가합니다 . 그래도 도움이되지 않으면 언제든지 새로운 질문을하여 문맥에 대한 답변을 참조하십시오
roaima

1
역방향 연결은 로컬에서 ~ / .ssh / config를 읽지 않습니다. SSH 구성 파일이없는 것처럼 해결할 수있는 것을 사용해야합니다
Florenz Kley

1
'두 서버가 서로 직접 대화 할 수 없다고 가정합니다.' 이 솔루션은 직접 SSH 연결 을 방해하는 방화벽 또는 NAT 문제를 해결 합니다 . 그러나 보안상의 이유로 호스트 1의 소스 사용자에게 키 또는 자격 증명이 없거나 대상에 대한 쓰기 권한이 충분하지 않은 경우에는 다루지 않습니다. 이에 대해서는 Kevin Cox의 솔루션을 참조하거나 스크립트 또는를 사용하여 간접 연결을 사용하십시오 scp -3.
Cedric Knight

22

왜 한 호스트에 로그인하고 싶지 않은지 다른 호스트에 복사하고 싶지 않은 이유를 말하지 않았으므로 이유와 솔루션 중 하나를 공유 할 것입니다.

호스트에 다른 시스템에 로그인 할 수있는 SSH 키가 없기 때문에 한 시스템에 로그인 한 다음 다른 시스템에 rsync 할 수 없습니다. SSH 에이전트 전달을 사용하여 로그인 한 동안 첫 번째 호스트가 내 SSH 키를 사용할 수 있도록하여이 문제를 해결했습니다.

경고 : SSH 전달을 통해 호스트는 로그인 기간 동안 SSH 키를 사용할 수 있습니다. 키를 복사 할 수는 없지만 키를 사용하여 다른 컴퓨터에 로그인 할 수 있습니다. 위험을 이해하고 신뢰할 수없는 컴퓨터에 에이전트 전달을 사용하지 않아야합니다.

다음 명령에서 직접 연결을 열 수 SSH 에이전트 포워딩을 사용 host1하는 방법에 대해 host2. 이것은 명령을 실행하는 머신이 전송에 병목 현상을 일으키지 않는다는 이점이 있습니다.

ssh -A host1 rsync -vuar /var/www host2:/var/www

3
유효한 사용 사례를 설명하기위한 +1 (host1의 원격 사용자에게 대상 서버에 대한 권한이 없음); 중요한 보안 경고 (사용 포트 포워딩을위한 -D것이 아니라 -A오히려 키 제한보다는 네트워크를 해결하기 위해); 장점을 설명하기 위해; 명령이 짧기 때문에; 실제로 작동합니다. username@host1로컬 사용자 이름과 다른 경우 지정해야 할 수도 있습니다 . 또한 rsync는 host2에 연결할 때 호스트 키 확인을 수행하므로 host1의 키는 이미 host2의 ~ / .ssh / known_hosts에 있어야합니다. 그렇지 않으면 명령이 실패합니다.
Cedric Knight

놀랍게도 이것은 TeamCity에서 이전에는 할 수 없었던 일들을 조정하는 데 도움이되었습니다 (다른 TeamCity 사용자의 경우, 사용하기 전에 "SSH 에이전트"라는 "빌드 기능"을 빌드 구성에 추가해야합니다 . Confluencessh -A 참조) . jetbrains.com/display/TCD10/SSH+Agent ).
John Zwinck

12

나는 roaima의 대답을 좋아하지만 경로는 두 예제에서 동일하며 어느 것이 어느 것인지 모호합니다. 다음은 작동하지 않는다는 것을 확인했습니다.

rsync -vuar host1:/host1/path host2:/host2/path

그러나 이것은 ( -R기본값이므로 옵션 에서 localhost의 명시 적 bind_address를 생략했습니다 ) :

ssh -R 50000:host2:22 host1 'rsync -e "ssh -p 50000" -vuar /host1/path localhost:/host2/path'

host1의 개인 키와 host2의 공개 키를 사용하여 두 원격 호스트간에 ssh 키를 올바르게 설정해야합니다.

연결을 디버그하려면 두 부분으로 나누고 자세한 상태를 추가하십시오.

localhost$ ssh -v -R 50000:host2:22 host1

이것이 작동하면 host1에 쉘이 있습니다. 이제 host1에서 rsync 명령을 시도하십시오. 자세한 ssh 정보가 rsync 상태 정보와 섞이지 않도록 다른 창 에서이 작업을 수행하는 것이 좋습니다.

host1$ rsync -e "ssh -p 50000" -vuar /host1/path localhost:/host2/path

내 예제에서 경로는 소스, 대상입니다. 는 rsynchost2의 목표와 host1에서 시작됩니다. (의견에 설명을 요청했을 수도 있습니다.)
roaima

1
댓글을 달았지만 50 명 이상의 평판이 없으면 다른 사람의 게시물에 댓글을 달 수 없습니다 .
jaybrau

7

bash 스크립트 구문에서 roaima로 답변 형식을 변경하고 명확성을 위해 줄 연속 문자 '\'를 추가하면 포트 22000을 임의로 선택했습니다 ...

SOURCE_USER=user1
SOURCE_HOST=hostname1
SOURCE_PATH=path1

TARGET_USER=user2
TARGET_HOST=host2
TARGET_PATH=path2

ssh -l $TARGET_USER -A -R localhost:22000:$TARGET_HOST:22 \
$SOURCE_USER@$SOURCE_HOST "rsync -e 'ssh -p 22000' -vuar $SOURCE_PATH \
$TARGET_USER@localhost:$TARGET_PATH"

1
당신이 한 모든 것은 임의의 호스트 이름을 변수로 바꾸는 것입니까?
Jeff Schaller

3
그래, 내가 했어. 소스 머신, 대상, 소스 및 대상 경로가 어디인지에 대한 명확성을 추가합니다. 모든 것을 해결하는 데 시간이 걸렸으며 단순한 자리 표시 자 호스트 이름에서 명확하지 않았습니다.
David I.

다음에는 다른 사람의 답변을 직접 수정하여 수정하십시오.
roaima

이 대답은 ssh-agent 전달 (-A)과 리버스 터널 (-R)을 결합한 솔루션입니다.
camelthemammel

3

이상적인 방법은 rsync해당 서버 중 하나 에서 실행하는 것입니다. 그러나 원격 서버에서 스크립트를 실행하지 않으려면 로컬 시스템에서 스크립트를 실행하고 ssh를 수행하고 거기서 rsync를 실행할 수 있습니다.

ssh user@$host1 <<ENDSSH >> /tmp/rsync.out 2>&1 rsync -vuar /var/www host2:/var/www ENDSSH

또한 rysnc는 한 가지 방법으로 동기화를 수행합니다. 양방향 동기화를 원한다면 osync ( https://github.com/deajan/osync )를 볼 수 있습니다 . 나는 그것을 사용하고 도움이되는 것으로 나타났습니다.


0

추가 정보와 마찬가지로 :

점프 호스트를 사용하여 다른 두 시스템을 연결하지만 서로 직접 연결할 수없는 경우 sshfs를 다음 두 시스템 사이에서 매체로 사용할 수 있습니다 (점프 호스트에서).

$ mkdir ~/sourcepath ~/destpath
$ sshfs sourcehost:/target/dir ~/sourcepath
$ sshfs desthost:/target/dir ~/destpath
$ rsync -vua ~/sourcepath ~/desthpath

SSHFS는 점프 호스트에서 두 가지 경로를 제공하고 rsync는 파일이 항상 로컬에서 수행되는 것과 달리 항상 동기화되는 방식으로 파일의 동기화를 관리합니다.


1
성능이 끔찍합니다. 변경 사항을 감지하기 위해 rsync가 소스 서버에서 파일을 읽고 네트워크를 통해 모든 것을 전송하기 때문입니다. 직접 전송을 할 수 없다면 rsync를 사용하는 경우 이것을 먹어야한다고합니다. 또한 대상을 마운트하지 마십시오. 불필요하며 로컬 디스크와 통신한다고 생각하기 때문에 rsync가 일부 기본값을 변경하게합니다.
Kevin Cox

0

컴퓨터 중 하나에서 rsyncd (서버)를 실행할 수 있습니다.

이 방법은 ssh를 사용하여 rsync와 함께 SSH 터널링을 사용하는 데 필요한 비밀번호없이 루트로 '대상'(rsync 말로) '대상'에 대한 액세스를 허용하지 않기 때문에 내가 취하는 접근법입니다. 대본)

필자의 경우 소스 PC에서 단일 사용자를 허용하고 소스 측에서 rsync를 사용하여 대상 컴퓨터에 rsyncd 서버를 설정했습니다.

잘 작동합니다.


0

이것을 사용해보십시오. 그것은 나를 위해 작동합니다.

ssh src_user@src_host 'rsync -av /src/dir/location/ dest_user@dest_host:/dest/dir/loc/'

0

사용하기 쉬운 스크립트

수년에 걸쳐 나는 여기의 다른 모든 대답에서와 거의 같은 트릭으로 여러 번 이것을 해왔습니다. 그러나 세부 사항을 잘못 이해하고 문제를 파악하는 데 많은 시간을 소비하기 때문에 아래 스크립트를 생각해 냈습니다.

  1. 모든 세부 사항 (소스, 대상, 옵션)을 쉽게 지정할 수 있습니다
  2. 모든 단일 단계를 증분 테스트하고 문제가 발생하면 피드백을 제공하여 수정해야 할 사항을 알 수 있습니다.
  3. 경우 주위에 작동 ssh -A인증 데이터를 전파하는 데 실패 (이 가끔 발생하는 이유 해결 방법은 근본 원인을 찾는 것보다 쉽게 이후 모른다)
  4. 마지막으로 작업을 수행합니다.

스크립트를 사용하는 방법

  1. 암호 입력 하지 않고 localhost에서 두 호스트 모두로 ssh 할 수 있는지 확인하십시오 .
  2. 스크립트의 처음 몇 줄에 변수를 설정하십시오.
  3. 그것을 실행하십시오.

작동 원리

내가 말했듯이 여기의 다른 모든 대답과 동일한 트릭을 사용합니다.

  • ssh의 -Rlocalhost에서 host1로 ssh하는 옵션과 동시에 포트 전달을 설정하여 host1이 localhost를 통해 local2를 통해 host2 ( -R localhost:$FREE_PORT:$TARGET_ADDR_PORT) 로 연결할 수 있도록합니다.
  • -A두 번째 ssh 샤넬을 쉽게 인증 할 수있는 ssh의 옵션

나의 이것은 복잡하다! 더 쉬운 방법이 있습니까?

소스에서 대상으로 모든 또는 대부분의 바이트를 복사 할 때 그건 FAR 쉽게 사용할 수 tar:

ssh $SOURCE_HOST "tar czf - $SOURCE_PATH" \
    | ssh $TARGET_HOST "tar xzf - -C $TARGET_PATH/"

스크립트

#!/bin/bash
#-------------------SET EVERYTHING BELOW-------------------
# whatever you type after ssh to connect to SOURCE/TARGE host 
# (e.g. 1.2.3.4:22, user@host:22000, ssh_config_alias, etc)
# So if you use "ssh foo" to connect to SOURCE then 
# you must set SOURCE_HOST=foo
SOURCE_HOST=host1 
TARGET_HOST=host2 
# The IP address or hostname and ssh port of TARGET AS SEEN FROM LOCALHOST
# So if ssh -p 5678 someuser@1.2.3.4 will connect you to TARGET then
# you must set TARGET_ADDR_PORT=1.2.3.4:5678 and
# you must set TARGET_USER=someuser
TARGET_ADDR_PORT=1.2.3.4:5678
TARGET_USER=someuser

SOURCE_PATH=/mnt/foo  # Path to rsync FROM
TARGET_PATH=/mnt/bar  # Path to rsync TO

RSYNC_OPTS="-av --bwlimit=14M --progress" # rsync options
FREE_PORT=54321 # just a free TCP port on localhost
#---------------------------------------------------------

echo -n "Test: ssh to $TARGET_HOST: "
ssh $TARGET_HOST echo PASSED| grep PASSED || exit 2

echo -n "Test: ssh to $SOURCE_HOST: "
ssh $SOURCE_HOST echo PASSED| grep PASSED || exit 3

echo -n "Verifying path in $SOURCE_HOST "
ssh $SOURCE_HOST stat $SOURCE_PATH | grep "File:" || exit 5

echo -n "Verifying path in $TARGET_HOST "
ssh $TARGET_HOST stat $TARGET_PATH | grep "File:" || exit 5

echo "configuring ssh from $SOURCE_HOST to $TARGET_HOST via locahost"
ssh $SOURCE_HOST "echo \"Host tmpsshrs; ControlMaster auto; ControlPath /tmp/%u_%r@%h:%p; hostname localhost; port $FREE_PORT; user $TARGET_USER\" | tr ';' '\n'  > /tmp/tmpsshrs"

# The ssh options that will setup the tunnel
TUNNEL="-R localhost:$FREE_PORT:$TARGET_ADDR_PORT"

echo 
echo -n "Test: ssh to $SOURCE_HOST then to $TARGET_HOST: "
if ! ssh -A $TUNNEL $SOURCE_HOST "ssh -A -F /tmp/tmpsshrs tmpsshrs echo PASSED" | grep PASSED ; then
        echo
        echo "Direct authentication failed, will use plan #B:"
        echo "Please open another terminal, execute the following command"
        echo "and leave the session running until rsync finishes"
        echo "(if you're asked for password use the one for $TARGET_USER@$TARGET_HOST)"
        echo "   ssh -t -A $TUNNEL $SOURCE_HOST ssh -F /tmp/tmpsshrs tmpsshrs"
        read -p "Press [Enter] when done..."
fi

echo "Starting rsync"
ssh -A $TUNNEL $SOURCE_HOST "rsync -e 'ssh -F /tmp/tmpsshrs' $RSYNC_OPTS $SOURCE_PATH tmpsshrs:$TARGET_PATH"

echo
echo "Cleaning up"
ssh $SOURCE_HOST "rm /tmp/tmpsshrs"

tar단일 (비 증분) 전송이 있고 전송이 단일 패스로 완료된 경우 유용합니다 . 반면, rsync전달 핸들을 사용하면 재시작 및 증분 전송이 수행됩니다.
roaima

1
물론 @roaima-타르와 동등한 것으로 간주하지 않습니다. 나는 rsync가 100 % 필요하지 않은 문제를 해결하기 위해 이것을 읽을 날 에이 전달 참조를 남겼습니다.
ndemou

-1

tarvia 를 사용 ssh하여 파일을 전송할 수 있습니다.

ssh -n user1@host1 'tar jcf - -C /var/www .' | ssh user2@host2 'tar jxvf - -C /var/www'

대신을 사용 하여 아카이브를 압축하려면 j매개 변수 (for tar)를 z두 위치 로 변경하십시오 . 일반적으로 보다 압축률이 높지만 속도가 느리므로 필요에 따라 변경하십시오 ( bzip2 vs gzip 참조 ).gzipbzip2bzip2gzip

관련 : 타르를 사용하여 두 원격 호스트 사이에 복사하는 방법은 방화벽 원격 서버에서 SSH로 파이프?


또는 (투명한 압축으로 인해 대역폭을 안전하게하기 sshfs위해) 원격 파일 시스템을 로컬로 마운트 rsync하고 평소 와 같이 사용할 수 있습니다.

$ sshfs user1@host1:/var/www /mnt
$ rsync -vuar /mnt user2@host2:/var/www

1
파일 시스템을 로컬로 마운트하면 소스와 로컬 시스템 간의 대역폭이 절약되지 않습니다. 그것은 것입니다 (이 로컬로 마운트되지 않는) 그러나 지역과 대상 사이의 대역폭을 저장합니다. 이 방법으로 rsync를 사용하면 대상에서 대역폭을 절약하려는 경우에만 의미가 있습니다.
Kevin Cox
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.