ให้ Xorg ฟังบน TCP แต่เฉพาะ localhost เท่านั้น


12

ฉันมีโปรแกรมไคลเอนต์ X ซึ่งจำเป็นต้องเข้าถึงเซิร์ฟเวอร์ X มันสามารถเข้าถึงเซิร์ฟเวอร์ X ด้วย TCP เท่านั้นไม่ใช่วิธีอื่น ๆ เช่นซ็อกเก็ตโดเมน unix มันจะทำงานบนโฮสต์เดียวกันกับเซิร์ฟเวอร์เพื่อให้ง่าย

ดังนั้นฉันจะทำให้เซิร์ฟเวอร์ Xorg ของฉันฟังบนพอร์ต TCP 6000 ได้ แต่สำหรับการเชื่อมต่อจาก localhost เท่านั้น

ฉันพบวิธีทำให้ X.org ฟังการเชื่อมต่อระยะไกลบนพอร์ต 6000 ได้อย่างไร ซึ่งอธิบายวิธีการเปิดใช้งานการเข้าถึงสำหรับโฮสต์ระยะไกล แต่ฉันไม่ต้องการการเข้าถึงระยะไกลจริงๆ (สำหรับเหตุผลด้านความปลอดภัยส่วนใหญ่)

ฉันคิดถึงการส่งต่อการขนส่งเริ่มต้นไปยัง TCP แต่ฉันไม่พบข้อมูลเกี่ยวกับการขนส่งเริ่มต้นอย่างแท้จริง

(ฉันใช้ kdm เป็นผู้จัดการการแสดงผลของฉันที่นี่ แต่ฉันคิดว่าฉันสามารถถ่ายโอนโซลูชั่นสำหรับตัวจัดการการแสดงผลหรือแม้กระทั่งสลับตัวจัดการการแสดงผลได้)

ความคิดใด ๆ

นี่คือ 11.04 ในการติดตั้ง Kubuntu-Ubuntu-XUbuntu แบบผสม (เดิมคือ Kubuntu แต่ฉันเพิ่ม ubuntu-desktop และ xubuntu-desktop ในการบูตตอนนี้พูดว่า Xubuntu 11.04) ตอนนี้ฉันกำลังใช้เดสก์ท็อป gnome-classic ฉันคิดว่าจาก KDM


สำหรับทุกคนที่สงสัยว่าไคลเอนต์ X นี้คืออะไรในความเป็นจริงแล้วการใช้งาน Java SSH ( JSch ) ซึ่งพยายามทำการส่งต่อ X ไปยังโฮสต์อื่น Java ไม่สามารถเข้าถึงซ็อกเก็ตโดเมน unix ได้ฉันคิดว่า ปัญหาเดียวกันนี้จะนำไปใช้กับโครงการของฉันอีก (หยุดชั่วคราว) ของฉันที่ฉันต้องการใช้ไคลเอนต์ X ใน Java บริสุทธิ์ (เช่นโดยการอ่าน / เขียนซ็อกเก็ตไม่ใช้ห้องสมุดหน้าต่างบางส่วน)
Paŭlo Ebermann

@Paulo, java สามารถใช้ซ็อกเก็ตโดเมน unix ได้ (คุณสามารถเขียนไลบรารี่เนทีฟซึ่งจะให้สิทธิ์การเข้าถึง syscalls ที่ต้องการหรือเพียงแค่ค้นหาว่าเขียนไว้แล้ว) แต่แล้ว fwiw คุณสูญเสียผลประโยชน์หลักของ java: การพกพาสูง ดังนั้นหากคุณต้องการยากจริงๆคุณสามารถเขียนไลบรารี่ X client ใน java อย่างง่ายซึ่งจะทำงานกับ PF_LOCAL ได้ โปรดสังเกตว่าอินเตอร์เฟส TCP over loopback นั้นมีโอเวอร์เฮดที่สูงกว่าซ็อกเก็ตยูนิกซ์มาตรฐานมาก
ulidtko

