rsync Hack zum Bouncen von Dateien zwischen zwei nicht verbundenen Servern

8

Hier ist die Verbindung:

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

Server1 und Server2 dürfen nicht direkt miteinander sprechen (nicht fragen). Mein Desktop kann jedoch über ssh auf beide Server zugreifen.

Ich muss Dateien von Server1 nach Server2 kopieren.

Traditionell habe ich einen ssh + tar-Hack als solchen verwendet:

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

Und das funktioniert großartig, aber ich möchte noch einen Schritt weiter gehen und rsync zwischen den beiden Servern über meinen Desktop zum Laufen bringen.

Jetzt weiß ich, dass ich in einem Terminal einen SSH-Port-Forward-Tunnel starten und dann in einem anderen Fenster über diesen Tunnel synchronisieren kann, aber ich möchte nicht mit einem zweiten Terminal herumspielen oder einen separaten Port-Forward-Tunnel erstellen und brechen. was ich will ist:

  • Ein Liner-Befehl zum Synchronisieren von Dateien von Server1 auf Server2 über meinen Desktop
  • Alles in EINER Befehlszeile, einem Terminalfenster
  • Ich möchte, dass der Port-Forward-Tunnel nur für die Lebensdauer des Befehls rsync vorhanden ist.
  • Ich möchte nicht scp, ich möchte rsync.

Hat jemand einen Trick dafür?

EDIT: Hier ist der Arbeitsbefehl! Tolle Arbeit an alle: 1. Für den rsa-Schlüsselpfad kann ich keine Tildae verwenden, musste "/ root /" verwenden. 2. Hier ist die letzte Befehlszeile:

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 macht das Dynamit.

regulatre
quelle
Das ist wirklich hervorragend. Das einzige, was geändert werden muss, ist das Deaktivieren der Hostschlüsselüberprüfung. Sie haben den SSH-Schlüssel für die TTYless-Authentifizierung, aber da die Server noch nie miteinander gesprochen haben, können sie die Hostschlüssel nicht überprüfen. Deaktivieren Sie es am besten: -o StrictHostKeyChecking = no nach den Flags -p oder -i.
Amala

Antworten:

5

Wenn Sie gerne eine Kopie der Daten auf dem Zwischencomputer behalten möchten, können Sie einfach ein Skript schreiben, das die lokale Kopie mit Server1 als Referenz aktualisiert und dann die Sicherung auf Server2 mit der lokalen Kopie als Referenz aktualisiert hat:

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

Die Verwendung eines einfachen Skripts bedeutet, dass Sie einen einzelnen Befehl für alles gewünscht haben. Dies kann natürlich ein Sicherheits-Nein-Nein sein, wenn die Daten vertraulich sind (Sie oder andere in Ihrem Unternehmen möchten möglicherweise keine Kopie auf Ihrem Laptop). Wenn server1 für Sie lokal ist, können Sie die lokale Kopie anschließend einfach löschen (da sie beim nächsten Mal schnell über das lokale LAN wiederhergestellt werden kann).

Der Bau eines Tunnels, damit die Server effektiver und direkter miteinander kommunizieren können, sollte folgendermaßen möglich sein:

  1. Erstellen Sie auf Server 2 eine Kopie von / bin / sh als / usr / local / bin / shforkeepalive. Verwenden Sie einen symbolischen Link anstelle einer Kopie, dann müssen Sie ihn nach Sicherheitsupdates, die patch / bin / sh sind, nicht aktualisieren.
  2. Erstellen Sie auf Server 2 ein Skript, das nur ein paar Sekunden lang in einer Schleife schläft und dann eine kleine Textmenge wiedergibt. Verwenden Sie dazu die jetzt "Kopie" von sh:

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

    ( echoDies wird wahrscheinlich nicht benötigt, da die Sitzung nicht lange genug inaktiv sein wird, um eine Zeitüberschreitung zu verursachen, selbst wenn SSHd so konfiguriert ist, dass Keep-Alive-Pakete vom SSH-Client ignoriert werden.)

  3. Jetzt können Sie ein Skript auf Ihren Laptop schreiben, das Ihren Reverse-Tunnel im Hintergrund startet, Server1 anweist, rsync zum Ausführen des Kopiervorgangs zu verwenden, und dann den Reverse-Tunnel beenden, indem Sie das Schleifenskript beenden (wodurch die SSH-Sitzung geschlossen wird):

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

