ssh -L chuyển tiếp nhiều cổng


126

Tôi hiện đang chạy một loạt:

sudo ssh -L PORT:IP:PORT root@IP

Trong đó IP là mục tiêu của một máy được bảo mật và PORT đại diện cho các cổng tôi đang chuyển tiếp.

Điều này là do tôi sử dụng rất nhiều ứng dụng mà tôi không thể truy cập mà không có chuyển tiếp này. Sau khi thực hiện điều này, tôi có thể truy cập thông qua localhost:PORT.

Vấn đề chính xảy ra bây giờ là tôi thực sự có 4 cổng này mà tôi phải chuyển tiếp.

Giải pháp của tôi là mở 4 shell và liên tục tìm kiếm lịch sử của tôi ngược lại để tìm chính xác cổng nào cần được chuyển tiếp, v.v., sau đó chạy lệnh này - mỗi cái trong mỗi shell (phải điền mật khẩu, v.v.).

Giá như tôi có thể làm một cái gì đó như:

sudo ssh -L PORT1+PORT2+PORT+3:IP:PORT+PORT2+PORT3 root@IP

sau đó sẽ thực sự có ích.

Có cách nào để làm điều này dễ dàng hơn không?

Câu trả lời:


193

Các -Ltùy chọn có thể được quy định nhiều lần trong cùng một lệnh. Mỗi lần với các cổng khác nhau.


19
Lúc đầu tôi không hiểu câu trả lời này. Vì vậy, đăng một ví dụ ở đây trong trường hợp bất cứ ai cũng bị như vậy. Tác giả có nghĩa là "ssh -L port0: ip: port0 -L port1: ip: port1 ..."
Mong H. Ng

96

Chính xác những gì NaN đã trả lời, bạn chỉ định nhiều đối số -L. Tôi làm điều này tất cả các thời gian. Dưới đây là một ví dụ về chuyển tiếp đa cổng:

ssh remote-host -L 8822:REMOTE_IP_1:22 -L 9922:REMOTE_IP_2:22

Lưu ý : Điều này giống như -L localhost:8822:REMOTE_IP_1:22nếu bạn không chỉ định localhost.

Bây giờ với điều này, bây giờ bạn có thể (từ thiết bị đầu cuối khác) làm:

ssh localhost -p 8822

để kết nối REMOTE_IP_1trên cổng22

và tương tự

ssh localhost -p 9922

để kết nối REMOTE_IP_2trên cổng22

Tất nhiên, không có gì ngăn bạn gói nó vào một tập lệnh hoặc tự động hóa nó nếu bạn có nhiều máy chủ / cổng khác nhau để chuyển tiếp và đến một số cụ thể nhất định.

Hi vọng điêu nay co ich.


Bổ sung tuyệt vời cho câu trả lời của Nan. Cảm ơn.
AFP_555

1
Hãy cẩn thận về điều này: "Lưu ý: Điều này giống như -L localhost: 8822: REMOTE_IP_1: 22 nếu bạn không chỉ định localhost." Điều này chỉ đúng nếu cài đặt GatewayPort là 'không', được thừa nhận là mặc định. Nhưng xem xét các hàm ý nếu không, bạn nên xác minh cài đặt hoặc, tốt hơn nữa, hãy rõ ràng và sử dụng "-L localhost: 8822 ...".
David

Tôi đồng ý với By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address: ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com @David ssh.com/ssh/tunneling/example
Karl Pokus

24

Bạn có thể sử dụng hàm bash sau (chỉ cần thêm nó vào của bạn ~/.bashrc):

function pfwd {
  for i in ${@:2}
  do
    echo Forwarding port $i
    ssh -N -L $i:localhost:$i $1 &
  done  
}

Ví dụ sử dụng:

pfwd hostname {6000..6009}

2
Sử dụng -fđể chạy trong nền
Karl Pokus

Ehmmm ... tại sao bạn muốn làm theo cách đó?
Anton Bessonov

12

