Користувальницькькі налаштування

Налаштування сайту


Сайдбар

Розділи

Загальний опис
Історія змін
Рекомендації щодо оновлення
Плани на майбутнє
Відомі проблеми
Онлайн демо
Допомога проєкту
Люди
Трохи про безпеку

FAQ



Редагувати сайдбар

option82

Mini FAQ

Q: Що потрібно від свіча, щоб запрацювала option 82?
A: Мати налаштований і працюючий dhcp relay з увімкненою option 82, dhcp snooping, що не пропускає клієнтські запити в обхід рілею, та ip source guard, що дропає пакети для айпішок, які не отримано крізь рілей.\\.

Q: На яких свічах має бути рілей?
A: На всіх - рівня доступу.

Q: У нас тут пів мережі на мильницях, це буде працювати? А можна тримати частину мережі на IP+MAC та іншу частину на option 82?
A: Сталася критична помилка - у вас недостатньо грошей для використання цього функціоналу.

Налаштування Ubilling та DHCP option 82

Для того, щоб усе запрацювало в базовому варіанті, нам потрібно виконати шість простих кроків:

1. Підмережу користувачів додано як:

ID Початкова ІР Остання ІР Мережа/CIDR Тип мережі
1 172.16.0.0 172.16.0.255 172.16.0.0/24 dhcp82

2. /etc/rc.conf виглядає наступним чином

rc.conf
ifconfig_em0="inet 172.16.0.1 netmask 255.255.255.0"
ifconfig_em0_alias0="inet 172.32.0.1 netmask 255.255.240.0"
ifconfig_em0_alias1="inet 192.168.94.1 netmask 255.255.255.0"

3. Шаблон config/dhcp/global.template

global.template
option domain-name "ourisp";
option domain-name-servers 172.16.0.1;
default-lease-time 3600;
max-lease-time 43200;
authoritative;
ddns-update-style none;
log-facility local7;
one-lease-per-client true;
deny duplicates;
 
shared-network ourisp {
 
{SUBNETS}
 
subnet 192.168.94.0 netmask 255.255.255.0 {
}
 
subnet 172.32.0.0 netmask 255.255.240.0 {
  default-lease-time 3600;
  option domain-name "isp";
  option subnet-mask 255.255.240.0;
  option domain-name-servers 172.32.0.1;
  option routers 172.32.0.1;
 
  pool {
   range 172.32.0.100 172.32.0.254;
    {DENYMEMBERS}
   }
 
log(info, "==");
if exists agent.remote-id and exists agent.circuit-id {
if binary-to-ascii(16, 8, "", substring(option agent.remote-id, 2, 1)) = "0" {
set switch-mac = concat("0", binary-to-ascii(16, 8, "", substring(option agent.remote-id, 2, 1)), ":", binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 3, 6)));
# log(info,concat("SWITCH-MAC1:",switch-mac));
} else {
# set switch-mac = binary-to-ascii(16, 8, ":", substring(option agent.remote-id, 2, 6));
# log(info,concat("SWITCH-MAC2:",switch-mac));
set switch-mac = concat (
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,2,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,3,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,4,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,5,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,6,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(option agent.remote-id,7,1))),2)
);
# log(info,concat("SWITCH-MAC3:",switch-mac3));
}
set clip = binary-to-ascii(10,8,".",leased-address);
set clremote = binary-to-ascii(16,8,"",option agent.remote-id);
set clcircuit = binary-to-ascii(10,8,"",option agent.circuit-id);
set switch-port = binary-to-ascii(10, 8, "", substring(option agent.circuit-id, 5, 1));
set switch-port-vlan = binary-to-ascii(10, 16, "", substring(option agent.circuit-id, 2, 2));
 
log( info,concat("OPTION82 INFO - SWITCHMAC: ",switch-mac," PORTSW: ",switch-port," VLAN: ",switch-port-vlan));
 
log( info,concat("*Leased IP: ",clip, " SWITCH: ",clremote," PORT: ",clcircuit," SWITCHMAC: ",switch-mac," PORTSW: ",switch-port," VLAN: ",switch-port-vlan," (with opt82)") );
} else {
set clhw = concat (
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
);
 
log( info,concat("*Leased IP: ",binary-to-ascii(10,8,".",leased-address), " MAC: ", clhw," (without opt82)") );
}
log(info, "==");
 
}
 
}

4. Шаблон config/dhcp/option82.template перебуває в дефолтному стані (підтримувані макроси)

5. У конфізі alter.ini встановлено опцію NMLEASES = /var/log/dhcpd.log і налаштовано правильне логування ISP-DHCPD

6. В OnConnect вимкнено прибивання за MAC-у. Тепер це проблема ip source guard і dhcp snooping вашого свіча (192.168.94.4 у прикладі).

Виходячи з усього вищевказаного, не складно зробити висновок, що прив'язка планується за парою повних remote-id/circuit-id. Перевірити поведінку такого конфіга не складно за допомогою наступних нехитрих рухів тіла

Відлагодження scapy

p="\x01\x01\x05\x02\x06\x11\x22\x34\x44\x55\x66"
dhcp_discover =  Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=RandString(12,'0123456789abcdef'))/DHCP(options=[("message-type","discover"),("relay_agent_Information",p),"end"])
sendp(dhcp_discover)

у відповідь на що ми маємо отримати щось на кшталт:

