Reverse SSH tunnel: ฉันจะส่งหมายเลขพอร์ตของฉันไปยังเซิร์ฟเวอร์ได้อย่างไร


12

ฉันมีสองเครื่องไคลเอนต์และเซิร์ฟเวอร์

ลูกค้า (ที่อยู่หลังไฟร์วอลล์ขององค์กร) เปิดอุโมงค์ SSH ย้อนกลับไปยังเซิร์ฟเวอร์ซึ่งมีที่อยู่ IP ที่สาธารณชนสามารถเข้าถึงได้โดยใช้คำสั่งนี้:

ssh -nNT -R0: localhost: 2222 insecure@server.example.com

ใน OpenSSH 5.3+ การ0เกิดขึ้นหลังจาก-Rหมายถึง "เลือกพอร์ตที่พร้อมใช้งาน" แทนที่จะเรียกใช้อย่างชัดเจน เหตุผลที่ฉันทำสิ่งนี้เพราะฉันไม่ต้องการเลือกพอร์ตที่ใช้งานแล้ว ในความเป็นจริงมีลูกค้าจำนวนมากออกมีที่ต้องตั้งอุโมงค์ที่คล้ายกัน

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

ฉันรู้ว่า ssh รายงานหมายเลขพอร์ตไปยังบรรทัดคำสั่งเมื่อใช้ในลักษณะข้างต้น อย่างไรก็ตามฉันยังต้องการใช้การตรวจสอบอัตโนมัติเพื่อให้เซสชันมีชีวิตชีวา autossh เรียกใช้กระบวนการลูกผ่าน fork / exec สันนิษฐานว่าเพื่อให้ผลลัพธ์ของคำสั่ง ssh จริงจะหายไปในอีเธอร์

นอกจากนี้ฉันไม่สามารถคิดวิธีอื่นเพื่อรับพอร์ตระยะไกลจากลูกค้า ดังนั้นฉันสงสัยว่ามีวิธีการตรวจสอบพอร์ตนี้บนเซิร์ฟเวอร์

หนึ่งความคิดที่ฉันมีคือการใช้ / etc / sshrc ซึ่งควรจะเป็นสคริปต์ที่ทำงานสำหรับทุกการเชื่อมต่อ อย่างไรก็ตามฉันไม่ทราบวิธีที่จะได้รับข้อมูลที่เกี่ยวข้องที่นี่ (อาจ PID ของกระบวนการ sshd โดยเฉพาะการจัดการการเชื่อมต่อนั้นได้อย่างไร) ฉันรักตัวชี้บางอย่าง

ขอบคุณ!


2
VPN จะไม่เหมาะสมกว่านี้ใช่ไหม OpenVPN นั้นง่ายในการกำหนดค่า
Ben Lessani - Sonassi

ฟังดูน่าสนใจ. ฉันไม่รู้เกี่ยวกับ VPN มากนัก นี่เป็นสิ่งที่สามารถใช้งานได้แม้ว่าเครื่องไคลเอนต์จะได้รับการกำหนดค่าให้ใช้ DHCP หรือไม่?
Tom

1
ใช่มันวิ่งออกไปจากอินเตอร์เฟส TUN / TAP อื่นดังนั้นอินเตอร์เฟสอื่นจึงไม่เกี่ยวข้อง
Ben Lessani - Sonassi

@sonassi ดูเหมือนว่าสิ่ง VPN นี้จะทำเคล็ดลับ ขอบคุณสำหรับข้อมูล.
Tom

ฉันได้เพิ่มคำตอบด้านล่างโดยเฉพาะเพื่อนำทางคุณผ่านกระบวนการ VPN ด้วย OpenVPN (จาก Debian / Ubuntu)
Ben Lessani - Sonassi

คำตอบ:


4

VPN จะไม่เหมาะสมกว่านี้ใช่ไหม OpenVPN นั้นง่ายในการกำหนดค่า นี่คือตัวอย่างการกำหนดค่าและลิงก์บางอย่างเพื่อแนะนำคุณตลอดกระบวนการสร้างใบรับรอง:

apt-get install openvpn
mkdir /etc/openvpn/easy-rsa
mkdir -p /etc/openvpn/ccd/client_server
touch /etc/openvpn/ipp.txt
cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
source ./vars
./clean-all
./build-ca 
./build-dh
./build-key-server server
cd /etc/openvpn/easy-rsa/keys
openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt -certfile ca.crt

จากนั้นสร้างไฟล์ใหม่/etc/openvpn/client_server.confและใส่ต่อไปนี้ในมันเปลี่ยนSERVER_IP_ADDRESSตามความเหมาะสม

local SERVER_IP_ADDRESS
port 8443
proto udp
dev tun
ca /etc/openvpn/easy-rsa/keys/ca.crt
pkcs12 /etc/openvpn/easy-rsa/keys/server.p12
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
ifconfig-pool-persist /etc/openvpn/ipp.txt
server 192.168.100.0 255.255.255.0
client-config-dir /etc/openvpn/ccd/client_server
ccd-exclusive
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
reneg-sec 0

จากนั้นสร้างคีย์ต่อผู้ใช้ที่กำลังจะเชื่อมต่อและสร้างไฟล์กำหนดค่าใน ccd dir

