Давайте посмотрим, что еще можно сделать с нашей конфигурацией Shorewall. Первое, что приходит на ум, - прозрачный прокси-сервер: прием, о порочности которого было сказано достаточно много, но тем не менее широко распространенный. Неудивительно, что соответствующие настройки можно найти прямо в примерах на man-странице
shorewall-rules(5):
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL
# PORT PORT(S) DEST
REDIRECT loc 3128 tcp www - !192.168.0.2
Действие REDIRECT передает пакет локальному (для шлюза) процессу, прослушивающему порт, указанный в колонке DEST (у нас это 3128 - стандартная настройка Squid и большинства других HTTP-прокси). Правило удовлетворяет TCP-соединениям, имеющим в качестве порта назначения 80 (в примере использован псевдоним www, заданный в /etc/services), кроме адресованных 192.168.0.2 (вероятно, внутреннему веб-серверу).
Рассмотренное выше перенаправление является частным случаем DNAT-преобразования (в том смысле, что REDIRECT можно рассматривать как DNAT на локальный IP-адрес), которое можно применять с самыми разными целями. Например, классический проброс портов (port forwarding) интернет-соединений на все тот же внутренний веб-сервер может быть организован следующим образом:
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATE
# PORT PORT(S) DEST LIMIT
DNAT net loc:192.168.0.2 tcp http - - 3/sec:10
Зона и адрес, на который должны быть переправлены запросы, указывается в поле DEST. Если у шлюза несколько IP-адресов, а проброс портов нужно производить только для одного, укажите его в колонке ORIGINAL DEST.
Наконец, RATE LIMIT задает максимально допустимую нагрузку: в среднем 3 запроса в секунду, но не более 10 пиково.
Действие DNAT удобно тем, что создает сразу два правила iptables: одно непосредственно для преобразования адресов, а другое - для приема трафика, удовлетворяющего заданным критериям. В большинстве ситуаций это именно то, что требуется. Если же вы по каким-либо причинам хотите добавить только DNAT и ничего больше, используйте действие DNAT.
DNAT-преобразование можно применить для создания "виртуальных сервисов": сетевых служб, которые, с точки зрения клиентов локальной сети, выполняются на шлюзе, а на самом деле находятся где-то в другом месте. Возьмем, к примеру, электронную почту: если сеть сравнительно невелика, то вполне вероятно, что в ней не будет собственного SMTP-сервера: всю корреспонденцию будут просто отправлять через сервер провайдера. Если эти самые провайдеры (а вместе с ними и SMTP-серверы) меняются достаточно часто (да, такое тоже бывает: в первые две недели месяца связь обеспечивает компания A, по исчерпанию лимита - компания Б), перенастройка почтовых клиентов на компьютерах пользователей превращается в головную боль.
Следующее правило избавит вас от нее:
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL
# PORT PORT(S) DEST
DNAT- loc net:1.2.3.4 tcp 25 - 192.168.0.1
Мы осуществляем прозрачную передачу всех TCP-соединений на 192.168.0.1:25 серверу с адресом 1.2.3.4 (использовать здесь доменные имена можно, хотя и настоятельно не рекомендуется). Теперь можно сообщить вашим пользователям, что для исходящей почты нужно указать сервер 192.168.0.1 (особые эстеты могут завести для него доменное имя - при наличии в сети DNS-сервера это займет пару секунд) - и дело в шляпе.
Конечно, такой прием имеет ряд ограничений. Во-первых, он будет плохо работать в том случае, когда для защиты соединения используются SSL-шифрование (получив сертификат для неожиданного доменного имени, приличный почтовый клиент должен, как минимум, выдать серьезное предупреждение), во-вторых, редактировать адрес интернет-сервера каждый раз при смене провайдера - дело муторное, неблагодарное и чреватое сбоями ("человеческий фактор" рано или поздно даст о себе знать).
Здесь может пригодиться еще одна особенность Shorewall - умение получать параметры извне и работать с переменными. Центральная роль здесь отводится файлу /etc/shorewall/params: это сценарий на языке оболочки, который копируется в результирующий скрипт, генерируемый Shorewall в процессе компиляции. Он, например, может иметь такой вид:
ROUTER_IP=192.168.0.1
SMTP=$(get_current_smtp)
Здесь подразумевается, что в вашей системе реализована команда get_current_smtp, возвращающая IP-адрес SMTP-сервера текущего провайдера. Тогда правило для "виртуального сервера" можно переписать следующим образом:
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL
# PORT PORT(S) DEST
DNAT- loc net:$SMTP tcp 25 - $ROUTER_IP
Имена переменных рекомендуется начинать с большой буквы - так вы гарантированно избежите конфликта имен с внутренними переменными Shorewall. Теперь при смене провайдера достаточно просто выполнить команду shorewall restart.