D-LINK DHCP Relay option 82: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
 
(не показано 12 промежуточных версий этого же участника)
Строка 1: Строка 1:
  +
[[Категория:DlinkSwitch]]
  +
[[Категория:DHCP]]
  +
[[Категория:Switch]]
 
=Настройка коммутатора Д-линк =
 
=Настройка коммутатора Д-линк =
 
Задача: настроить коммутатор для релеинга DHCP-запросов с включением в них опции 82.
 
Задача: настроить коммутатор для релеинга DHCP-запросов с включением в них опции 82.
Строка 197: Строка 200:
 
Сравним с тем что получено от коммутатора
 
Сравним с тем что получено от коммутатора
 
Agent Circuit ID: 000408BC0001
 
Agent Circuit ID: 000408BC0001
Т.е. фактически, первые 2 байта нужно просто отбросить и нигде изх не учитывать (при вычислении сдвигов, и т.п.) (почему так?)
+
Т.е. фактически, первые 2 байта нужно просто отбросить и нигде не учитывать (при вычислении сдвигов, и т.п.) (почему так?)
   
 
<TABLE border=1>
 
<TABLE border=1>
Строка 251: Строка 254:
 
ignore client-updates;
 
ignore client-updates;
 
</PRE>
 
</PRE>
===Примеры написания классов===
+
===Правила написания классов===
   
 
'''suffix (data-expr, length)'''
 
'''suffix (data-expr, length)'''
Строка 295: Строка 298:
 
* man dhcp-eval — описано как создавать такие выражения и описаны другие операторы.
 
* man dhcp-eval — описано как создавать такие выражения и описаны другие операторы.
   
=== Просмотр информации на коммутаторе ===
 
Надо знать, каким образом кодируется номер порта коммутатора, чтобы затем правильно распознавать номера в пришедших запросах.
 
   
Например, в коммутаторе [[ProCurve]] опция 82 выглядит следующим образом:
 
<pre>
 
Value: 010200030206001560792800
 
Agent Circuit ID: 0003
 
Agent Remote ID: 001560792800
 
</pre>
 
В коммутаторах других производителей
 
она выглядит аналогично.
 
 
Для того чтобы увидеть, каким образом кодируются номера портов в коммутаторе Procurve, необходимо выполнить команду:
 
<pre>
 
sw(config)# walkMIB ifname
 
ifName.1 = 1
 
ifName.2 = 2
 
ifName.3 = 3
 
ifName.4 = 4
 
ifName.5 = 5
 
ifName.6 = 6
 
ifName.7 = 7
 
ifName.8 = 8
 
ifName.9 = 9
 
ifName.10 = 10
 
ifName.11 = 11
 
..............
 
ifName.47 = 47
 
ifName.48 = 48
 
ifName.102 = DEFAULT_VLAN
 
ifName.103 = VLAN2
 
ifName.4197 = lo0
 
</pre>
 
 
Информация о MAC-адресе коммутатора:
 
<pre>
 
sw# sh system-information
 
 
Status and Counters - General System Information
 
 
System Name : sw
 
System Contact :
 
System Location :
 
 
MAC Age Time (sec) : 300
 
 
Time Zone : 0
 
Daylight Time Rule : None
 
 
 
Firmware revision : M.10.06 Base MAC Addr : 001560-792800
 
ROM Version : I.08.11 Serial Number : SG602SG00C
 
 
Up Time : 2 days Memory - Total : 94,690,424
 
CPU Util (%) : 6 Free : 80,214,320
 
 
IP Mgmt - Pkts Rx : 10,267 Packet - Total : 1998
 
Pkts Tx : 7874 Buffers Free : 1483
 
Lowest : 1473
 
Missed : 0
 
</pre>
 
 
=== Примеры правил ===
 
 
Указываем, что нас интересует последний байт в circuit-id:
 
<pre>
 
suffix( option agent.circuit-id, 1)
 
</pre>
 
 
Делаем преобразование вырезанного байта из двоичного формата в десятичный и указываем, что запрос попадет под правило класса, если результат преобразования будет равен 5.
 
 
Правило для порта 5.
 
<pre>
 
class "port-5"
 
{
 
match if binary-to-ascii (10, 8, "", suffix( option agent.circuit-id, 1)) = "5";
 
}
 
 
pool {
 
range 192.168.1.155;
 
allow members of "port-5";
 
}
 
