D-LINK DHCP Relay option 82: различия между версиями
Sirmax (обсуждение | вклад) (Новая: =Настройка коммутатора Д-линк =) |
Sirmax (обсуждение | вклад) |
||
| (не показаны 74 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
| + | [[Категория:DlinkSwitch]] |
||
| + | [[Категория:DHCP]] |
||
| + | [[Категория:Switch]] |
||
=Настройка коммутатора Д-линк = |
=Настройка коммутатора Д-линк = |
||
| + | Задача: настроить коммутатор для релеинга DHCP-запросов с включением в них опции 82. |
||
| + | На основании значения опции 82 выдавать раздичные адреса для разных вланов/портов/коммутатров. |
||
| + | |||
| + | ==Настройки коммутатора== |
||
| + | <PRE> |
||
| + | 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 |
||
| + | |||
| + | </PRE> |
||
| + | |||
| + | <PRE> |
||
| + | 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 |
||
| + | </PRE> |
||
| + | http://xgu.ru/wiki/%D0%9E%D0%BF%D1%86%D0%B8%D1%8F_82_DHCP |
||
| + | |||
| + | =Настойка DHCPd= |
||
| + | ==DHCP - пакет (детально)== |
||
| + | <PRE> |
||
| + | 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 |
||
| + | </PRE> |
||
| + | |||
| + | Меня в первую очередь интересует Option 82 |
||
| + | <PRE> |
||
| + | 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 |
||
| + | </PRE> |
||
| + | |||
| + | И с другого свитча (но с такими же настройками, для сравнения) |
||
| + | <PRE> |
||
| + | 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 |
||
| + | </PRE> |
||
| + | |||
| + | ==Формат поля DHCP option 82 для DES-35XX:== |
||
| + | ===Поле Circuit ID=== |
||
| + | Формат поля опции с Circuit ID - в ней указывается порт коммутатора, за которым находится клиент и VID соответствующего VLAN: |
||
| + | (Взято с Dlink.ru) |
||
| + | <TABLE border=1> |
||
| + | <TR> |
||
| + | <TD>1</TD><TD>2</TD><TD>3</TD><TD>4</TD><TD>5</TD><TD>6</TD><TD>7</TD> |
||
| + | </TR> |
||
| + | <TR> |
||
| + | <TD>Тип опции=1</TD><TD>Длина=6</TD><TD>Тип Circuit ID=0</TD><TD>Длина=4</TD><TD>VLAN ID</TD><TD>Module</TD><TD>Port</TD> |
||
| + | <TR> |
||
| + | <TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>2 байта</TD><TD>1 байт</TD><TD>1 байт</TD> |
||
| + | </TR> |
||
| + | </TABLE> |
||
| + | |||
| + | *Module : Для автономного коммутатора, поле Module всегда 0; для стекируемого коммутатора, Module = Unit ID. |
||
| + | *Port : Порт коммутатора, с которого получен DHCP-запрос (начинается с 1) port |
||
| + | |||
| + | Сравним с тем что получено от коммутатора |
||
| + | Agent Circuit ID: 000408BC0001 |
||
| + | Т.е. фактически, первые 2 байта нужно просто отбросить и нигде не учитывать (при вычислении сдвигов, и т.п.) (почему так?) |
||
| + | |||
| + | <TABLE border=1> |
||
| + | <TR> |
||
| + | <TD>1</TD><TD>2</TD><TD>3</TD><TD>4</TD><TD>5</TD><TD>6</TD><TD>7</TD> |
||
| + | </TR> |
||
| + | <TR> |
||
| + | <TD>Тип опции=01 (hex)</TD><TD>Длина=06 (hex)</TD><TD>Тип Circuit ID=00 (hex)</TD><TD>Длина=04 (hex) </TD><TD>VLAN ID=08BC (hex)</TD><TD>Module (=00) (hex)</TD><TD>Port=01 (hex)</TD> |
||
| + | </TR> |
||
| + | <TR> |
||
| + | <TD>Тип опции=01 (dec)</TD><TD>Длина=06 (dec)</TD><TD>Тип Circuit ID=00 (dec)</TD><TD>Длина=04 (dec)</TD><TD>VLAN ID=2236 (dec)</TD><TD>Module (=00) (dec)</TD><TD>Port=01 (dec)</TD> |
||
| + | </TR> |
||
| + | <TR> |
||
| + | <TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>2 байта</TD><TD>1 байт</TD><TD>1 байт</TD> |
||
| + | </TR> |
||
| + | </TABLE> |
||
| + | |||
| + | ===Поле Remote ID=== |
||
| + | Формат поля опции с Remote ID - в ней указывается MAC-адрес коммутатора, являющегося агентом DHCP Relay: |
||
| + | |||
| + | |||
| + | <TABLE border=1> |
||
| + | <TR> |
||
| + | <TD>1</TD><TD>2</TD><TD>3</TD><TD>4</TD><TD>5</TD> |
||
| + | </TR> |
||
| + | <TR> |
||
| + | <TD>Тип опции=2</TD><TD>Длина=8</TD><TD>Тип Тип Remote ID=0</TD><TD>Длина=4</TD><TD>Agent ID</TD> |
||
| + | <TR> |
||
| + | <TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>1 байт</TD><TD>6 байт</TD> |
||
| + | </TR> |
||
| + | </TABLE> |
||
| + | |||
| + | 1. Тип опции 2. Длина 3. Тип Remote ID type 4. Длина |
||
| + | 5. Agent ID : Строкк, по умолчанию - мак-адресс коммутатора, в моем примере - ip-адресс |
||
| + | |||
| + | Remote ID = 020F010D3137322E32392E31342E3132 |
||
| + | |||
| + | Аналогично с Circit ID, первые 2 байта отбросить ... |
||
| + | |||
| + | (аналогично для DES-3028, DES-3052, вероятно для DES-3528) |
||
| + | |||
| + | ==Конфигурирование DHCPd== |
||
| + | ===Базовый конфиг=== |
||
| + | <PRE> |
||
| + | 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; |
||
| + | </PRE> |
||
| + | ===Правила написания классов=== |
||
| + | |||
| + | '''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. |
||
| + | |||
| + | Пример: |
||
| + | <PRE> |
||
| + | concat (binary-to-ascii (10, 8, ".", |
||
| + | reverse (1, leased-address)), |
||
| + | ".in-addr.arpa."); |
||
| + | </PRE> |
||
| + | Берём адрес ''leased-address'', инвертируем его, а потом делим на |
||
| + | 8 битные числа, каждые из которых преобразуем в 10-чную систему счисления. |
||
| + | Полученные числа объединяем между собой через "." и присоединяем |
||
| + | ".in-addr.arpa." справа. |
||
| + | |||
| + | Дополнительная информация: |
||
| + | * man dhcp-eval — описано как создавать такие выражения и описаны другие операторы. |
||
| + | |||
| + | |||
| + | |||
| + | ====match-vlan==== |
||
| + | Следующему классу будут соответвовать все запросы из VLAN 2236. Читать эту запись следует так:из circuit-id выделить 2 байта по смещению 2, перевести в десятичный вид и сравнить с 2236 |
||
| + | <PRE> |
||
| + | class "match_vlan_2236" |
||
| + | { |
||
| + | match if ( binary-to-ascii(10, 16, "", substring(option agent.circuit-id, 2, 2)) = "2236"); |
||
| + | } |
||
| + | </PRE> |
||
| + | ====match-port==== |
||
| + | Пример класса в котором проверяется соответвие номера влана и номера порта |
||
| + | <PRE> |
||
| + | 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" |
||
| + | ); |
||
| + | } |
||
| + | </PRE> |
||
| + | |||
| + | ====match-hw-address==== |
||
| + | Класс в котором проверяется МАК-адрес, номер порта и номер влана |
||
| + | <PRE> |
||
| + | 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" |
||
| + | ); |
||
| + | } |
||
| + | </PRE> |
||
| + | |||
| + | ====match-remote-id==== |
||
| + | Класс в котром проверяется номер влана, номер порта, МАК-адрес и ID коммутатора. |
||
| + | В примере ID коммутатора совпадает с его IP хотя фактически - является просто строкой, и может принимать любые строковые значения. |
||
| + | <PRE> |
||
| + | 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" |
||
| + | ); |
||
| + | } |
||
| + | </PRE> |
||
| + | |||
| + | ===Логгирование=== |
||
| + | <PRE> |
||
| + | 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)) |
||
| + | ) |
||
| + | ); |
||
| + | } |
||
| + | </PRE> |
||
| + | |||
| + | ===Пулы=== |
||
| + | Описываем адреса котрые будем выдавать соответвующим классам |
||
| + | <PRE> |
||
| + | 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"; |
||
| + | } |
||
| + | } |
||
| + | } |
||
| + | </PRE> |
||
| + | |||
| + | Пример не идеален, и если запрос соответвует нескольким классам то попадет в первый. |
||
| + | |||
| + | =Благодарности= |
||
| + | Спасибо:<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)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| Тип опции=1 | Длина=6 | Тип Circuit ID=0 | Длина=4 | VLAN ID | Module | Port |
| 1 байт | 1 байт | 1 байт | 1 байт | 2 байта | 1 байт | 1 байт |
- Module : Для автономного коммутатора, поле Module всегда 0; для стекируемого коммутатора, Module = Unit ID.
- Port : Порт коммутатора, с которого получен DHCP-запрос (начинается с 1) port
Сравним с тем что получено от коммутатора Agent Circuit ID: 000408BC0001 Т.е. фактически, первые 2 байта нужно просто отбросить и нигде не учитывать (при вычислении сдвигов, и т.п.) (почему так?)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| Тип опции=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:
| 1 | 2 | 3 | 4 | 5 |
| Тип опции=2 | Длина=8 | Тип Тип Remote ID=0 | Длина=4 | Agent 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
Даниил Подольский