Пусть Xorg прослушивает TCP, но только на localhost?

12

У меня есть некоторая программа X-клиента, которой нужен доступ к X-серверу. Доступ к X-серверу возможен только по протоколу TCP, но не с помощью других методов, таких как доменные сокеты Unix. Он будет работать на том же хосте, что и сервер, чтобы упростить процесс.

Итак, как я могу заставить свой сервер Xorg прослушивать TCP-порт 6000, но только для соединений с локального хоста?

Я нашел Как заставить X.org прослушивать удаленные соединения через порт 6000? , который объясняет, как включить доступ для удаленных хостов, но я не хочу удаленного доступа (в основном по соображениям безопасности).

Я думал о пересылке транспорта по умолчанию в TCP, но я не нашел информации о том, что такое транспорт по умолчанию.

(Я использую kdm в качестве диспетчера дисплеев, но думаю, что могу перенести решения для диспетчера дисплеев или даже переключить диспетчер дисплеев.)

Есть идеи?

Это 11.04 на смешанной установке Kubuntu-Ubuntu-XUbuntu (изначально Kubuntu, но я добавил ubuntu-desktop и xubuntu-desktop. При загрузке теперь говорится Xubuntu 11.04). Я сейчас использую классическую версию gnome, я думаю, из KDM.

Пауло Эберманн
источник
Для всех, кто интересуется, что это за X-клиент: На самом деле это Java-реализация SSH ( JSch ), которая пытается переадресовать X на другой хост. Я думаю, что Java не может получить доступ к доменным сокетам Unix. Та же самая проблема также применима к другому моему (теперь приостановленному) проекту, где я хотел реализовать X-клиент на чистой Java (например, читая / записывая сокет, не используя некоторую библиотеку окон).
Пауло Эберманн
@Paulo, java на самом деле может использовать доменные сокеты Unix (вы можете написать собственную библиотеку, которая предоставит доступ к необходимым системным вызовам, или просто найти уже написанную). Но тогда, между прочим, вы фактически теряете главное преимущество Java: высокую мобильность. Поэтому, если вам действительно нужно очень сложно, вы можете довольно легко написать клиентскую библиотеку X на Java, которая будет работать над PF_LOCAL. Также обратите внимание, что интерфейс TCP over loopback имеет намного больше служебных данных, чем стандартный сокет Unix.
ulidtko
Да, я нашел несколько библиотек, но это мне не поможет, пока я не знаю фактический UDS-адрес. Это где-то задокументировано?
Пауло Эберманн
1
@Paulo, доменные сокеты unix обычно используют пространство имен файловой системы. Их адреса являются именами файлов . Соответствующие файловые узлы являются «специальными файлами сокетов». В моей системе у меня есть многочисленные соединения с /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 с других компьютеров.

alanc
источник
2

Просто некоторые другие мысли ...

  1. Разрешить, но заблокировать с помощью xhost (и / или сетевой фильтрации)

Традиционный способ сделать это - X-сервер прослушивает сокет TCP и использует xhost, чтобы определить, каким хостам разрешено подключаться. Смотрите справочную страницу для xhost (1). (Кроме того, конечно, здесь также может помочь фильтрация IP-адресов и портов, как отмечалось в предыдущих предложениях.)

  1. Слушайте только на локальном интерфейсе

Согласно приведенному выше комментарию Аланка, там сейчас нет кода, но почти!

Помните, что (почти) все хосты имеют как минимум два интерфейса, петлевой интерфейс lo0 (всегда 127.0.0.1) и обычный ethernet eth0 (или wlan0 или любой другой, который, скажем, 192.168.0.128), и многие имеют больше. Обычно серверы TCP / IP (т. Е. X-сервер) разрешают входящие подключения к любому из их IP-адресов на любом из их интерфейсов, но большая часть программного обеспечения позволяет вам указать IP-адрес, если хотите. Фактическая работа выполняется с помощью bind (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

Надеюсь, что это полезно.

С уважением

Джонатан.

Джонатан
источник
На данный момент я использую магическую аутентификацию cookie, поэтому даже подключения с одного хоста не будут разрешены. xhostрасширит доступ, а не сократит его.
Paŭlo Ebermann
И я не думаю, что взломаю свой X-сервер, но спасибо за предложение, где это сделать.
Пауло Эберманн
9 лет спустя и это не изменилось. gitlab.freedesktop.org/xorg/lib/libxtrans/blob/master/...
daveloyall