Страница 1 из 1

Снова ipfw и kernel nat

Добавлено: 2009-07-09 8:13:56
Locus
Дано:
  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
 
И я никак не могу понять, чего же не хватает. Безрезультатно бьюсь уже второй день :( Подскажите, пожалуйста, а?..

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-09 9:00:41
princeps
на сервере, куда ты rdp пробрасываешь, шлюз какой указан?

Re: Снова ipfw и kernel nat

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

Re: Снова ipfw и kernel nat

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

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-09 9:32:13
princeps
Locus писал(а):Разумеется, не этот, а общий для всей внутренней сети — с адресом 192.168.0.236.
у тебя пакеты обратную дорогу найти не могут

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-09 9:33:59
Locus
тогда ничего не выйдет
Да пакеты-то не уходят с этой машины во внутреннюю сеть, совсем не уходят! Это видно по дампу 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'ания в логах нет. Куда деваются пакеты, непонятно. Во внутреннюю сеть не уходят точно.

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-09 9:41:38
princeps
Ну хз, попробуй тут не inner_ip, а интерфейс указать

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

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

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-09 9:48:53
Locus
Значит на том сервере маршрут прописан для линукса, пропиши и для фри тоже, все равно без этого не заработает.
Не прописан. Указан только общий шлюз, больше никаких изменений. Проблема, повторюсь, не в том, что отклики уходят не туда,а в том, что с фри запросы не уходят во внутреннюю сеть. И я не знаю, на каком этапе они рубятся.

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-10 13:19:28
CrazyPilot
А покажите

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

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

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-10 19:54:23
Locus
gateway_enable="yes", да. Буду на месте, выложу подробности (уже работает).

Re: Снова ipfw и kernel nat

Добавлено: 2009-07-13 15:07:21
Locus
Во-первых, 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