Câu hỏi Đường hầm SSH qua nhiều bước nhảy


Dữ liệu đường hầm qua SSH khá đơn giản:

ssh -D9999 username@example.com

thiết lập cổng 9999 trên localhost như một đường hầm đến example.comnhưng tôi có nhu cầu cụ thể hơn:

  • Tôi đang làm việc tại địa phương localhost
  • host1 có thể truy cập localhost
  • host2 chỉ chấp nhận các kết nối từ host1
  • Tôi cần tạo một đường hầm từ localhost đến host2

Có hiệu quả, tôi muốn tạo một đường hầm SSH "multi-hop". Tôi có thể làm cái này như thế nào? Lý tưởng nhất, tôi muốn làm điều này mà không cần phải là superuser trên bất kì của các máy.


289
2018-01-16 05:58


gốc


Bạn đã sử dụng nó để làm gì? Tôi muốn sử dụng nó cho vớ proxy. Nó có hoạt động không? - prongs
Có, bạn sẽ có thể sử dụng kết nối đường hầm làm proxy SOCKS, trừ khi host2 từ chối chuyển tiếp - Mala
Tôi đã suy nghĩ về việc tạo ra một wrapper qua SSH mà sẽ thiết lập mà sử dụng nhiều sử dụng ProxyCommand. - Pavel Šimerda
@prongs Bạn đã quản lý để sử dụng điều này cho SOCKS proxy (tất cả những năm trước)? - Drux


Các câu trả lời:


Về cơ bản bạn có ba khả năng:

  1. Đường hầm từ localhost đến host1:

    ssh -L 9999:host2:1234 -N host1
    

    Như đã nói ở trên, kết nối từ host1 đến host2 sẽ không được bảo mật.

  2. Đường hầm từ localhost đến host1 và từ host1 đến host2:

    ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
    

    Điều này sẽ mở một đường hầm từ localhost đến host1 và một đường hầm khác từ host1 đến host2. Tuy nhiên cổng 9999 đến host2:1234 có thể được sử dụng bởi bất cứ ai trên host1. Điều này có thể hoặc không có thể là một vấn đề.

  3. Đường hầm từ localhost đến host1 và từ localhost đến host2:

    ssh -L 9998:host2:22 -N host1
    ssh -L 9999:localhost:1234 -N -p 9998 localhost
    

    Điều này sẽ mở một đường hầm từ localhost đến host1 thông qua dịch vụ SSH trên host2 có thể được sử dụng. Sau đó, một đường hầm thứ hai được mở ra từ localhost đến host2 qua đường hầm đầu tiên.

Thông thường, tôi sẽ đi với tùy chọn 1. Nếu kết nối từ host1 đến host2 cần được bảo mật, đi với tùy chọn 2. Tùy chọn 3 chủ yếu là hữu ích để truy cập dịch vụ trên host2 chỉ có thể truy cập từ host2 chinh no.


274
2018-01-17 21:31



