Làm cách nào để chuyển Multihop SCP?


85

Tôi muốn sao chép một tập tin từ máy A của mình sang máy chủ C, nhưng chỉ có quyền truy cập vào máy chủ C thông qua máy chủ B.

Thay vì đầu tiên chuyển đến máy chủ B, đăng nhập và sau đó chuyển sang máy chủ C, Có thể chuyển tệp trực tiếp bằng SCP hoặc các chương trình tương tự không?

(Chế độ tramp Emacs có tính năng này để chỉnh sửa tệp từ xa).

Câu trả lời:


48

Bạn có thể thêm -otùy chọn để scpthay vì .ssh/config.

scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path

$jump_host là "máy chủ B" của bạn trong trường hợp này.


Thi si cách ưa thích của tôi để làm điều này. Lộn xộn .ssh / config cho multihopping không phải là giải pháp tốt nhất nếu bạn truy cập cùng một máy chủ từ một cổng và trực tiếp.
GabrieleV

Làm thế nào điều này sẽ được với các tên người dùng và cổng khác nhau / tùy chỉnh?
Pablo A

Tôi thử cái này và phải nhập mật khẩu. Làm thế nào tôi có thể sửa lỗi này. Cảm ơn.
hqt

44

Giả sử OpenSSH, thêm vào cấu hình SSH của bạn trong .ssh / config

Host distant
ProxyCommand ssh near nc distant 22

Điều này sẽ khiến SSH có thể kết nối "trực tiếp" với máy có tên xa bằng cách ủy quyền qua máy có tên gần. Sau đó, nó có thể sử dụng các ứng dụng như scp và sftp cho máy ở xa.

Để làm việc này, bạn cần 'nc' aka netcat được cài đặt trên máy có tên gần. Nhưng rất nhiều hệ thống hiện đại sẽ có nó.

Giải pháp tar của Towo hiệu quả hơn cho các sự cố một lần, giả sử bạn đã ghi nhớ cú pháp và quy tắc hoạt động của tar.


Đây là cùng một phương pháp tôi sử dụng ... Trong ví dụ này, 'xa' sẽ là máy chủ C và 'gần' sẽ là máy chủ B để làm rõ ...
Jeremy Bouse

Rất nhiều máy móc hiện đại không có 'nc': nó thường chỉ có sẵn cho các máy Linux và chỉ theo yêu cầu (không phải là một phần của bản cài đặt tiêu chuẩn).
Mei

1
ssh hiện có tùy chọn -W, nó tự động thực hiện mà không có 'nc', nhưng tôi tự hỏi tại sao không có scp -W
kubanchot

3
Trong trường hợp tôi không phải là người duy nhất không rõ ràng: nếu tên người dùng trên nearkhác với tên người dùng trên distant, người dùng gần sẽ đi vào ProxyCommand ssh nearuser@near...và người dùng ở xa đi vào một User distantuserdòng riêng biệt .
Mu Tâm

Chỉ cần gõ ssh multi
Hope

19

Với các phiên bản gần đây hơn của ssh trên máy chủ gần (B), phần sau sẽ hoạt động mà không cần netcat:

Host distant
    ProxyCommand ssh near -W distant:22

Tuy nhiên, nó sẽ yêu cầu AllowTcpForwarding là có (mặc định) trên máy gần (B)

chỉnh sửa: yêu cầu OpenSSH 5.4+ trên B


hoạt động như một bùa mê :)
gongzhitaao

1
Và ít nhất là trong OpenSSH 7.4p1, có một lệnh "ProxyJump" trong đó người ta chỉ phải liệt kê mỗi người dùng @ host: port được phân tách bằng dấu phẩy. Đẹp!
hmijail

ProxyJump là tốt, nhưng nó đã không lấy User và IdentityFile từ tệp cấu hình. ProxyCommand -W thực hiện điều này và cũng hoạt động với scp.
rickfoosusa

18

Bạn có thể ssh đến máy chủ B bằng cách sử dụng một cái gì đó như

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>

Sau đó, bạn có thể ssh đến máy chủ C bằng cách sử dụng

ssh -p 5022 <user_serverC>@localhost 

Tương tự scp sẽ làm việc bằng cách sử dụng

scp -P 5022 foo.txt <user_serverc>@localhost:

Nhớ sử dụng đúng trường hợp p với scp và ssh


5

Điều đó có thể và tương đối dễ dàng, ngay cả khi bạn cần sử dụng chứng chỉ để xác thực (điển hình trong môi trường AWS).

Lệnh dưới đây sẽ sao chép các file từ một remotePathtrên server2trực tiếp vào máy tính của bạn tại localPath. Trong nội bộ yêu cầu scp được ủy quyền thông qua server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Cách khác cũng hoạt động (tải lên tập tin):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>

Nếu bạn sử dụng xác thực mật khẩu thay thế, hãy thử với

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Nếu bạn sử dụng cùng một thông tin người dùng trong cả hai máy chủ:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>

3