Đối với những người đang chuyển tiếp nhiều cổng thông qua cùng một máy chủ, có thể thiết lập một cái gì đó như thế này trong ~ / .ssh / config của họ

Host all-port-forwards Hostname 10.122.0.3 User username LocalForward PORT_1 IP:PORT_1 LocalForward PORT_2 IP:PORT_2 LocalForward PORT_3 IP:PORT_3 LocalForward PORT_4 IP:PORT_4

và nó trở thành một đơn giản ssh all-port-forwardsđi.


Tôi thích cách tiếp cận này.
BMW

7

jbchichoko và yuval đã đưa ra các giải pháp khả thi. Nhưng câu trả lời của jbchichoko không phải là một câu trả lời linh hoạt như một chức năng và các đường hầm được mở bằng câu trả lời của yuval không thể bị tắt bởi ctrl+cvì nó chạy trong nền. Tôi đưa ra giải pháp của mình dưới đây để giải quyết cả hai lỗ hổng:

Định nghĩa một hàm trong ~/.bashrchoặc~/.zshrc :

# fsshmap multiple ports
function fsshmap() {
  echo -n "-L 1$1:127.0.0.1:$1 " > $HOME/sh/sshports.txt
  for ((i=($1+1);i<$2;i++))
  do
    echo -n "-L 1$i:127.0.0.1:$i " >> $HOME/sh/sshports.txt
  done
  line=$(head -n 1 $HOME/sh/sshports.txt)
  cline="ssh "$3" "$line
  echo $cline
  eval $cline
}

Một ví dụ về việc chạy chức năng:

fsshmap 6000 6010 hostname

Kết quả của ví dụ này:

Bạn có thể truy cập 127.0.0.1:16000~16009giống nhưhostname:6000~6009


2

Trong công ty của tôi, cả tôi và các thành viên trong nhóm của tôi đều cần truy cập vào 3 cổng của máy chủ "mục tiêu" không thể truy cập, vì vậy tôi đã tạo một đường hầm vĩnh viễn (đó là một đường hầm có thể chạy trong nền vô thời hạn, xem thông số -f-N) từ máy chủ có thể truy cập mục tiêu một. Trên dòng lệnh của máy chủ có thể truy cập, tôi đã thực hiện:

ssh root@reachableIP -f -N  -L *:8822:targetIP:22  -L *:9006:targetIP:9006  -L *:9100:targetIP:9100

Tôi đã sử dụng người dùng rootnhưng người dùng của bạn sẽ làm việc. Bạn sẽ phải nhập mật khẩu của người dùng đã chọn (ngay cả khi bạn đã kết nối với máy chủ có thể truy cập với người dùng đó).

Bây giờ cổng 8822 của máy có thể truy cập tương ứng với cổng 22 của máy đích (đối với ssh / PuTTY / WinSCP) và cổng 9006 và 9100 trên máy có thể truy cập tương ứng với cùng một cổng của máy đích (chúng lưu trữ hai dịch vụ web trong trường hợp của tôi ).


1

Một trong những lợi ích của việc đăng nhập vào máy chủ bằng chuyển tiếp cổng là tạo điều kiện cho việc sử dụng Jupyter Notebook. Liên kết này cung cấp một mô tả tuyệt vời về cách nó. Ở đây tôi muốn làm một số tóm tắt và mở rộng cho tất cả các bạn tham khảo.

Tình huống 1. Đăng nhập từ một máy cục bộ có tên Host-A (ví dụ: máy tính xách tay của riêng bạn) vào một máy làm việc từ xa có tên Host-B.

ssh user@Host-B -L port_A:localhost:port_B
jupyter notebook --NotebookApp.token='' --no-browser --port=port_B

Sau đó, bạn có thể mở trình duyệt và nhập: http: // localhost: port_A / để thực hiện công việc của mình trên Host-B nhưng hãy xem nó trong Host-A.

