TL; DR: не используйте Netcat, используйте Socat для экспериментов. Это обрабатывает что-нибудь лучше.
Причина, по которой он не работает, не в именованных каналах (даже если это уродливый метод с другими скрывающимися проблемами), а в ограничении netcat.
Как только Netcat получает соединение UDP, он связывается с ним. Таким образом, он больше не слушает порт 53, он подключен к порту, который отправил исходный пакет, точно так же, как это было бы с TCP. Каждый раз, когда вы делаете запрос DNS, инструмент меняет порт, а Netcat никогда не получит запрос. Так что будет работать только первый запрос.
Когда вы настраиваете свой пример, попробуйте эту команду перед первым запросом:
netstat -aunp|grep -w 53
udp 0 0 0.0.0.0:53 0.0.0.0:* 12316/nc.openbsd
Сделайте (только рабочий) запрос и попробуйте еще раз netstat:
# netstat -aunp|grep -w 53
udp 0 0 127.0.0.1:53 127.0.0.1:44335 ESTABLISHED 12316/nc.openbsd
Как вы можете видеть, netcat только что изменил режим: от прослушивания до зацикливания соединения. Поскольку это UDP, Netcat не будет автоматически знать, что «установленное соединение» больше не существует.
У меня есть подтверждение концепции (которая заставляет его работать и показывает, что проблема связана с этим режимом UDP), но он требует socat в дополнение к netcat на клиенте. Цель состоит в том, чтобы все запросы достигли netcat, используя один и тот же исходный порт UDP. На стороне сервера ничего не меняется, но я вставляю socat в начале цепочки (то есть в последнюю команду), чтобы заставить исходный порт UDP-запроса к Netcat.
Во-первых, на стороне клиента, сделайте это:
ssh -N -L 6667:localhost:6667 user@server
Затем на стороне сервера сделайте это:
mkfifo /tmp/fifo
nc -k -l 6667 < /tmp/fifo | nc -u ip_of_dns_server 53 > /tmp/fifo
Наконец, вернемся на сторону клиента и сделаем это:
mkfifo /tmp/fifo
nc -k -l -u 5555 < /tmp/fifo | nc 127.0.0.1 6667 > /tmp/fifo
socat udp4-listen:53,reuseaddr,fork udp:127.0.0.1:5555,sourceport=55550,reuseaddr
Теперь я могу сделать несколько запросов.
Перед 1-м запросом:
# netstat -aunp|egrep -w '53|5555'
udp 0 0 0.0.0.0:5555 0.0.0.0:* 12715/nc.openbsd
udp 0 0 0.0.0.0:53 0.0.0.0:* 12717/socat
После 1-го:
udp 0 0 127.0.0.1:55550 127.0.0.1:5555 ESTABLISHED 12736/socat
udp 0 0 127.0.0.1:5555 127.0.0.1:55550 ESTABLISHED 12715/nc.openbsd
udp 0 0 0.0.0.0:53 0.0.0.0:* 12717/socat
После 2-го запроса:
udp 0 0 127.0.0.1:55550 127.0.0.1:5555 ESTABLISHED 12750/socat
udp 0 0 127.0.0.1:5555 127.0.0.1:55550 ESTABLISHED 12715/nc.openbsd
udp 0 0 0.0.0.0:53 0.0.0.0:* 12717/socat
udp 0 0 127.0.0.1:53 127.0.0.1:53255 ESTABLISHED 12750/socat
Сокат столкнулся бы с той же проблемой, но с опцией fork
он снова прослушивает и, кажется, обнаруживает предыдущее потерянное «соединение»; Я думаю, что это вызывает задержку.
Вы можете получить старое поведение (работает один раз), просто удалив часть ,sourceport=55550,reuseaddr
в команде socat.