วิธีการส่งต่อพอร์ตจากเครื่องหนึ่งไปยังอีกเครื่องหนึ่ง


19

พิจารณาสถานการณ์ต่อไปนี้:

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

บางครั้งฉันต้องการทำให้แอพบางตัว (ซึ่งฟังบนพอร์ตบางพอร์ตบน M เช่น 8888) สามารถเข้าถึงได้จากอินเทอร์เน็ตภายนอก

เพื่อที่ฉันต้องการตั้งค่าบางพอร์ตใน S (2222) เพื่อส่งต่อไปยังพอร์ต M 8888 ดังนั้นใครก็ตามที่เข้าถึง S: 2222 จะรู้สึกเหมือนเขากำลังเข้าถึง M: 8888

ฉันพยายามใช้การส่งต่อพอร์ต ssh ความพยายามที่ดีที่สุดของฉันคือ:

ssh -L 2222:M:8888 -N M

แต่นั่นทำให้ฉันสามารถเข้าถึงพอร์ต 2222 จากเซิร์ฟเวอร์เองไม่ใช่จากเครื่องอื่น

มีวิธีทำอย่างถูกต้องหรือไม่? โดยเฉพาะอย่างยิ่งฉันต้องการให้มันเป็นคำสั่งง่ายๆซึ่งฉันจะสามารถเริ่มและปิดด้วย ^ C เมื่อฉันไม่ต้องการการส่งต่อนั้นอีกต่อไป


ลองใช้ localhost.run ซึ่งเป็นเว็บไซต์ที่คุณสามารถไปที่localhost.runฉันคิดว่ามีวิธีที่จะทำให้ผลิตภัณฑ์ของคุณอยู่ที่นั่น ..
Angelena Neilsomt

คำตอบ:


16

ใช่สิ่งนี้เรียกว่าGatewayPortsใน SSH ข้อความที่ตัดตอนมาจากssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

และคุณสามารถใช้localhostแทนMการส่งต่อเนื่องจากคุณส่งต่อไปยังเครื่องเดียวกับที่คุณใช้ SSH - ถ้าฉันเข้าใจคำถามของคุณถูกต้อง

ดังนั้นคำสั่งจะกลายเป็นสิ่งนี้:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

และจะมีลักษณะเช่นนี้ในnetstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

ตอนนี้ใครก็ตามที่เข้าถึงเครื่องนี้ที่พอร์ต 2222 TCP จะคุยกับ localhost จริง ๆ : 8888 ตามที่เห็นในเครื่อง M โปรดทราบว่านี่ไม่เหมือนกับการส่งต่อธรรมดาไปยังพอร์ต 8888 ของ M


1
ขอบคุณ! ได้ผลจริง! แต่มีความผิดปกติบางประการ - ด้วยเหตุผลบางประการผลลัพธ์มีบรรทัด "ผูก: ที่อยู่ที่ใช้งานอยู่" นั่นแปลว่าอะไร?
Rogach

1
คุณมีกระบวนการที่ทำงานอยู่บนพอร์ตนั้นแล้ว ใช้netstatคำสั่งเดียวกันเพื่อค้นหาว่าอะไรกันแน่ อาจเป็น SSH อื่นที่คล้ายกันที่ยังคงทำงานอยู่ในพื้นหลังและฆ่ามันโดยใช้ PID netstat บอกคุณ
gertvdijk

สิ่งที่สนุกคือฉันทำไปแล้ว - ไม่มีกระบวนการในพอร์ตเหล่านั้นทั้งบน S และ M หากมีบางอย่างการก่อสร้างทั้งหมดอาจจะล้มเหลวในการทำงาน
Rogach

10

มีอีกวิธีคือ คุณสามารถตั้งค่าการส่งต่อพอร์ตจาก S: 2222 ถึง W: 8888 ด้วย iptables คำสั่งเดียว:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

โดยที่ 1.2.3.4 เป็นที่อยู่ IP ของ M มันเรียกว่า NAT (Network Address Translation)


1
ในขณะที่คุณกำลังทำ NAT ปลายทางที่นี่ (ตรงข้ามกับ NAT ต้นทาง) สิ่งนี้จะทำงานได้อย่างน่าเชื่อถือในสถานการณ์เฉพาะและอาจต้องแก้ไขตารางเส้นทาง สำหรับการส่งต่อไปยังเครื่องเสมือน (M) ที่ทำงานบนโฮสต์ (S) สิ่งนี้อาจใช้งานได้ดี
gertvdijk

คำสั่งนี้ควรใช้กับเกตเวย์ ฉันคิดว่า S และ M อยู่บน LAN เดียวกัน NAT ต้นทางจะทำโดยอัตโนมัติโดยตัวติดตามการเชื่อมต่อในเคอร์เนล Linux ที่ทันสมัย ฉันมีการกำหนดค่าดังกล่าวในเครือข่ายสำนักงานของฉันและทำงานได้อย่างสมบูรณ์ อย่างไรก็ตามมันเป็นไปได้ที่จะทำให้คำสั่งเฉพาะเจาะจงมากขึ้น (ตัวอย่างเช่นการบอก iptables -i eth0 โดยที่ eth0 เป็นอินเตอร์เฟสภายนอก)
Gevial

หาก S และ M อยู่บน LAN เดียวกันคุณไม่จำเป็นต้องส่งต่อพอร์ตที่นั่นเนื่องจากไม่มีการรับส่งข้อมูลระหว่างพวกเขาผ่านเกตเวย์
gertvdijk

1
Yeap แต่การเชื่อมต่อกับ M: 8888 นั้นทำจากอินเทอร์เน็ตฉันถือว่า Somebody form Internet -> S: 2222 -> เราเตอร์ M และ S LAN พร้อม iptables -> M: 8888
Gevial

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