rsync แฮ็กเพื่อตีกลับไฟล์ระหว่างสองเซิร์ฟเวอร์ที่ไม่ได้เชื่อมต่อ


8

นี่คือการเชื่อมต่อ:

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

Server1 และ server2 ไม่ได้รับอนุญาตให้พูดคุยกับแต่ละคนโดยตรง (ไม่ต้องถาม) เดสก์ท็อปของฉันอย่างไรก็ตามสามารถเข้าถึงเซิร์ฟเวอร์ทั้งสองผ่าน ssh

ฉันต้องการคัดลอกไฟล์จาก server1 ไปยัง server2

ฉันมักจะใช้แฮ็ค ssh + tar อย่างเช่น:

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

และใช้งานได้ดี แต่ฉันต้องการที่จะก้าวไปอีกขั้นและทำให้ rsync ทำงานระหว่างสองเซิร์ฟเวอร์ VIA บนเดสก์ท็อปของฉัน

ตอนนี้ฉันรู้แล้วว่าฉันสามารถเริ่มต้นช่องสัญญาณส่งต่อพอร์ต ssh ในเทอร์มินัลหนึ่งแล้ว rsync เหนือช่องสัญญาณนั้นในหน้าต่างอื่น แต่ฉันไม่ต้องการยุ่งกับเทอร์มินัลที่สองหรือสร้างและทำลายช่องทางส่งต่อพอร์ตแยก สิ่งที่ฉันต้องการคือ:

  • คำสั่งซับหนึ่งเพื่อ rsync ไฟล์จาก Server1 ถึง server2 ผ่านทางเดสก์ทอปของฉัน
  • ทั้งหมดในหนึ่งบรรทัดคำสั่งหนึ่งหน้าต่างเทอร์มินัล
  • ฉันต้องการให้ช่องสัญญาณส่งต่อพอร์ตมีอยู่สำหรับอายุการใช้งานของคำสั่ง rsync เท่านั้น
  • ฉันไม่ต้องการ scp ฉันต้องการ rsync

ใครมีเคล็ดลับในการทำเช่นนั้น?

แก้ไข: นี่คือคำสั่งการทำงาน! ผลงานยอดเยี่ยมทุกคน: 1. สำหรับเส้นทางคีย์ rsa ไม่สามารถใช้ tildae ได้ต้องใช้ "/ root /" 2. นี่คือ commandline สุดท้าย:

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 = no หลังจากแฟล็ก -p หรือ -i
Amala

คำตอบ:


5

หากคุณยินดีที่จะเก็บสำเนาข้อมูลไว้ในเครื่องระดับกลางคุณสามารถเขียนสคริปต์ที่อัพเดตสำเนาโลคัลโดยใช้ server1 เป็นข้อมูลอ้างอิงจากนั้นอัปเดตข้อมูลสำรองบนเซิร์ฟเวอร์ 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

การใช้สคริปต์อย่างง่ายหมายความว่าคุณต้องการให้คำสั่งเดี่ยวทำทุกอย่าง แน่นอนว่านี่อาจเป็นการรักษาความปลอดภัยหากข้อมูลมีความอ่อนไหว (คุณหรือคนอื่น ๆ ใน บริษัท ของคุณอาจไม่ต้องการสำเนาที่ลอยอยู่บนแล็ปท็อปของคุณ) หาก server1 เป็นไฟล์โลคอลสำหรับคุณคุณสามารถลบสำเนาโลคัลได้หลังจากนั้น (เนื่องจากจะเป็นการสร้างขึ้นใหม่อย่างรวดเร็วใน LAN ครั้งถัดไป)

การสร้างอุโมงค์เพื่อให้เซิร์ฟเวอร์สามารถพูดคุยกันได้อย่างมีประสิทธิภาพควรเป็นไปได้โดยตรงเช่น:

  1. บนเซิร์ฟเวอร์ 2 ทำสำเนา / bin / sh เป็น / usr / local / bin / shforkeepalive ใช้ลิงก์สัญลักษณ์แทนที่จะเป็นสำเนาจากนั้นคุณไม่ต้องอัปเดตหลังจากอัปเดตความปลอดภัยที่ patch / 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 ด้วย reverse tunnel และเรียกใช้สคริปต์ keepalive ผ่านทางมันเพื่อเปิด การติดตาม & บอกว่าทุบตีเพื่อเรียกใช้สิ่งนี้ในพื้นหลังเพื่อให้บรรทัดถัดไปสามารถทำงานได้โดยไม่ต้องรอให้เสร็จ
  • บรรทัดที่ 3: เริ่มช่องสัญญาณที่จะเชื่อมต่อกับช่องสัญญาณด้านบนเพื่อให้เซิร์ฟเวอร์ 1 สามารถดูเซิร์ฟเวอร์ 2 และเรียกใช้ rsync เพื่อดำเนินการคัดลอก / อัปเดตผ่านการจัดเรียงนี้
  • บรรทัดที่ 4: ฆ่าสคริปต์ keep-alive เมื่อการดำเนินการ rsync เสร็จสมบูรณ์ (และดังนั้นการโทร SSH ที่สองจะส่งคืน) ซึ่งจะและเซสชันแรกของ ssh

