Заметка: Бесклассовые маршруты DHCP

Вопросы настройки и работы с этой ОС.
Правила форума
Убедительная просьба юзать теги [cоde] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
BlackCat
прапорщик
Сообщения: 469
Зарегистрирован: 2007-10-16 22:40:42

Заметка: Бесклассовые маршруты DHCP

Непрочитанное сообщение BlackCat » 2010-08-16 6:45:09

Введение

Есть провайдер предоставляющий доступ в Интернет через PPPoE-соединение, которое устанавливается через внутреннюю сеть. Клиентам разрешён обмен, как через PPPoE соединение, так и через внутреннюю сеть. Скорость внутренней сети 100 Мбит/с, скорость PPPoE - контрактная. Для нормальной работы внутренней сети требуется прописать несколько маршрутов, которые провайдер раздаёт с использованием поля опций в DHCP-пакетах - бесклассовые маршруты.

Т.к. планировалось использовать внутреннюю сеть провайдера, то необходимо настроить получение и установку маршрутов. Конечно, можно было прописать их вручную, но это всё равно, что рыть себе яму - что-то изменится, и танцы с бубном обеспечены.

Теоретическая часть подробно описана в [1, 2, 3].

Исходные данные:
  • ОС на шлюзе: OpenBSD 4.6;
  • внешний интерфейс: rl0;
  • подсеть: 192.168.15.0/24;
  • DHCP-сервер: 192.168.15.3;
  • маршруты: 10.1.0.0/16 через 192.168.15.1, 10.2.0.0/16 через 192.168.15.2;
Внимание: далее подразумевается, что встроенный DHCP-клиент не используется в настоящий момент. Если это не так, то необходимо внести соответствующие поправки. Например, при пробных запусках, сразу указывать новые PID и конфигурационный файлы.

1. Установка DHCP-клиента

Уже установленный DHCP-клиент для решения поставленной задачи не подходит, т.к. не поддерживает данную опцию и не имеет возможности описывать собственные опции. Так что придётся ставить дополнительный клиет из пакетов.

Листинг 1.1 Установка DHCP-клиента

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

# pkg_add -i -v ftp://ftp.openbsd.org/pub/OpenBSD/4.6/packages/i386/isc-dhcp-client
Скрипт DHCP-клиента в пакет содержит пару опечаток и не поддерживает работу с файлом resolv.conf.tail, поэтому его необходимо немного доработать.

Листинг 1.2. Патч для dhclient-script

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

# cat dhclient-script.patch
--- /usr/local/sbin/dhclient-script.bak Fri Aug 13 01:15:23 2010
+++ /usr/local/sbin/dhclient-script     Fri Aug 13 02:10:46 2010
@@ -1,7 +1,7 @@
 #!/bin/sh

 make_resolv_conf() {
-  if x"$new_domain_name_servers" != x ]; then
+  if [ x"$new_domain_name_servers" != x ]; then
     cat /dev/null > /etc/resolv.conf.dhclient
     if [ x"$new_domain_search" != x ]; then
       echo search $new_domain_search >> /etc/resolv.conf.dhclient
@@ -15,7 +15,11 @@
       echo nameserver $nameserver >>/etc/resolv.conf.dhclient
     done

-    mv /etc/ersolv.conf.dhclient /etc/resolv.conf
+    if [ -f /etc/resolv.conf.tail ]; then
+      cat /etc/resolv.conf.tail >> /etc/resolv.conf.dhclient
+    fi
+
+    mv /etc/resolv.conf.dhclient /etc/resolv.conf
   fi
 }
Теперь можно проверить работоспособность нового клиента.

Листинг 1.3 Проверка DHCP-клиента

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

# /usr/local/sbin/dhclient -d rl0
Internet Systems Consortium DHCP Client V3.1.1
Copyright 2004-2008 Internet Systems Consortium.
All rights reserved.
For info, please visit http://www.isc.org/sw/dhcp/

Listening on BPF/rl0/xx:xx:xx:xx:xx:xx
Sending on   BPF/rl0/xx:xx:xx:xx:xx:xx
Sending on   Socket/fallback
DHCPDISCOVER on rl0 to 255.255.255.255 port 67 interval 7
DHCPOFFER from 192.168.15.3
DHCPREQUEST on rl0 to 255.255.255.255 port 67
DHCPACK from 192.168.15.3
New Network Number: 192.168.15.0
New Broadcast Address: 192.168.15.255
bound to 192.168.15.240 -- renewal in 1590 seconds.
^C
2. Конфигурационный файл

Во избежание конфликтов с уже установленным клиентом настройки нового клиента будут сохранены в файле dhclient-isc.conf. Указываем путь к скрипту обработки данных, описываем новую опцию и перечисляем опции которые хотим получить от DHCP-сервера.

Листинг 2.1 Конфигурационный файл DHCP-клиента

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

# cat /etc/dhclient-isc.conf | grep -v "^#"

script "/usr/local/sbin/dhclient-script";

option classless-static-routes code 121 = array of { unsigned integer 8 } ;

request subnet-mask, broadcast-address, classless-static-routes,
      domain-name, domain-name-servers;
require subnet-mask, domain-name-servers;
Запускаем с новым конфигурационным файлом, должны мелькать строки о переименовании опции.

Листинг 2.2 Проверка новой конфигурации

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

# /usr/local/sbin/dhclient -d rl0 -cf /etc/dhclient-isc.conf
3. Конфигурационный файла интерфейса

Т.к. используется не стандартный DHCP-клиент, то простой строкой "dhcp" здесь не отделаться - придётся прописывать полные пути. Для избежания конфликтов со стандартным клиентом используются отличные PID и lease файлы.

Листинг 3.1 Конфигурационный файл интерфейса

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

# cat /etc/hostname.rl0
!/usr/local/sbin/dhclient rl0 \
        -lf /var/db/dhclient-isc.leases \
        -cf /etc/dhclient-isc.conf \
        -pf /var/run/dhclient-isc.pid
Проверяем корректность настроек.

Листинг 3.2 Проверка конфигурации интерфейса

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

# sh /etc/netstart rl0
4. Обработка опции "Бесклассовые маршруты"

Формат опции был описан выше, в конфигурационном файле, остаётся только обработать полученные данные. В реализации ISC, DHCP-клиент после получения данных от сервера вызывает скрипт, устанавливающий необходимые параметры. Этот скрипт поддерживает использование т.н. Hook'ов - дополнительных скриптов, которые вызываются до (/etc/dhclient-enter-hooks) и после (/etc/dhclient-exit-hooks) выполнения основных действий. Для установки маршрутов удобнее использовать последний. Необходимо будет разобрать входные данные (строка чисел, разделённая пробелами) в соответствии с [3] и установить маршруты.

Листинг 4.1 Скрипт для обработки опции "Бесклассовые маршруты"

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

# cat /etc/dhclient-exit-hooks

#
# Process classless static route DHCP option (code 121)
# By BlackCat
#
# TODO: perform sanity checks.
# TODO: process other reasons (RENEW, REBIND, etc)
#

if [ -n "$new_classless_static_routes" ]; then
        if [ x"$reason" == x"BOUND" -o x"$reason" == x"REBOOT" ]; then

                state=STATE_PREF_LEN
                for byte in $new_classless_static_routes; do
                        case $state in
                        STATE_PREF_LEN)
                                pref_len=$byte
                                cnt=`expr $byte % 8`
                                if [ $cnt -eq 0 ]; then
                                        cnt=`expr $byte / 8`
                                else
                                        cnt=`expr $byte / 8 + 1`
                                fi
                                state=STATE_DEST
                                dest=
                                gw=
                                ;;
                        STATE_DEST)
                                if [ -z $dest ]; then
                                        dest=$byte
                                else
                                        dest="$dest.$byte"
                                fi
                                cnt=`expr $cnt - 1`
                                if [ $cnt -eq 0 ]; then
                                        state=STATE_ROUTER
                                        cnt=4
                                fi
                                ;;
                        STATE_ROUTER)
                                if [ -z $gw ]; then
                                        gw=$byte
                                else
                                        gw="$gw.$byte"
                                fi
                                cnt=`expr $cnt - 1`
                                if [ $cnt -eq 0 ]; then
                                        state=STATE_PREF_LEN
                                        route add $dest/$pref_len \
                                                   $gw > /dev/null 2>&1
                                fi
                                ;;
                        *)
                                echo "Parsing error. Exit."
                                exit 1
                        esac
                done
        fi
fi
Перезапускаем DHCP-клиент, проверяем работоспособность и пользуемся сетью на скорости 100 Мбит/с.

5. Список литературы 6. Приложения
dhclient-script.patch.txt
Патч для dhclient-script
(754 байт) 68 скачиваний
dhclient-exit-hooks.txt
Скрипт для разбора и обработки опции "Бесклассовые маршруты"
(1.06 КБ) 78 скачиваний

Хостинговая компания 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/



Аватара пользователя
BlackCat
прапорщик
Сообщения: 469
Зарегистрирован: 2007-10-16 22:40:42

Re: Заметка: Бесклассовые маршруты DHCP

Непрочитанное сообщение BlackCat » 2010-08-17 4:02:55

Проходил мимо писал(а):Вот ссылка на работающие патчи, для штатного dhcp
Хм, а парсер маршрутов оригинальнее, чем мой.
Спасибо за ссылки - познавательно.