Làm cách nào để SSH tới máy A qua B trong một lệnh?


103

Tôi muốn truy cập vào một máy tính, giả sử máy A có trong mạng của trường đại học của tôi. Tuy nhiên, máy tính này chỉ có thể truy cập qua mạng nội bộ của trường đại học, vì vậy tôi không thể sử dụng SSH trực tiếp đến máy tính này ở nhà.

Đây là những gì tôi làm bây giờ:

  1. Đăng nhập vào một máy đại học khác, giả sử máy B

    (Máy B này có thể truy cập qua SSH từ máy tính ở nhà của tôi.)

  2. Sử dụng SSH trên B để kết nối với A.

Có cách nào để làm điều đó nhanh hơn? Chỉ sử dụng một lệnh ssh.


Câu trả lời:


97

Có, sử dụng ProxyCommandtrong cấu hình SSH của bạn.

Tạo tệp cấu hình SSH trong thư mục chính của bạn (trừ khi bạn muốn tạo toàn bộ hệ thống này) , ~/.ssh/config:

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

Bây giờ bạn có thể tiếp cận trực tiếp với Máy A bằng cách sử dụng

ssh user@internalmachine

Cũng lưu ý rằng bây giờ bạn có một tên mục tiêu máy chủ SSH duy nhất cho nó, bạn cũng có thể sử dụng tên này trong các ứng dụng khác. Ví dụ:

  • SCP để sao chép tập tin.

    scp somefile user@internalmachine:~/
    
  • Trong các ứng dụng GUI của bạn:

    sử dụng sftp://user@internalmachine/làm vị trí để duyệt trên máy.

    Dựa trên KDE (Cá heo): sử dụng fish://user@internalmachine/

Ghi chú

Thay đổi hostname.or.IP.address.internal.machinevà cổng ( 22) sang máy bạn muốn tiếp cận như thể bạn muốn từ unibrokermáy.

Tùy thuộc vào các phiên bản netcat trên máy chủ unibroker, -q0tùy chọn phải được bỏ qua. Về xác thực; về cơ bản bạn đang thiết lập hai kết nối SSH từ máy trạm của bạn. Điều này có nghĩa là cả máy chủ unibroker và máy chủ lưu trữ nội bộ đều được xác minh / xác thực lần lượt từng cái (đối với cả xác thực khóa / mật khẩu và xác minh khóa máy chủ).

Giải trình

Cách tiếp cận này của việc sử dụng ProxyCommandvà 'netcat' chỉ là một cách để làm điều đó. Tôi thích điều này, bởi vì máy khách SSH của tôi nói chuyện trực tiếp với máy đích để tôi có thể xác minh khóa máy chủ từ máy khách của mình và tôi có thể sử dụng xác thực khóa chung của mình mà không cần sử dụng khóa khác trên nhà môi giới.

Mỗi Hostđịnh nghĩa bắt đầu của một phần lưu trữ mới. Hostnamelà tên máy chủ đích hoặc địa chỉ IP của máy chủ đó. Userlà những gì bạn sẽ cung cấp như là một phần của người dùng ssh user@hostname.

ProxyCommandsẽ được sử dụng làm đường ống đến máy mục tiêu. Bằng cách sử dụng SSH cho máy đầu tiên và trực tiếp thiết lập một 'netcat' ( nc) đơn giản cho mục tiêu từ đó, về cơ bản, đây chỉ là một văn bản chuyển tiếp đến máy bên trong từ nhà môi giới giữa những người đó. Các -qtùy chọn là để tắt bất kỳ đầu ra nào (chỉ là một sở thích cá nhân).

Đảm bảo rằng bạn đã cài đặt netcat trên trình môi giới (thường có sẵn theo mặc định trên Ubuntu) - netcat-openbsdCài đặt netcat-openbsd hoặc netcat-truyền thốngCài đặt netcat-truyền thống .

Lưu ý rằng bạn vẫn đang sử dụng SSH với mã hóa hai lần tại đây. Trong khi kênh netcat là bản rõ, máy khách SSH trên PC của bạn sẽ thiết lập một kênh được mã hóa khác với máy đích cuối cùng.


4
Tôi đã phải xóa tùy chọn -q0 vì nó không được hỗ trợ bởi máy tôi đang sử dụng. Ngoài ra, tất cả đều hoạt động. Đây là một mẹo FANTASTIC. Cảm ơn bạn rất nhiều. :)
Gerry

Tôi gặp phải một vấn đề, câu trả lời của bạn hoạt động tốt với tôi từ thiết bị đầu cuối, nhưng tôi không thể làm điều đó bằng cách sử dụng gui sftp, nó nói: thông báo lỗi chưa được xử lý, đã hết thời gian trong khi đăng nhập.
Vikash B

@VikashB Vâng, nó thực sự nên hoạt động. Xem xét việc tạo một câu hỏi MỚI để xử lý tình huống cụ thể của bạn.
gertvdijk

Tôi đã làm ở đây là câu hỏi: Askubfox.com/questions/688567/ mẹo
Vikash B

