ssh -L ส่งต่อหลายพอร์ต


129

ฉันกำลังใช้งานกลุ่ม:

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

โดยที่ IP เป็นเป้าหมายของเครื่องที่ปลอดภัยและ PORT แสดงถึงพอร์ตที่ฉันกำลังส่งต่อ

นี่เป็นเพราะฉันใช้แอพพลิเคชั่นจำนวนมากซึ่งไม่สามารถเข้าถึงได้หากไม่มีการส่งต่อนี้ หลังจากดำเนินการแล้วฉันสามารถเข้าถึงlocalhost:PORTได้

ปัญหาหลักเกิดขึ้นตอนนี้จริงๆแล้วฉันมี 4 พอร์ตเหล่านี้ที่ฉันต้องส่งต่อ

วิธีแก้ปัญหาของฉันคือเปิด 4 เชลล์และค้นหาประวัติย้อนหลังอย่างต่อเนื่องเพื่อค้นหาว่าพอร์ตใดที่ต้องส่งต่อ ฯลฯ จากนั้นรันคำสั่งนี้ - หนึ่งในแต่ละเชลล์ (ต้องกรอกรหัสผ่าน ฯลฯ )

ถ้าเพียงฉันสามารถทำสิ่งที่ชอบ:

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

นั่นจะช่วยได้จริงๆ

มีวิธีทำให้ง่ายขึ้นไหม

คำตอบ:


195

-Lตัวเลือกที่สามารถระบุได้หลายครั้งภายในคำสั่งเดียวกัน ทุกครั้งด้วยพอร์ตต่างๆ


20
ตอนแรกฉันไม่เข้าใจคำตอบนี้ ดังนั้นการโพสต์ตัวอย่างที่นี่เผื่อว่าใครจะได้รับความทุกข์ ผู้เขียนหมายถึง "ssh -L port0: ip: port0 -L port1: ip: port1 ... "
Mong H. Ng

96

สิ่งที่NaNตอบคุณระบุอาร์กิวเมนต์ -L หลายรายการ ฉันทำแบบนี้ตลอดเวลา นี่คือตัวอย่างของการส่งต่อหลายพอร์ต:

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

หมายเหตุ : นี่เป็นเช่นเดียวกับถ้าคุณไม่ได้ระบุ -L localhost:8822:REMOTE_IP_1:22localhost

ด้วยสิ่งนี้ตอนนี้คุณสามารถ (จากเทอร์มินัลอื่น) ทำ:

ssh localhost -p 8822

เพื่อเชื่อมต่อREMOTE_IP_1กับพอร์ต22

และในทำนองเดียวกัน

ssh localhost -p 9922

เพื่อเชื่อมต่อREMOTE_IP_2กับพอร์ต22

แน่นอนว่าไม่มีอะไรหยุดคุณจากการรวมสิ่งนี้ลงในสคริปต์หรือทำให้เป็นอัตโนมัติได้หากคุณมีโฮสต์ / พอร์ตที่แตกต่างกันจำนวนมากเพื่อส่งต่อและไปยังโฮสต์ที่เฉพาะเจาะจง

หวังว่านี่จะช่วยได้


เติมเต็มคำตอบของแนนได้เป็นอย่างดี ขอบคุณ
AFP_555

1
โปรดระวังสิ่งนี้: "หมายเหตุ: นี่เหมือนกับ -L localhost: 8822: REMOTE_IP_1: 22 หากคุณไม่ระบุ localhost" นี่จะเป็นจริงก็ต่อเมื่อการตั้งค่า GatewayPorts เป็น 'ไม่' ซึ่งเป็นค่าเริ่มต้น แต่เมื่อพิจารณาถึงผลกระทบหากไม่เป็นเช่นนั้นคุณควรตรวจสอบการตั้งค่าหรือยังดีกว่าให้ชัดเจนและใช้ "-L localhost: 8822 ... "
เดวิด

ฉันเห็นด้วยกับ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

