ส่งต่อปริมาณข้อมูล SSH ผ่านเครื่องกลาง


110

การขุดอุโมงค์ SSH ทำให้ฉันสับสนมาก ฉันสงสัยว่าฉันสามารถทำได้ใน Linux

ฉันมี 3 เครื่อง ..

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

ดังนั้นฉันสามารถ SSH จาก A -> B และจาก B -> C แต่ไม่ใช่จาก A -> C

มีวิธีการตั้งค่าอุโมงค์ SSH จาก A ถึง B ดังนั้นเมื่อฉันเรียกใช้คำสั่ง SSH อื่น ๆ พวกเขาเพียงแค่ทำงานจากเครื่องท้องถิ่นของฉัน? โดยทั่วไปฉันพยายามโคลน repo git จากที่บ้าน (และฉันไม่สามารถติดตั้ง git บนเครื่อง B)

นอกจากนี้เมื่อตั้งค่า .. ฉันจะยกเลิกการตั้งค่าได้อย่างไร?


ฉันเชื่อว่ามีคำถามซ้ำ ๆ อยู่รอบ ๆ แต่การค้นหาของฉันอ่อนแอในวันนี้
ต้มตุ๋น quixote

2
นั่นจะเป็นของฉัน: superuser.com/questions/96489/ssh-tunnel-via-multiple-hops
Mala

2
มีความเป็นไปได้ที่ซ้ำกันของอุโมงค์ SSH ผ่านการกระโดดหลายครั้ง
Geza Kerecsenyi

หากคุณใช้ Linux บนเครื่อง A ให้ใช้เครื่องมือที่ชื่อว่า sshuttle ซึ่งช่วยให้คุณสามารถเลือกส่งต่อการรับส่งข้อมูลทั้งหมดสำหรับ C ผ่าน A-> B tunnel (สมมติว่า C มองเห็นได้จาก B)
ร่วม

คำตอบ:


128

วางสิ่งนี้ลงใน.ssh/configไฟล์ของคุณบน hostA (ดูman 5 ssh_configสำหรับรายละเอียด):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

ตอนนี้คำสั่งต่อไปนี้จะทำการอุโมงค์ผ่าน hostB โดยอัตโนมัติ

hostA:~$ ssh hostC

คุณอาจต้องการเพิ่มตัวเลือกเช่น-oCiphers=arcfourและ-oClearAllForwardings=yesเพิ่มความเร็วเนื่องจากการห่อsshด้านในsshนั้นมีราคาแพงกว่าและความพยายามเพิ่มเติมและตัวห่อหุ้มไม่จำเป็นต้องมีความปลอดภัยเมื่อมีการจราจรในอุโมงค์ที่เข้ารหัสแล้ว


หากคุณใช้ OpenSSH ก่อนหน้า 5.3 -Wตัวเลือกนี้จะไม่สามารถใช้ได้ ในกรณีนี้คุณสามารถใช้งานได้โดยใช้ netcat ( nc):

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB

1
มันยอดเยี่ยมมาก! ขอขอบคุณ. สิ่งนี้แก้ปัญหาที่ทำให้ฉันกินใน 2 วันที่ผ่านมา: hostC ตั้งอยู่หลังไฟร์วอลล์และมีข้อมูลที่ฉันต้องการเข้าถึงจาก hostA แล็ปท็อปที่สามารถอยู่ได้ทุกที่ในโลก hostB ยังอยู่หลังไฟร์วอลล์เดียวกันกับ hostC แต่มีพอร์ต SSH ที่เปิดให้คนทั่วโลก ดังนั้นฉันสามารถ ssh จาก hostC -> hostB ฉันตั้งค่าอุโมงค์ SSH แบบย้อนกลับระหว่าง hostC & hostB ดังนั้นฉันจึงสามารถ ssh จาก hostB -> hostC (ส่งต่อผ่าน localhost) ด้วยเคล็ดลับของคุณฉันสามารถไปจาก hostA -> hostC! มันทำงานร่วมกับ SCP & Fugu บน OSX ได้อย่างราบรื่น! ขอขอบคุณ!
AndyL

-Wตัวเลือกที่ควรจะนำมาใช้แทนของncตัวเลือก
vy32

SSH ใดควรสนับสนุน-Wเพียงอันเดียวใน hostA (ที่มา) หรืออย่างใดอย่างหนึ่งบน hostB (เครื่องกลาง)
gioele

สำหรับข้อมูลหากคุณมีหลายโฮสต์ที่คุณต้องเข้าถึงผ่านเหมือนกันhostBเป็นไปได้ที่จะประกาศหลายHost hostCบรรทัดด้านบนProxyCommandทำให้ง่ายต่อการเข้าถึงโฮสต์หลายโฮสต์ผ่านเซิร์ฟเวอร์กลาง
fduff

7

แก้ไข: นี่เป็นวิธีที่ผิด ดูคำตอบของ ephemientแทน คำตอบนี้จะได้ผล แต่อาจมีความปลอดภัยน้อยกว่าและน่ากลัวน้อยกว่า

ดูเหมือนว่าคุณต้องการโซลูชันดังต่อไปนี้:

ssh -L localhost:22:machinec:22 machineb