./build-key-pkcs12 user1@domain.com
echo "ifconfig-push 192.168.100.2 255.255.255.0" > /etc/openvpn/ccd/client_server/user1@domain.com

ที่อยู่ IP ต้องเหมาะสำหรับ / 30 subnet (ดูhttp://www.subnet-calculator.com/cidr.php ) เนื่องจากมีเพียง 2 ที่อยู่ (เซิร์ฟเวอร์และไคลเอนต์) ต่อการเชื่อมต่อ ดังนั้น IP ไคลเอ็นต์ที่พร้อมใช้งานถัดไปของคุณจะเป็น 192.168.100.6

ตอนนี้คุณมี IP คงที่ต่อผู้ใช้ที่เชื่อมต่อ

จากนั้นส่งthe user1@domain.com.p12ไฟล์ไปยังผู้ใช้ปลายทางและใช้ไฟล์กำหนดค่าต่อไปนี้

client
dev tun
proto udp
remote SERVER_IP_ADDRESS 8443
pkcs12 user1@domain.com.p12
resolv-retry infinite
nobind
ns-cert-type server
comp-lzo
verb 3
reneg-sec 0

ขอบคุณสำหรับคำตอบอย่างละเอียด! ฉันมีคำถามสองข้อเกี่ยวกับเรื่องนี้แม้ว่า A) การระบุ 255.255.255.0 สำหรับบรรทัด ifconfig-push ของไคลเอ็นต์ดูเหมือนจะไม่ทำงาน แต่จะทำงานถ้าฉันระบุที่อยู่ IP ที่สอง ทำไมนี้ และ B) วิธีนี้หมายความว่ามีการใช้ที่อยู่ IP 4 รายการต่อการเชื่อมต่อหรือไม่
Tom

บนระบบ Linux บางระบบไวยากรณ์สำหรับบรรทัด ifconfig-push จะแตกต่างกัน เช่น. ifconfig-push 192.168.100.2 192.168.100.3- ฉันไม่รู้ว่าทำไมมันถึงแตกต่างบนแพลตฟอร์ม และใช่มันหมายถึง 4 IP ที่ใช้ต่อลูกค้า (สิ้นเปลือง แต่เป็นธรรมชาติของสัตว์ร้าย)
Ben Lessani - Sonassi

3

หากลูกค้าแต่ละคนมีชื่อผู้ใช้ที่แตกต่างกันคุณสามารถใช้netstatเพื่อค้นหาว่าพอร์ตใดที่sshdกระบวนการของผู้ใช้กำลังรับฟังอยู่ ตัวอย่างเช่น:

% sudo netstat -tlpn | grep 'sshd: mgorven@'
tcp        0      0 127.0.0.1:22220         0.0.0.0:*               LISTEN      5293/sshd: mgorven@
tcp        0      0 127.0.0.1:5120          0.0.0.0:*               LISTEN      5293/sshd: mgorven@

3

คุณสามารถเปลี่ยนช่วงพอร์ตชั่วคราว ( /proc/sys/net/ipv4/ip_local_port_rangeสำหรับ Linux) จากนั้นใช้พอร์ตที่จัดสรรแบบคงที่นอกช่วงนั้น


ไม่จำเป็นต้องเปลี่ยนช่วงชั่วคราวสำหรับสิ่งนั้น โดยค่าเริ่มต้นช่วงชั่วคราวจะสิ้นสุดที่ 61000 ดังนั้นจึงมีหมายเลขพอร์ตมากมายที่มีอยู่ด้านบน ฉันมักจะใช้echo $[61002+RANDOM%4532]เพื่อเลือกหมายเลขพอร์ตในช่วงนั้น
kasperd

2

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

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

คำสั่งลูกค้า: ssh -N -R0:127.0.0.1:5522 connector@example.com

บันทึกเซิร์ฟเวอร์:

Jun 30 11:28:59 debsid sshd[27577]: debug1: Local forwarding listening on 127.0.0.1 port 35391

ที่นั่นคุณเห็นหมายเลขพอร์ต


0

คุณควรจะสามารถดึงข้อมูลที่เกี่ยวข้องจากผลลัพธ์ของ:

lsof -i tcp

เรียกใช้เป็นราก


0

รันสคริปต์นี้บนเซิร์ฟเวอร์:

sudo lsof -i -n | grep "sshd" | grep "(LISTEN)" | awk '{print $2}' | while read line; do sudo lsof -i -n | egrep $line | sed 3~3d | sed 's/.*->//' | sed 's/:......*(ESTABLISHED)//' | sed 's/.*://' | sed 's/(.*//' | sed 'N;s/\n/:/' 2>&1 ;done

คุณอาจหรือไม่ต้องการสอง sudo ลบหากคุณไม่

ป.ล. - นี่เป็นเวอร์ชั่นที่ได้รับการแก้ไขแล้วของโซลูชันที่ฉันพบที่อื่นในขณะที่ย้อนกลับไป ฉันคิดว่ามันอาจมาจาก StackOverflow แต่ฉันไม่พบการอ้างอิงดั้งเดิม

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