วิธีง่ายๆในการสร้างอุโมงค์จากพอร์ตท้องถิ่นหนึ่งไปยังอีก?


76

ฉันมีเซิร์ฟเวอร์การพัฒนาซึ่งสามารถเข้าถึงได้จาก 127.0.0.1:8000 ไม่ใช่ 192.168.1.x: 8000 ในฐานะที่เป็นแฮ็คที่รวดเร็วมีวิธีตั้งค่าบางอย่างให้ฟังบนพอร์ตอื่น (เช่น 8001) เพื่อให้จากเครือข่ายท้องถิ่นฉันสามารถเชื่อมต่อ 192.168.1.x: 8001 และจะสร้างการรับส่งข้อมูลระหว่างไคลเอ็นต์และ 127.0 .0.1: 8000?


4
netcatสามารถทำได้
Andy

คำตอบ:


44

การใช้ ssh เป็นทางออกที่ง่ายที่สุด

ssh -g -L 8001: localhost: 8000 -f -N user@remote-server.com

ส่งต่อพอร์ตโลคัล 8001 บนเวิร์กสเตชันของคุณไปยังที่อยู่ localhost บน remote-server.com พอร์ต 8000
-gหมายความว่าอนุญาตให้ไคลเอนต์อื่น ๆ บนเครือข่ายของฉันเชื่อมต่อกับพอร์ต 8001 บนเวิร์กสเตชันของฉัน มิฉะนั้นเฉพาะลูกค้าในพื้นที่บนเวิร์กสเตชันของคุณเท่านั้นที่สามารถเชื่อมต่อกับพอร์ตที่ส่งต่อได้
-Nหมายความว่าสิ่งที่ฉันทำคือส่งต่อพอร์ตอย่าเริ่มเชลล์
-fหมายถึง fork ลงในพื้นหลังหลังจากการเชื่อมต่อ SSH สำเร็จและเข้าสู่ระบบ
พอร์ต 8001 จะยังคงเปิดอยู่สำหรับการเชื่อมต่อจำนวนมากจนกระทั่ง ssh ตายหรือถูกฆ่า หากคุณเกิดขึ้นบน Windows ลูกค้า SSH ที่ยอดเยี่ยม PuTTY สามารถทำสิ่งนี้ได้เช่นกัน ใช้ 8001 เป็นพอร์ตท้องถิ่นและ localhost: 8000 และปลายทางและเพิ่มการส่งต่อพอร์ตท้องถิ่นในการตั้งค่า คุณสามารถเพิ่มได้หลังจากเชื่อมต่อสำเร็จด้วย PuTTY


4
อะไรuser@remote-server.comทำอย่างไร มันไม่จำเป็นอย่างแน่นอนสำหรับการส่งต่อพอร์ตอย่างไรก็ตามเอกสารที่มีอาร์กิวเมนต์นี้มากกว่านั้นพยายามเชื่อมต่อที่นั่น และเมื่อตั้งค่าตัวเลือกที่น่ารำคาญนี้ชื่อโฮสต์มันจะออกผลลัพธ์…port 22: Connection refused (ไม่ผมไม่ได้ใช้พอร์ต 22) ถ้าฉันไม่มีบางสิ่งบางอย่างคำสั่งก็ไม่ทำงาน
Hi-Angel

@ Hi-Angel user@remote-server.comเป็นเพียงตัวอย่างและคุณไม่ควรใช้มันอย่างแท้จริง คุณต้องแทนที่ด้วยชื่อคอมพิวเตอร์ที่คุณต้องการเชื่อมต่อและชื่อผู้ใช้ของคุณบนคอมพิวเตอร์นี้ ข้อมูลนี้จำเป็นสำหรับการสร้างการเชื่อมต่อ ssh เฉพาะหลังจากที่การเชื่อมต่อ ssh ถูกสร้างขึ้นพอร์ตสามารถส่งต่อผ่านการเชื่อมต่อนี้
Piotr Dobrogost

หากคุณต้องการให้พอร์ตพร้อมใช้งานจากการบู๊ตให้ดูที่ "autossh" ในบริการ systemd โดยใช้วิธีการด้านบน - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richardcoll.org

ฉันยังได้รับ "การเชื่อมต่อถูกปฏิเสธ" และฉันก็ยังไม่เข้าใจว่าทำไมต้องมีอาร์กิวเมนต์ user@remote-server.com เมื่อไม่มีการเชื่อมต่อ SSH (ตาม -N) ควรส่งต่อแพ็กเก็ต
Alexander Taylor