Nếu bạn muốn thực sự độc ác, bạn có thể xâu chuỗi ssh và tar, đại loại như thế tar c mydir | ssh server "ssh otherserver | tar x", nhưng điều này có thể gặp phải tất cả các vấn đề.

Cách dễ dàng hơn là chỉ cần thiết lập một đường hầm SSH với các phương thức SSH tích hợp; nhìn vào công -Dtắc trong trang và chỉ cần chuyển một số cổng sang cổng ssh của máy chủ khác.


2

Bạn cũng có thể làm điều này ngược lại và có thể dễ dàng hơn.

Giả sử bạn có một phiên ssh được mở bằng máy bạn muốn gửi tệp đến. PC xa nhất này, chúng tôi sẽ gọi đây là hop2. Máy chủ "proxy" của bạn sẽ là hop1. PC có nguồn gốc tệp, chúng tôi sẽ gọi nguồn gốc đó.

origin:~/asdf.txt  --> hop1 --> hop2:~/asdf.txt

Bạn có thể xây dựng các đường hầm làm cho một cổng cục bộ có sẵn trên một PC từ xa. Do đó, chúng tôi đang xác định một cổng để mở trên PC từ xa, đây sẽ là một chuyển hướng đến cổng mà bạn đã kéo qua khi bạn xây dựng đường hầm.

Trên hop2:

ssh -R 5555:127.0.0.1:22 <hop1_user>@<hop1_IP>
#this has the effect of building a tunnel from hop2 to hop1, making hop2's port 22 available on hop1 as port 5555

Bây giờ trong phiên đường hầm đã mở, bạn có thể thực hiện tương tự từ hop1 đến file_origin.

Trên hop1:

ssh -R 6666:127.0.0.1:5555 <origin_user>@<origin_IP>
#this has the effect of building a tunnel from hop1 to origin while also pulling the active tunnel with it, making hop1's port 5555 (hop2's port 22) available on origin as port 6666.

Bây giờ bạn đã được tạo đường hầm từ hop2 đến hop1 để khởi tạo. Thật trùng hợp, hiện tại cả hai cổng 5555 và 6666 đều được mở trên nguồn gốc, là các chuyển hướng đến cổng 22. của hop2. Trong phiên này, cả hai cách sau đây đều là các tuyến scp hợp lệ đến hop2:

Về nguồn gốc:

scp -P 6666 ~/asdf.txt <hop2_user>@<127.0.0.1>:~/asdf.txt

Theo cách này, bạn có thể có một số bước nhảy tùy ý ở giữa và dễ dàng hơn để làm việc với nhau về mặt kết nối nhiều hơn hai bước nhảy.


1

Hãy thử điều chỉnh ví dụ openssh config sau đây để thiết lập có thể được sử dụng cho nhiều máy chủ:

Host uat-*
     ProxyCommand ssh bastion-uat nc %h %p

Điều này giả định một tập hợp các máy chủ bắt đầu bằng "uat-" chỉ có thể truy cập thông qua máy chủ jumpbox / gateway "bastion-uat". Bạn cũng có thể muốn thêm ForwardAgent yesnếu bạn đang sử dụng một khóa để đăng nhập.


Đừng sử dụng ForwardAgent yescho việc này. Chuyển tiếp tác nhân là không cần thiết trong trường hợp này vì không có máy khách ssh nào sẽ chạy trên pháo đài và chuyển tiếp một tác nhân khi không cần thiết chỉ là để giảm bảo mật. Và tôi nghĩ sshlà thiếu từ lệnh của bạn. Nếu một sshphiên bản gần đây đang được sử dụng mà bạn không cần nc, bạn có thể nhập ssh -W %h:%p bastion-uatthay thế.
kasperd

@kasperd Đã chỉnh sửa để bao gồm ssh. Chuyển tiếpAgent; một máy khách ssh sẽ chạy để chạy lệnh nc. Có lẽ bạn đang đề cập đến vỏ?
Benjamin Goodacre

1

Đây không phải là scp (mà OP yêu cầu), nhưng tôi thấy nó rất đơn giản để sử dụng rsyncđể sao chép từ cục bộ sang từ xa qua một bước nhảy với:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination

Nguồn: http://mjbright.blogspot.com/2012/09/USE-rsync-over-multi-hop-ssh.html

Tôi đã thử đề xuất -o ProxyPass ở trên và không muốn thay đổi cấu hình cho nhu cầu thay đổi của mình. Là tác giả trong liên kết ở trên, các tệp đích trước dấu hai chấm (:) rất quan trọng để chỉ ra đường dẫn được chỉ định nằm trên máy chủ đích. Ngoài ra, bằng cách sử dụng rsync, bạn có các tùy chọn so sánh ngày, đồng bộ thư mục, v.v ... Tôi hy vọng điều này sẽ giúp được ai đó!


-2

scp -o 'ProxyJump jumpboxname' somefilename.txt Finaldestinationhost: / tmp /.


3
Đừng bỏ một chút mã không giải thích được ở đây. Có rất nhiều câu trả lời hay cho câu hỏi này và bạn cần thêm giá trị cho những câu hỏi hiện có - điều này không.
Sven
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.