Home

вторник, 10 ноября 2009 г.

Ручной NAT

Вторая статья из серии "Что нам стоит NAT построить" с руководством по настройке и запуску NAT руками. Первую вводную статью прочесть можно тут.

Тренироваться и проверять содеянное мы будем на тестовой конфигурации, которая не сильно отличается от вариантов, которые встречаются в реальной жизни. Провайдер и мак у нас уже есть, а еще один компьютер можно легко сэмулировать при помощи виртуальной машины в режиме сети LocalHost Only, чтобы встроенный виртуальный NAT и прочие прелести не мешали экспериментам.

Топологию сети можно представить как-то так:

nat_test_schema.png

Провайдер предоставляет по wi-fi нам ip адрес 172.16.101.13, принадлежащий сети 172.16.101.0/28 (маска сети 255.255.255.240, шлюз по-умолчанию и DNS находятся по адресу 172.16.101.14)

Нам необходимо вывести в Интернет домашнюю win-машину, соединив ее кабелем с нашим маком. Для этого активируем на маке сетевую карту, руками назначим ей адрес 192.168.56.1 маска сети 255.255.255.0, шлюза по-умолчанию на этой карте нет. В установках легко узнать умолчательные цыфирьки VirtualBox, только не забудьте выключить виртуальный DHCP сервер.

Win-машине выдадим адрес 192.168.56.101, маска 255.255.255.0, шлюз по-умолчанию - наш мак, 192.168.56.1, DNS выставим провайдерский, 172.16.101.14

nat_win_settings.png

Все, первый этап пройден, проверяем реальные и виртуальные кабеля, выключаем всякие файерволы на win-машине и пробуем работоспособность:

ping 192.168.56.1

Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.

ping 192.168.56.1
Обмен пакетами с 192.168.56.1 по 32 байт:

Ответ от 192.168.56.1: число байт=32 время=1мс TTL=64
Ответ от 192.168.56.1: число байт=32 время=3мс TTL=64
Ответ от 192.168.56.1: число байт=32 время=1мс TTL=64
Ответ от 192.168.56.1: число байт=32 время=1мс TTL=64

Статистика Ping для 192.168.56.1:
Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь),
Приблизительное время приема-передачи в мс:
Минимальное = 1мсек, Максимальное = 3 мсек, Среднее = 1 мсек

Переходим к следующему пункту, набираемся наглости и с win-машины пробуем пинговать провайдера. Но предварительно вернемся на Мак, получим неободимые привилегии в терминале

sudo bash

Теперь мы будем отлавливать пакеты, уходящие в сторону провайдера по сетевой карте en1 и посланные с win-машины

tcpdump -i en1 src 192.168.56.101 and dst 172.16.101.14

Запускаем пинг с win-машины ping 172.16.101.14 , переключаемся в мак и смотрим на перехваченные пакеты. И ... тишина. Нихт арбайтен. Жмем Ctrl-C дабы прервать tcpdump и решаем, что все должно работать и так:

nat_ip_forwarding.png

... и пакеты должны бы бегать. Все дело в том, что в Mac OS X по умолчанию запрещен проброс пакетов между интерфейсами. Исправим ситуацию, сказав

sysctl -w net.inet.ip.forwarding=1

Мы укажем ядру системы пробрасывать пакеты. Чтобы не делать это руками каждый раз после перезагрузки достаточно добавить строку net.inet.ip.forwarding=1 в файл настроек ядра /etc/sysctl.conf (создайте его, если у вас его еще нет)

nano /etc/sysctl.conf

Повторяем проверку и видим бегущие строки перехваченных пакетов

20:42:08.558422 IP 192.168.56.101 > 172.16.101.14: ICMP echo request, id 512, seq 256, length 40

Пока все работает. Правда, win-машина ответа на пинг не дождется. так как провайдер абсолютно не в курсе, что такое сеть 192.168.56.0, куда отсылать пакеты в ее сторону. Более того, вполне может быть у него есть своя собственная сеть с такими адресами, ведь диапазон частный и каждый волен его использовать по своему усмотрению. Но на этом этапе наличие ответов не важно, главное - Мак работает как роутер.

Теперь заставим работать доброго дядю-доктора, который будет препарировать пакеты.

В Mac OS X, как и в других BSD-like системах, функционал трансляции адресов состоит из двух взаимосвязанных частей:

nat_5.png
  1. Файервол на уровне ядра перехватывает нужные пакеты, которые необходимо препарировать и передает его сообщнику.
  2. Демон NAT (natd) берет перехваченные пакеты, изменяет их (транслирует адреса) и отдает обратно в файервол, который отправляет их в дальнейшее путешествие по назначению.

Начинаем отлавливать. Просмотрим существующие правила

ipfw list

При выключенном файерволе есть как-бы одно правило "делайте все, что хотите"

65535 allow ip from any to any