tùy chọn 3 là những gì tôi đang tìm kiếm, cảm ơn! - Mala
Tôi muốn duyệt theo cách này. Cái nào tốt nhất? Tôi đã thử đầu tiên nhưng nó không hoạt động. Tôi đặt proxy vớ trong trình duyệt localhost của tôi: 1234 nhưng không may mắn. :( Hãy giúp tôi.. - prongs
@prongs thử tùy chọn 3 - Mala
là có một cách để chuyển tiếp khóa công khai của tôi từ localhost, thông qua đường hầm của máy chủ 1, trên host2? - Noli
@Noli Nếu bạn sử dụng ssh-agent (mà bạn nên), bạn có thể chuyển tiếp nó thông qua các kết nối bằng cách sử dụng -Atùy chọn để ssh. - Mika Fischer


Đây là một câu trả lời tuyệt vời giải thích việc sử dụng ProxyCommand chỉ thị cấu hình cho SSH:

Thêm cái này vào ~/.ssh/config (xem man 5 ssh_config để biết chi tiết):

Host host2
  ProxyCommand ssh host1 -W %h:%p

Sau đó ssh host2 sẽ tự động xuyên qua host1 (cũng hoạt động với X11 chuyển tiếp, vv).

Điều này cũng hoạt động đối với toàn bộ lớp máy chủ, ví dụ: được xác định theo tên miền:

Host *.mycompany.com
  ProxyCommand ssh gateway.mycompany.com -W %h:%p

Cập nhật

Giới thiệu OpenSSH 7.3 một ProxyJump chỉ thị, đơn giản hóa ví dụ đầu tiên thành

Host host2
  ProxyJump host1

138
2017-08-01 17:10



Có cách nào để thực hiện điều kiện này không? Tôi chỉ muốn làm điều này đôi khi. Ngoài ra, đây là đặc biệt cho các lệnh, nhưng tôi đang tìm một cái gì đó cho tất cả các cổng 22 (ssh, sftp, vv). - Stephane
@Stephane ý bạn là gì? đặc biệt cho các lệnh? Cấu hình SSH của bạn được sử dụng bởi bất kỳ thứ gì sử dụng ssh, kể cả git, sftp v.v. afaik. - kynan
@Stephane Tôi không biết cách bật điều kiện này (ví dụ: chỉ khi bạn ở bên ngoài mạng của máy chủ mục tiêu). Tôi đặt tùy chọn này cho tất cả các máy chủ được đề cập trong khối cấu hình và sau đó (bỏ) nhận xét dòng khi cần. Không hoàn hảo, nhưng nó hoạt động. - kynan
@Stephane chắc chắn: ssh -F /path/to/altconfig. Hãy coi chừng điều này sẽ bỏ qua hệ thống rộng /etc/ssh/ssh_config. - kynan
Một cách dễ dàng để thực hiện cài đặt "có điều kiện" là xác định hai máy chủ khác nhau trong .ssh / config, có cùng một HostName. Kết nối với host2-tunnel khi bạn muốn đường hầm, và host2 khi bạn không. - Steve Bennett


Chúng tôi có một cổng ssh vào mạng riêng của mình. Nếu tôi ở bên ngoài và muốn một vỏ từ xa trên một máy tính trong mạng riêng, tôi sẽ phải ssh vào cổng và từ đó đến máy riêng.

Để tự động hóa quy trình này, tôi sử dụng tập lệnh sau:

#!/bin/bash
ssh -f -L some_port:private_machine:22 user@gateway "sleep 10" && ssh -p some_port private_user@localhost

Điều gì đang xảy ra:

  1. Thiết lập đường hầm cho giao thức ssh (cổng 22) đến máy riêng.
  2. Chỉ khi điều này thành công, hãy ssh vào máy riêng bằng đường hầm. (&& operater đảm bảo điều này).
  3. Sau khi đóng phiên ssh riêng, tôi cũng muốn đường hầm ssh đóng lại. Điều này được thực hiện thông qua thủ thuật "ngủ 10". Thông thường, lệnh ssh đầu tiên sẽ đóng sau 10 giây, nhưng trong thời gian này, lệnh ssh thứ hai sẽ thiết lập kết nối bằng đường hầm. Kết quả là, lệnh ssh đầu tiên giữ đường hầm mở cho đến khi hai điều kiện sau được thỏa mãn: ngủ 10 đã hoàn thành và đường hầm không còn được sử dụng nữa.

20
2018-01-24 18:47



Rất thông minh!!! YÊU NÓ! - Hendy Irawan


Sau khi đọc phần trên và dán tất cả mọi thứ lại với nhau, tôi đã tạo kịch bản Perl sau đây (lưu nó dưới dạng mssh trong / usr / bin và làm cho nó thực thi được):

#!/usr/bin/perl

$iport = 13021;
$first = 1;

foreach (@ARGV) {
  if (/^-/) {
    $args .= " $_";
  }
  elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
    $user = $1;
    $host = $3;
    $port = $4 || 22;
    if ($first) {
      $cmd = "ssh ${user}${host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $first = 0;
    }
    else {
      $cmd .= " -L $iport:$host:$port";
      push @cmds, "$cmd -f sleep 10 $args";
      $cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $iport ++;
    }
  }
}
push @cmds, "$cmd $args";

foreach (@cmds) {
  print "$_\n";
  system($_);
}

Sử dụng:

Để truy cập HOSTC qua HOSTA và HOSTB (cùng một người dùng):

mssh HOSTA HOSTB HOSTC

Để truy cập HOSTC qua HOSTA và HOSTB và sử dụng SSH-portnumbers không mặc định và những người dùng khác nhau:

mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231

Để truy cập HOSTC qua HOSTA và HOSTB và sử dụng chuyển tiếp X:

mssh HOSTA HOSTB HOSTC -X

Để truy cập cổng 8080 trên HOSTC qua HOSTA và HOSTB:

mssh HOSTA HOSTB -L8080:HOSTC:8080

17
2018-01-11 11:02



điều này thật tuyệt - Mala
Tôi nghiêm túc không thể cảm ơn bạn đủ, kịch bản này làm cho cuộc sống của tôi dễ dàng hơn trên cơ sở hàng ngày. Điều duy nhất tôi thay đổi là thêm int (rand (1000)) vào iport, để cho phép nhiều cá thể chạy cùng một lúc. Tôi chắc chắn nợ bạn một ly bia. - Mala
Điều này hoạt động thực sự tốt. Một cải tiến nữa sẽ là giải quyết HOSTB, HOSTC, vv bằng cách sử dụng máy chủ lưu trữ / etc / localhost và ~ / .ssh / config - Steve Bennett
Ngoài ra tôi thứ hai bình luận của Mala. Nếu không có cổng ngẫu nhiên, nếu bạn cố gắng mssh HOSTA HOSTD bạn sẽ thực sự kết thúc tại HOSTB (và có thể sẽ không nhận ra ..) - Steve Bennett


