rsync-хак для відмов файлів між двома непоєднаними серверами


8

Ось підключення:

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

Server1 і server2 заборонено спілкуватися безпосередньо з іншими (не запитувати). Однак мій робочий стіл може отримати доступ до обох серверів через ssh.

Мені потрібно скопіювати файли з server1 на server2.

Традиційно я використовую ssh + tar hack як такий:

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

І це чудово працює, але я хотів би зробити його крок далі і примусити rsync працювати між двома серверами VIA на моєму робочому столі.

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

  • Одна команда вкладиша для rsync файлів з Server1 на server2 VIA мого робочого столу
  • всі в одному командному рядку, одне вікно терміналу
  • Я хочу, щоб тунель переходу в порт існував лише протягом життя команди rsync.
  • Я не хочу робити scp, я хочу rsync.

Хтось має хитрість робити це?

EDIT: Ось робоча команда! Відмінна робота для всіх: 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"

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


Це справді чудово. Єдине, що потрібно змінити - це вимкнути перевірку ключів хоста. У вас є ключ SSH для аутентифікації TTYless, але оскільки сервери ніколи не спілкувалися один з одним, вони не можуть перевірити ключі хоста. Тож краще відключити його: -o StrictHostKeyChecking = немає після прапорців -p або -i.
— Amala

Відповіді:


5

Якщо ви раді зберігати копію даних на проміжній машині, тоді ви можете просто написати сценарій, який оновив локальну копію за допомогою сервера1 як посилання, а потім оновив резервну копію на сервері2, використовуючи локальну копію як довідку:

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

Використання простого сценарію означає, що ви хотіли, щоб одна команда виконала все. Звичайно, це може бути безпекою, ні - якщо дані є конфіденційними (ви або інші особи у вашій компанії, можливо, не хочете, щоб копія плавала навколо вашого ноутбука). Якщо сервер1 є локальним для вас, ви можете просто видалити локальну копію згодом (оскільки це буде швидко відновити через локальну локальну мережу наступного разу).