2
@AlexanderTaylor -Nไม่ได้หมายความว่าไม่มีการเชื่อมต่อ SSH มันหมายถึงdo not execute a remote command(ดูหน้าคน ) <user>@<host>อาร์กิวเมนต์เป็นสิ่งที่จำเป็นเพราะจะเปิดการเชื่อมต่อไปยัง SSH <host>(ซึ่งในกรณี OP จะเป็นlocalhost) และส่งต่อพอร์ตที่ต้องการผ่านอุโมงค์ SSH ว่า มันเป็นทางออกหนึ่งสำหรับปัญหาของ OP แต่ไม่ใช่วิธีที่ง่ายที่สุด หากต้องการส่งต่อไปยังsocatnetcat

94

ด้วยsocatบนเซิร์ฟเวอร์:

socat tcp-listen:8001,reuseaddr,fork tcp:localhost:8000

โดยค่าเริ่มต้นsocatจะฟังบนพอร์ต TCP 8001 บนที่อยู่ IPv4 หรือ IPv6 ใด ๆ (หากรองรับ) บนเครื่อง คุณสามารถ จำกัด มัน IPv4 / 6 โดยการแทนที่tcp-listenด้วยtcp4-listenหรือหรือไปยังที่อยู่ที่เฉพาะเจาะจงในท้องถิ่นโดยการเพิ่มtcp6-listen,bind=that-address

เช่นเดียวกับซ็อกเก็ตเชื่อมต่อที่คุณอยู่ใกล้คุณสามารถใช้ที่อยู่ใดก็ได้localhostแทนและแทนที่tcpด้วยtcp4หรือtcp6ถ้าคุณต้องการ จำกัด การแก้ไขที่อยู่เป็นที่อยู่ IPv4 หรือ IPv6

โปรดทราบว่าสำหรับเซิร์ฟเวอร์ที่รับฟังพอร์ต 8000 การเชื่อมต่อจะปรากฏว่ามาจากพร็อกซี (ในกรณีlocalhostที่จะเป็นlocalhost) ไม่ใช่ไคลเอ็นต์ดั้งเดิม คุณต้องใช้วิธีการของ DNAT (แต่ต้องใช้สิทธิ์ superuser) เพื่อให้เซิร์ฟเวอร์สามารถบอกได้ว่าใครเป็นลูกค้า


1
ขอบคุณนี่เป็นสิ่งที่ยอดเยี่ยมเพราะคุณไม่ต้องเปิดใช้งานเซิร์ฟเวอร์ ssh
jontro

ฉันสามารถใช้พอร์ตเดียวกัน แต่ที่อยู่ที่แตกต่างกันได้หรือไม่
Amos

@amos โปรดดูการแก้ไข
Stéphane Chazelas

เป็นไปได้ไหมที่จะส่งต่อปริมาณข้อมูลจาก IP ที่ระบุเท่านั้น
Phate

1
@Phate ดูที่socat บอกให้ฟังการเชื่อมต่อจากที่อยู่ IP เดียว ( rangeและtcpwrapตัวเลือกและในsocatหน้า man)
Stéphane Chazelas

46

การใช้งานแบบดั้งเดิมncเป็นวิธีที่ง่ายที่สุด:

nc -l -p 8001 -c "nc 127.0.0.1 8000"

เวอร์ชันนี้ncอยู่ในnetcat-traditionalแพ็คเกจบน Ubuntu (คุณต้องupdate-alternativesหรือเรียกว่าnc.traditional)

โปรดทราบว่าในทางตรงกันข้ามกับ ssh นี้ไม่ได้เข้ารหัส พึงระลึกไว้เสมอว่าคุณใช้มันนอกโฮสต์เดียว


2
ใครรู้ว่าเทียบเท่ากับnetcat-openbsd?
Sridhar Sarnobat

2
อะนาล็อกสำหรับnetcatรุ่นที่รวมอยู่ในbusybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( คำอธิบายของ params )
Ivan Kolmychek

2
ทำงานได้ แต่ncคำสั่งจะจบลงหลังจากการเชื่อมต่อระยะไกลครั้งแรก เพิ่ม-kถ้าคุณต้องการให้มันทำงานต่อไป
Sopalajo de Arrierez

ฉันได้รับข้อผิดพลาดนี้: nc: cannot use -p and -lบน CentOS 6.4 มีวิธีแก้ไขไหม?
Nick Predey

ฉันชอบโซลูชันนี้มากกว่า ssh one เพราะมันทำให้ง่ายต่อการใช้งานเป็น root เมื่อต้องการส่งต่อพอร์ตที่มีสิทธิ์แบบโลคัล
คริสเตียน

24

OpenBSD netcat มีให้ใช้งานตามค่าเริ่มต้นบน Linux และบน OS X

OSX:

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &

ลินุกซ์:

mkfifo backpipe
nc -l 12345 0<backpipe | nc www.google.com 80 1>backpipe

ทางเลือกที่ทำงานบน OS X ทุบตีคือการใช้ท่อแบบสองทิศทาง มันอาจทำงานบน Unixes อื่น ๆ :