Tình huống 2. Đăng nhập từ một máy cục bộ có tên Host-A (ví dụ: máy tính xách tay của riêng bạn) vào máy đăng nhập từ xa có tên Host-B và từ đó đăng nhập vào máy làm việc từ xa có tên Host-C. Đây thường là trường hợp cho hầu hết các máy chủ phân tích trong các trường đại học và có thể đạt được bằng cách sử dụng hai ssh -Lkết nối với -t.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C
jupyter notebook --NotebookApp.token='' --no-browser --port=port_C

Sau đó, bạn có thể mở trình duyệt và nhập: http: // localhost: port_A / để thực hiện công việc của mình trên Host-C nhưng xem nó trong Host-A.

Tình huống 3. Đăng nhập từ máy cục bộ có tên Host-A (ví dụ: máy tính xách tay của bạn) vào máy đăng nhập từ xa có tên Host-B và từ đó đăng nhập vào máy làm việc từ xa có tên Host-C và cuối cùng đăng nhập vào máy làm việc từ xa Host- D Điều này thường không xảy ra nhưng đôi khi có thể xảy ra. Đây là phần mở rộng của Tình huống 2 và logic tương tự có thể được áp dụng trên nhiều máy hơn.

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C -t ssh -L port_C:localhost:port_D user@Host-D
jupyter notebook --NotebookApp.token='' --no-browser --port=port_D

Sau đó, bạn có thể mở trình duyệt và nhập: http: // localhost: port_A / để thực hiện công việc của mình trên Host-D nhưng hãy xem nó trong Host-A.

Lưu ý rằng port_A, port_B, port_C, port_D có thể là các số ngẫu nhiên ngoại trừ các số cổng phổ biến được liệt kê ở đây . Trong Tình huống 1, port_A và port_B có thể giống nhau để đơn giản hóa thủ tục.


Một lời nhắc nhở, cùng một cổng trên các máy chủ khác nhau là các cổng khác nhau. Do đó, nó luôn có thể làm cho mọi thứ dễ dàng hơn bằng cách chỉ định một số cổng giống hệt nhau!
Fei Yao

0

Tôi đã phát triển loco để được giúp đỡ với chuyển tiếp ssh. Nó có thể được sử dụng để chia sẻ các cổng 5000 và 7000 trên điều khiển từ xa cục bộ tại cùng một cổng:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

0

Nếu bạn muốn một giải pháp đơn giản chạy trong nền và dễ bị giết - hãy sử dụng ổ cắm điều khiển

# start
$ ssh -f -N -M -S $SOCKET -L localhost:9200:localhost:9200 $HOST
# stop
$ ssh -S $SOCKET -O exit $HOST

0

Đây là một giải pháp lấy cảm hứng từ một từ Yuval Atzmon.

Nó có một vài lợi ích so với giải pháp ban đầu:

  • đầu tiên, nó tạo ra một quá trình nền đơn và không phải là một trên mỗi cổng
  • nó tạo ra bí danh cho phép bạn giết các đường hầm của bạn
  • nó chỉ liên kết với 127.0.0.1, nó an toàn hơn một chút

Bạn có thể sử dụng nó như:

  • tnl your.remote.com 1234
  • tnl your.remote.com {1234,1235}
  • tnl your.remote.com {1234..1236}

Và cuối cùng giết tất cả chúng với tnlkill.

function tnl {
  TUNNEL="ssh -N "
  echo Port forwarding for ports:
  for i in ${@:2}
  do
    echo " - $i"
    TUNNEL="$TUNNEL -L 127.0.0.1:$i:localhost:$i"
  done
  TUNNEL="$TUNNEL $1"
  $TUNNEL &
  PID=$!
  alias tnlkill="kill $PID && unalias tnlkill"
}

-1

Bạn có thể sử dụng chức năng zsh này (có thể cũng hoạt động với bash) (Đặt nó vào ~/.zshrc):

ashL () {
    local a=() i
    for i in "$@[2,-1]"
    do
        a+=(-L "${i}:localhost:${i}")
    done
    autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NT "$1" "$a[@]"
}

Ví dụ:

ashL db@114.39.161.24 6480 7690 7477

ashL db@114.39.161.24 {6000..6050} # Forwards the whole range. This is simply shell syntax sugar.

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.