ใช่ฉันพบห้องสมุดบางแห่ง แต่สิ่งนี้จะไม่ช่วยฉันตราบใดที่ฉันไม่รู้ที่อยู่ UDS จริง เอกสารนี้อยู่ที่ไหนสักแห่ง?
Paŭlo Ebermann

1
@Paulo ซ็อกเก็ตโดเมน unix มักใช้ namespace ของระบบไฟล์ ที่อยู่ของพวกเขามีชื่อไฟล์ โหนดไฟล์ที่เกี่ยวข้องคือ "ไฟล์ซ็อกเก็ตพิเศษ" ในระบบของฉันฉันมีการเชื่อมต่อมากมาย/tmp/.X11-unix/X0- นี่คือตัวอย่างของที่อยู่ AF_UNIX (ใช้netstat -xเพื่อดูของคุณเอง) ข้อกำหนดคุณสมบัติของโปรโตคอล X11 ควรกำหนดที่อยู่ที่แน่นอนในการเชื่อมต่อ และคุณต้องอ่านถ้าคุณกำลังเขียนไลบรารี่ของไคลเอ็นต์สำหรับโปรโตคอลนั้น
ulidtko

1
/tmp/.X11-unix/X0มีอยู่เป็นซ็อกเก็ตที่นี่ (OpenSUSE) เช่นกันฉันจะตรวจสอบอีกครั้งที่บ้าน (ในระบบ Ubuntu ที่ตั้งชื่อตามคำถาม) ตอนนี้ฉันต้องดูว่าจะส่งต่อสิ่งนี้ไปยังซ็อกเก็ต TCP ที่ 6000 ได้อย่างไร
Paŭlo Ebermann

คำตอบ:


8

socatดูเหมือนว่าการแก้ปัญหาจะใช้ นี่คือบรรทัดคำสั่งที่ใช้งานได้หากเซิร์ฟเวอร์ X ไม่ได้ทำงานบน TCP:

socat -d -d TCP-LISTEN:6000,fork,bind=localhost UNIX-CONNECT:/tmp/.X11-unix/X0

จากนั้นฉันก็ทำได้

xlogo -display localhost:0

น่าแปลกที่มันดูเหมือนจะไม่ทำงานถ้าผมปล่อยให้มันฟังบน 6001 แล้วระบุการแสดงผลlocalhost:1แทนlocalhost:0- No protocol specifiedฉันได้รับ ดูเหมือนว่าฉันจะต้องอ่านโปรโตคอล X อีกครั้ง (และเหนือ JSch ก็จะหยุดทำงานInvalid MIT-MAGIC-COOKIE-1 keyแต่นี่เป็นปัญหาอื่น)


ใช่!! ฉันกำลังมองหาวิธีที่จะทำให้xserver-allow-tcp=true หลังจาก X ได้เริ่มต้นด้วย -nolisten tcp ใน/etc/X11/xinit/xserverrcโดยไม่ต้องเริ่มต้นใหม่ เฉพาะในกรณีของฉันbind=0.0.0.0เพื่ออนุญาตให้โฮสต์ภายนอกของฉัน
มาร์กอส

5

รหัส Xorg ในขณะนี้ไม่มีตัวเลือกสำหรับการควบคุมอินเทอร์เฟซที่จะฟัง มันไม่ควรเพิ่มยาก แต่ควรจะง่ายกว่าเพียงกำหนดค่าไฟร์วอลล์ของคุณเพื่อบล็อกการเชื่อมต่อขาเข้าพอร์ต 6000 จากเครื่องอื่น ๆ


2

แค่ความคิดอื่น ๆ ...

  1. อนุญาตยกเว้นบล็อกด้วย xhost (และ / หรือการกรองเครือข่าย)