1
Để bổ sung cho từ thông thái của @gertvdijk, có một wikibook tuyệt vời về chủ đề proxy ssh và máy chủ nhảy có thể phục vụ như một tài liệu tham khảo vô giá.
Travis Clarke

51

Nhảy trong một lần

Một thay thế rõ ràng cho cách tiếp cận ProxyCommand mà tôi đã cung cấp trong câu trả lời khác của mình sẽ là 'nhảy' trực tiếp vào máy đích:

ssh -t user@machineB ssh user@machineA

Lưu ý lệnh -tđầu tiên ssh. Không có nó, nó sẽ thất bại:

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

Nó sẽ buộc một TTY thực sự được phân bổ

Nhược điểm của điều này là bây giờ tất cả cấu hình, xác minh và xác thực diễn ra tại Máy B, điều mà tôi thực sự không thích trong tình huống của mình vì lý do bảo mật. Tôi thích sự tuyệt vời của mình trên PC của chính mình và xác thực và xác minh máy mục tiêu cuối cùng từ PC của chính tôi. Ngoài ra, bạn chỉ có thể sử dụng trình vỏ tương tác cho SSH, vì vậy điều này sẽ không xử lý các công cụ khác như SCP hoặc sử dụng trình quản lý tệp GUI của bạn.

Đối với tất cả các lý do đã nói ở trên, tôi thực sự khuyên bạn nên sử dụng phương pháp ProxyCommand , nhưng để kết nối nhanh, điều này hoạt động tốt.


Tại sao không có một câu trả lời với cả giải pháp 'Một lần' và Giải pháp vĩnh viễn?
demure

5
@demure Đó là cách các trang web StackExchange hoạt động ... Xem: Nghi thức chính thức khi trả lời một câu hỏi hai lần là gì? nói "tốt hơn là đăng hai câu trả lời khác nhau, hơn là đặt chúng vào một câu trả lời." . Và tôi không coi đây là giải pháp tương tự. Theo tôi, vĩnh viễn / tạm thời không phải là điều làm cho cách tiếp cận này khác đi.
gertvdijk

Ngoài ra, các hướng dẫn khác nói sử dụng công tắc -A, nhưng chỉ ra rằng điều này có ý nghĩa bảo mật. Bạn có biết ý nghĩa của việc chuyển tiếp hay không, kết nối tác nhân xác thực?
chéo

@gertvdijk siêu ninja đây! bạn có các giải pháp HAI hàng đầu. Tôi chưa bao giờ thấy điều đó trước đây. siêu mát. cách tốt hơn so với việc tạo ra một giải pháp dài lớn với các giải pháp N (đó là những gì tôi thường thấy).
Trevor Boyd Smith

Điều này thuận tiện hơn nhiều so với việc thiết lập một cấu hình cũng sẽ cản trở các ssh khác.
Nikhil Sahu

37

Bạn có thể sử dụng -Jtùy chọn dòng lệnh:

ssh -J user@machineB user@machineA

Từ man ssh:

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

Nó được giới thiệu trong OpenSSH phiên bản 7.3 (phát hành vào tháng 8 năm 2016). Nó có sẵn trong Ubuntu 16.10 trở lên.


3
+1 vì điều này hoạt động ngay cả khi bạn cần chỉ định tệp chính cho máyA
Đau buồn

1
+1, đây là phiên bản tốt hơn so với câu trả lời ProxyCommand của tôi nếu tất cả các máy chủ của bạn đang chạy phiên bản OpenSSH gần đây.
gertvdijk

Máy chủ OpenSSH nên được cài đặt trên cả máy A và B trong trường hợp này? Tôi có hiểu đúng không?
Mikhail

17

Hãy thử sử dụng

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

trong ~ / .ssh / config của bạn và thực hiện tất cả trong một lần chụp với các phím chỉ nằm trên máy tính của bạn.


1
Điều này là sạch hơn so với việc đưa netcat vào hỗn hợp. Ngoài ra, khóa SSH riêng cũng không cần tồn tại trên Bmáy.
danemacmillan

1

Đây là một gợi ý rất hữu ích. Sau khi nhắn tin hàng giờ, tôi tìm thấy ghi chú này và xác nhận nó hoạt động chính xác như tài liệu. Để kết nối thông qua MachineA với MachineB, từ máy từ xaC:

ví dụ: [xuser @ machineC ~] ssh -t MachineA ssh MachineB

