2010-01-27 3 views
34

Предположим, что устаревшее приложение Linux прослушивает сокет домена UNIX /tmp/foo.Перенаправление TCP-трафика в сокет под UNIX под Linux

В дополнение к общению с этим унаследованным приложением через сокет домена механизма UNIX Я хочу, чтобы иметь возможность подключиться к нему через TCP-соединения на порт 1234. сказать

Что это самый простой способ для привязки к TCP порт 1234, а затем перенаправить все входящие соединения на доменное имя UNIX /tmp/foo?

ответ

49

Оказывается socat может можно использовать для достижения этой цели:

socat TCP-LISTEN:1234,reuseaddr,fork UNIX-CLIENT:/tmp/foo 

И с немного дополнительной безопасности:

socat TCP-LISTEN:1234,bind=127.0.0.1,reuseaddr,fork,su=nobody,range=127.0.0.0/8 UNIX-CLIENT:/tmp/foo 

Эти примеры были протестированы и работают должным образом.

+0

socat, netcat, в любом случае. Вы могли бы даже обернуть «stunnel» вокруг него для большего количества уровней сложности! –

+0

Если кто-то хочет использовать это для совместного использования док-сокета, он должен удалить часть '' 'su = nobody''' – Dmitriusan

+0

Чтобы разделить сокет докера, просто скажите демону Docker прослушивать локальный порт, передав' -H tcp: //127.0.0.1: 4321' (обратите внимание, что он позволяет получить доступ к демону докеров для всех, кто может открыть соединение с «127.0.0.1». Нет проверок uid/gid или что-то еще, но это также верно для 'netcat'/'socat') – svvac

3

Вы должны иметь возможность связываться с TCP 1234, получить сокет fd для/tmp/foo и использовать вызов select для прослушивания данных как на 1234, так и на/tmp/foo. Любые данные, записанные на 1234, вы переписываете в/tmp/foo и наоборот.

Теперь вы действуете как прокси-сервер и передаете данные взад и вперед.

А вот веб-страница, которая может помочь: http://osr507doc.sco.com/en/netguide/dusockC.io_multiplexing.html

0

Не пробовал: но это выглядит как «Lighttpd» может сделать это для вас:

http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore

+3

К сожалению Lighttpd массивен избыточна для того, что хочет плакат. –

+0

Это действительно работает для произвольного TCP и не только для HTTP? – Anton

17

Простенький? Возможно Netcat (так называемый nc):

nc -l 1234 | nc -U /tmp/foo 

Первая команда прослушивает порт 1234 для входящих соединений, а также трубопроводы результирующие данные на второй команды. Второй подключается к гнезду домена Unix /tmp/foo и записывает его вход в этот сокет. Обратите внимание, что это будет принимать только одно соединение и выйти, как только это соединение будет удалено. Если вы хотите продолжить прослушивание для более соединений, используйте -k вариант:

nc -lk 1234 | nc -U /tmp/foo 

Вы можете проверить, что это работает, настраивая слушателя для этого сокета в одном терминале:

nc -lUk /tmp/foo 

И пишущего к нему в другом:

nc localhost 1234 

socat как recommended by knorv, более способен, но более сложным в использовании.

+0

похоже на nc под ubuntu (quantal) не поддерживает UNIX-сокеты :( – gucki

+0

@gucki Действительно? У вас нет опции «nc -U»? У меня нет тестовой машины Quantal, но на Precise 'nc' имеет опцию' -U', и то, что я сказал в своем комментарии, отлично работает. Вы пытались именно то, что я написал? Если вы не находите, что 'nc' работает для вас, я бы порекомендовал попробовать' socat' , он может делать намного больше, чем 'nc', с гораздо более тонким контролем над тем, как он работает, но немного сложнее выяснить, как использовать. –

+1

Да, я просто проверил снова (netcat 1.10-40): 'nc -l 1234 | nc -U/tmp/foo' дает' nc: недопустимый вариант - 'U'' и 'nc -h для справки'.' socat' отлично работает :) – gucki

0

В ДОБАВЛЕНИЯ К @ knorv-х answer: с xinetd он может работать как демон

# cat /etc/xined.d/mysrv 
service mysrv 
{ 
disable = no 
type = UNLISTED 
socket_type = stream 
protocol = tcp 
wait = no 
server = /usr/bin/socat 
server_args = STDIN UNIX-CLIENT:/tmp/mysocket.sock 
bind = 127.0.0.1 
port = 1234 
}