Поиск по этому блогу

четверг, 27 октября 2016 г.

RouterOS та передача маршрутної інформації у DHCP

Певно, що тим, хто читає цей нотаток, відомо, що у DHCP можна передавати окрім всього іншого й маршрутну інформацію. Тут розглянемо як це робиться у RouterOS та намалюємо маленький скрипт який допоможе в цій роботі у подальшому.

RFC3442 має назву The Classless Static Route Option for Dynamic Host Configuration Protocol (DHCP) version 4 і описує формат опції 121, в якій передається маршрутна інформація. Для тієї самої задачі слугує й опція 249, але про неї окремо.

Формат опції у RFC виглядає так:
  Code Len Destination 1    Router 1
   +-----+---+----+-----+----+----+----+----+----+
   | 121 | n | d1 | ... | dN | r1 | r2 | r3 | r4 |
   +-----+---+----+-----+----+----+----+----+----+

    Destination 2       Router 2
   +----+-----+----+----+----+----+----+
   | d1 | ... | dN | r1 | r2 | r3 | r4 |
   +----+-----+----+----+----+----+----+
Тобто маємо безпосередньо код опції, наступний байт це кількість мережевих бітів (маска мережі), потім йдуть октети, що описують номер мережі та 4 байти/октети, що описують маршрутизатор через який має бути побудовано маршрут. Також у RFC читаємо, що для декількох маршрутів вони можуть бути склеєні.

Окрему увагу заслуговує кількість Destination октетів. У RFC можна побачити наступне:
        Width of subnet mask     Number of significant octets
                     0                     0
                  1- 8                     1
                  9-16                     2
                 17-24                     3
                 25-32                     4
Це все справедливо як для опції 121 так і для опції 249. Єдине зауваження щодо опції 249, яке знайшов на хабрі, те, що до маршрутної інформації варто додавати 00[адреса шлюзу]. Пишуть, що це справедливо для комп'ютерів під керуванням ОС Windows.

Все це була не дуже цікава, але не менш важлива теорія, приступимо до практики.

Озброївшись знаннями з RFC3442 можна доволі швидко написати додаток, що буде обчислювати маршрути й формувати відповідний вивід. Я полюбляю Perl тому скрипт було написано саме на ньому, https://github.com/oldengremlin/route-4-dhcp/blob/master/rfc3442.route-4-dhcp.pl:

Поставимо на меті описати маршрут на мережі RFC1918 через /dev/null. Взагалі то було б непогано змаршрутизувати їх через 127.0.0.1, але ж через описані опції маршрути можуть бути додано лише через ті адреси до яких клієнт може знати як дістатися. Тому, припустимо, що у нашій мережі 192.168.88.0/24 не існує хоста 192.168.88.2, а трафік пустимо через нього.

Назвемо скрипт rfc3442.route-4-dhcp та запустимо його з параметрами:
$ rfc3442.route-4-dhcp 10.0.0.0/8 192.168.88.2 172.16.0.0/12 192.168.88.2 192.168.0.0/16 192.168.88.2
option_121_route_10.0.0.0/8_via_192.168.88.2 : 0x080ac0a85802
option_249_route_10.0.0.0/8_via_192.168.88.2 : 0x080ac0a85802
option_121_route_172.16.0.0/12_via_192.168.88.2 : 0x0cac10c0a85802
option_249_route_172.16.0.0/12_via_192.168.88.2 : 0x0cac10c0a85802
option_121_route_192.168.0.0/16_via_192.168.88.2 : 0x10c0a8c0a85802
option_249_route_192.168.0.0/16_via_192.168.88.2 : 0x10c0a8c0a85802
aggregate_opt_121 : 0x080ac0a858020cac10c0a8580210c0a8c0a85802
aggregate_opt_249 : 0x080ac0a858020cac10c0a8580210c0a8c0a85802

Передаємо скрипту пари у вигляді мережа-шлюз і отримуємо попарний вивід для окремих мереж і останніми строками сукупну маршрутну інформацію для всіх мереж.

Тепер перенесемо всю цю інформацію у RouterOS:
/ip dhcp-server option
add code=121 name=aggregate_opt_121_over_fakeip_192.168.88.2 value=0x080ac0a858020cac10c0a8580210c0a8c0a85802
add code=249 name=aggregate_opt_249_over_fakeip_192.168.88.2 value=0x080ac0a858020cac10c0a8580210c0a8c0a8580200c0a85801

Щодо опції 249 читаємо зауваження нагорі і дивимося як було додано маршрут через основну адресу маршрутизатора - 192.168.88.1.

Опції задано, тепер їх можна додати у список опцій у описі мережі в налаштуваннях dhcp-серверу. Якщо у dhcp-сервері вже було налаштовано передачу інформації щодо wpad то разом з маршрутною інформацією команда налаштування мережі може виглядати якось так:
/ip dhcp-server network
add address=192.168.88.0/24 comment=dhcp-server dhcp-option=\
    auto-proxy-config,aggregate_opt_121_over_fakeip_192.168.88.2,aggregate_opt_249_over_fakeip_192.168.88.2,disable_nbt dns-server=\
    192.168.88.1 gateway=192.168.88.1 netmask=24 ntp-server=192.168.88.1

Домашнім завданням може бути написання скрипту якій розшифровує 0x080ac0a858020cac10c0a8580210c0a8c0a85802 у зворотньому напрямку ;)