"-T" là rất quan trọng, ssh thất bại nếu nó không xuất hiện. Bạn sẽ được nhắc hai lần, lần đầu tiên cho mật khẩu trên MachineA, sau đó lần thứ hai cho MachineB. Ngoài ra, lưu ý rằng điều này giả sử bạn có "xuser" người dùng được xác định trên cả ba máy. Nếu không, chỉ cần sử dụng cú pháp ssh: "yuser @ MachineA ...". Cũng lưu ý rằng bạn có thể sử dụng IP # s quad rải rác, nếu bạn muốn. Điều này rất hữu ích nếu bạn đang liên kết thông qua một mạng riêng cục bộ đang sử dụng IP không được tiếp xúc với thế giới - tức là. không có trong tệp lưu trữ cục bộ của bạn hoặc bất kỳ DNS nào. Để lấy tệp từ MachineB, đến máyC từ xa, bạn có thể chuyển từ MachineB sang MachineA, sau đó từ MachineA sang máyC từ xa. (Ví dụ: máy từ xaC có thể ping MachineA, nhưng không phải MachineB.) Hãy cẩn thận: Tôi đã thử nghiệm với Fedora và WindowsXP, MachineA là một hộp XP chạy ICS (Chia sẻ kết nối Internet), trong khi MachineB và machineC từ xa là các hộp Fedora-Linux. Đề nghị này đã giải quyết một vấn đề quan trọng đối với tôi - tức là. hạn chế, theo dõi truy cập từ xa vào lan trang web từ xa của tôi. Cũng lưu ý, khi bạn "đăng xuất" từ MachineB, bạn sẽ thấy hai "Kết nối tới xxx.xxx.xxx.xxx đã đóng." tin nhắn.


Nếu bạn thiết lập và định cấu hình xác thực khóa chung, thì bạn không cần phải lo lắng về việc nhập mật khẩu của mình. Nhưng -tvẫn được yêu cầu.
Felipe Alvarez

@FelipeAlvarez Bạn vẫn phải lo lắng về việc nhập mật khẩu thứ hai nếu bạn không tin tưởng máy B để có mật khẩu đăng nhập vào A!
Michael

1

ProxyCommand là một giải pháp sạch cho trường hợp khi bạn cho phép truy cập shell trong cả hai hệ thống. Chúng tôi muốn cung cấp cho người dùng từ xa quyền truy cập vào một máy nội bộ (A) thông qua một nhà môi giới (B), nhưng không cho phép người dùng truy cập shell vào B để bảo mật được cải thiện. Điều này đã làm việc:

Thay thế vỏ đăng nhập

Thay thế vỏ đăng nhập (sử dụng chsh) cho extuserngười môi giới bằng tập lệnh sau (được lưu trong tệp):

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

Với điều kiện không có mật khẩu đăng nhập đã được thiết lập trong extuser @ B cho người dùng từ xa và trong Internaluser @ A cho extuser @ B, sau đó thực hiện lệnh sau sẽ trực tiếp đưa người dùng từ xa đến A

ssh extuser@B

Mẹo : Tạo không cần thiết mật khẩu đăng nhập ủy quyền thiết lập ủy quyền trong extuser @ B trước khi thay đổi sang vỏ đăng nhập tùy chỉnh. Sau khi thay đổi, vì tài khoản này không thể truy cập được đối với bất kỳ ai thông qua trình bao, chỉ sudoer @ B có thể thay đổi tệp được ủy quyền bằng cách chỉnh sửa trực tiếp.

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

Dòng cuối cùng là thay thế hiển thị biểu ngữ đăng nhập từ B, vì vậy người dùng từ xa có quyền truy cập rõ ràng vào A.


Cách tiếp cận rất thú vị. Tuy nhiên, nhược điểm chính của điều này là: 1) Việc sử dụng bị giới hạn trong việc sử dụng SSH tiêu chuẩn (không hỗ trợ SFTP / SCP). 2) Người dùng không thể chọn máy chủ đích khác ngoài máy chủ duy nhất (vì được mã hóa cứng trong vỏ đăng nhập) 3) Xác thực khóa máy chủ không thể được thực hiện từ máy trạm đến máy chủ đích cuối cùng (kể từ khi sử dụng nhị phân SSH của nhà môi giới) . 4) Khóa riêng để người dùng truy cập máy chủ đích cuối cùng đang cư trú trên nhà môi giới hơn là với người dùng. Điều này cho phép mạo danh người dùng bởi một quản trị viên (điều này thường không thể thực hiện được).
gertvdijk

Tất cả các điểm đúng, cảm ơn cho công phu. Tuy nhiên, mục đích chính là cung cấp quyền truy cập ssh của người dùng đáng tin cậy vào A mà không cần đăng nhập vào B. Vì chỉ quản trị viên mới có thể thêm khóa chung của người dùng đáng tin cậy trên B (thông qua sudo, không cần đăng nhập), điều này đã ngụ ý rằng người dùng có ( quản trị viên) truy cập vào khóa riêng của bộ mở rộng @ B (không phải của người dùng đáng tin cậy bên ngoài) và đã thiết lập nó ngay từ đầu!
Sunthar

1

Bạn có nghĩa là bạn cần một vài người nhảy :)

Gần đây, tôi đã gặp vấn đề này với jumper1 jumper2 và máy cuối cùng của tôi, như đối với sol của tôi

kịch bản địa phương:

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

sau đó trên jumper thứ nhất (là bộ định tuyến của tôi), tôi đã đặt một tập lệnh có tên Y00.sh:

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

Bạn có thể thay thế chúng bằng IP và mật khẩu của bạn, chúc may mắn!

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.