วิธีดั้งเดิมในการทำเช่นนี้คือเพื่อให้เซิร์ฟเวอร์ X ฟังบนซ็อกเก็ต TCP และใช้ xhost เพื่อกำหนดว่าโฮสต์ใดที่ได้รับอนุญาตให้เชื่อมต่อ ดู man page สำหรับ xhost (1) (แน่นอนว่าที่อยู่ IP และการกรองพอร์ตจะช่วยได้เช่นกันตามที่ได้กล่าวไว้ก่อนหน้านี้)

  1. ฟังบนอินเตอร์เฟสในเครื่องเท่านั้น

ตามความคิดเห็นของ alanc ข้างต้นตอนนี้ไม่มีรหัส แต่เกือบ!

จำไว้ว่า (เกือบ) โฮสต์ทั้งหมดมีอย่างน้อยสองอินเตอร์เฟส, อินเตอร์เฟส loopback lo0 (เสมอ 127.0.0.1) และอีเธอร์เน็ตทั่วไป eth0 (หรือ wlan0 หรืออะไรก็ตามซึ่งก็คือ 192.168.0.128) และอีกมากมายมีอีกมากมาย โดยปกติแล้วเซิร์ฟเวอร์ TCP / IP (เช่นเซิร์ฟเวอร์ X) จะอนุญาตให้มีการเชื่อมต่อขาเข้าไปยังที่อยู่ IP ใด ๆ ของพวกเขาบนอินเทอร์เฟซใดก็ได้ แต่ซอฟต์แวร์ส่วนใหญ่จะให้คุณระบุที่อยู่ IP หากคุณต้องการ งานจริงทำโดยการผูก (2) ซึ่งรับ INADDR_ANY (0.0.0.0) หรือที่อยู่ IP จริง

เซิร์ฟเวอร์ Xorg ใช้ -name local-address แต่น่าเสียดายสำหรับ XDMCP เท่านั้น (ดูที่ไฟล์ os / xdmcp.c ซึ่งใช้อย่างถูกต้องเท่าที่ฉันรู้) การเชื่อมต่อจริงสำหรับโปรโตคอล X เชื่อว่าทำได้โดย SocketINETCreateListener ในไฟล์ /usr/include/X11/Xtrans/Xtranssock.c ซึ่งตั้งค่าที่อยู่เป็น INADDR_ANY แล้วผูกเข้ากับมันโดยไม่มีการประมวลผลเพิ่มเติม สิ่งที่จะต้องมีคือแฟล็ก -from (ซึ่งจัดการโดย os / xdmcp.c เป็น FromAddress) เพื่อเชื่อมต่อกับตัวแปร 'sockname' ก่อน SocketCreateListener () ใน Xtranssock.c แน่นอนว่าปัญหาคือสิ่งที่ขนส่งทั้งหมดนั้นทำในลักษณะที่เป็นกลางในการขนส่งดังนั้นจึงเป็นเรื่องยากที่จะรับข้อมูลเข้าสู่ Xtranssock.c

เส้นทางของไฟล์และอื่น ๆ อาจแตกต่างกันไปดูที่ Ubuntu 10.04 LTS และสังเกตว่าชื่อฟังก์ชั่นใน Xtranssock.c เปลี่ยนโดยแมโคร TRANS http://cgit.freedesktop.org/xorg/xserver/tree/os/xdmcp.c

หวังว่าจะมีประโยชน์

ขอแสดงความนับถือ

โจนาธาน


สำหรับตอนนี้ฉันใช้การตรวจสอบคุกกี้มายากลดังนั้นแม้การเชื่อมต่อจากโฮสต์เดียวกันจะไม่ได้รับอนุญาต xhostจะขยายการเข้าถึงไม่ลดขนาดลง
Paŭlo Ebermann

และฉันไม่คิดว่าฉันจะแฮ็คเข้าสู่เซิร์ฟเวอร์ X ของฉัน แต่ขอบคุณสำหรับคำแนะนำในการทำเช่นนั้น
Paŭlo Ebermann

9 ปีต่อมาและสิ่งนี้ไม่เปลี่ยนแปลง gitlab.freedesktop.org/xorg/lib/libxtrans/blob/master/…
daveloyall
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.