คุณสามารถใช้ฟังก์ชั่นทุบตีต่อไปนี้ (เพียงแค่เพิ่มลงในของคุณ~/.bashrc):

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

ตัวอย่างการใช้งาน:

pfwd hostname {6000..6009}

2
ใช้-fเพื่อทำงานในพื้นหลัง
Karl Pokus

เอิ่มมม ... ทำไมถึงอยากทำแบบนั้นล่ะ?
Anton Bessonov

14

สำหรับผู้ที่ส่งต่อหลายพอร์ตผ่านโฮสต์เดียวกันสามารถตั้งค่าบางอย่างเช่นนี้ได้ใน~ / .ssh / config

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

และจะกลายเป็นง่ายssh all-port-forwardsทันที


ฉันชอบแนวทางนี้
BMW

8

jbchichoko และ yuval ได้ให้คำตอบที่เป็นไปได้ แต่คำตอบของ jbchichoko ไม่ใช่คำตอบที่ยืดหยุ่นในฐานะฟังก์ชันและอุโมงค์ที่เปิดโดยคำตอบของ yuval ไม่สามารถปิดลงได้ctrl+cเพราะมันทำงานในพื้นหลัง ฉันให้วิธีแก้ปัญหาด้านล่างเพื่อแก้ไขข้อบกพร่องทั้งสอง:

การกำหนดฟังก์ชันใน~/.bashrcหรือ~/.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
}

ตัวอย่างการเรียกใช้ฟังก์ชัน:

fsshmap 6000 6010 hostname

ผลลัพธ์ของตัวอย่างนี้:

คุณสามารถเข้าถึงได้127.0.0.1:16000~16009เช่นเดียวกับhostname:6000~6009


3

ข้อดีอย่างหนึ่งของการล็อกอินเข้าสู่เซิร์ฟเวอร์ด้วยการส่งต่อพอร์ตคือการอำนวยความสะดวกในการใช้งาน Jupyter Notebook ลิงก์นี้ให้คำอธิบายที่ดีเยี่ยมเกี่ยวกับวิธีการ ฉันอยากจะสรุปและขยายความให้พวกคุณทุกคนอ้างอิง

สถานการณ์ 1. เข้าสู่ระบบจากเครื่องท้องถิ่นชื่อ Host-A (เช่นแล็ปท็อปของคุณเอง) ไปยังเครื่องทำงานระยะไกลชื่อ Host-B

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

จากนั้นคุณสามารถเปิดเบราว์เซอร์และป้อน: http: // localhost: port_A /เพื่อทำงานบน Host-B แต่จะเห็นใน Host-A

สถานการณ์ที่ 2. ล็อกอินจากเครื่องโลคัลชื่อ Host-A (เช่นแล็ปท็อปของคุณเอง) ไปยังเครื่องล็อกอินระยะไกลชื่อ Host-B และจากนั้นล็อกอินไปยังเครื่องทำงานระยะไกลชื่อ Host-C นี้มักจะเป็นกรณีสำหรับเซิร์ฟเวอร์การวิเคราะห์มากที่สุดภายในมหาวิทยาลัยและสามารถทำได้โดยการใช้สองเชื่อมต่อกับssh -L-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

จากนั้นคุณสามารถเปิดเบราว์เซอร์และป้อน: http: // localhost: port_A /เพื่อทำงานของคุณบน Host-C แต่จะเห็นใน Host-A

สถานการณ์ 3. เข้าสู่ระบบจากเครื่องโลคัลชื่อ Host-A (เช่นแล็ปท็อปของคุณเอง) ไปยังเครื่องล็อกอินระยะไกลชื่อ Host-B และจากนั้นล็อกอินไปยังเครื่องทำงานระยะไกลชื่อ Host-C และสุดท้ายเข้าสู่ระบบเครื่องทำงานระยะไกล Host- D. โดยปกติจะไม่เป็นเช่นนั้น แต่อาจเกิดขึ้นในบางครั้ง เป็นส่วนขยายของสถานการณ์ 2 และสามารถใช้ตรรกะเดียวกันกับเครื่องอื่น ๆ ได้

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

