rsync hack để trả lại các tập tin giữa hai máy chủ không được kết nối


8

Đây là kết nối:

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

Server1 và server2 không được phép nói chuyện trực tiếp với nhau (không hỏi). Máy tính để bàn của tôi, tuy nhiên có thể truy cập cả hai máy chủ thông qua ssh.

Tôi cần sao chép các tập tin từ server1 sang server2.

Thực tế, tôi đã sử dụng hack ssh + tar, như sau:

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

Và nó hoạt động rất tốt, nhưng tôi muốn tiến thêm một bước và để rsync hoạt động giữa hai máy chủ VIA máy tính để bàn của tôi.

Bây giờ tôi biết rằng tôi có thể bắt đầu một đường hầm chuyển tiếp ssh trong một thiết bị đầu cuối và sau đó rsync qua đường hầm đó trong một cửa sổ khác, nhưng tôi không muốn làm phiền với một thiết bị đầu cuối thứ hai hoặc tạo và phá vỡ một đường hầm chuyển tiếp cổng riêng biệt. điều tôi muốn là:

  • Một lệnh lót để rsync tập tin từ Server1 đến server2 VIA máy tính để bàn của tôi
  • tất cả trên MỘT dòng lệnh, một cửa sổ đầu cuối
  • Tôi muốn đường hầm chuyển tiếp cổng chỉ tồn tại trong vòng đời của lệnh rsync.
  • Tôi không muốn scp, tôi muốn rsync.

Có ai có một mẹo để làm điều đó?

EDIT: Đây là lệnh làm việc! Mọi người làm tốt lắm 1. Đối với đường dẫn khóa rsa, không thể sử dụng dấu ngã, phải sử dụng "/ root /". 2. Đây là dòng lệnh cuối cùng:

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 đi thuốc nổ.


Điều này thực sự xuất sắc. Một điều cần phải thay đổi là vô hiệu hóa xác minh khóa máy chủ. Bạn có khóa SSH để xác thực TTYless, nhưng vì các máy chủ chưa bao giờ nói chuyện với nhau nên họ không thể xác minh các khóa máy chủ. Vì vậy, tốt nhất để vô hiệu hóa nó: -o StricthostKeyChecking = no sau các cờ -p hoặc -i.
Amala

Câu trả lời:


5

Nếu bạn vui lòng giữ một bản sao dữ liệu trên máy trung gian thì bạn có thể chỉ cần viết một tập lệnh cập nhật bản sao cục bộ bằng server1 làm tài liệu tham khảo sau đó cập nhật bản sao lưu trên server2 bằng bản sao cục bộ làm tài liệu tham khảo:

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

Sử dụng một tập lệnh đơn giản có nghĩa là bạn có một lệnh đơn lẻ để làm mọi thứ. Điều này tất nhiên có thể là không bảo mật nếu dữ liệu nhạy cảm (bạn hoặc những người khác trong công ty của bạn, có thể không muốn một bản sao trôi nổi trên máy tính xách tay của bạn). Nếu server1 là cục bộ với bạn thì bạn có thể xóa bản sao cục bộ sau đó (vì nó sẽ nhanh chóng được xây dựng lại qua mạng LAN cục bộ vào lần tới).

