Снова ipfw и kernel nat

Проблемы установки, настройки и работы Правильной Операционной Системы

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [cоde] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-09 8:13:56

Дано:
  1. Старая как world задача о пробросе портов, 1 шт.
  2. Болван, 1 шт.
Есть FreeBSD 7.2 с пересобранным ядром:

Код: Выделить всё

...
options	LIBALIAS
options	IPFIREWALL
options	IPFIREWALL_NAT
options	IPFIREWALL_FORWARD
options	IPFIREWALL_VERBOSE
...
Не забыт и параметр one_pass:

Код: Выделить всё

sysctl net.inet.ip.fw.one_pass=0
Машинка работает НЕ как шлюз для выхода внутренней сети в инет (для этой задачи рядом стоит ее брат-близнец, выполняющий роль шлюза с учетом трафика, кешированием на Сквиде и пр., и пр. — не о нем речь). Нужно сделать так, чтобы обращения именно на эту машину извне с одного статического айпи по RDP перебрасывались на сервер во внутренней сети — банально, правда? Не работает.

Есть такой rc.firewall (немного видоизмененный):

Код: Выделить всё

outer_if="re0"
outer_ip="123.45.6.78"	# Ну-у...

inner_if="sk0"
inner_ip="192.168.0.234"

rdserver="192.168.0.206"
rdclient="78.6.45.123"	# Ну-у...

fw="/sbin/ipfw -q"
${fw} -f flush

${fw} nat 1 config ip ${inner_ip} redirect_addr ${rdserver} ${outer_ip} log
${fw} add nat 1 tcp from ${rdclient} to ${outer_ip} rdp via ${out_if}

${fw} add pass all from any to any via lo0
${fw} add deny all from ${inner_nw} to any via ${outer_if}

${fw} add pass tcp from any to any established

...

${fw} add deny log tcp from any to any
Вот что попадает в var/log/security:

Код: Выделить всё

kernel: ipfw: 100 Nat TCP 78.6.45.123:1637 123.45.6.78:3389 in via re0
last message repeated 2 times
kernel: ipfw: 100 Nat TCP 78.6.45.123:1638 123.45.6.78:3389 in via re0
last message repeated 2 times
И вот что видит на интерфейсах tcpdump:

Код: Выделить всё

listening on re0, link-type EN10MB (Ethernet), capture size 96 bytes
IP 78.6.45.123.1637 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>
IP 78.6.45.123.1637 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>
IP 78.6.45.123.1637 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>
IP 78.6.45.123.1638 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>
IP 78.6.45.123.1638 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>
IP 78.6.45.123.1638 > 123.45.6.78.rdp: S 1319421240:1319421240(0) win 65535 <mss 1460,nop,nop,sackOK>

listening on re0, link-type EN10MB (Ethernet), capture size 96 bytes
 
