В предыдущем посте мы с вами поставили Дебиан на виртуальную машину с целью превратить его в сервер, раздающий интернет в нашу локалку. Попытаемся претворить это в жизнь и начнём с самого простого - дать доступ всем ко всему.
Самое просто решение - NAT. Network address translation. Трансляция сетевых адресов. Суть этого механизма довольна проста: клиент отправляет пакеты через сервер NAT, который в свою очередь меняет в каждом пакете поле "адрес отправителя" с адреса клиента на свой адрес; в ответных пакетах сервер делает обратное преобразование - ставит на место адрес клиента. Посмотрите на картинку, станет проще:
Итак, что же на ней? Допустим у нас два компа (PC1 и PC2) и сервер между ними (NAT). У PC1 и PC2 по одному интерфейсу, у сервера NAT - 2. Адреса подписаны на картинке. PC1 хочет послать пакет на PC2 и получить от него ответный пакет. Но они в разных подсетях, то есть связи напрямую между ними нет - пакеты ходят через сервер. Пусть для PC1 шлюз по умолчанию - сервер NAT. Итак по этапам:
- PC1 не имеет прямой связи с PC2, так что отправляет пакет на шлюз по умолчанию - на сервер NAT. При этом в поле "адрес источника" (src на картинке) он пишет свой адрес, а в поле "адрес назначения" - адрес конечного узла, то есть адрес PC2.
- Сервер получает пакет, выбирает маршрут для него и меняет поле "адрес источника" с адреса PC1 на свой адрес. Это изменение запоминается во временной таблице, чтобы потом знать, кому перенаправить ответный пакет от PC2. Адрес назначения остаётся тем же. Пакет идёт на PC2.
- PC2 получает пакет. Он думает, что этот пакет сформирован сервером NAT и ничего не подозревает о существовании PC1. Формируется ответ, который уходит на сервер NAT.
- Сервер получает ответный пакет. Видит, что согласно таблице NAT, это ответный пакет для PC1. Адрес назначения меняется на PC1, и пакет пересылается на PC1.
- PC1 получает пакет. Ни о каких изменениях в ходе его следования PC1 не в курсе - весь механизм сработал прозрачно, то есть незаметно.
Всё, конец. Все счастливы.
Вообще-то механизм маршрутизации сработал бы тут не менее эффективно. То есть сервер бы просто переслал пакет без изменений и вернул бы ответ. Никакого НАТа. Но тут есть одно ограничение: чтобы пакет ушёл и вернулся обратно, должны существовать маршруты в обе стороны. Иногда это можно организовать, иногда нет. В случае соединения компа из локальной сети с интернетом это организовать невозможно. Почему? Потому что у компа из локалки так называемый серый айпишник - никто о нём не знает, за пределами локалки этот адрес никому неизвестен, соответственно и маршрута к нему быть не может. Однако, у сервера, раздающего инет на локальную сеть, айпишник белый (глобально маршрутизируемый) - он получен от провайдера и все знают о нём. Поэтому можно воспользоваться этим адресом - он будет своего рода пропуском в интернет для всех компов из локалки.
Ну что ж, мы знаем, что делать в теории, осталось реализовать это на практике. Наверное думаете, сейчас придётся искать подходящий софт, выбирать, качать, может даже компилировать? Нет. Всё гораздо проще. В Линуксе есть межсетевой экран iptables, который встроен в ядро и помимо прочего умеет NAT. Собственно сам межсетевой экран называется netfilter, а iptables - это консольный интерфейс к нему, но это не суть. К слову, NAT есть и в Винде (и даже не в серверных версиях):
Помните такое, да? Вот это собственно и есть NAT. Ну чтобы увидеть такую херню, надо иметь хотя бы 2 сетевых интерфейса, так что не удивляйтесь, если вдруг этого пункта где-то не будет. Но кроме этой несчастной галочки больше никаких настроек и нет. Повесить NAT на два и более интерфейсов тоже нельзя. Ну оно и понятно - икспиха всё-таки клиентская ось.
В серверной Винде возможностей заметно больше (можете добавить роль "Службы политики сети и доступа" с компонентами "Службы маршрутизации и удалённого доступа" и потыкаться там), но всё же по уровню гибкости и удобству настройки, а также по наглядности конечного результата всё это счастье уступает юниксовым системам.
Но вернёмся к нашим пингвинам. Логинимся на виртуальной машине с маршрутизатором под рутом. Сеть мы настроили в прошлой статье, сейчас только проверим её работоспособность - запустим пинг с маршрутизатора на контроллер домена и наоборот. Пинги должны ходить в обе стороны. Далее включаем ip-форвардинг на маршрутизаторе:
Теперь через наш сервер смогут ходить транзитные пакеты (идущие от одного удалённого хоста к другому через наш сервер).
И собственно NAT:
Вот он, великий и ужасный iptables. Мы добавили в таблицу NAT в цепочку POSTROUTING (в ней вносятся изменения в пакеты на выходе) правило, которое всем пакетам с адресом источника из подсети 192.168.100.0/24 будет подставлять в качестве обратного адреса 10.0.2.15 (это адрес внешнего интерфейса маршрутизатора, его можно посмотреть в выводе ifconfig). После этих двух команд с любой машины из нашей виртуальной локалки можно пользоваться интернетом. Однако тут есть одно но: внешний интерфейс получает адрес (в данном случае 10.0.2.15) по dhcp, а следовательно в следующий раз адрес может быть и другим. В этом случае правило айпитэйблс будет срабатывать всё так же, но результат уже будет не тем - пакетам будет подставляться неправильный адрес. Чтобы избежать этого, немного изменим приведённое выше правило. Для начала удалим старое:
И добавим новое:
Маскарадинг - это то же самое подставление адреса, только на этот раз адрес будет определяться динамически. То есть iptables сначала посмотрит адрес интерфейса, с которого уходит пакет и потом подставит его в поле "адрес отправителя" в пакете. По сравнению с первым методом маскарадинг очевидно более ресурсоёмок, но как видите в данном случае без него никак.
Сейчас можно зайти с любой из виртуальных машин проверить результат - интернет должен быть везде (если, конечно, он есть на реальной машине).
Обмен пакетами с 8.8.8.8 по с 32 байтами данных:
Ответ от 8.8.8.8: число байт=32 время=197мс TTL=125
Статистика Ping для 8.8.8.8:
Пакетов: отправлено = 1, получено = 1, потеряно = 0
(0% потерь)
Приблизительное время приема-передачи в мс:
Минимальное = 197мсек, Максимальное = 197 мсек, Среднее = 197 мсек
Угу. Оно.
Следующее "но". Все настройки правил iptables хранятся в памяти и сбрасываются при перезагрузке. Значит нам надо поставить скрипт, забивающий правила, в автозагрузку. Сделаем это. В файле /etc/network/interfaces добавим после описания интерфейса, смотрящего в инет, строчку:
Этот скрипт будет выполняться каждый раз при поднятии интерфейса. Собственно надо только создать файл /root/iptables-script и прописать в нём всё, что надо:
touch iptables-script
chmod u+x iptables-script
vim iptables-script
Создали файл, дали ему права на выполнение и открыли его в текстовом редакторе. Вот содержание скрипта:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE
Теперь при перезагрузке всё будет хорошо. Ну это примитив. Можно немного улучшить. Сохраним уже забитые в память правила следующей командой:
А в /etc/network/interfaces заменим
на
iptables-save и iptables-restore - утилиты для сохранения и восстановления правил iptables. Отличие от предыдущего варианта в том, что тогда правила забивались по одному (сейчас оно у нас всего одно, но дальше будет больше) - одно обращение к ядру/одно правило. Тут же всё забьётся за одно обращение к ядру. Экономия ресурсов на лицо, да же? Ну и после точки с запятой (последовательное выполнение команд) добавили разрешение прохождения транзитных пакетов.
Ну и хватит на сегодня. Детально проработаем правила в следующей статье.
Pishi ischo, please...)
ОтветитьУдалить