machinebนี้คุณจะได้รับเปลือกบน ทิ้งไว้คนเดียว ย่อขนาดหน้าต่างเทอร์มินัล

ตอนนี้ทุกครั้งที่คุณเชื่อมต่อ SSH เพื่อlocalhostคุณจะจริงจะเชื่อมต่อกับผ่านmachinec machinebเมื่อคุณทำกับอุโมงค์เพียงแค่ปิดสถานีที่คุณใช้คำสั่งข้างต้น

โปรดทราบว่าคุณจะต้องมีสิทธิ์ผู้ใช้ขั้นสูงเพื่อเรียกใช้คำสั่ง


+1 ขอบคุณเวสลีย์ นี่คือคำตอบที่แท้จริงของการขุดอุโมงค์ นี่คือบทความเกี่ยวกับมัน: securityfocus.com/infocus/1816
Larry K

3
โดยรวมแล้วนี่เป็นสิ่งที่เลวร้ายมาก ... แต่ฉันต้องทำสิ่งนี้กับ OpenSSH เวอร์ชั่นเก่าหรือไคลเอนต์ ssh อื่น ๆ คุณสามารถเลือกพอร์ตที่สูงเช่น 8022: วิธีนี้จะไม่รบกวนบริการ ssh ใด ๆ บน localhost และไม่จำเป็นต้องเรียกใช้ในฐานะ root เพียงเพิ่ม-p 8022คำสั่ง ssh ของคุณ และก็ Braindead ง่ายด้วยคอมไพล์: ใช้ ssh://localhost:8022/path/to/repo.gitURI
ephemient

3

ดูเหมือนว่าคุณต้องการนามแฝงของเชลล์บน A ที่ทำให้ ssh เกิดขึ้นบน C

  1. ฉันคิดว่าใน A คุณสามารถพิมพ์ ssh me @ b "ssh me @ c hostname" และกลับมาที่ "C"
  2. สร้างนามแฝง sshc ซึ่งขยาย sshc foo เป็น ssh me @ b "ssh me @ c foo"
  3. สำหรับไวยากรณ์ที่แน่นอนของการสร้างนามแฝงปรึกษา superuser.com

1
คุณอาจจะต้องเพิ่ม-tตัวเลือกของ ssh ภายนอกถ้าคุณต้องการเชลล์แบบโต้ตอบเนื่องจากsshถือว่า-Tถ้ามันได้รับคำสั่ง
ephemient

1

สำหรับเชลล์เชิงโต้ตอบคุณสามารถใช้คำสั่งง่าย ๆ นี้:

ssh -J <user>@<hostB> <user>@<hostC>

ตัวเลือก -J สำหรับการกระโดด


0

หากนายจ้างของคุณให้ VPN ฉันขอแนะนำให้ใช้สิ่งนั้นแทน

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


6
บางครั้ง VPN ของตนนั่นคือเหตุผลที่เราต้องการเทคนิคเหล่านี้ ...
หลุยส์

0

YASS อีกวิธีง่ายๆ

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • คำสั่งแรกเปิดการเชื่อมต่อ SSH เพื่อHostBและบอกHostBเพื่อส่งต่อการเชื่อมต่อจากlocalhost: 2222เพื่อHostC: 22
  • -fพารามิเตอร์บอก SSH เพื่อไปยังพื้นหลังเชื่อมต่อที่สร้างครั้งเดียว
  • คำสั่งที่สองเปิดได้อย่างง่ายดายเพียงเชื่อมต่อไคลเอนต์กับlocalhost: 2222
  • ไม่จำเป็นต้องใช้ตัวเลือกHostKeyAliasแต่สามารถช่วยป้องกันการเชื่อมต่อไปยังโฮสต์ที่ไม่ถูกต้อง
  • Nota: sleep 10จำเป็นต้องใช้คำสั่งเพื่อรักษาการเชื่อมต่อจนกว่าคำสั่ง ssh ที่สองจะใช้พอร์ตที่ส่งต่อ จากนั้นsshแรกจะปิดเมื่อsshที่สองออกจากพอร์ตที่ส่งต่อ

ตอนนี้คุณสามารถเรียกใช้เซสชัน ssh ที่ตามมา:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

ตัวแปร:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

เซสชัน ssh ที่ตามมาสามารถเปิดได้โดยการเรียกใช้:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

ข้อได้เปรียบหลักของการใช้ -M และ -S param คือการเชื่อมต่อเดียวเท่านั้นที่เปิดจาก HostA ถึง HostC เซสชั่นที่ตามมาจะไม่ตรวจสอบอีกครั้งและทำงานได้เร็วขึ้นมาก


0

กรณีพิเศษ, แพลตฟอร์มผสมระวัง:

  hostA (linux) -> HostB (solaris) -> HostC (linux)

หากต้องการแอปพลิเคชั่น X บน hostC และสื่อกลาง hop อยู่ในกล่อง Solaris ... ในกรณีนี้ฉันพบ netcat (nc) ที่ต้องการบน ProxyCommand เช่นนั้น:

hostA: ~ $ vi .ssh / config:

โฮสต์ hostC
    ProxyCommand ssh hostB nc% h% p # โดยที่ nc คือ netcat

จากนั้นอุโมงค์อัตโนมัติจะทำงาน:

hostA: ~ $ ssh hostC

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