</pre>
 
 
Аналогично для порта 45:
 
<pre>
 
class "port-45"
 
{
 
match if binary-to-ascii (10, 8, "", suffix( option agent.circuit-id, 1)) = "45";
 
}
 
 
pool {
 
range 192.168.1.45;
 
allow members of "port-45";
 
}
 
</pre>
 
 
Эти правила могут отличаться при использовании как коммутаторов других производителей,
 
так и при использовании модульных коммутаторов ProCurve.
 
Необходимо выяснять каким образом кодируется номер порта.
 
 
Если нам необходимо учитывать от какого relay-агента пришел запрос, то можно создать соответствующее правило:
 
<pre>
 
class "relay-1"
 
{
 
match if binary-to-ascii (16, 8, ":", suffix ( option agent.remote-id, 6)) = "00:15:60:79:28:00";
 
}
 
</pre>
 
 
{{caution|text=
 
Если нужно привязать IP-адреса не к портам коммутатора,
 
а к самим коммутаторам как таковым,
 
учитывать порт, с которого пришел DHCP-запрос (Agent Circuit ID), не обязательно, а важно настроить совпадение MAC-адреса или IP-адреса DHCP-ретранслятора (Agent Remote ID) в пришедшей опции 82.
 
}}
 
 
=== Пример конфигурационного файла DHCP-сервера ===
 
<pre>
 
ddns-update-style none;
 
default-lease-time 600;
 
max-lease-time 7200;
 
log-facility local7;
 
local-address 192.168.2.9;
 
if exists agent.circuit-id
 
{
 
 
log ( info, concat( "Lease for ", binary-to-ascii (10, 8, ".", leased-address),
 
" raw option-82 info is CID: ", binary-to-ascii (10, 8, ".", option agent.circuit-id), " AID: ",
 
binary-to-ascii(16, 8, ".", option agent.remote-id)));
 
}
 
subnet 192.168.2.0 netmask 255.255.255.0 {
 
range 192.168.2.20 192.168.2.40;
 
allow unknown-clients;
 
}
 
 
subnet 192.168.1.0 netmask 255.255.255.0 {
 
class "port-5" {
 
match if binary-to-ascii (10, 8, "", suffix( option agent.circuit-id, 1)) = "5";
 
}
 
class "port-3" {
 
match if binary-to-ascii (10, 8, "", suffix( option agent.circuit-id, 1)) = "3";
 
}
 
class "port-45" {
 
match if binary-to-ascii (10, 8, "", suffix( option agent.circuit-id, 1)) = "45";
 
}
 
 
pool {
 
range 192.168.1.155;
 
allow members of "port-5";
 
}
 
pool {
 
range 192.168.1.133;
 
allow members of "port-3";
 
}
 
pool {
 
range 192.168.1.45;
 
allow members of "port-45";
 
}
 
}
 
</pre>
 
   
 
====match-vlan====
 
====match-vlan====
Строка 553: Строка 398:
   
 
Пример не идеален, и если запрос соответвует нескольким классам то попадет в первый.
 
Пример не идеален, и если запрос соответвует нескольким классам то попадет в первый.
  +
  +
=Благодарности=
  +
Спасибо:<BR>
  +