จากนั้นคุณสามารถเปิดเบราว์เซอร์และป้อน: http: // localhost: port_A /เพื่อทำงานบน Host-D แต่จะเห็นใน Host-A

โปรดทราบว่า port_A, port_B, port_C, port_D สามารถยกเว้นตัวเลขสุ่มหมายเลขพอร์ตทั่วไปที่ระบุไว้ที่นี่ ในสถานการณ์ที่ 1 port_A และ port_B สามารถเหมือนกันเพื่อลดความซับซ้อนของขั้นตอน


คำเตือนพอร์ตเดียวกันบนเซิร์ฟเวอร์ต่างกันเป็นพอร์ตที่แตกต่างกัน ดังนั้นจึงสามารถทำให้สิ่งต่างๆง่ายขึ้นได้เสมอโดยการระบุหมายเลขพอร์ตที่เหมือนกัน!
Fei Yao

3

ใน บริษัท ของฉันทั้งฉันและสมาชิกในทีมของฉันต้องการการเข้าถึง 3 พอร์ตของเซิร์ฟเวอร์ "เป้าหมาย" ที่ไม่สามารถเข้าถึงได้ดังนั้นฉันจึงสร้างอุโมงค์ถาวร (นั่นคืออุโมงค์ที่สามารถทำงานในพื้นหลังได้โดยไม่มีกำหนดดูพารามิเตอร์-fและ-N) จากเซิร์ฟเวอร์ที่เข้าถึงได้ไปยัง เป้าหมายหนึ่ง บนบรรทัดคำสั่งของเซิร์ฟเวอร์ที่สามารถเข้าถึงได้ฉันดำเนินการ:

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

ฉันใช้ผู้ใช้rootแต่ผู้ใช้ของคุณจะทำงานได้ คุณจะต้องป้อนรหัสผ่านของผู้ใช้ที่เลือก (แม้ว่าคุณจะเชื่อมต่อกับเซิร์ฟเวอร์ที่เข้าถึงได้กับผู้ใช้รายนั้นแล้วก็ตาม)

ตอนนี้พอร์ต 8822 ของเครื่องที่เข้าถึงได้ตรงกับพอร์ต 22 ของเป้าหมายหนึ่ง (สำหรับ ssh / PuTTY / WinSCP) และพอร์ต 9006 และ 9100 บนเครื่องที่เข้าถึงได้นั้นสอดคล้องกับพอร์ตเดียวกันของเป้าหมายหนึ่ง (โฮสต์สองบริการเว็บในกรณีของฉัน )


1

ฉันได้พัฒนาlocoเพื่อขอความช่วยเหลือในการส่งต่อ ssh สามารถใช้เพื่อแชร์พอร์ต 5000 และ 7000 บนรีโมตในเครื่องที่พอร์ตเดียวกัน:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

1

หากคุณต้องการโซลูชันง่ายๆที่ทำงานอยู่เบื้องหลังและง่ายต่อการฆ่า - ใช้ซ็อกเก็ตควบคุม

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

1

นี่คือโซลูชันที่ได้รับแรงบันดาลใจจาก Yuval Atzmon

มีประโยชน์บางประการในการแก้ปัญหาเบื้องต้น:

  • ขั้นแรกจะสร้างกระบวนการพื้นหลังเดียวไม่ใช่หนึ่งกระบวนการต่อพอร์ต
  • มันสร้างนามแฝงที่อนุญาตให้คุณฆ่าอุโมงค์ของคุณ
  • มันผูกกับ 127.0.0.1 เท่านั้นซึ่งปลอดภัยกว่าเล็กน้อย

คุณสามารถใช้เป็น:

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

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

คุณสามารถใช้ฟังก์ชั่น zsh นี้ (อาจใช้งานได้กับ bash ด้วย) (ใส่เข้าไป~/.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[@]"
}

ตัวอย่าง:

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.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.