nc 127.0.0.1 8000 <&1 | nc -l 8001 >&0

ฉันไม่ได้สังเกตในตอนแรกว่าคุณกำลังใช้ openbsd netcat สิ่งนี้ดีกว่าต้องติดตั้ง netcat อีกอันจากแพ็คเกจ Ubuntu
RobertR

ตัวอย่าง OpenBSD ล้มเหลวบน Ubuntu 15.04 ด้วยการเปลี่ยนเส้นทางเปลือก netcat ล้มเหลวในการเปิดพอร์ตสำหรับการฟังเมื่อเห็นหรือss -tan netstat -tan
Justin C

⁺¹ FTR: วิธีอื่นใน Ubuntu
Hi-Angel

ฉันไม่เข้าใจทางออกของคุณ คุณอธิบายได้ไหม
Trismegistos

@trismegistos ในตัวอย่างเหล่านี้ผู้ฟัง netcat และไคลเอนต์เปลี่ยนเส้นทางไปยังไฟล์ที่ใช้ร่วมกันบางส่วน (mkfifo ท่อ .. แรกเข้าก่อน) และใช้ไฟล์ที่ใช้ร่วมกันเหล่านั้นเป็นแหล่งที่มา / ปลายทางของอินพุต / เอาท์พุตสร้างอุโมงค์อย่างมีประสิทธิภาพ โดยปกติแล้วจะใช้ไคลเอนต์ / ผู้ฟัง แต่เทคนิคบางอย่างใช้ไคลเอนต์ + ไคลเอนต์ / ฟัง - ฟังwiki.securityweekly.com/ และ slideshare.net/amiable_indian/secrets-of-top-pentestersจะต้องอ่าน
Info5ek

4

การอ้างอิงคำตอบของDavid Spillettใน ServerFault

rinetd ควรทำงานและ Windows ไบนารีสำหรับมันสามารถมีได้จากhttp://www.boutell.com/rinetd/ (สำหรับทุกคนที่กำลังมองหาสิ่งเดียวกันภายใต้ Linux, rinetd อยู่ในที่เก็บมาตรฐานของ distro ทุกคน ดังนั้นสามารถติดตั้งได้ด้วย "apt-get install rinetd" หรือ "yum install rinetd" หรือคล้ายกัน)

มันเป็นไบนารีง่าย ๆ ที่ใช้ไฟล์กำหนดค่าในรูปแบบ

bindaddress bindport connectaddress connectport

ตัวอย่างเช่น:

192.168.1.1 8001 127.0.0.1 8000

หรือ

0.0.0.0 8001 127.0.0.1 8000

หากคุณต้องการผูกพอร์ตขาเข้ากับอินเทอร์เฟซทั้งหมด


3
iptables -t nat -A PREROUTING -p tcp --dport <origin-port> -j REDIRECT --to-port <destination-port>

service iptables save
service iptables restart

เมื่อพยายามที่จะเชื่อมต่อไปdportในขณะที่ฉันได้รับnc -v localhost 2345 Connection refusedฉันไม่ค่อยดีใน ​​iptables แต่ฉันเดาว่า dport จะต้องมีแอพฟัง
Hi-Angel

เกิดอะไรขึ้นถ้า Origin-Port นั้นอยู่บนอินเตอร์เฟสที่ต่างจากพอร์ตปลายทาง?
Trismegistos

0

จากคำตอบของMark A.ฉันต้องปรับแต่งเล็กน้อยเพื่อให้ใช้งานได้กับ Mac ของฉัน (อย่างน้อยใน macOS Mojave เวอร์ชั่น 10.14.4)

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &
printf "" > a

คำสั่ง printf นั้นดูเหมือนจะสำคัญมาก มิฉะนั้นคำสั่ง netcat เพื่อเชื่อมต่อกับพอร์ต 8000 จะไม่พยายามเชื่อมต่อจริงและคำสั่ง netcat เพื่อฟังบนพอร์ต 8001 จะไม่เคยฟังบนพอร์ต 8001 จริง ๆ โดยไม่ใช้ printf ทุกครั้งที่ฉันพยายามเชื่อมต่อกับพอร์ต 8001 ฉันจะได้รับ การเชื่อมต่อถูกปฏิเสธ

สมมติฐานของฉันคือ netcat ต้องปิดกั้น stdin (อาจพยายามอ่านด้วยเหตุผลบางอย่าง) ก่อนที่จะทำการดำเนินการซ็อกเก็ตใด ๆ ดังนั้นหากไม่มีคำสั่ง printf เขียนถึง Fifo a คำสั่ง netcat จะไม่เริ่มฟังพอร์ต 8001

หมายเหตุ: ฉันจะทิ้งคำตอบไว้ที่โพสต์ของ Mark แต่ฉันยังไม่มีชื่อเสียง


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