[http://vorona.com.ua Voron]<BR>
  +
Даниил Подольский

Текущая версия на 12:42, 11 февраля 2021

Настройка коммутатора Д-линк

Задача: настроить коммутатор для релеинга DHCP-запросов с включением в них опции 82. На основании значения опции 82 выдавать раздичные адреса для разных вланов/портов/коммутатров.

Настройки коммутатора

create vlan vlanid 2236
config vlan vlanid 2236 add untagged 1-24
config vlan vlanid 2236 add tagged 25-26
create vlan vlanid 3002
config vlan vlanid 3002 add tagged 25-26
config ipif System ipaddress 172.29.14.122/24 vlan VLAN3002
create iproute default 172.29.14.1

enable dhcp_relay
config dhcp_relay hops 4 time 0
config dhcp_relay option_82 state enable
config dhcp_relay option_82 check disable
config dhcp_relay option_82 policy replace
config dhcp_relay option_82 remote_id user_define "172.29.14.122"
config dhcp_relay option_60 state disable
config dhcp_relay option_60 default mode drop
config dhcp_relay option_61 state disable
config dhcp_relay option_61 default drop
config dhcp_relay add ipif System 172.29.14.1

http://xgu.ru/wiki/%D0%9E%D0%BF%D1%86%D0%B8%D1%8F_82_DHCP

Настойка DHCPd

DHCP - пакет (детально)

tshark -V ...


Frame 19 (366 bytes on wire, 366 bytes captured)
    Arrival Time: Mar  9, 2009 15:24:42.257042000
    [Time delta from previous captured frame: 15.000093000 seconds]
    [Time delta from previous displayed frame: 15.000093000 seconds]
    [Time since reference or first frame: 780.215513000 seconds]
    Frame Number: 19
    Frame Length: 366 bytes
    Capture Length: 366 bytes
    [Frame is marked: False]
    [Protocols in frame: eth:ip:udp:bootp]
Ethernet II, Src: D-Link_17:c6:28 (00:1c:f0:17:c6:28), Dst: IntelCor_06:8b:c7 (00:1c:c0:06:8b:c7)
    Destination: IntelCor_06:8b:c7 (00:1c:c0:06:8b:c7)
        Address: IntelCor_06:8b:c7 (00:1c:c0:06:8b:c7)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Source: D-Link_17:c6:28 (00:1c:f0:17:c6:28)
        Address: D-Link_17:c6:28 (00:1c:f0:17:c6:28)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
    Type: IP (0x0800)
Internet Protocol, Src: 172.29.14.122 (172.29.14.122), Dst: 172.29.14.1 (172.29.14.1)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 352
    Identification: 0x00c6 (198)
    Flags: 0x00
        0... = Reserved bit: Not set
        .0.. = Don't fragment: Not set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 128
    Protocol: UDP (0x11)
    Header checksum: 0xc411 [correct]
        [Good: True]
        [Bad : False]
    Source: 172.29.14.122 (172.29.14.122)
    Destination: 172.29.14.1 (172.29.14.1)
User Datagram Protocol, Src Port: bootpc (68), Dst Port: bootps (67)
    Source port: bootpc (68)
    Destination port: bootps (67)
    Length: 332
    Checksum: 0x4a5c [correct]
        [Good Checksum: True]
        [Bad Checksum: False]
Bootstrap Protocol
    Message type: Boot Request (1)
    Hardware type: Ethernet
    Hardware address length: 6
    Hops: 1
    Transaction ID: 0xa9dbdf39
    Seconds elapsed: 28 (little endian bug?)
    Bootp flags: 0x8000 (Broadcast)
        1... .... .... .... = Broadcast flag: Broadcast
        .000 0000 0000 0000 = Reserved flags: 0x0000
    Client IP address: 0.0.0.0 (0.0.0.0)
    Your (client) IP address: 0.0.0.0 (0.0.0.0)
    Next server IP address: 0.0.0.0 (0.0.0.0)
    Relay agent IP address: 172.29.14.122 (172.29.14.122)
    Client MAC address: Dell_95:8d:8b (00:1c:23:95:8d:8b)
    Server host name not given
    Boot file name not given
    Magic cookie: (OK)
    Option: (t=53,l=1) DHCP Message Type = DHCP Discover
        Option: (53) DHCP Message Type
        Length: 1
        Value: 01
    Option: (t=116,l=1) DHCP Auto-Configuration
        Option: (116) DHCP Auto-Configuration
        Length: 1
        Value: 01
    Option: (t=61,l=7) Client identifier
        Option: (61) Client identifier
        Length: 7
        Value: 01001C23958D8B
        Hardware type: Ethernet
        Client MAC address: Dell_95:8d:8b (00:1c:23:95:8d:8b)
    Option: (t=50,l=4) Requested IP Address = 169.254.86.169
        Option: (50) Requested IP Address
        Length: 4
        Value: A9FE56A9
    Option: (t=12,l=6) Host Name = "tester"
        Option: (12) Host Name
        Length: 6
        Value: 746573746572
    Option: (t=60,l=8) Vendor class identifier = "MSFT 5.0"
        Option: (60) Vendor class identifier
        Length: 8
        Value: 4D53465420352E30
    Option: (t=55,l=11) Parameter Request List
        Option: (55) Parameter Request List
        Length: 11
        Value: 010F03062C2E2F1F21F92B
        1 = Subnet Mask
        15 = Domain Name
        3 = Router
        6 = Domain Name Server
        44 = NetBIOS over TCP/IP Name Server
        46 = NetBIOS over TCP/IP Node Type
        47 = NetBIOS over TCP/IP Scope
        31 = Perform Router Discover
        33 = Static Route
        249 = Classless Static Route (Microsoft)
        43 = Vendor-Specific Information
    Option: (t=43,l=2) Vendor-Specific Information
        Option: (43) Vendor-Specific Information
        Length: 2
        Value: DC00
    Option: (t=82,l=25) Agent Information Option
        Option: (82) Agent Information Option
        Length: 25
        Value: 0106000408BC0001020F010D3137322E32392E31342E3132...
        Agent Circuit ID: 000408BC0001
        Agent Remote ID: 010D3137322E32392E31342E313232
    End Option

Меня в первую очередь интересует Option 82

    Option: (t=82,l=25) Agent Information Option
        Option: (82) Agent Information Option
        Length: 25
        Value: 0106000408BC0001020F010D3137322E32392E31342E3132...
        Agent Circuit ID: 000408BC0001
        Agent Remote ID: 010D3137322E32392E31342E313232

И с другого свитча (но с такими же настройками, для сравнения)

    Option: (t=82,l=25) Agent Information Option
        Option: (82) Agent Information Option
        Length: 25
        Value: 0106000408BC0001020F010D3137322E32392E31342E3132...
        Agent Circuit ID: 000408BC0001
        Agent Remote ID: 010D3137322E32392E31342E313232
    End Option

Формат поля DHCP option 82 для DES-35XX:

Поле Circuit ID

Формат поля опции с Circuit ID - в ней указывается порт коммутатора, за которым находится клиент и VID соответствующего VLAN: (Взято с Dlink.ru)

1234567
Тип опции=1Длина=6Тип Circuit ID=0Длина=4VLAN IDModulePort
1 байт1 байт1 байт1 байт2 байта1 байт1 байт
  • Module : Для автономного коммутатора, поле Module всегда 0; для стекируемого коммутатора, Module = Unit ID.
  • Port : Порт коммутатора, с которого получен DHCP-запрос (начинается с 1) port

Сравним с тем что получено от коммутатора Agent Circuit ID: 000408BC0001 Т.е. фактически, первые 2 байта нужно просто отбросить и нигде не учитывать (при вычислении сдвигов, и т.п.) (почему так?)

1234567
Тип опции=01 (hex)Длина=06 (hex)Тип Circuit ID=00 (hex)Длина=04 (hex) VLAN ID=08BC (hex)Module (=00) (hex)Port=01 (hex)
Тип опции=01 (dec)Длина=06 (dec)Тип Circuit ID=00 (dec)Длина=04 (dec)VLAN ID=2236 (dec)Module (=00) (dec)Port=01 (dec)
1 байт1 байт1 байт1 байт2 байта1 байт1 байт

Поле Remote ID

Формат поля опции с Remote ID - в ней указывается MAC-адрес коммутатора, являющегося агентом DHCP Relay:


12345
Тип опции=2Длина=8Тип Тип Remote ID=0Длина=4Agent ID
1 байт1 байт1 байт1 байт6 байт

1. Тип опции 2. Длина 3. Тип Remote ID type 4. Длина 5. Agent ID  : Строкк, по умолчанию - мак-адресс коммутатора, в моем примере - ip-адресс

Remote ID = 020F010D3137322E32392E31342E3132

Аналогично с Circit ID, первые 2 байта отбросить ...

(аналогично для DES-3028, DES-3052, вероятно для DES-3528)

Конфигурирование DHCPd

Базовый конфиг

lease-file-name            "/var/lib/dhcp/dhcpd.leases";
option domain-name-servers 193.33.**.**,193.33.**.**;
local-address              172.29.14.1;
log-facility               local7;

authoritative;
ddns-update-style          none;

ignore                     client-updates;

Правила написания классов

suffix (data-expr, length)

Оператор suffix анализирует выражение data-expr и возвращает последние байты в указанном количестве. length — это числовое значение. Если data-expr или length равны нулю, то результат также будет равен 0. Если длина указанная в length больше чем сами данные, то suffix возвращает все данные.


substring (data-expr, offset, length)

Оператор substring анализирует данные и возвращает строку данных, которая начинается от указанного значения offset и имеет длину, равную указанной в length. Offset и length — числовые выражения. Если data-expr, offset или length равны нулю, то результат также равен 0. Если значение offset больше или равно длине data-expr, то будет возвращена нулевая строка. Если длина length больше чем длина данных оставшихся после offset, тогда возвращаемая строка будет содержать все данные от значения offset до конца.


binary-to-ascii (numeric-expr1, numeric-expr2, data-expr1, data-expr2)

Преобразует результат вычисления data-expr2 в текстовую строку, содержащую по одному числу для каждого элемента результата вычисления data-expr2. Числа разделены между собой результатом вычисления data-expr1. Параметр numeric-expr1 указывает основание системы исчисления (от 2 до 16), в которую должны преобразовываться числа. Параметр numeric-expr2 указывает количество битов на каждое число, полученное в результате преобразования. Оно может быть равно 8, 16 или 32.

Пример:

               concat (binary-to-ascii (10, 8, ".",
                               reverse (1, leased-address)),
                      ".in-addr.arpa.");

Берём адрес leased-address, инвертируем его, а потом делим на 8 битные числа, каждые из которых преобразуем в 10-чную систему счисления. Полученные числа объединяем между собой через "." и присоединяем ".in-addr.arpa." справа.

Дополнительная информация:

  • man dhcp-eval — описано как создавать такие выражения и описаны другие операторы.


match-vlan

Следующему классу будут соответвовать все запросы из VLAN 2236. Читать эту запись следует так:из circuit-id выделить 2 байта по смещению 2, перевести в десятичный вид и сравнить с 2236

class "match_vlan_2236"
{
      match if ( binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 2, 2)) = "2236");
}