OpenSSH v7.3 trở đi hỗ trợ -J chuyển đổi và một ProxyJump tùy chọn, cho phép một hoặc nhiều máy chủ nhảy được phân tách bằng dấu phẩy, vì vậy, bạn có thể thực hiện điều này ngay bây giờ:

ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@host

16
2017-08-10 09:11



ssh -J user1 @ host1 -YC4c arcfour, blowfish-cbc user2 @ host2 firefox-no-remote Điều này sẽ tăng tốc độ nhận firefox từ host2 đến localhost. - Jaur


Câu trả lời này tương tự như kynan, vì nó liên quan đến việc sử dụng ProxyCommand. Nhưng nó thuận tiện hơn khi sử dụng IMO.

Nếu bạn đã cài đặt netcat trong các máy hop của mình, bạn có thể thêm đoạn mã này vào ~ / .ssh / config của mình:

Host *+*
    ProxyCommand ssh $(echo %h | sed 's/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') nc $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')

Sau đó

ssh -D9999 host1+host2 -l username

sẽ làm những gì bạn hỏi.

Tôi đến đây tìm nơi ban đầu nơi tôi đọc mẹo này. Tôi sẽ đăng một liên kết khi tôi tìm thấy nó.


8
2018-03-13 09:57



Tôi tin rằng đây là nguyên nhân của mẹo: wiki.gentoo.org/wiki/SSH_jump_host - slm
@slm có, đó là nó! Cảm ơn! - silviot


ssh -L 9999:host2:80 -R 9999:localhost:9999 host1

-L 9999: host2: 80

Có nghĩa là liên kết với localhost: 9999 và bất kỳ gói nào được gửi đến localhost: 9999 chuyển tiếp nó đến host2: 80

-R 9999: localhost: 9999

Có nghĩa là bất kỳ gói nào nhận được bởi host1: 9999 chuyển tiếp nó trở lại máy chủ cục bộ: 9999


4
2018-01-19 02:03



Brilliant, câu trả lời đơn giản nhất để tạo một đường hầm để bạn có thể truy cập ứng dụng trên host2 trực tiếp từ localhost: 9999 - dvtoever
Theo câu trả lời này, tôi nhận được channel 3: open failed: administratively prohibited: open failed  thông báo lỗi. - Franck Dernoncourt


bạn sẽ có thể sử dụng cổng chuyển tiếp để truy cập dịch vụ trên host2 từ localhost. Hướng dẫn viên tốt đây. Trích:

Có hai loại cổng chuyển tiếp: chuyển tiếp cục bộ và từ xa. Họ cũng được gọi là đường hầm đi và đến, tương ứng. Chuyển tiếp cổng cục bộ chuyển tiếp lưu lượng đến một cổng cục bộ đến một cổng từ xa được chỉ định.

Ví dụ, nếu bạn phát lệnh

ssh2 -L 1234:localhost:23 username@host

tất cả lưu lượng truy cập đến cổng 1234 trên máy khách sẽ được chuyển tiếp đến cổng 23 trên máy chủ (máy chủ). Lưu ý rằng localhost sẽ được giải quyết bởi sshdserver sau khi kết nối được thiết lập. Trong trường hợp này, localhost đề cập đến chính máy chủ (máy chủ).

Chuyển tiếp cổng từ xa ngược lại: nó chuyển tiếp lưu lượng đến một cổng từ xa đến một cổng cục bộ được chỉ định.

Ví dụ, nếu bạn phát lệnh

ssh2 -R 1234:localhost:23 username@host

tất cả lưu lượng truy cập đến cổng 1234 trên máy chủ (máy chủ) sẽ được chuyển tiếp đến cổng 23 trên máy khách (máy chủ cục bộ).

Trong dàn diễn viên của bạn, hãy thay thế localhost trong ví dụ với host2 và host với host1.


2
2018-01-16 06:34



theo bài báo đó, kết nối sẽ chỉ được bảo mật cho đến khi máy giữa (host1). Có cách nào để đảm bảo toàn bộ mọi thứ vẫn an toàn không? - Mala
Tôi đã không bao giờ thử điều này, nhưng nếu host1 và host2 là cả hai máy chủ ssh, bạn có thể thiết lập một đường hầm từ host1 đến host2, sau đó thiết lập một đường hầm từ localhost đến host1 cho cùng một dịch vụ (nhận địa phương và từ xa của bạn cổng bên phải). Tôi không biết nếu đó là có thể trong một lệnh từ localhost. - fideli


Tôi đã làm những gì tôi suy nghĩ bạn muốn làm với

ssh -D 9999 -J host1 host2

Tôi được nhắc cho cả hai mật khẩu, sau đó tôi có thể sử dụng localhost: 9999 cho một proxy SOCKS đến host2. Đó là gần nhất tôi có thể nghĩ đến ví dụ bạn đã cho thấy ở nơi đầu tiên.


2
2017-11-21 11:06