สิ่งนี้ไม่รู้สึกสะอาดเป็นพิเศษ แต่ควรใช้งานได้ ฉันไม่ได้ทดสอบด้านบนดังนั้นคุณอาจต้องปรับแต่ง การทำให้คำสั่ง rsync เป็นสคริปต์บรรทัดเดียวบน server1 อาจช่วยลดความจำเป็นในการหลีกเลี่ยงอักขระเช่น 'บนคำสั่ง ssh

BTW: คุณพูดว่า "ไม่ต้องถาม" ว่าทำไมเซิร์ฟเวอร์ทั้งสองไม่สามารถมองเห็นกันโดยตรง แต่มักจะมีเหตุผลที่ดีสำหรับเรื่องนี้ เซิร์ฟเวอร์ภายในบ้านของฉันและเซิร์ฟเวอร์ที่มีการสำรองข้อมูลออนไลน์ไว้ไม่สามารถลงชื่อเข้าใช้ซึ่งกันและกันได้ (และมีรหัสผ่าน + ปุ่มที่แตกต่างกันสำหรับผู้ใช้ทั้งหมด) - ซึ่งหมายความว่าหากหนึ่งในสองถูกแฮ็กมันไม่สามารถใช้เป็นเส้นทางได้ง่าย แฮ็กคนอื่นเพื่อให้การสำรองข้อมูลออนไลน์ของฉันปลอดภัยยิ่งขึ้น (มีคนลบข้อมูลที่เป็นอันตรายจากชีวิตไม่สามารถใช้ความสามารถในการอัปเดตการสำรองข้อมูลเพื่อลบการสำรองข้อมูลดังกล่าวเนื่องจากไม่มีความสามารถโดยตรงในการสัมผัสเว็บไซต์สำรองหลัก เซิร์ฟเวอร์ทั้งสองสามารถเชื่อมต่อกับเซิร์ฟเวอร์กลางที่อื่นได้ - เซิร์ฟเวอร์สดถูกตั้งค่าให้ส่งข้อมูลสำรอง (ผ่าน 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 ซึ่งจะส่งต่อผ่านอุโมงค์อื่นไปยัง localhost ของเซิร์ฟเวอร์ 2: 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 ซึ่งสามารถใช้เป็นสำเนา + วางหนึ่งซับในแทนสคริปต์


มันเป็นข้อมูลจำนวนมาก (20 + gb) และฉันชอบที่จะสตรีมข้อมูลเข้าและออกในเวลาเดียวกันแทนที่จะเก็บไว้ในเครื่อง ฉันต้องการที่จะสตรีมข้อมูลผ่านพีซีของฉันโดยไม่มีการจัดเก็บข้อมูลใด ๆ คุณพูดถูก "อย่าถาม" มันมีเหตุผลที่ดีแม้ว่าจะเป็น Pita
กฎระเบียบ

กรุณาดูการแก้ไขใหม่สำหรับคำถามเดิม
ระเบียบ

ฉันคิดว่าการแก้ไขครั้งล่าสุดของฉัน (โพสต์วินาทีก่อนที่ความคิดเห็นของคุณตามเวลาที่บันทึกไว้ดังนั้นเราอาจพิมพ์ในเวลาเดียวกัน) อาจทำให้คุณได้รับหนึ่งซับที่คุณต้องการ
David Spillett

ไชโย !!! มันได้ผล! 1. สำหรับคีย์ rsa ไม่สามารถใช้ tildae ได้ต้องใช้ "/ root /" 2. นี่คือ commandline สุดท้าย: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 ขอบคุณสำหรับแฮ็คที่ยอดเยี่ยมนี้ อย่างไรก็ตามเพื่อให้มันทำงานได้ฉันต้องการรหัสของเซิร์ฟเวอร์ 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 ที่ยอมรับการเชื่อมต่อ) บนเดสก์ท็อปของคุณ ใช้เพื่อสร้างการเชื่อมต่อ ssh จาก server1 ไปยัง server2 รัน 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 สองวิธี (เฉพาะ local-> ระยะไกลหรือ remote-> ท้องถิ่น) - แม้ว่าการใช้งานของsleepและtrapเป็น neater กว่า "ให้มีชีวิตอยู่และฆ่า" วิธีการในคำตอบของฉัน .
David Spillett

โปรดดูการแก้ไขคำถามเดิม
ระเบียบ

ห่าคุณพูดถูก ไม่อนุญาตให้ระบุสองโฮสต์เป็นอาร์กิวเมนต์บนคำสั่ง ling ... hmmm ..
Aaron Digulla

โอเคฉันได้ปรับปรุงวิธีแก้ปัญหาของฉันแล้ว คุณต้องสร้างสองพอร์ตขึ้นไปเพื่อให้บริการ ssh ของ server2 ปรากฏบนเซิร์ฟเวอร์ 1
Aaron Digulla

เพิ่มสอง ";" เพื่อเปลี่ยนเป็นซับเดียว แนวคิดนี้ง่ายต่อการเข้าใจด้วยสคริปต์
Aaron Digulla
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.