8

Вот связь:

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

Сервер1 и сервер2 не могут напрямую общаться друг с другом (не спрашивайте). Мой рабочий стол, однако, может получить доступ к обоим серверам через SSH.

Мне нужно скопировать файлы с сервера1 на сервер2.

Традиционно я использую ssh+tar, как таковой:

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

И это прекрасно работает, но я хотел бы сделать еще один шаг и заставить rsync работать между двумя серверами VIA на моем рабочем столе.

Теперь я знаю, что могу запустить туннель пересылки портов ssh в одном терминале, а затем выполнить rsync через этот туннель в другом окне, но я не хочу возиться со вторым терминалом или создавать и разбивать отдельный туннель переадресации портов. что я хочу это:

  • Одна команда liner для rsync файлов с сервера 1 на сервер 2 через мой рабочий стол
  • все в ОДНОЙ командной строке, одно окно терминала
  • Я хочу, чтобы туннель переадресации портов существовал только в течение жизни команды rsync.
  • Я не хочу scp, я хочу rsync.

У кого-нибудь есть хитрость для этого?

РЕДАКТИРОВАТЬ: Вот рабочая команда! Отличная работа всех: 1. Для пути ключа rsa не могу использовать tildae, пришлось использовать "/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"

Бум идет динамитом.

3 ответа3

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
    

    (echo вероятно, не требуется, так как сеанс не будет простаивать достаточно долго для тайм-аута, даже если SSHd настроен на игнорирование пакетов keep-alive от клиента ssh)

  3. Теперь вы можете написать скрипт на своем ноутбуке, который запускает обратный туннель в фоновом режиме, говорит server1 использовать 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: уничтожить скрипт keep-alive после завершения операции rsync (и, таким образом, возвращается второй вызов SSH), что и первый сеанс ssh.

Это не кажется особенно чистым, но это должно работать. Я не проверял вышеизложенное, поэтому вам может понадобиться настроить его. Создание команды rsync в виде однострочного сценария на сервере server1 может помочь, уменьшив необходимость в экранировании таких символов, как 'в вызывающей команде ssh.

Кстати: вы говорите «не спрашивайте», почему два сервера не могут видеть друг друга напрямую, но для этого часто есть веская причина. Мой домашний сервер и сервер, на котором хранятся его резервные копии в онлайн-хранилище, не могут войти друг в друга (и имеют разные пароли + ключи для всех пользователей) - это означает, что если один из двух файлов взломан, он не может использоваться в качестве простого маршрута к взломайте другой, чтобы мои резервные копии в Интернете были безопаснее (кто-то, кто удаляет мои данные из живого хранилища, не может использовать его для обновления резервных копий, чтобы удалить указанные резервные копии, поскольку у него нет прямой возможности доступа к основному сайту резервного копирования). Оба сервера могут подключаться к промежуточному серверу где-либо еще - живой сервер настроен на передачу своих резервных копий (через rsync) на промежуточную машину рано утром, а резервный сервер настроен (через некоторое время, чтобы завершить первый шаг) для подключения и собирать обновления (снова через rsyc с последующим шагом моментального снимка для сохранения нескольких возрастов резервного копирования). Эта техника может быть полезна и в ваших обстоятельствах, и в этом случае я бы порекомендовал ее как более чистый способ ведения дел.

Редактировать: объединяя мой взлом с Аароном, чтобы избежать всего этого с копиями /bin /sh и отдельным скриптом keep-alive на server2, этот скрипт на вашем ноутбуке должен делать всю работу:

#!/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, который пересылает через другой туннель к local2 сервера server2: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, который можно использовать как однострочник копирования + вставки вместо скрипта.

2

Вот несколько методов, которые делают синхронизацию простой однострочной, но требуют некоторой работы по настройке.

  • Настройте обратный туннель ssh от server1 к вашему рабочему столу (извините, я не могу сказать вам заклинание .ssh/config в верхней части моей головы). Цепь это с подключением с вашего рабочего стола на сервер2. Запустите rsync с сервера1.

  • Установите прокси socks (или прокси http, который принимает CONNECT) на вашем рабочем столе. Используйте его, чтобы установить ssh-соединение с server1 на server2. Запустите rsync с сервера2.

  • Используйте unison вместо rsync. Но рабочий процесс отличается.

  • Смонтируйте каталоги с одного или обоих серверов на рабочем столе, используя 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 не будет завершен, пока кто-то использует канал.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .