Использование iptables и dhcpd

iptables: теория

Прежде всего дадим ссылку на документацию: iptables tutorial Оскара Андреассона в переводе Андрея Киселева. Это очень хорошее руководство, начинающее с азов и понемногу подводящее читателя к сложным и интересным темам (с подробным описанием идущих в системе процессов).

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

Заметим, что с денежными расчетами ситуация особая. Одно дело --- показатели работы сетевых интерфейсов, и совсем другое --- алгоритм, по которому мы можем выписывать счета. Именно это --- право манипулировать денежными документами --- и называется биллинг (англ. billing --- выписывание счёта). Для получения этого права нужна государственная сертификация соответствующего программного обеспечения. Заметим, что сам рассматриваемый нами инструмент --- iptables --- такой сертификации не имеет (это привилегия больших программных систем, например UTM).

iptables позволяет производить многие из необходимых для решения указанных задач действий (большей частью --- на уровне IP). Сетевой пакет может обрабатываться нашей системой в трех возможных ситуациях:

  • пакет приходит на нашу машину и потребляется некоторым процессом;
  • пакет производится некоторым процессом нашей машины и покидает ее;
  • пакет перекладывается из одного сетевого интерфейса в другой.

Отметим, что когда хост обращается сам к себе, пакет уходит в интерфейс loopback и тут же из него появляется (здесь работают сразу первый и второй пункты этого списка).

Для удобства манипуляции сетевым трафиком и решения наиболее популярных задач у трех перечисленных путей пакетов через хост есть общие части, что видно из следующей схемы:

Books/LinuxIntro/15ChapterService/IPTables.dia.png

Большие блоки PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING называются цепочками. Заметим, что все возможные пути проходят хотя бы через одно принятие решения о маршрутизации, причем порядок действий для исходящих и входящих пакетов в этом смысле несимметричен.

Обработка пакетов, проходящих через iptables, происходит с помощью правил. Правила объединены в таблицы, а таблицы --- в цепочки. Можно считать, что цепочки --- это именно цепочки таблиц, которые друг другу передают пакеты. Таблицы могут иметь одно из четырёх названий: mangle, nat, filter, raw.

Таблица mangle предназначена для преобразований в заголовках пакетов. Здесь можно изменять QoS, ToS, TTL и другие служебные параметры.

В таблице nat происходит преобразование IP-адресов --- network address translation (NAT). Это, вообще говоря, тоже является изменением заголовков, но поскольку оно затрагивает адреса отправителя и получателя (а следовательно, непосредственно влияет на решение о маршрутизации), то вынесено в отдельную таблицу.

В таблице filter размещаются правила, которые занимаются собственно фильтрацией пакетов. Здесь принимаются решения о выбрасывании пакета, о перекладывании его в другую цепочку. Можно создавать и свои собственные цепочки, состоящие по умолчанию из пустых таблиц.

Таблица raw существует для обработки пакетов без отслеживания IP-соединения, по которому они проходят. Позволяет, соответственно, обрабатывать произвольные "сырые" (англ. raw --- сырой, необработанный) пакеты. Ввиду узкоспецифичности использования по умолчанию пуста.

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

Результаты анализа привели к следующим решениям. Во-первых, было выделено пять основных блоков, в которых происходит обработка пакетов. Во-вторых, произведено разделение на четыре основные задачи --- служебная модификация пакетов, содержательная модификация (подмена IP-адресов), фильтрация и предмодификационная обработка. Эти задачи соответствуют таблицам iptables, а блоки обработки --- основным цепочкам.

Итак, устройство iptables можно представить в виде ориентированного графа с пятью вершинами (это цепочки). Каждая вершина, в свою очередь, представляет собой другой ориентированный граф, в котором обыкновенно от двух до четырёх вершин (таблицы). Каждая таблица --- упорядоченный набор (список) правил вида "если для пакета выполняется такое-то условие, сделать то-то" (по сути дела, это просто пары "условие --- действие"). Перемещение пакета по графу осуществляется следующим образом: последовательно проверяются все условия, причем как только одно из них оказывается выполненым, соответствующее действие немедленно применяется. Если при этом пакет продолжает свое путешествие (он не был выброшен или, наоборот, принят в данной таблице) то будут проверяться следующие условия и так далее. При выходе из таблицы пакет переходит в следующую таблицу, а при выходе из всех таблиц цепочки --- в следующую цепочку. Принятие пакета в одной из таблиц также означает переход к следующей таблице (цепочке).

К сожалению, пользовательская документация к iptables составлена на основе внутреннего устройства этого программного продукта. Поэтому в ней (и в большинстве документации к iptables вообще, в том числе и в iptables tutorial) принято другое соглашение о логической структуре: цепочки объединяются в таблицы (таблица --- это группа цепочек одного типа, расположенных в разных местах). Понятно, что такая договоренность влияет лишь на способ представления, но не на принципы функционирования сетевого фильтра. Заметим, однако, что команд типа "показать по порядку все правила всех типов для исходящих пакетов" в стандартной поставке нет.

Необходимо сказать, что можно встретить и иное название для системы iptables --- netfilter. Это --- оригинальное название сетевого фильтра первого поколения в ядре Linux. После netfilter использовалась система ipchains, которую называют сетевым фильтром второго поколения (iptables представляет третье). В последнее время название iptables более распространено и почти всегда означает не просто утилиту управления, а все части этого сетевого фильтра как единую систему.

Посмотрим теперь, какие правила действуют сейчас в нашей системе:

[root@demo net]# iptables-save
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:13:06 2008
*mangle
:PREROUTING ACCEPT [428:365625]
:INPUT ACCEPT [394:361829]
:FORWARD ACCEPT [7:296]
:OUTPUT ACCEPT [278:27722]
:POSTROUTING ACCEPT [361:43691]
COMMIT
# Completed on Tue Jul  8 18:13:06 2008
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:13:06 2008
*nat
:PREROUTING ACCEPT [36:4238]
:POSTROUTING ACCEPT [30:2757]
:OUTPUT ACCEPT [29:2705]
COMMIT
# Completed on Tue Jul  8 18:13:06 2008
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:13:06 2008
*filter
:INPUT ACCEPT [65:29557]
:FORWARD ACCEPT [7:296]
:OUTPUT ACCEPT [69:10645]
:stdin - [0:0]
COMMIT
# Completed on Tue Jul  8 18:13:06 2008

Как видно, в настоящее время заданных пользователем (администратором) правил нет.

Практика использования iptables

Покажем, как настроить iptables для решения простейших задач.

Пусть у нас есть две доступные машины. На одной, которая называется demo, имеется два сетевых интерфейса, через один из которых она имеет доступ в Интернет. Второй интерфейс --- внутренний. А у второй машины под названием lite есть только соединение с внутренним интерфейсом первой. Для второй машины мы будем создавать доступ в интернет, а также попытаемся ограничить этот доступ.

Сформулируем задачу. Мы хотим сделать две вещи:

  • Вторая машина должна получить доступ в Интернет. Для этого нужно связать две имеющиеся у нас машины, сделать demo фильтром пакетов и включить там NAT (network address translation)
  • Поупражняться с фильтрацией, чтобы посмотреть, как iptables добавляет правила для фильтрации в разных местах.

Для начала выберем какую-то сеть внутреннего диапазона. И назначим второй машине адрес из этого диапазона. Пусть это будет 172.16.0.2 с маской 255.255.255.0 (172.16.0.1 -- адрес для нашего "сервера". Конечно, не обязательно так делать, можно назначить для маршрутизатора любой адрес, но принято присваивать ему первый адрес в диапазоне).

root@lite# ip addr add 172.16.0.2/24 dev eth0

А на demo, если дать команду ip a, мы увидим, что сработал конфигуратор по умолчанию (при помощи zeroconf, на что намекает название интерфейса eth1:avahi).

root@demo# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 08:00:27:50:7a:b1 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 08:00:27:7f:75:e2 brd ff:ff:ff:ff:ff:ff
    inet 169.254.8.10/16 brd 169.254.255.255 scope global eth1:avahi

Создадим в /etc/net конфигурацию для eth1 и перезапустим сеть:

root@demo# mkdir /etc/net/ifaces/eth1
root@demo# cd /etc/net/ifaces/eth1
root@demo# echo "172.16.0.1/24" > ipv4address
root@demo# cat > options
DISABLED=no
BOOTPROTO=static
root@demo# service network restart

Проверим результат этих действий:

root@demo# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 08:00:27:50:7a:b1 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 08:00:27:7f:75:e2 brd ff:ff:ff:ff:ff:ff
    inet 172.16.0.1/24 brd 172.16.0.255 scope global eth1
root@demo# ip r
172.16.0.0/24 dev eth1  proto kernel  scope link  src 172.16.0.1 
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
default via 10.0.2.2 dev eth0 

Итак, наша машина demo имеет адрес 10.0.2.15 во внешней сети и 172.16.0.1 во внутренней. Также на ней правильно настроен роутинг для этих сетей.

Возвращаемся на lite и проверяем:

root@lite# ping 172.16.0.1
PING 172.16.0.1 (172.16.0.1) 56(84) bytes of data.
64 bytes from 172.16.0.1: icmp_seq=1 ttl=64 time=36.5 ms
64 bytes from 172.16.0.1: icmp_seq=2 ttl=64 time=19.6 ms
64 bytes from 172.16.0.1: icmp_seq=3 ttl=64 time=3.57 ms
64 bytes from 172.16.0.1: icmp_seq=4 ttl=64 time=16.9 ms
64 bytes from 172.16.0.1: icmp_seq=5 ttl=64 time=5.05 ms
64 bytes from 172.16.0.1: icmp_seq=6 ttl=64 time=3.86 ms
64 bytes from 172.16.0.1: icmp_seq=7 ttl=64 time=5.37 ms

--- 172.16.0.1 ping statistics ---
7 packets transmitted, 7 received, 0% packet loss, time 6014ms
rtt min/avg/max/mdev = 3.571/13.014/36.595/11.405 ms

Добавляем на lite маршрут по умолчанию (сейчас прописан только маршрут до компьютеров нашей внутренней подсети):

root@lite# ip route add default via 172.16.0.1

Но при этом маршрутизация не работает. Это можно увидеть попробовав зайти на какой-нибудь сайт при помощи команды netcat:

root@lite# netcat 80.68.240.144 80

Доустановим пакет tcpdump (для этого должен быть включён какой-нибудь репозиторий --- updates или branch):

root@demo# apt-get install tcpdump

Этот пакет необходим для просмотра пакетов, проходящих через сетевые интерфейсы нашего компьютера.

Теперь запустим tcpdump на сервере, на другой машине netcat. Мы видим, что c адреса 172.16.0.2 идут пакеты на указанный адрес, но сервер не пересылает эти приходящие к нему пакеты, и поэтому мы не можем получить доступ к сайту с машины lite. Убедимся, что пакеты не проходят: tcpdump -i eth0 host 80.68.240.144:

root@demo# tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
18:00:32.777207 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:00:35.798593 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:00:35.968782 IP demo.local.5353 > 224.0.0.251.5353: 0 PTR (QM)? 117.200.168.192.in-addr.arpa. (46)
18:00:37.822276 arp who-has demo.local tell 172.16.0.2
18:00:37.822365 arp reply demo.local is-at 08:00:27:7f:75:e2 (oui Unknown)
18:00:41.818490 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:00:53.803214 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:01:17.798826 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:01:22.825093 arp who-has demo.local tell 172.16.0.2
18:01:22.825233 arp reply demo.local is-at 08:00:27:7f:75:e2 (oui Unknown)
18:02:05.822643 IP 172.16.0.2.4471 > 192.168.200.117.webcache: S 2740685371:2740685371(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:02:10.810226 arp who-has demo.local tell 172.16.0.2
18:02:10.810354 arp reply demo.local is-at 08:00:27:7f:75:e2 (oui Unknown)

13 packets captured
13 packets received by filter
0 packets dropped by kernel

Пакеты не проходят потому, что машина demo не работает в режиме маршрутизатора. Для того, чтобы включить режим маршрутизации, нужно заменить значение параметра net.ipv4.ip_forward в файле /etc/net/sysctl.conf с 0 на 1.

root@demo# cd /etc/net/
root@demo# grep forward sysctl.conf
# IPv4 packet forwarding.
net.ipv4.ip_forward = 0
root@demo# sed -i '/net.icv4.ip_forward = 0/s/0/1/' sysctl.conf
root@demo# grep forward sysctl.conf
# IPv4 packet forwarding.
net.ipv4.ip_forward = 1

В пятой строчке этого кода использовалась команда sed, которая используется для преобразования текстовых фаилов. В этой команде используются регулярные выражения. В данной команде указано, что нужно найти строчку содержащую net.icv4.ip_forward = 0 и в ней заменить 0 на 1. При желании это, конечно, можно сделать вручную.

После этого маршрутизация работает, но преобразования ip не происходит, поэтому ответы от 80.68.240.144 не приходят. Для того, чтобы мы могли получать ответы, нужен NAT:

root@demo# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source=10.0.2.15

Что в результате получилось? Утилита iptables предназначена для редактирования тех самых таблиц, про цепочки которых было рассказано выше. Параметры этой утилиты: -t --- редактируемая таблица, -A --- команда (добавить), -o указывает, какой интерфейс используется при переадресации, -j --- действие, которое надо произвести. Далее дадим команду iptables-save, чтобы посмотреть что в действительности произошло с нашими таблицами. Для этого также можно использовать команду iptables -t nat -L.

root@demo# iptables-save 
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:17:08 2008
*mangle
:PREROUTING ACCEPT [428:365625]
:INPUT ACCEPT [394:361829]
:FORWARD ACCEPT [7:296]
:OUTPUT ACCEPT [278:27722]
:POSTROUTING ACCEPT [361:43691]
COMMIT
# Completed on Tue Jul  8 18:17:08 2008
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:17:08 2008
*nat
:PREROUTING ACCEPT [36:4238]
:POSTROUTING ACCEPT [30:2757]
:OUTPUT ACCEPT [29:2705]
-A POSTROUTING -o eth0 -j SNAT --to-source 10.0.2.15 
COMMIT
# Completed on Tue Jul  8 18:17:08 2008
# Generated by iptables-save v1.3.7 on Tue Jul  8 18:17:08 2008
*filter
:INPUT ACCEPT [65:29557]
:FORWARD ACCEPT [7:296]
:OUTPUT ACCEPT [69:10645]
:stdin - [0:0]
COMMIT
# Completed on Tue Jul  8 18:17:08 2008
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       0    --  anywhere             anywhere            to:10.0.2.15 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

iptables-save выдаёт все цепочки, отсортированные по принадлежности к типам таблиц, iptables -L выдаёт правила цепочек в том порядке в котором они исполняются, но только для одного типа таблицы. В выводах обоих комманд видно, что наше правило добавилось. После этого должен работать NAT.

Теперь посмотрим, работает ли это на самом деле. Запускаем tcpdump сначала на внешнем интерфейсе, потом на внутреннем:

root@demo# tcpdump -i eth0 host 80.68.240.144
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
18:22:35.220616 IP 10.0.2.15.4802 > 80.68.240.144.http: S 4121055896:4121055896(0) win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 2>
18:22:35.227257 IP 80.68.240.144.http > 10.0.2.15.4802: S 389504001:389504001(0) ack 4121055897 win 8192 <mss 1460>
18:22:35.232999 IP 10.0.2.15.4802 > 80.68.240.144.http: . ack 1 win 5840
18:22:36.160388 IP 10.0.2.15.4802 > 80.68.240.144.http: P 1:2(1) ack 1 win 5840
18:22:36.161985 IP 80.68.240.144.http > 10.0.2.15.4802: . ack 2 win 8760
18:22:43.145085 IP 10.0.2.15.4802 > 80.68.240.144.http: P 2:7(5) ack 1 win 5840
18:22:43.145817 IP 80.68.240.144.http > 10.0.2.15.4802: . ack 7 win 8760
18:22:43.153304 IP 80.68.240.144.http > 10.0.2.15.4802: P 1:217(216) ack 7 win 8760
18:22:43.153570 IP 80.68.240.144.http > 10.0.2.15.4802: F 217:217(0) ack 7 win 8760
18:22:43.156774 IP 10.0.2.15.4802 > 80.68.240.144.http: . ack 217 win 6432
18:22:43.160685 IP 10.0.2.15.4802 > 80.68.240.144.http: F 7:7(0) ack 218 win 6432
18:22:43.164320 IP 80.68.240.144.http > 10.0.2.15.4802: . ack 8 win 8760

12 packets captured
12 packets received by filter
0 packets dropped by kernel

На внутреннем интерфейсе --- тот же трафик, но с другим адресом. Обратите внимание, что произошла подмена адресов. Таким образом, мы настроили компьютер для работы в качестве простейшего маршрутизатора.

Практика использования iptables: продолжение

Выше был приведён пример полностью ручной настройки фаерволла, но писать большое количество правил неудобно, и желание полуавтоматизировать процесс вполне естественно. Существует два способа сделать это. Первый достался по наследству от дистрибутива Mandrake и позволяет записать все правила кучей в /etc/sysconfig/iptables. Теперь они будут добавляться при запуске iptables. Второй способ -- вписать нужные настройки в соответствующий подкаталог /etc/net/. Полную информацию о том, как это делать можно прочитать в /usr/share/doc/etcnet-<version>/examples/firewall-hiddenman/ifaces/default/fw/iptables/nat. Один из примеров фрагмента довольно сложной конфигурации:

# cat POSTROUTING 
snat-to 5.6.7.8 if marked as 1

Для примера настроим NAT (Network Address Translation, преобразование сетевых адресов) для второй машины, подключенной к интерфейсу eth1 и заблокируем для неё соединения с некоторым адресом. Настройки интерфейса eth0 на второй машине и соединённого с ним eth1 на первой не приводятся по причине рассмотренности ранее (Автоматическая настройка сетевых подключений). Для того, чтобы серверная машина смогла маршрутизировать пакеты необходимо включить в /etc/net/sysctl.conf опцию net.ipv4.ip_forward:

# grep forward sysctl.conf 
# IPv4 packet forwarding.
net.ipv4.ip_forward = 0
# sed -i '/net.ipv4.ip_forward = 0/s/0/1/' sysctl.conf 
# grep forward sysctl.conf 
# IPv4 packet forwarding.
net.ipv4.ip_forward = 1

Создадим каталог fw/iptables/nat в /etc/net/ifaces/eth0:

# cd /etc/net/ifaces/eth0
# mkdir -p fw/iptables/nat
# cd fw/iptables/nat
# echo 'snat-to 10.0.2.15' > POSTROUTING

Существует проблема управления iptables в etc-net, связанная с различными форматами синтаксиса. В файле документации /etc/net/ifaces/default/fw/iptables/syntax описано их взаимооднозначное соответствие. В связи с этим правильно заменить ip-адрес на ${IPV4ADDRESS}:

# echo '-o ${NAME} -j SNAT --to-source ${IPV4ADDRESS}' > POSTROUTING

Таким образом мы совершили настройку iptables через /etc/net. То есть, при выполнении service network restart соответствующие правила будут применены. При этом iptables может быть выключен по умолчанию (например, в версии дистрибутива Lite), в таком случае редактирование /etc/net не приведёт к его работе -- фаерволл следует сначала включить.

Для примера запретим для второй машины соединения с адресом linux.org.ru. Добавим правило (таблица filter уже используется по умолчанию, но мы это традиционно укажем явно)

iptables -t filter -A FORWARD -d linux.org.ru -j LOG --log-level warning
iptables -t filter -A FORWARD -d linux.org.ru -j DROP

Первой строчкой мы добавили в syslog предупреждение о попытке посещения неким пользователем указанного сайта, а второй оборвали связь. Для сохранения этих настроек будет достаточно добавить аргументы команды iptables в файл FORWARD в рассмотренном выше каталоге /etc/net/ifaces/eth0/fw/iptables/nat.

Обратите внимание, что мы написали правила для перенаправляемых (проходящих "сквозь" маршрутизатор) пакетов, следовательно к пакетам, отправленным с маршрутизатора, эти правила не будут применяться. Проверим, что получилось.

На demo (серверной машине) попробуем соединиться с 80 портом (послав туда некие данные, в нашем примере --- текст календаря за этот месяц, выводимый командой cal):

# cal | netcat linux.org.ru 80
HTTP/1.1 400 Bad Request
Date: Tue, 08 Jul 2008 15:19:53 GMT
Server: Apache/2.2.8 (Fedora)
Content-Length: 352
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Request header field is missing ':' separator.<br />
<pre>
Su Mo Tu We Th Fr Sa       1  2  3  4  5 6  7  8  9 10 11 12</pre>
</p>
</body></html>

Соединение проходит, пакеты идут в обе стороны.

Попробуем соединиться с linux.org.ru с клиентской машины localhost, использующей demo в качестве маршрутизатора:

# cal | netcat linux.org.ru 80

Соединение не проходит, и в syslog на demo появляется запись:

# tail -2 /var/log/syslog/messages
Jul  8 19:19:13 demo kernel: IN=eth1 OUT=eth0 SRC=172.16.0.2 DST=217.76.32.61 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=16897 DF PROTO=TCP SPT=1395 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 
Jul  8 19:19:16 demo kernel: IN=eth1 OUT=eth0 SRC=172.16.0.2 DST=217.76.32.61 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=16898 DF PROTO=TCP SPT=1395 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0

Include: Nothing found for "^== Настройка DHCP ==$"!

Настройка DHCP

Настройка DHCP-сервера

Для начала следует напомнить, что из себя представляет служба DHCP. Предположим, что в процессе подготовки класса уже настроены маршрутизация и трансляция сетевых адресов. Теперь возникает необходимость настроить рабочие машины класса для работы в локальной сети и доступа в Интернет. Есть два пути:

  • вручную прописывать все необходимые настройки (как минимум это IP-адрес, маршрутизатор по умолчанию и DNS) на всех клиентских машинах;
  • использовать службу DHCP.

Работает служба DHCP на нескольких уровнях стека TCP/IP, и, вообще говоря, ее возможности шире чем просто выдача IP-адреса, адреса маршрутизатора по умолчанию и адресов DNS --- например с помощью DHCP можно организовать загрузку бездискового клиента по сети или автоматическое определение параметров прокси-сервера клиентами.

Для начала установим на маршрутизаторе класса dhcp-сервер.

# apt-get install dhcp-server

Существует несколько вариантов поведения сервера DHCP. Далее рассмотрим два наиболее распространенных.

Динамическое распределение IP-адресов

В этом режиме клиенту выдается адрес из указанного администратором диапазона. По истечении определенного времени --- срока аренды (leasing), клиент обязан снова запросить настройки у сервера, причем новые настройки могут не совпадать с предыдущими. Сервер считает свободными те IP-адреса диапазона, для которых истек срок аренды. Алгоритм выбора сервером IP-адреса обычно следующий: по первому запросу выдается последний адрес диапазона, по второму -- предпоследний, и т. д. Клиенту, запрашивающему адрес не в первый раз, выдается, если возможно, тот же адрес, что у него был, поскольку сервер хранит MAC-адреса клиентов. У такого алгоритма есть хорошее свойство --- если появляется новый клиент, то ему, по возможности, выдается ранее не использовавшийся адрес.

Итак, рассмотрим настройку динамического распределения IP-адресов с помощью службы DHCP. Возьмем имеющийся файл с примером настройки и скопируем его для упрощения создания конфигурации. Файл /etc/dhcpd.conf.sample в ALTLinux создается автоматически, если отсутствует правильный конфигурационный файл для DHCP.

# cd /etc/dhcp/
# cp dhcpd.conf.sample dhcpd.conf
# # Воспользуйтесь любым текстовым редактором
# mcedit dhcpd.conf

В результате редактирования файл /etc/dhcpd.conf должен выглядеть так:

# See dhcpd.conf(5) for further configuration

ddns-update-style none;

subnet 172.16.0.0 netmask 255.255.255.0 {
        option routers                  172.16.0.1;
        option subnet-mask              255.255.255.0;

        option domain-name              "demo.class.altlinux.ru";
        option domain-name-servers      10.0.2.3;

        range dynamic-bootp 172.16.0.10 172.16.0.90;
        default-lease-time 21600;
        max-lease-time 43200;

}

Кроме того, в dhcpd.conf необходимо перечислить все сети, которые непосредственно подсоединены к данному компьютеру. В нашем случае достаточно добавить строку с информацией о существовании внешней сети 10.0.2.0/24

subnet 10.0.2.0 netmask 255.255.255.0 {}

Осталось лишь запустить службу DHCP. Для этого на сервере необходимо выполнить:

# services dhcpd restart

На клиенте, если он уже включен, следует также перезапустить службу network, предварительно настроенную на использование DHCP.

# cd /etc/net/ifaces/eth0
# cd /etc/net/ifaces/eth0
# echo 'DISABLED=no' > options
# echo 'BOOTPROTO=dhcp' >> options
# services network restart

Динамическое обновление DNS

Так как разработкой данного DHCP-сервера и сермера DNS bind занимаются одни и те же люди, между этими этими проектами существует тесная связь. Например, поддерживается автоматическое обновление имени и IP-адреса в DNS-зоне --- это и называется dynamic DNS update. В отдельных случаях подобное может быть удобно, но обычно рекомендуется отключить это функцию.

Распределение IP-адресов по MAC-адресам

Вторым вариантом использования DNS является выдача определенного IP-адреса компьютеру с определенным MAC-адресом сетевой карты. Для этого достаточно добавить в файл dhcpd.conf следующие строки для каждого клиента:

host host01 {
 fixed-address 172.16.0.98;
 hardware ethernet 08:00:27:b7:69:b9
}

Заметим, что выдаваемый таким образом IP-адрес в случае DHCP-сервера из ПСПО должен лежать вне диапазона адресов, распределяемых динамически.

Вариант с фиксированным выделением адресов по MAC-адресу удобен, если есть необходимость знать, какой адрес получит конкретный клиент. Подобная схема работоспособна, так как в большинстве случаев MAC-адреса уникальны. Узнать список MAC-адресов компьютеров сети можно либо посмотрев адреса вручную на каждом из клиентов командой ip a, либо используя файл /var/lib/dhcp/dhcpd/state/dhcpd.leases, в котором записана информация, в том числе MAC-адреса, всех клиентов, которым когда-либо выдавались в аренду IP-адреса DHCP-сервером.


CategoryLectures CategoryPspo CategoryMpgu CategoryUneex