จะ จำกัด พอร์ตการรับส่งข้อมูล SSH แบบย้อนกลับได้อย่างไร?


9

เรามีเซิร์ฟเวอร์สาธารณะที่ยอมรับการเชื่อมต่อ SSH จากไคลเอนต์หลายหลังไฟร์วอลล์

ไคลเอนต์เหล่านี้แต่ละคนสร้างอุโมงค์ SSH แบบย้อนกลับโดยใช้ssh -Rคำสั่งจากเว็บเซิร์ฟเวอร์ที่พอร์ต 80 ไปยังเซิร์ฟเวอร์สาธารณะของเรา

พอร์ตปลายทาง (ที่ฝั่งไคลเอ็นต์) ของ Reverse SSH Tunnel คือ 80 และพอร์ตต้นทาง (ที่ด้านเซิร์ฟเวอร์สาธารณะ) ขึ้นอยู่กับผู้ใช้ เราวางแผนที่จะบำรุงรักษาแผนที่ที่อยู่ของพอร์ตสำหรับผู้ใช้แต่ละคน

ตัวอย่างเช่นไคลเอ็นต์ A จะทำการส่งผ่านเว็บเซิร์ฟเวอร์ที่พอร์ต 80 ไปยังพอร์ต 8000 ของเรา ลูกค้า B จาก 80 ถึง 8001; ไคลเอนต์ C จาก 80 ถึง 8002

Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver

Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver

Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver

โดยทั่วไปสิ่งที่เราพยายามทำคือผูกผู้ใช้แต่ละคนด้วยพอร์ตและไม่อนุญาตให้ผู้ใช้ทันเนลไปยังพอร์ตอื่น ๆ

หากเรากำลังใช้คุณลักษณะการส่งสัญญาณไปข้างหน้าของ SSH ด้วยssh -Lเราสามารถอนุญาตให้พอร์ตใดที่จะถูกช่องสัญญาณโดยใช้การpermitopen=host:portกำหนดค่า อย่างไรก็ตามไม่มีอะไรเทียบเท่ากับอุโมงค์ SSH ย้อนกลับ

มีวิธี จำกัด พอร์ตการย้อนกลับช่องสัญญาณต่อผู้ใช้หนึ่งคนหรือไม่?


1
โดยนโยบายทั้งระบบเช่น SELinux หรือ IPTABLES
Andrew Smith

คำตอบ:


6

เนื่องจากคุณไม่อนุญาตให้ใช้ตัวหนาฉันคิดว่าคุณต้องการการปฏิเสธแบบรันไทม์ที่ฝั่งไคลเอ็นต์ SSH ที่ป้องกันพอร์ตผูก ดังนั้นฉันมีรหัสแหล่งขุดสำหรับคุณ:

serverloop.c:

/* check permissions */
if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)
#endif
    ) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");
} else {
        /* Start listening on the port */
        success = channel_setup_remote_fwd_listener(
            listen_address, listen_port,
            &allocated_listen_port, options.gateway_ports);
}

น่าเสียดายที่มีหลายเงื่อนไขที่จะป้องกันการส่งต่อพอร์ตนอกเหนือจากมาตรฐาน

ฉันกำลังจะแนะนำข้อเสนอแนะเดียวกันสำหรับการใช้mod_ownerภายในiptablesแต่เจฟฟ์ได้เอาชนะฉันไปแล้ว

โซลูชันที่สะอาดที่สุดของคุณเพียงแค่ปรับเปลี่ยนไฟล์นี้ (ตัวอย่างเช่นคุณสามารถใช้pw->pw_uidเพื่อรับ uid ของการเชื่อมต่อผู้ใช้และแมปพอร์ตนั้นไปยังพอร์ตที่ถูกต้อง) และคอมไพล์เซิร์ฟเวอร์ SSH ของคุณอีกครั้ง .


นี่เป็นสิ่งที่ดีจริงๆ ฉันสามารถคัดลอกไวยากรณ์ที่เหมือนกันจากตัวเลือก -L (การขุดอุโมงค์) และทำให้มันทำงานได้ ขอบคุณ.
Utku Zihnioglu

3

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

iptablesหรือคุณอาจลองใช้

iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT

ที่จะป้องกันไม่ให้พวกเขาเปิดพอร์ตและปฏิเสธผู้ใช้รายอื่นอย่างไรก็ตาม


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