Проброс портов в OpenWrt
Мне никогда не нравилось, что в интерфейсе OpenWrt нельзя указать несколько портов при пробросе, можно указать только диапазон. А если мне нужно несколько, объединенных одним сервисом? Например, почта. Если указывать все порты, то получается, что на каждый из них нужно создавать свое правило. В итоге получается такая простыня правил, что ориентироваться в ней становится затруднительно.
По сути, эта заметка — напоминание себе как нужно правильно прокинуть порты во внутреннюю сеть, используя iptables. И, заодно, там же сделаем так, чтобы из локальной сети можно было обращаться к своим серверам по доменному имени.
Идем в раздел Network — Firewall и открываем вкладку Custom rules. Добавляем туда строку такого вида:
iptables -t nat -A zone_wan_prerouting -p tcp -m multiport --dports 25,110,143,465,587,993,995,4190 -j DNAT --to-destination 192.168.1.100
Здесь мы помещает в цепочку zone_wan_prerouting таблицы nat правило, указывающее, что сервисы, обращающиеся из внешней сети на перечисленные порты, должны перенаправляться на сервер с адресом 192.168.1.100. Параметр -р указывает протокол tcp, а параметр -m multiports позволяет указать не один порт, а несколько. Это правило позволит открыть порты для доступна извне, но при обращении к ним из локальной сети придется указывать «прямой» адрес 192.168.1.100. Если вписать свой внешний адрес (IP или DNS), то ничего не выйдет. Чтобы это стало возможным, нужно дописать еще две строки:
iptables -t nat -A zone_lan_prerouting -d 95.170.188.45 -p tcp -m multiport --dports 25,110,143,465,587,993,995,4190 -j DNAT --to-destination 192.168.1.100
iptables -t nat -A zone_lan_postrouting -d 192.168.1.100 -p tcp -m multiport --dports 25,110,143,465,587,993,995,4190 -j MASQUERADE
В первой строке мы говорим, что все обращения к внешнему адресу на указанные порты должны перенаправляться на локальный адрес 192.168.1.100. Во второй строке мы, если так можно выразиться, прячем, что обращаемся из локальной сети.
После нажатия кнопки Save содержимое поля Custom Rules будет сохранено на роутере в файле /etc/firewall.user. Для применения эти необходимо перезапустить файрволл:
/etc/init.d/firewall restart
После этого почта станет доступной из внешней сети и из локальной, причем по доменному имени или внешнему IP-адресу.
Обновление Если оставить последнее правило в таком виде, то исходящий IP-адрес (адрес клиента) будет отображаться как адрес самого роутера в локальной сети: 192.168.1.1. Поэтому следует немного изменить правило, чтобы оно выглядело следующим образом:
iptables -t nat -A zone_lan_postrouting -s 192.168.1.0/24 -d 192.168.1.100 -p tcp -m multiport --dports 25,110,143,465,587,993,995,4190 -j MASQUERADE
В этом случае внешние адреса останутся «настоящими», а все запросы из локальной сети будут отображаться как 192.168.1.1. На мой взгляд, это приемлемо.