Побудувати тунель, щоб сервери могли ефективніше спілкуватися один з одним безпосередньо, повинно бути можливим так:

  1. На сервері 2 зробіть копію / bin / sh as / usr / local / bin / shforkeepalive. Використовуйте символічне посилання, а не копію, тоді ви цього не робите; не потрібно буде оновлювати його після оновлень безпеки, які патч / бін / ш.
  2. На сервері 2 створіть сценарій, який не робить нічого, крім циклу, який спить протягом декількох секунд, після чого повторюється невелика кількість тексту, і використовуйте для цього тепер "копію" sh:

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

    ( echoнапевно, це не потрібно, оскільки сеанс не буде простоювати досить довго, щоб затримати час, навіть якщо SSHd налаштований ігнорувати збережені пакети від 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 через нього, щоб тримати його відкритим. Trailing & каже bash запустити це у фоновому режимі, щоб наступні рядки могли працювати, не чекаючи, коли він закінчиться
  • Рядок 3: запустіть тунель, який підключиться до тунелю вище, щоб сервер1 міг бачити server2 та запустити rsync, щоб виконати копіювання / оновлення для цієї домовленості
  • Рядок 4: вбити сценарій збереження в живих, коли операція rsync завершиться (і так повернеться другий дзвінок SSH), що буде і першим сеансом ssh.

Це не особливо чисто, але це має працювати. Я не перевіряв вищезазначене, тому вам може знадобитися налаштувати його. Зробити команду rsync однорядковою скриптом на сервері1 може допомогти, зменшивши будь-яку необхідність уникнути символів, таких як 'у виклику команди ssh.

BTW: ви кажете "не запитувати", чому два сервери не можуть бачити один одного безпосередньо, але для цього часто є вагомі причини. Мій домашній сервер і сервер, на якому зберігаються його резервні копії в Інтернеті, не можуть входити один до одного (і мати різні паролі + ключі для всіх користувачів) - це означає, що якщо один з двох зламаний, його не можна використовувати як простий шлях до зламати інше, щоб мої онлайн-резервні копії були безпечнішими (хтось шкідливий, видаляючи мої дані з живих, не може використовувати його здатність оновити резервні копії для видалення зазначених резервних копій, оскільки він не має прямої можливості торкатися головного резервного веб-сайту). Обидва сервери можуть обидва підключитися до проміжного сервера в іншому місці - сервер в реальному часі встановлюється для того, щоб рано вранці проштовхувати його резервні копії (через rsync) на проміжну машину, а сервер резервного копіювання встановлюється (на деякий час пізніше, щоб дозволити завершити крок перший) для підключення і збирати оновлення (знову через rsyc з подальшим кроком зйомки з метою збереження кількох віків резервного копіювання). Ця методика може бути корисною і за ваших обставин, і якщо так, я рекомендував би її як набагато чистіший спосіб робити речі.

Редагувати: Об’єднавши мій хак з Аароном, щоб уникнути всіх маніпуляцій із копіями / bin / sh та окремим сценарієм збереження в режимі "живий" на сервері2, цей сценарій на вашому ноутбуці повинен виконати всю роботу:

#!/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, який передає через інший тунель до localhost сервера2: 22.

Редагування 2: Якщо ви не заперечуєте, щоб сервер1 мав ключ, який дозволяє йому автентифікувати сервер2 безпосередньо (хоча він не може бачити сервер2 без тунелю), ви можете додатково спростити:

#!/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 - це загальнодоступна адреса для сервера2, яка може використовуватися як копія + вставлення однокласника замість сценарію.


Це великий об'єм даних (20 + gb), і я вважаю за краще передавати їх у той чи інший час, а не зберігати локально. Я хочу передавати дані через свій ПК, не зберігаючи нічого. Ви маєте рацію щодо "не запитуйте", це з поважної причини, хоч і піта.
— регулятор

Plesae бачить нові зміни в оригінальному запитанні
— regulalatre

Я думаю, що моя остання редакція (розміщена за секунди до Вашого коментаря відповідно до часових позначок, тому ми, ймовірно, вводили одночасно), може дати вам шукати один вкладиш.
— Девід Спіллетт

ХОРАЙ !!! Це працює! 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"
— регулятор

Привіт @David, дякую за цей чудовий хак. Однак для того, щоб він працював, мені потрібен ключ сервера 2 на сервері 1, використовуючи обидва рішення (у першому та другому редагуванні). Я думаю, що це нормально (переадресація порту чи ні, server1 все ще намагається пройти автентифікацію на server2), але ви пишете If you don't mind server1 having a key .... Чи можете ви сказати мені, чи справді можливо уникнути наявності ключа server2 на сервері1?
— ssssteffff

2

Ось кілька методів, які роблять синхронізацію простим однолінійним, але вимагають певної роботи з налаштуванням.

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

  • Встановіть на робочому столі проксі-носок (або http-проксі, який приймає CONNECT). Використовуйте його для встановлення ssh-з'єднання з сервера1 на сервер2. Запустіть rsync з сервера2.

  • Використовуйте унісон замість 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не припиняється, поки хтось використовує канал.


Я майже впевнений, що rsync таким чином не може працювати між двома віддаленими серверами через SSH (лише локальний-> віддалений чи віддалений-> локальний) - хоча ваше використання sleepі trapчудовіше, ніж у моїй відповіді метод "зберігайте життя і вбивайте". .
— Девід Спіллетт

дивіться правки на оригінальне запитання.
— регулятор

Чорт, ти маєш рацію. Не можна вказувати два хости як аргументи на команді ling. ... хммм ..
— Аарон Дігулла

Гаразд, я покращив своє рішення. Вам потрібно створити два порти вперед, щоб зробити ssh-сервер server2 видимим на сервері1.
— Аарон Дігулла

Додайте пару ";" щоб перетворити його в однолінійний. Ідею простіше зрозуміти за допомогою сценарію.
— Аарон Дігулла
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.