So funktioniert das:

  • Zeile 1: Standardmarkierung "Befehl zum Interpretieren dieses Skripts"
  • Zeile 2: Starten Sie eine SSH-Verbindung mit Reverse Tunnel und führen Sie das Keepalive-Skript darüber aus, um es offen zu halten. Das nachfolgende & weist bash an, dies im Hintergrund auszuführen, damit die nächsten Zeilen ausgeführt werden können, ohne darauf zu warten, dass sie beendet werden
  • Zeile 3: Starten Sie einen Tunnel, der eine Verbindung zum obigen Tunnel herstellt, damit Server1 Server2 sehen kann, und führen Sie rsync aus, um das Kopieren / Aktualisieren über diese Anordnung durchzuführen
  • Zeile 4: Beenden Sie das Keep-Alive-Skript, sobald der rsync-Vorgang abgeschlossen ist (und der zweite SSH-Aufruf zurückkehrt), und die erste ssh-Sitzung.

Das fühlt sich nicht besonders sauber an, sollte aber funktionieren. Ich habe das oben genannte nicht getestet, daher müssen Sie es möglicherweise optimieren. Wenn Sie den Befehl rsync auf Server1 zu einem einzeiligen Skript machen, können Sie möglicherweise weniger Zeichen wie den Befehl 'auf dem aufrufenden ssh-Befehl maskieren.

Übrigens: Sie sagen "fragen Sie nicht", warum sich die beiden Server nicht direkt sehen können, aber es gibt oft gute Gründe dafür. Mein Heimserver und der Server, auf dem seine Online-Backups gespeichert sind, können sich nicht gegenseitig anmelden (und haben unterschiedliche Kennwörter + Schlüssel für alle Benutzer). Dies bedeutet, dass einer der beiden Server, wenn er gehackt wird, nicht als einfacher Weg zu verwendet werden kann Hacken Sie den anderen, damit meine Online-Backups sicherer sind (jemand, der böswillig meine Daten aus dem Live-Modus löscht, kann seine Fähigkeit zum Aktualisieren der Backups nicht nutzen, um diese Backups zu löschen, da er die direkte Backup-Site nicht direkt berühren kann). Beide Server können an anderer Stelle eine Verbindung zu einem Zwischenserver herstellen. Der Live-Server ist so eingestellt, dass er seine Backups (über rsync) am frühen Morgen auf den Zwischencomputer überträgt, und der Sicherungsserver wird eingestellt (eine Weile später, damit Schritt 1 abgeschlossen werden kann), um eine Verbindung herzustellen und sammeln Sie die Updates (erneut über rsyc, gefolgt von einem Snapshot-Schritt, um mehrere Sicherungsalter aufrechtzuerhalten). Diese Technik kann auch unter Ihren Umständen verwendet werden, und wenn ja, würde ich sie als viel sauberere Art und Weise empfehlen, Dinge zu tun.

Bearbeiten: Wenn ich meinen Hack mit dem von Aaron zusammenführe, um zu vermeiden, dass mit Kopien von / bin / sh und einem separaten Keep-Alive-Skript auf Server2 herumgespielt wird, sollte dieses Skript auf Ihrem Laptop den gesamten Job erledigen:

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

Wie oben beschrieben stellt rsync eine Verbindung zu localhost: 2222 her, das den Tunnel zum localhost: 2222 Ihres Laptops weiterleitet und über den anderen Tunnel zum localhost: 22 von server2 weiterleitet.

Bearbeiten 2: Wenn es Ihnen nichts ausmacht, dass Server1 über einen Schlüssel verfügt, mit dem er sich direkt bei Server2 authentifizieren kann (obwohl Server2 ohne Tunnel nicht angezeigt werden kann), können Sie dies weiter vereinfachen:

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