Добавим правило для отлова пакетов и передачи в natd, пусть его номер будет 666. Главное, чтобы его номер был меньше каких-нибудь запрещающих, которые существуют уже у вас и наше новое находилось и срабатывало раньше.

ipfw add 666 divert 8668 ip from any to any via en1 ipfw list

Мы создали правило 666, которое отлавливает все пакеты на интерфейсе en1 (AirPort) и передает напарнику, который ждет их на порту 8668 (порт natd по-умолчанию). Удалить правило можно командой

ipfw delete 666

В этот момент интернет на маке должен временно пропасть, так пакеты перехватываются, а обрабатывать их пока некому. Если это напрягает, достаточно удалить правило.

Теперь сконфигурируем демона NAT. Дабы не передавать каждый раз все параметры в командной строке, создадим ему конфигурацию.

nano /etc/natd.conf

И впишем такие параметры в файл

alias_address 172.16.101.13
interface en1
use_sockets
same_ports

В переводе на человеческий это означает: в исходящих пакетах на интерфейсе en1 подставлять адрес отправителя 172.16.101.13 и по-возможности сохранять номера исходящих портов.

Теперь запустим демона в работу, но в режиме отладки

natd -f /etc/natd.conf -v

Результат работы будет отображаться прямо в консоли. Пока не прервем работу демона нажатием Ctrl-C Теперь можно вернуться в win и опробовать ping 172.16.101.14 natd рапортует:

Out [ICMP] [ICMP] 192.168.56.101 -> 172.16.101.14 8(0) aliased to
   [ICMP] 172.16.101.13 -> 172.16.101.14 8(0)
In [ICMP] [ICMP] 172.16.101.14 -> 172.16.101.13 0(0) aliased to
   [ICMP] 172.16.101.14 -> 192.168.56.101 0(0)

В принципе, эту часть мы завершили успешно, осталось прервать работу демона и запустить его без параметра -v, чтобы он запустился в фоне. Остается напомнить, что в файл /etc/rc.local можно записывать команды, которые будут исполняться при старте системы.

И, на закуску, домашнее задание для особенно дотошных: данные правила ipfw применяются и самой системой, если включить общий доступ к Интернет при помощи графических пультов управления. Но если вглядеться внимательно в отчет о работе natd, то можно обнаружить явно лишнюю работу, которую он выполняет. К примеру: если в этот момент запустить закачку на самом маке, то в natd будут попадать и пакеты самого мака, а не только пришедшие с win-машины или предназначенные ей.

Как можно догадаться, виной тому слишком широкое правило 666, оно отлавливает абсолютно все пакеты, проходящие через en1. Эту ситуацию можно улучшить. Почему, если разбить одно правило на два и пытаться отловить пакеты туда и обратно только от win-машины,

ipfw add 666 divert 8668 ip from 192.168.56.0/24 to any via en1 ipfw add 666 divert 8668 ip from any to 192.168.56.0/24 via en1

то это не будет работать? Подсказку может дать отчет natd.

Ой.

4 коммент.:

Big Guy комментирует...

хелло!
вопрос, почему не работают счетчики на аутбаунд трафик в следующей конфигурации, и что означают большие циферки?
Big-Disaster:~ red$ sudo ipfw show
00099 1 64 deny tcp from any to 65.54.83.0/24
00100 636215 224195365 divert 8668 ip from any to any via ppp0
00101 0 0 count ip from 192.168.1.13 to any out via ppp0
00102 0 0 count ip from 192.168.1.7 to any out via ppp0
00103 0 0 count ip from 192.168.1.10 to any via ppp0
00104 51776 18298071 count ip from any to 192.168.1.7 in via ppp0
00105 175518 74853488 count ip from any to 192.168.1.10 in via ppp0
00106 82130 68651574 count ip from any to 192.168.1.13 in via ppp0
65535 170553704 77428401454 allow ip from any to any

tsybulin комментирует...

1. Потому что над ними уже NAT поработал и исходящий адрес изменился

см http://www.papasha.kiev.ua/2009/10/blog-post_28.html подробнее

2. rule_number, packet_count, byte_count

Big Guy комментирует...

туплю - не понимаю, где там будет срабатывать count и как правильнее было написать.
сейчас входящий оставил как есть, исходящий считается правилами вида:
ipfw add 102 count ip from 192.168.1.7 to any
хотя не уверен, что правильно
и еще, до того входящий считал тоже без всяких in via - в итоге посчитался дважды.
еще не уверен, что 99 правилом я запретил хождение на микрософтовские сервера (ведь есть правило номер 65535? и само оно стоит перед 100)
еще интересно правило с номером 65535 - это 77 гигабайт с момента последнего flush? так это было в пять вечера - быть того не может!

pavel комментирует...

allow ip from any to any
Это не говорит об инете, это читай как разрешаем айпи трафик от всех ко всем!
Итого, тут и локалка тут может быть и loopback )

Отправить комментарий