В минувшие выходные познакомился с relayd(8). Это Layer 7 балансировщик и прокси, этакий F5 для бедных. Запустил я его на своем домашнем маршрутизаторе под управлением OpenBSD. Балансировать мне дома конечно нечего, а вот спроксировать есть чего.
У меня есть IP-телефон. Конфигурируется он, как и положено современному домашнему устройству, с помощью браузера. По умолчанию, из соображений безопасности, он дает себя конфигурировать только из той сети, в которой он сам находится. Проблема в том, что у моего маршрутизатора три внутренних интерфейса, в один из которых кросс-кабелем воткнут IP-телефон, в другой — десктоп, а третий интерфейс — PCI WiFi карта — раздает Интернет в эфир. Столь странная конфигурация связана с тем, что у меня на полочке, где стоит маршрутизатор, абсолютно нет места еще и для коммутатора. Но даже с коммутатором остается отдельная беспроводная сеть, в которой, в частности, находится мой лаптоп.
Раньше я все три интерфейса помещал в бридж, но потом решил, что это нехорошо, и сделал отдельные сети с маршрутизацией. Таким образом IP-телефон можно конфигурировать только lynx’ом с маршрутизатора, все остальные машины в квартире к нему доступа не имеют.
Вообще, описанное поведение телефона легко изменить, убрав соответствующую галочку в настройках, но я решил не ковырять дополнительную дырку в его безопасности. Кроме того мне не хотелось менять заводской пароль, который так легко запоминается: 0000. И я решил проксировать на маршрутизаторе запросы на 80 порт телефона из других сетей.
Первая мысль была вставить в inetd.conf что-то вроде
*:8080 stream tcp nowait nobody /usr/bin/nc nc -w 30 192.168.201.32 80
Это сработало, но было ужасно некрасиво, кроме того вынуждало добавлять в URL в браузере номер порта. И тут я вспомнил, что в OpenBSD был какой-то демон relayd, название которого указывало на то, что он может мне помочь. Чтение документации подтвердило мои ожидания. В результате была сделана следующая конфигурация.
В relayd.conf:
relay "phone" { listen on 127.0.0.1 port 8080 forward to 192.168.201.32 port http }
В pf.conf:
pass in quick on !$ext_if proto tcp to 192.168.201.32 port http \ rdr-to 127.0.0.1 port 8080
Получилась красивая прозрачная схема, похожая на ftp-proxy. Теперь можно на любой машине набирать адрес телефона в браузере, и pf будет заворачивать соединение на relayd, который, в свою очередь, будет проксировать его на телефон.