Today Sep 15, 2011 at 19:01 Denis Zaika wrote:

> Так как дефолтные маршруты есть в оба интерфейса, путь к произвольному
> адресу в сети до попытки связаться с ним неопределен. Если с такого
> адреса пробовать подключаться к внутренней машине через нат, обратный
> пакет может выйти через другой интерейс. То есть связи через один из
> внешних адресов не будет. Причем когда запись в ECMP устареет, следующая
> попытка может оказаться неуспешной уже на адресе, к которому раньше
> коннектилось.
> 
> Можно ли это вообще как-то правильно отконфигурировать? У меня идеи
> кончились :(.

  Пролетала тут ссылочка на статью Вадима Гончарова:
  http://nuclight.livejournal.com/124348.html
  Она идей добавит :)

В частности, с использованием появившегося во FreeBSD 6.2 параметра tag на 
каждый пакет
можно навешивать внутриядерный тег, что в применении со skipto позволяет 
сделать,
к примеру, запоминание, с какого шлюза пришел входящий пакет на машине с 
каналами
к двум разным провайдерам, и ответные пакеты отправлять в тот канал, откуда они
пришли (допустим, у вашей машины только один IP-адрес, и сделать fwd на базе
внешнего адреса не получится), т.е. реализовать аналог reply-to из pf:

ipfw add 100 skipto 300 tag 1 in recv $ext_if1 keep-state
ipfw add 200 skipto 300 tag 2 in recv $ext_if2 keep-state
ipfw add 300 allow { recv $ext_if1 or recv $ext_if2 }  # входящие снаружи
ipfw add 400 allow in recv $int_if   # разрешить ответы на внутреннем проходе
ipfw add 500 fwd $gw1 tagged 1      # остались ответы на внешнем интерфейсе,
ipfw add 600 fwd $gw2 tagged 2      # зарулим их куда надо

UPDATE:
2. Динамические правила и ipfw fwd; теги.

Приведенный в посте пример того, как на динамических правилах сделать 
аналог reply-to в pf, на самом деле, не работает. В исходниках был 
обнаружен запрет специально именно этого случая в мохнатом 2000 году из-за 
какой-то паники ядра на тех версиях. Что давно уже не актуально, но это, 
конечно же, поправить забыли. Патчится одной строчкой - открываете 
/sys/netinet/ip_fw2.c, находите слова case O_FORWARD_IP: (конкретный патч 
не приведу, зависит от версии системы). И вот там чуть ниже в строчке кусок
if (!q || dyn_dir == MATCH_FORWARD)
надо заменить на
if (sa->sin_port && (!q || dyn_dir == MATCH_FORWARD))
[UPD: 06.07.11 патч закоммичен в 7.x и 8.x, патч более неактуален, теперь всё 
работает так, как и описано в посте]

Еще, кстати, не стоит забывать, что все имеющиеся на пакетах теги, будь то 
метаинформация самой системы (от того же IPSEC и много чего еще) или явно 
навешенные теги ipfw/pf - существуют только внутри ядра. То есть, если 
вывести пакет из ядра через divert, они потеряются.

-- 
WNGS-RIPE

Ответить