dhcpd.log
Oct 15 00:38:20 test dhcpd: Wrote 0 class decls to leases file.
Oct 15 00:38:20 test dhcpd: Wrote 1 leases to leases file.
Oct 15 00:38:34 test dhcpd: ==
Oct 15 00:38:34 test dhcpd: *Leased IP: 172.16.0.2 SWITCH: 112234445566 PORT: 5 (with opt82)
Oct 15 00:38:34 test dhcpd: ==
Oct 15 00:38:34 test dhcpd: ==
Oct 15 00:38:34 test dhcpd: *Leased IP: 172.16.0.2 SWITCH: 112234445566 PORT: 5 (with opt82)
Oct 15 00:38:34 test dhcpd: ==
Oct 15 00:38:34 test dhcpd: DHCPDISCOVER from 30:32:63:30:35:62 via em0
Oct 15 00:38:35 test dhcpd: DHCPOFFER on 172.16.0.2 to 30:32:63:30:35:62 via em0

а також під час прослуховування за допомогою

tcpdump -n -i em0 -s 0 -v -vv

ми спостерігатимемо прилітаючі до нас

Agent-Information Option 82, length 13: 
              Remote-ID........
	      Circuit-ID.......

Особливості роботи на комутаторах Zyxel

GS-4012, GS-3012 взагалі не повертають remote-id. Тому орієнтуватися варто тільки на sub-option 1 (Agent Circuit ID). Тож при побудові шаблону потрібно керуватися ось цим: http://zyxel.ru/kb/2030

У чорновому варіанті можна оформити це приблизно так:

    set clremote = binary-to-ascii(10,16,"",substring(option agent.circuit-id,4,2));
    set clcircuit = binary-to-ascii(10,16,"",substring(option agent.circuit-id,1,2));

а також виправити option82.template відповідно до цих реалій

що в результаті дає нам такий лог

Oct 15 16:52:00 test dhcpd: ==
Oct 15 16:52:00 test dhcpd: *Leased IP: 172.32.0.100 SWITCH: 18259 PORT: 768 (with opt82)
Oct 15 16:52:00 test dhcpd: ==

Приклад конфігурації Zyxel GS-3012:

ip address inband-default 192.168.94.4 255.255.255.0 
ip address default-gateway 192.168.94.1
interface port-channel 12  
  dhcp snooping trust 
exit 
dhcp smart-relay 
dhcp smart-relay helper-address 192.168.94.1 
dhcp smart-relay option 
dhcp smart-relay information 
dhcp snooping 
dhcp snooping vlan 1  
dhcp snooping vlan 1 option 
dhcp snooping vlan 1 information 
dhcp dhcp-vlan 1 

Спрощення життя

Для зручнішого виловлювання пар remote-id і circuit-id існує сервіс аналогічний UHW, що знаходиться в docs/opt82_uhw. Налаштування в основному аналогічне такому в оригінального сервісу. Ходять чутки, що погрожували дописати ще й самостійну активацію абонентом ;)

Патч для isc-dhcp44-server

Для того, щоб користувачі могли змінювати свої пристрої скільки завгодно разів, і не чекати, поки на сервері закінчиться ліза під їхню адресу, - до DHCP-сервера потрібно застосувати патч і перезібрати пакет із вихідного коду.

--- server/dhcp.c.orig	2017-07-25 16:39:54.000000000 +0300
+++ server/dhcp.c	2017-09-13 00:26:29.330284000 +0300
@@ -31,6 +31,7 @@
 #include <limits.h>
 #include <sys/time.h>
 
+extern int flag_dd_option;
 static void maybe_return_agent_options(struct packet *packet,
 				       struct option_state *options);
 static int reuse_lease (struct packet* packet, struct lease* new_lease,
@@ -4900,8 +4901,13 @@
 		{
 			if (LEASE_NOT_EMPTY(pool->free))
 				candl = LEASE_GET_FIRST(pool->free);
-			else
+			else if (LEASE_NOT_EMPTY(pool->abandoned))
 				candl = LEASE_GET_FIRST(pool->abandoned);
+			else if (flag_dd_option)
+			{
+				candl = LEASE_GET_FIRST(pool->active);
+				candl -> ends = cur_time;
+			}
 		}
 
 		/*
--- server/dhcpd.c.orig	2017-07-25 16:39:54.000000000 +0300
+++ server/dhcpd.c	2017-09-13 03:25:44.556962000 +0300
@@ -57,6 +57,7 @@
 gid_t set_gid = 0;
 #endif /* PARANOIA */
 
+int flag_dd_option = 0;
 struct iaddr server_identifier;
 int server_identifier_matched;
 
@@ -184,6 +185,7 @@
 		  "             [-play trace-input-file]\n"
 #endif /* TRACING */
 		  "             [-pf pid-file] [--no-pid] [-s server]\n"
+		  "             [-dd] - enable dd mode\n"
 		  "             [if0 [...ifN]]",
 		  isc_file_basename(progname));
 }
@@ -329,6 +331,8 @@
 				usage(use_noarg, argv[i-1]);
 			set_chroot = argv [i];
 #endif /* PARANOIA */
+		} else if (!strcmp (argv [i], "-dd")) {
+			flag_dd_option = 1;
 		} else if (!strcmp (argv [i], "-cf")) {
 			if (++i == argc)
 				usage(use_noarg, argv[i-1]);

Після того, як перезібрали пакет та встановили його в системі, необхідно через rc.conf ввімкнути даний функціонал, додавши опцію -dd до параметрів запуску, наприклад:

rc.conf
dhcpd_flags="-q -dd"
option82.txt · Востаннє змінено: 2023/07/08 14:11 повз nightfly