И я никак не могу понять, чего же не хватает. Безрезультатно бьюсь уже второй день :( Подскажите, пожалуйста, а?..

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Снова ipfw и kernel nat

Непрочитанное сообщение princeps » 2009-07-09 9:00:41

на сервере, куда ты rdp пробрасываешь, шлюз какой указан?
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Re: Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-09 9:09:56

на сервере, куда ты rdp пробрасываешь, шлюз какой указан?
Разумеется, не этот, а общий для всей внутренней сети — с адресом 192.168.0.236. Обратите внимание, что пакеты не уходят во внутреннюю сеть (tcpdump на внутреннем интерфейсе sk0 молчит, см. выше). Мне вообще непонятно, что происходит после NAT'ания входящих, т.к. в логах после этого пусто.

Аватара пользователя
schizoid
подполковник
Сообщения: 3228
Зарегистрирован: 2007-03-03 17:32:31
Откуда: Украина, Чернигов
Контактная информация:

Re: Снова ipfw и kernel nat

Непрочитанное сообщение schizoid » 2009-07-09 9:20:05

Locus писал(а):
на сервере, куда ты rdp пробрасываешь, шлюз какой указан?
Разумеется, не этот, а общий для всей внутренней сети — с адресом 192.168.0.236. Обратите внимание, что пакеты не уходят во внутреннюю сеть (tcpdump на внутреннем интерфейсе sk0 молчит, см. выше). Мне вообще непонятно, что происходит после NAT'ания входящих, т.к. в логах после этого пусто.
тогда ничего не выйдет
ядерный взрыв...смертельно красиво...жаль, что не вечно...

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Снова ipfw и kernel nat

Непрочитанное сообщение princeps » 2009-07-09 9:32:13

Locus писал(а):Разумеется, не этот, а общий для всей внутренней сети — с адресом 192.168.0.236.
у тебя пакеты обратную дорогу найти не могут
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Re: Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-09 9:33:59

тогда ничего не выйдет
Да пакеты-то не уходят с этой машины во внутреннюю сеть, совсем не уходят! Это видно по дампу tcpdump (см. выше). Если бы они уходили, но не получали отклика, я бы стал смотреть в сторону основного шлюза — но до этого этапа дело даже не доходит, пакеты, предназначенные внутреннему серверу, каким-то образом пропадают на этой машине.

Рядом стоит Линукс, то же НЕ основной шлюз, со внутренним адресом 192.168.0.238, и тамошний iptables прекрасно справляется с задачей, отправляя отклики внутреннему серверу и без проблем получая (и перенаправляя адресату) его отклики:

Код: Выделить всё

$fw -t nat -A PREROUTING -p tcp -s $rdclient  -d $outer_ip --dport rdp -j DNAT --to-destination $rdserver:rdp
... 
$fw -t nat -A POSTROUTING -o $inner_if -j SNAT --to-source $inner_ip
Связка из DNAT'а для переброса входящих и SNAT'а для корректного обомена пакетами по внутренней сети работает исправно. Нужно лишь повторить то же самое на фряхе. Если б в логах было что-то похожее на deny tcp, я б понял. Но ничего этого после NAT'ания в логах нет. Куда деваются пакеты, непонятно. Во внутреннюю сеть не уходят точно.

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Снова ipfw и kernel nat

Непрочитанное сообщение princeps » 2009-07-09 9:41:38

Ну хз, попробуй тут не inner_ip, а интерфейс указать

Код: Выделить всё

${fw} nat 1 config ip ${inner_ip} redirect_addr ${rdserver} ${outer_ip} log
<em>Locus</em> писал(а):Рядом стоит Линукс, то же НЕ основной шлюз, со внутренним адресом 192.168.0.238, и тамошний iptables прекрасно справляется с задачей, отправляя отклики внутреннему серверу и без проблем получая (и перенаправляя адресату) его отклики:
Значит на том сервере маршрут прописан для линукса, пропиши и для фри тоже, все равно без этого не заработает.
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Re: Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-09 9:48:53

Значит на том сервере маршрут прописан для линукса, пропиши и для фри тоже, все равно без этого не заработает.
Не прописан. Указан только общий шлюз, больше никаких изменений. Проблема, повторюсь, не в том, что отклики уходят не туда,а в том, что с фри запросы не уходят во внутреннюю сеть. И я не знаю, на каком этапе они рубятся.

CrazyPilot
ст. сержант
Сообщения: 321
Зарегистрирован: 2008-08-14 9:17:58
Откуда: Санкт-Петербург
Контактная информация:

Re: Снова ipfw и kernel nat

Непрочитанное сообщение CrazyPilot » 2009-07-10 13:19:28

А покажите

Код: Выделить всё

cat /etc/rc.conf | grep 'gateway'

Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Re: Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-10 19:54:23

gateway_enable="yes", да. Буду на месте, выложу подробности (уже работает).

Locus
рядовой
Сообщения: 15
Зарегистрирован: 2009-07-09 7:03:10

Re: Снова ipfw и kernel nat

Непрочитанное сообщение Locus » 2009-07-13 15:07:21

Во-первых, config ip/if вместе с redirect_addr не работают. Почему — вопрос не ко мне, мне пришлось изобретать костыли.

Сначала делаем редирект:

Код: Выделить всё

${fw} nat 1 config redirect_addr ${rdserver} ${outer_ip} same_ports
Поскольку машина, к которую обращаются RDP-клиенты, не является шлюзом по умолчанию, то исходный адрес также пришлось преобразовать:

Код: Выделить всё

${fw} nat 2 config ip ${inner_ip} same_ports
Теперь запросы к внутреннему серверу идут с айпи во внутренней же сети, и отклики возвращается куда надо, а не на шлюз по умолчанию.
Теперь собственно прикручиваем объявленные наты на интерфейсы:

Код: Выделить всё

${fw} add nat 1 tcp from any to any rdp via ${outer_if}
${fw} add nat 1 tcp from any rdp to any via ${outer_if}
${fw} add nat 2 tcp from any to any rdp via ${inner_if}
Если вы заметили (см. выше), далее идет правило, запрещающее пакеты якобы внутренней сети на внешнем интерфейсе. Именно это правило и рубило все пакеты, так как после NAT на внешнем интерфейсе запрос превращался в запрос к адресу внутренней сети. Прямо перед ним, чтобы они не рубились добавляем особые разрешения:

Код: Выделить всё

${fw} add pass tcp from ${rdclient} to ${rdserver} rdp via ${outer_if} setup
Вот так пришлось выкручиваться. Итоговая конфигурация (работающая):

Код: Выделить всё

${fw} nat 1 config redirect_addr ${rdserver} ${outer_ip} same_ports
${fw} nat 2 config ip ${inner_ip} same_ports

${fw} add nat 1 tcp from any to any rdp via ${outer_if}
${fw} add nat 1 tcp from any rdp to any via ${outer_if}
${fw} add nat 2 tcp from any to any rdp via ${inner_if}
${fw} add pass tcp from ${rdclient} to ${rdserver} rdp via ${outer_if} setup

${fw} add pass all from any to any via lo0
${fw} add deny all from ${inner_nw} to any via ${outer_if}

${fw} add pass tcp from any to any established

...

${fw} add deny log tcp from any to any