Xây dựng một đường hầm để các máy chủ có thể nói chuyện với nhau một cách hiệu quả hơn nên có thể như vậy:

  1. Trên máy chủ 2 tạo một bản sao của / bin / sh dưới dạng / usr / local / bin / shforkeepalive. Sử dụng một liên kết tượng trưng thay vì một bản sao sau đó bạn không phải cập nhật nó sau khi cập nhật bảo mật bản vá / bin / sh.
  2. Trên máy chủ 2 tạo một tập lệnh không có gì ngoài vòng lặp ngủ trong vài giây sau đó lặp lại một lượng nhỏ văn bản và sử dụng "bản sao" hiện tại của sh:

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

    (các echo có lẽ không cần thiết, vì phiên sẽ không hoạt động đủ lâu để hết thời gian ngay cả khi SSHd được định cấu hình để bỏ qua các gói duy trì từ máy khách ssh)

  3. Bây giờ bạn có thể viết một tập lệnh trên máy tính xách tay của bạn để bắt đầu đường hầm ngược của bạn ở chế độ nền, yêu cầu server1 sử dụng rsync để thực hiện thao tác sao chép, sau đó giết đường hầm ngược bằng cách hủy tập lệnh lặp (sẽ đóng phiên 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
    

Cách thức hoạt động:

  • Dòng 1: lệnh "tiêu chuẩn để sử dụng để diễn giải kịch bản lệnh" này
  • Dòng 2: bắt đầu kết nối SSH với đường hầm ngược và chạy tập lệnh keepalive thông qua nó để giữ cho nó mở. Các dấu & amp; bảo bash chạy cái này trong nền để các dòng tiếp theo có thể chạy mà không cần đợi nó kết thúc
  • Dòng 3: bắt đầu một đường hầm sẽ kết nối với đường hầm ở trên để server1 có thể thấy server2 và chạy rsync để thực hiện sao chép / cập nhật qua sự sắp xếp này
  • Dòng 4: giết tập lệnh giữ nguyên khi hoạt động rsync hoàn thành (và do đó, cuộc gọi SSH thứ hai trả về), phiên này sẽ và phiên ssh đầu tiên.

Điều này không cảm thấy đặc biệt sạch sẽ, nhưng nó sẽ hoạt động. Tôi đã không kiểm tra ở trên vì vậy bạn có thể cần phải điều chỉnh nó. Tạo lệnh rsync thành một tập lệnh dòng đơn trên server1 có thể giúp bằng cách giảm bất kỳ nhu cầu thoát các ký tự như 'trên lệnh gọi ssh.

BTW: bạn nói "đừng hỏi" tại sao hai máy chủ không thể nhìn thấy nhau trực tiếp, nhưng thường có lý do chính đáng cho việc này. Máy chủ gia đình của tôi và máy chủ sao lưu trực tuyến của nó được giữ không thể đăng nhập lẫn nhau (và có mật khẩu + khóa khác nhau cho tất cả người dùng) - điều này có nghĩa là nếu một trong hai bị hack thì không thể sử dụng như một cách dễ dàng hack cái khác để sao lưu trực tuyến của tôi an toàn hơn (ai đó độc hại xóa dữ liệu của tôi khỏi trực tiếp không thể sử dụng khả năng cập nhật các bản sao lưu để xóa các bản sao lưu nói trên, vì nó không có khả năng trực tiếp chạm vào trang web sao lưu chính). Cả hai máy chủ đều có thể kết nối với máy chủ trung gian ở nơi khác - máy chủ trực tiếp được đặt để đẩy các bản sao lưu của nó (thông qua rsync) vào máy trung gian vào sáng sớm và máy chủ dự phòng được thiết lập (một lúc sau để cho phép hoàn thành bước một) và thu thập các bản cập nhật (một lần nữa qua rsyc theo sau là một bước chụp nhanh để duy trì nhiều độ tuổi sao lưu). Kỹ thuật này cũng có thể sử dụng được trong hoàn cảnh của bạn, và nếu vậy tôi sẽ khuyên bạn nên sử dụng nó như một cách làm việc sạch sẽ hơn nhiều.

Chỉnh sửa: Hợp nhất bản hack của tôi với Aaron để tránh tất cả các bản sao của / bin / sh và một tập lệnh giữ riêng trên server2, tập lệnh này trên máy tính xách tay của bạn sẽ thực hiện toàn bộ công việc:

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

Cũng như trên, rsync đang kết nối với localhost: 2222, chuyển tiếp xuống đường hầm đến localhost của máy tính xách tay của bạn: 2222 chuyển tiếp qua đường hầm khác đến localhost của server2: 22.

Chỉnh sửa 2: Nếu bạn không nhớ server1 có khóa cho phép xác thực trực tiếp với server2 (mặc dù nó không thể thấy server2 mà không có đường hầm), bạn có thể đơn giản hóa thêm với:

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

trong đó 123.123.123.123 là một địa chỉ công khai cho server2, có thể được sử dụng làm bản sao + dán một lớp thay vì tập lệnh.


Đó là một lượng lớn dữ liệu (20 + gb) và tôi thích truyền dữ liệu vào và ra cùng lúc hơn là lưu trữ cục bộ. Tôi muốn truyền dữ liệu qua PC mà không cần lưu trữ bất cứ thứ gì. bạn nói đúng về "đừng hỏi", đó là lý do chính đáng, mặc dù là pita.
regulatre

Xin vui lòng xem các chỉnh sửa mới về câu hỏi ban đầu
regulatre

Tôi nghĩ rằng lần chỉnh sửa cuối cùng của tôi (được đăng vài giây trước khi bình luận của bạn theo dấu thời gian để chúng tôi có thể gõ cùng một lúc) có thể cung cấp cho bạn một lớp lót mà bạn đang tìm kiếm.
David Spillett

HOAN HÔ!!! Nó hoạt động! 1. đối với khóa rsa, không thể sử dụng tildae, phải sử dụng "/ root /". 2. đây là dòng lệnh cuối cùng: 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

Xin chào @David, cảm ơn vì bản hack tuyệt vời này. Tuy nhiên, để làm cho nó hoạt động, tôi cần khóa của máy chủ 2 trên máy chủ 1 bằng cả hai giải pháp (trong lần chỉnh sửa thứ nhất và thứ hai). Tôi nghĩ đó là bình thường (chuyển tiếp cổng hay không, server1 vẫn đang cố xác thực với server2), nhưng bạn viết If you don't mind server1 having a key .... Bạn có thể cho tôi biết nếu thực sự có thể tránh việc có khóa server2 trên server1 không?
ssssteffff

2

Dưới đây là một vài phương pháp giúp đồng bộ hóa một lớp lót đơn giản, nhưng yêu cầu một số công việc thiết lập.

  • Thiết lập đường hầm ssh ngược từ server1 đến máy tính để bàn của bạn (xin lỗi, tôi không thể cho bạn biết .ssh/config câu thần chú ra khỏi đỉnh đầu của tôi). Xâu chuỗi nó với một kết nối từ máy tính để bàn của bạn đến máy chủ2. Chạy rsync từ máy chủ1.

  • Thiết lập proxy vớ (hoặc proxy http chấp nhận CONNECT) trên máy tính để bàn của bạn. Sử dụng nó để thiết lập kết nối ssh từ server1 đến server2. Chạy rsync từ máy chủ2.

  • Sử dụng đồng thanh thay vì rsync. Nhưng quy trình làm việc thì khác.

  • Gắn kết các thư mục từ một hoặc cả hai máy chủ trên máy tính để bàn của bạn bằng cách sử dụng sshfs .


1

Tại sao một dòng? Sử dụng tập lệnh shell nhỏ:

#!/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, bạn có thể đặt thời gian ngủ thấp hơn; người đầu tiên ssh sẽ không chấm dứt miễn là ai đó sử dụng kênh.


Tôi khá chắc chắn rằng rsync không thể hoạt động giữa hai máy chủ từ xa qua SSH theo cách đó (chỉ cục bộ- & gt; từ xa hoặc từ xa- & gt; cục bộ) - mặc dù bạn sử dụng sleeptrap gọn gàng hơn phương pháp "giữ sống và giết" trong câu trả lời của tôi.
David Spillett

xin vui lòng xem các chỉnh sửa trên câu hỏi ban đầu.
regulatre

Chết tiệt, bạn nói đúng. Không được phép chỉ định hai máy chủ làm đối số trên lệnh ling. ... Ừm ..
Aaron Digulla

Được rồi, tôi đã cải thiện giải pháp của mình. Bạn cần tạo hai cổng chuyển tiếp để hiển thị dịch vụ ssh của server2 trên server1.
Aaron Digulla

Thêm một vài ";" để biến nó thành một lớp lót. Ý tưởng dễ hiểu hơn với một kịch bản.
Aaron Digulla
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.