Всем, всего, и много!

Вкратце обрисую ситуацию: имеется сервер с кучей ВЛАН-ов, на которые
заведены куча локальных подсетей. На внешнем интерфейсе прописаны с
десяток "белых" адресов. Во внутренней сети имеется с десяток серверов,
которые должны быть доступны снаружи, и десяток-другой юзеров, которым
нужно ходить наружу. В общем, классическая задача. Более того, она уже
решена - но теперь я хочу найти _красивое_ решение! ;-)

Как известно, каждое соединение из Инета через NAT во внутреннюю сеть
требует 4-х разрешающих правил в файрволе (или даже 6-ти, если файрвол
"двухпроходный"). Хочется эти правила сделать как можно более общими.

Для соединений, инициируемых снаружи, всё решается просто:

nat 10 config ip ${ext_ip} <bla-bla> redirect_addr ${int_ip} ${ext_ip}
add 100 nat 10 all from any to ${ext_ip} in recv ${ext_if}
add 200 nat 10 all from ${int_ip} to any out xmit ${ext_if}

В самом файрволе имеются два "общих" правила:

add 1000 pass all from any to any out recv ${ext_if} xmit ${int_if}
add 1100 pass all from any to any established

Таким образом, для добавления нового внутреннего сервера достаточно
скопировать блок правил для NAT и поменять в нём адреса на нужные.

А вот для соединений, устанавливаемых _изнутри_ сети, требуется добавить
ещё одно правило, разрешающее проход пакетов через внутренний интерфейс,
причём мы ещё не знаем, будет ли этот пакет проходить через NAT и внешний
интерфейс, поэтому вынуждены использовать конструкцию вида:

add 300 pass tcp from ${int_ip} to any not dst-ip me not dst-ip \
${список_сетей} in recv ${int_if}

А так как во многих правилах вместо простого any требуется указать
конкретный адрес или список адресов, да ещё с портами, плюс те же
самые адреса могут использоваться для проброса соединений снаружи,
то не удивительно, что скрипт файрвола в области NAT очень быстро
превращается в неудобоваримую мешанину.

Была у меня идея заворачивать setup-пакеты изнутри сети в NAT сразу
на внутреннем интерфейсе правилом:

add 400 nat 10 tcp from ${int_ip} to any not dst-ip me not dst-ip \
${список_сетей} in recv ${int_if}

и потом уже выпускать их всех наружу одним "общим" правилом типа:

add 1200 pass tcp from me to any setup

но быстро выяснилось, что пакеты, попадающие в правило 400, NAT-ом
не обрабатываются. И это немного странно, ведь ему должно быть всё
равно, каким правилом мы пихаем в него пакеты, его дело их алиасить
и пускать дальше по стеку. Тем не менее, счётчик в правиле растёт,
а вот число трансляций в NAT не меняется - и на внешнем интерфейсе
эти пакеты тоже не появляются. Я был бы очень признателен, если б
кто-нибудь объяснил мне его поведение в данном случае. Может, ему
не нравится то, что у пакета ещё не определён выходной интерфейс?

В общем, хочется найти решение, позволяющее прописывать доступ к NAT
для каждого хоста изнутри сети одним правилом. Или я хочу странного?

--
WBR, Alexey Markov.

Ответить