Dabei ist 123.123.123.123 eine öffentliche Adresse für Server2, die anstelle eines Skripts als Einzeiler zum Kopieren und Einfügen verwendet werden kann.

David Spillett
quelle
Es ist eine große Datenmenge (20 + GB) und ich ziehe es vor, sie gleichzeitig ein- und auszustreamen, anstatt sie lokal zu speichern. Ich möchte die Daten über meinen PC streamen, ohne dass etwas gespeichert wird. Sie haben Recht mit dem "nicht fragen", es ist aus gutem Grund, wenn auch eine Pita.
regulatre
Bitte sehen Sie neue Änderungen an der ursprünglichen Frage
regulatre
Ich denke, meine letzte Änderung (die Sekunden vor Ihrem Kommentar gemäß den Zeitstempeln veröffentlicht wurde, sodass wir wahrscheinlich zur gleichen Zeit tippten) könnte Ihnen den Einzeiler geben, den Sie suchen.
David Spillett
HURRA!!! Es klappt! 1. für rsa key, kann tildae nicht verwenden, musste "/ root /" verwenden. 2. Hier ist die letzte Kommandozeile: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
Hallo @ David, danke für diesen tollen Hack. Damit es funktioniert, benötige ich jedoch den Schlüssel von Server 2 auf Server 1 mit beiden Lösungen (in der ersten und zweiten Bearbeitung). Ich denke, es ist normal (Portweiterleitung oder nicht, Server1 versucht immer noch, sich bei Server2 zu authentifizieren), aber Sie schreiben If you don't mind server1 having a key .... Können Sie mir bitte sagen, ob es wirklich möglich ist, den Schlüssel von Server2 auf Server1 zu vermeiden?
ssssteffff
2

Hier sind einige Methoden, die die Synchronisation zu einem einfachen Einzeiler machen, jedoch einige Einrichtungsarbeiten erfordern.

  • Richten Sie einen umgekehrten SSH-Tunnel von Server1 zu Ihrem Desktop ein (Entschuldigung, ich kann Ihnen die .ssh/configBeschwörung nicht sagen ). Verketten Sie es mit einer Verbindung von Ihrem Desktop zu Server2. Führen Sie rsync von Server1 aus.

  • Richten Sie auf Ihrem Desktop einen Socken-Proxy (oder einen http-Proxy, der CONNECT akzeptiert) ein. Verwenden Sie diese Option, um eine SSH-Verbindung von Server1 zu Server2 herzustellen. Führen Sie rsync von Server2 aus.

  • Verwenden Sie unisono anstelle von rsync. Der Workflow ist jedoch anders.

  • Hängen Sie die Verzeichnisse mit sshfs von einem oder beiden Servern auf Ihrem Desktop ein .

Gilles 'SO - hör auf böse zu sein'
quelle
1

Warum eine Zeile? Verwenden Sie ein kleines Shell-Skript:

#!/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 können Sie die Schlafzeit niedriger einstellen; Der erste sshwird nicht beendet, solange jemand den Kanal verwendet.

Aaron Digulla
quelle
Ich bin mir ziemlich sicher, dass rsync auf diese Weise nicht zwischen zwei Remote-Servern über SSH betrieben werden kann (nur lokal-> remote oder remote-> lokal) - obwohl Sie in meiner Antwort die Methode "Keep Alive and Kill" verwenden sleepund trapordentlicher sind als diese .
David Spillett
Bitte beachten Sie die Änderungen an der Originalfrage.
regulatre
Verdammt, du hast recht. Es ist nicht erlaubt, zwei Hosts als Argumente für den Befehl ling anzugeben. ... hmmm ..
Aaron Digulla
Okay, ich habe meine Lösung verbessert. Sie müssen zwei Port-Forwards erstellen, um den SSH-Dienst von Server2 auf Server1 sichtbar zu machen.
Aaron Digulla
Fügen Sie ein paar ";" um es in einen Einzeiler zu verwandeln. Die Idee ist mit einem Skript leichter zu verstehen.
Aaron Digulla