match-port

Пример класса в котором проверяется соответвие номера влана и номера порта

class "match_vlan_2236_port3"
{
      match if (
        binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 2, 2)) = "2236"
        and binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 4, 2)) = "3"
    );
}

match-hw-address

Класс в котором проверяется МАК-адрес, номер порта и номер влана

class "match_vlan_2236_port4_0:14:22:8d:ca:a6"
{
      match if (
        binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 2, 2)) = "2236"
        and binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 4, 2)) = "4"
        and binary-to-ascii(16,  8, ":", substring(hardware,                1, 6)) = "0:14:22:8d:ca:a6"
    );
}

match-remote-id

Класс в котром проверяется номер влана, номер порта, МАК-адрес и ID коммутатора. В примере ID коммутатора совпадает с его IP хотя фактически - является просто строкой, и может принимать любые строковые значения.

class "match_vlan_2236_port2_0:14:22:8d:ca:a6_sw_172.29.14.122"
{
      match if (
        binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 2, 2)) = "2236"
        and binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 4, 2)) = "2"
        and binary-to-ascii(16,  8, ":", substring(hardware,                1, 6)) = "0:14:22:8d:ca:a6"
        and substring(option agent.remote-id, 2, 15) = "172.29.14.122"
    );
}

Логгирование

if exists agent.circuit-id
  {
  log(info, concat("Lease"
                   ," IP ",     binary-to-ascii(10,  8, ".", leased-address)
                   ," MAC ",    binary-to-ascii(16,  8, ":", substring(hardware,                1, 6))
                   ," switch ", substring(option agent.remote-id, 2, 15)
                   ," port ",   binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 4, 2))
                   ," VLAN ",   binary-to-ascii(10, 16, "",  substring(option agent.circuit-id, 2, 2))
                  )
     );
  }

Пулы

Описываем адреса котрые будем выдавать соответвующим классам

shared-network "clients" {
    subnet 172.29.14.0  netmask 255.255.255.0 { }

    subnet 192.168.201.0 netmask 255.255.255.0 {
        option subnet-mask 255.255.255.0;
        option broadcast-address 192.168.201.255;
        option routers 192.168.201.254;

        pool {
            range 192.168.201.2;
            allow members of "match_vlan_2236";
        }

        pool {
            range 192.168.201.3;
            allow members of "match_vlan_2236_port3";
        }

        pool {
            range 192.168.201.4;
            allow members of "match_vlan_2236_port4_0:14:22:8d:ca:a6";
        }

        pool {
            range 192.168.201.5;
            allow members of "match_vlan_2236_port2_0:14:22:8d:ca:a6_sw_172.29.14.122";
        }
    }
}

Пример не идеален, и если запрос соответвует нескольким классам то попадет в первый.

Благодарности

Спасибо:
Voron
Даниил Подольский