DHCP+Mysql-servilo en Python

DHCP+Mysql-servilo en Python

La celo de ĉi tiu projekto estis:

  • Lerno pri DHCP en IPv4-reto
  • Lernante Python (iom pli ol de nulo 😉)
  • servilo anstataŭigo DB2DHCP (my fork), originalo tie, kiu fariĝas pli kaj pli malfacile kunvenebla por la nova OS. Kaj mi ne ŝatas, ke ĝi estas duuma, ke ne ekzistas maniero "ŝanĝi nun"
  • akirante funkciantan DHCP-servilon kun la kapablo elekti la IP-adreson de abonanto uzante la mac de la abonanto aŭ ŝaltilon mac+havenkombinaĵo (Opcio 82)
  • skribi alian biciklon (Ho! ĉi tio estas mia plej ŝatata agado)
  • ricevante komentojn pri via klubmaneco ĉe Habrahabr (aŭ pli bone, inviton) 😉

Rezulto: ĝi funkcias 😉 Provita ĉe FreeBSD kaj Ubuntu OS. Teorie, la kodo povas esti petita labori sub ajna OS, ĉar Ŝajnas esti neniuj specifaj ligoj en la kodo.
Zorge! Estas multe pli por veni.

Ligo al deponejo por amatoroj "tuŝu vivanta".

La procezo de instalo, agordo kaj uzado de la rezulto de "studado de la aparataro" estas multe pli malalta, kaj tiam iom da teorio pri la DHCP-protokolo. Por mi mem. Kaj por historio 😉

Iom da teorio

Kio estas DHCP

Ĉi tio estas retprotokolo, kiu permesas al aparato ekscii ĝian IP-adreson (kaj aliajn parametrojn kiel enirejo, DNS, ktp.) de DHCP-servilo. Pakoj estas interŝanĝitaj uzante la UDP-protokolon. La ĝenerala principo de funkciado de la aparato dum petado de retaj parametroj estas jena:

  1. La aparato (kliento) sendas UDP-elsendan peton (DHCPDISCOVER) tra la reto kun la peto "nu, iu donu al mi IP-adreson." Krome, kutime (sed ne ĉiam) la peto okazas de haveno 68 (fonto), kaj la celo estas haveno 67 (celloko). Iuj aparatoj ankaŭ sendas pakaĵojn de haveno 67. La MAC-adreso de la klienta aparato estas inkluzivita en la pakaĵo DHCPDISCOVER.
  2. Ĉiuj DHCP-serviloj situantaj en la reto (kaj povas esti pluraj da ili) formas DHCPOFFER-oferton kun retaj agordoj por la aparato, kiu sendis DHCPDISCOVER, kaj ankaŭ dissendis ĝin tra la reto. Identigo de kiu ĉi tiu pako estas celita estas bazita sur la MAC-adreso de la kliento provizita pli frue en la DHCPDISCOVER-peto.
  3. La kliento akceptas pakaĵojn kun proponoj por retaj agordoj, elektas la plej allogan (la kriterioj povas esti malsamaj, ekzemple la tempo de pakaĵeto, la nombro da mezaj itineroj), kaj faras "oficialan peton" DHCPREQUEST kun la retaj agordoj. de la DHCP-servilo kiun ĝi ŝatas. En ĉi tiu kazo, la pako iras al specifa DHCP-servilo.
  4. La servilo kiu ricevis la DHCPREQUEST sendas DHCPACK-formatan paketon, en kiu ĝi denove listigas la retajn agordojn destinitajn por ĉi tiu kliento.

DHCP+Mysql-servilo en Python

Krome, ekzistas DHCPINFORM-pakoj kiuj venas de la kliento, kaj kies celo estas informi la DHCP-servilon, ke la "kliento vivas" kaj uzas la eldonitajn retajn agordojn. En la efektivigo de ĉi tiu servilo, ĉi tiuj pakoj estas ignoritaj.

Formato de pako

Ĝenerale, Ethernet-pakaĵkadro aspektas kiel ĉi tio:

DHCP+Mysql-servilo en Python

En nia kazo, ni konsideros nur la datumojn rekte de la enhavo de la UDP-pako, sen OSI-tavolaj protokolaj kaplinioj, nome la DHCP-strukturo:

DHCPMalkovru

Do, la procezo akiri IP-adreson por aparato komenciĝas per la DHCP-kliento sendanta elsendopeton de la haveno 68 al 255.255.255.255:67. En ĉi tiu pako, la kliento inkluzivas sian MAC-adreson, kaj ankaŭ kion ĝuste ĝi volas ricevi de la DHCP-servilo. La paka strukturo estas priskribita en la suba tabelo.

DHCPDISCOVER Paka Struktura Tabelo

Pozicio en la pakaĵo
Valornomo
Ekzemplo:
Enkonduko
Bajto
Klarigo

1
Lanĉa Peto
1
Hekso
1
Mesaĝo tipo. 1 - peto de kliento al servilo, 2 - respondo de servilo al kliento

2
Aparataro tipo
1
Hekso
1
Tipo de aparatara adreso, en ĉi tiu protokolo 1 - MAC

3
Aparataro traktas longecon
6
Hekso
1
Longo de MAC-adreso de la aparato

4
Hops
1
Hekso
1
Nombro de mezaj vojoj

5
Transakcia ID
23:cf:de:1d
Hekso
4
Unika transakcia identigilo. Generita de la kliento komence de peta operacio

7
Dua pasis
0
Hekso
4
Tempo en sekundoj de la komenco de la procezo de akiro de adreso

9
Boot flagoj
0
Hekso
2
Certaj flagoj, kiujn oni povas agordi por indiki protokolajn parametrojn

11
IP-adreso de kliento
0.0.0.0
Linio
4
IP-adreso de kliento (se ekzistas)

15
Via kliento IP-adreso
0.0.0.0
Linio
4
IP-adreso ofertita de la servilo (se disponebla)

19
Sekva servila IP-adreso
0.0.0.0
Linio
4
IP-adreso de servilo (se konata)

23
Relaja agento IP-adreso
172.16.114.41
Linio
4
IP-adreso de la relajsa agento (ekzemple ŝaltilo)

27
Kliento MAC-adreso
14:d6:4d:a7:c9:55
Hekso
6
MAC-adreso de la pakaĵeto (kliento)

31
Klienta aparataro adresplenigo
 
Hekso
10
Rezervita sidloko. Kutime plenigita per nuloj

41
Servila gastiga nomo
 
Linio
64
DHCP-servilonomo. Kutime ne transdonita

105
Boot dosiernomo
 
Linio
128
Dosiernomo sur la servilo uzata de sendiskaj stacioj dum ekŝargo

235
Magiaj kuketoj
63: 82: 53: 63
Hekso
4
“Magia” nombro, laŭ kiu, inkl. vi povas determini ke ĉi tiu pako apartenas al la DHCP-protokolo

DHCP-opcioj. Povas iri en ajna ordo

236
Opcionumero
53
Dec
1
Opcio 53, kiu specifas la DHCP-paketspecon

1 - DHCPELKOVRO
3 - DHCPPETO
2 - DHCPOFERTO
5 - DHCPACK
8 - DHCPINFORM

 
Opcio longeco
1
Dec
1

 
Opciovaloro
1
Dec
1

 
Opcionumero
50
Dec
1
Kian IP-adreson la kliento volas ricevi?

 
Opcio longeco
4
Dec
1

 
Opciovaloro
172.16.134.61
Linio
4

 
Opcionumero
55
 
1
Retaj parametroj petitaj de la kliento. Komponado povas varii

01 — Reta masko
03 - Enirejo
06 - DNS
oc — Gastigantonomo
0f - retdomajna nomo
1c - adreso de elsendo-peto (elsendo)
42 - TFTP-servilonomo
79 - Senklasa Senmova Itinero

 
Opcio longeco
8
 
1

 
Opciovaloro
01:03:06:0c:0f:1c:42:79
 
8

 
Opcionumero
82
Dec
 
Opcio 82, kiu transdonas la MAC-adreson de la ripetila aparato kaj kelkajn kromajn valorojn.

Plej ofte, ĉi tiu estas la haveno de la ŝaltilo, sur kiu funkcias la fina DHCP-kliento. Ĉi tiu opcio enhavas pliajn parametrojn. La unua bajto estas la nombro de la "subopcio", la dua estas ĝia longo, tiam ĝia valoro.

En ĉi tiu kazo, en opcio 82, la subopcioj estas nestitaj:
Agent Circuit ID = 00:04:00:01:00:04, kie la lastaj du bajtoj estas la DHCP-klienthaveno de kiu venis la peto

Agent Remote ID = 00:06:c8:be:19:93:11:48 - MAC-adreso de la DHCP-ripetila aparato

 
Opcio longeco
18
Dec
 

 
Opciovaloro
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hekso
 

 
Fino de pako
255
Dec
1
255 simbolas la finon de la pako

DHCPOFERTO

Tuj kiam la servilo ricevas la DHCPDISCOVER-pakaĵon kaj se ĝi vidas, ke ĝi povas oferti al la kliento ion el la petita, tiam ĝi generas respondon por ĝi - DHCPDISCOVER. La respondo estas sendita al la haveno "de kie ĝi venis", per elsendo, ĉar en ĉi tiu momento, la kliento ankoraŭ ne havas IP-adreson, tial ĝi povas akcepti la pakaĵon nur se ĝi estas sendita per elsendo. La kliento rekonas, ke ĉi tio estas pakaĵo por li per sia MAC-adreso ene de la pakaĵo, same kiel la transakcia numero, kiun li generas kiam la unua pakaĵo estas kreita.

DHCPOFFER Paka Struktura Tabelo

Pozicio en la pakaĵo
Nomo de valoro (komuna)
Ekzemplo:
Enkonduko
Bajto
Klarigo

1
Lanĉa Peto
1
Hekso
1
Mesaĝo tipo. 1 - peto de kliento al servilo, 2 - respondo de servilo al kliento

2
Aparataro tipo
1
Hekso
1
Tipo de aparatara adreso, en ĉi tiu protokolo 1 - MAC

3
Aparataro traktas longecon
6
Hekso
1
Longo de MAC-adreso de la aparato

4
Hops
1
Hekso
1
Nombro de mezaj vojoj

5
Transakcia ID
23:cf:de:1d
Hekso
4
Unika transakcia identigilo. Generita de la kliento komence de peta operacio

7
Dua pasis
0
Hekso
4
Tempo en sekundoj de la komenco de la procezo de akiro de adreso

9
Boot flagoj
0
Hekso
2
Certaj flagoj, kiujn oni povas agordi por indiki protokolajn parametrojn. En ĉi tiu kazo, 0 signifas la Unicast-peton

11
IP-adreso de kliento
0.0.0.0
Linio
4
IP-adreso de kliento (se ekzistas)

15
Via kliento IP-adreso
172.16.134.61
Linio
4
IP-adreso ofertita de la servilo (se disponebla)

19
Sekva servila IP-adreso
0.0.0.0
Linio
4
IP-adreso de servilo (se konata)

23
Relaja agento IP-adreso
172.16.114.41
Linio
4
IP-adreso de la relajsa agento (ekzemple ŝaltilo)

27
Kliento MAC-adreso
14:d6:4d:a7:c9:55
Hekso
6
MAC-adreso de la pakaĵeto (kliento)

31
Klienta aparataro adresplenigo
 
Hekso
10
Rezervita sidloko. Kutime plenigita per nuloj

41
Servila gastiga nomo
 
Linio
64
DHCP-servilonomo. Kutime ne transdonita

105
Boot dosiernomo
 
Linio
128
Dosiernomo sur la servilo uzata de sendiskaj stacioj dum ekŝargo

235
Magiaj kuketoj
63: 82: 53: 63
Hekso
4
“Magia” nombro, laŭ kiu, inkl. vi povas determini ke ĉi tiu pako apartenas al la DHCP-protokolo

DHCP-opcioj. Povas iri en ajna ordo

236
Opcionumero
53
Dec
1
Opcio 53, kiu difinas la DHCP 2 pakaĵettipo - DHCPOFFER

 
Opcio longeco
1
Dec
1

 
Opciovaloro
2
Dec
1

 
Opcionumero
1
Dec
1
Opcio por oferti al la DHCP-kliento retan maskon

 
Opcio longeco
4
Dec
1

 
Opciovaloro
255.255.224.0
Linio
4

 
Opcionumero
3
Dec
1
Opcio por oferti al la DHCP-kliento defaŭltan enirejon

 
Opcio longeco
4
Dec
1

 
Opciovaloro
172.16.12.1
Linio
4

 
Opcionumero
6
Dec
1
Opcio por oferti DHCP al DNS-kliento

 
Opcio longeco
4
Dec
1

 
Opciovaloro
8.8.8.8
Linio
4

 
Opcionumero
51
Dec
1
La vivdaŭro de la elsenditaj retaj parametroj en sekundoj, post kiu la DHCP-kliento devas peti ilin denove

 
Opcio longeco
4
Dec
1

 
Opciovaloro
86400
Dec
4

 
Opcionumero
82
Dec
1
Opcio 82, ripetas kio venis en DHCPDISCOVER

 
Opcio longeco
18
Dec
1

 
Opciovaloro
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18

 
Fino de pako
255
Dec
1
255 simbolas la finon de la pako

DHCPPETO

Post kiam la kliento ricevas DHCPOFFER, li formas pakaĵeton petante retajn parametrojn ne al ĉiuj DHCP-serviloj en la reto, sed nur al unu specifa, kies DHCPOFFER-oferton li "ŝatis" plej. La "kiel" kriterioj povas esti malsamaj kaj dependi de la DHCP-efektivigo de la kliento. La ricevanto de la peto estas specifita uzante la MAC-adreson de la DHCP-servilo. Ankaŭ, DHCPREQUEST-pako povas esti sendita de la kliento sen unue generi DHCPDISCOVER, se la IP-adreso de la servilo jam estis akirita antaŭe.

DHCPREQUEST Paka Struktura Tabelo

Pozicio en la pakaĵo
Nomo de valoro (komuna)
Ekzemplo:
Enkonduko
Bajto
Klarigo

1
Lanĉa Peto
1
Hekso
1
Mesaĝo tipo. 1 - peto de kliento al servilo, 2 - respondo de servilo al kliento

2
Aparataro tipo
1
Hekso
1
Tipo de aparatara adreso, en ĉi tiu protokolo 1 - MAC

3
Aparataro traktas longecon
6
Hekso
1
Longo de MAC-adreso de la aparato

4
Hops
1
Hekso
1
Nombro de mezaj vojoj

5
Transakcia ID
23:cf:de:1d
Hekso
4
Unika transakcia identigilo. Generita de la kliento komence de peta operacio

7
Dua pasis
0
Hekso
4
Tempo en sekundoj de la komenco de la procezo de akiro de adreso

9
Boot flagoj
8000
Hekso
2
Certaj flagoj, kiujn oni povas agordi por indiki protokolajn parametrojn. En ĉi tiu kazo, "elsendo" estas agordita

11
IP-adreso de kliento
0.0.0.0
Linio
4
IP-adreso de kliento (se ekzistas)

15
Via kliento IP-adreso
172.16.134.61
Linio
4
IP-adreso ofertita de la servilo (se disponebla)

19
Sekva servila IP-adreso
0.0.0.0
Linio
4
IP-adreso de servilo (se konata)

23
Relaja agento IP-adreso
172.16.114.41
Linio
4
IP-adreso de la relajsa agento (ekzemple ŝaltilo)

27
Kliento MAC-adreso
14:d6:4d:a7:c9:55
Hekso
6
MAC-adreso de la pakaĵeto (kliento)

31
Klienta aparataro adresplenigo
 
Hekso
10
Rezervita sidloko. Kutime plenigita per nuloj

41
Servila gastiga nomo
 
Linio
64
DHCP-servilonomo. Kutime ne transdonita

105
Boot dosiernomo
 
Linio
128
Dosiernomo sur la servilo uzata de sendiskaj stacioj dum ekŝargo

235
Magiaj kuketoj
63: 82: 53: 63
Hekso
4
“Magia” nombro, laŭ kiu, inkl. vi povas determini ke ĉi tiu pako apartenas al la DHCP-protokolo

DHCP-opcioj. Povas iri en ajna ordo

236
Opcionumero
53
Dec
3
Opcio 53, kiu difinas la DHCP-pakaĵetan tipon 3 - DHCPREQUEST

 
Opcio longeco
1
Dec
1

 
Opciovaloro
3
Dec
1

 
Opcionumero
61
Dec
1
Kliento ID: 01 (por Ehernet) + kliento MAC-adreso

 
Opcio longeco
7
Dec
1

 
Opciovaloro
01:2c:ab:25:ff:72:a6
Hekso
7

 
Opcionumero
60
Dec
 
" Vendisto-klasidentigilo " . En mia kazo, ĝi raportas la DHCP-klientversion. Eble aliaj aparatoj redonas ion malsaman. Vindozo ekzemple raportas MSFT 5.0

 
Opcio longeco
11
Dec
 

 
Opciovaloro
udhcp 0.9.8
Linio
 

 
Opcionumero
55
 
1
Retaj parametroj petitaj de la kliento. Komponado povas varii

01 — Reta masko
03 - Enirejo
06 - DNS
oc — Gastigantonomo
0f - retdomajna nomo
1c - adreso de elsendo-peto (elsendo)
42 - TFTP-servilonomo
79 - Senklasa Senmova Itinero

 
Opcio longeco
8
 
1

 
Opciovaloro
01:03:06:0c:0f:1c:42:79
 
8

 
Opcionumero
82
Dec
1
Opcio 82, ripetas kio venis en DHCPDISCOVER

 
Opcio longeco
18
Dec
1

 
Opciovaloro
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18

 
Fino de pako
255
Dec
1
255 simbolas la finon de la pako

DHCPACK

Kiel konfirmo, ke "jes, ĝuste, ĉi tiu estas via IP-adreso, kaj mi ne donos ĝin al neniu alia" de la DHCP-servilo, servas pako en DHCPACK-formato de la servilo al la kliento. Ĝi estas sendita elsendo same kiel aliaj pakoj. Kvankam, en la suba kodo por DHCP-servilo efektivigita en Python, ĉiaokaze, mi duobligas ajnan elsendopeton sendante pakaĵeton al specifa kliento IP, se ĝi jam estas konata. Krome, la DHCP-servilo tute ne zorgas ĉu la DHCPACK-pako atingis la klienton. Se la kliento ne ricevas DHCPACK, tiam post iom da tempo ĝi simple ripetas DHCPREQUEST

DHCPACK Paka Strukturo

Pozicio en la pakaĵo
Nomo de valoro (komuna)
Ekzemplo:
Enkonduko
Bajto
Klarigo

1
Lanĉa Peto
2
Hekso
1
Mesaĝo tipo. 1 - peto de kliento al servilo, 2 - respondo de servilo al kliento

2
Aparataro tipo
1
Hekso
1
Tipo de aparatara adreso, en ĉi tiu protokolo 1 - MAC

3
Aparataro traktas longecon
6
Hekso
1
Longo de MAC-adreso de la aparato

4
Hops
1
Hekso
1
Nombro de mezaj vojoj

5
Transakcia ID
23:cf:de:1d
Hekso
4
Unika transakcia identigilo. Generita de la kliento komence de peta operacio

7
Dua pasis
0
Hekso
4
Tempo en sekundoj de la komenco de la procezo de akiro de adreso

9
Boot flagoj
8000
Hekso
2
Certaj flagoj, kiujn oni povas agordi por indiki protokolajn parametrojn. En ĉi tiu kazo, "elsendo" estas agordita

11
IP-adreso de kliento
0.0.0.0
Linio
4
IP-adreso de kliento (se ekzistas)

15
Via kliento IP-adreso
172.16.134.61
Linio
4
IP-adreso ofertita de la servilo (se disponebla)

19
Sekva servila IP-adreso
0.0.0.0
Linio
4
IP-adreso de servilo (se konata)

23
Relaja agento IP-adreso
172.16.114.41
Linio
4
IP-adreso de la relajsa agento (ekzemple ŝaltilo)

27
Kliento MAC-adreso
14:d6:4d:a7:c9:55
Hekso
6
MAC-adreso de la pakaĵeto (kliento)

31
Klienta aparataro adresplenigo
 
Hekso
10
Rezervita sidloko. Kutime plenigita per nuloj

41
Servila gastiga nomo
 
Linio
64
DHCP-servilonomo. Kutime ne transdonita

105
Boot dosiernomo
 
Linio
128
Dosiernomo sur la servilo uzata de sendiskaj stacioj dum ekŝargo

235
Magiaj kuketoj
63: 82: 53: 63
Hekso
4
“Magia” nombro, laŭ kiu, inkl. vi povas determini ke ĉi tiu pako apartenas al la DHCP-protokolo

DHCP-opcioj. Povas iri en ajna ordo

236
Opcionumero
53
Dec
3
Opcio 53, kiu difinas la DHCP-pakaĵetan tipon 5 - DHCPACK

 
Opcio longeco
1
Dec
1

 
Opciovaloro
5
Dec
1

 
Opcionumero
1
Dec
1
Opcio por oferti al la DHCP-kliento retan maskon

 
Opcio longeco
4
Dec
1

 
Opciovaloro
255.255.224.0
Linio
4

 
Opcionumero
3
Dec
1
Opcio por oferti al la DHCP-kliento defaŭltan enirejon

 
Opcio longeco
4
Dec
1

 
Opciovaloro
172.16.12.1
Linio
4

 
Opcionumero
6
Dec
1
Opcio por oferti DHCP al DNS-kliento

 
Opcio longeco
4
Dec
1

 
Opciovaloro
8.8.8.8
Linio
4

 
Opcionumero
51
Dec
1
La vivdaŭro de la elsenditaj retaj parametroj en sekundoj, post kiu la DHCP-kliento devas peti ilin denove

 
Opcio longeco
4
Dec
1

 
Opciovaloro
86400
Dec
4

 
Opcionumero
82
Dec
1
Opcio 82, ripetas kio venis en DHCPDISCOVER

 
Opcio longeco
18
Dec
1

 
Opciovaloro
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18

 
Fino de pako
255
Dec
1
255 simbolas la finon de la pako

fikso

La instalado fakte konsistas el instalo de la python-moduloj necesaj por laboro. Oni supozas, ke MySQL jam estas instalita kaj agordita.

FreeBSD

pkg instali python3 python3 -m certigipip pip3 instali mysql-konektilon

ubuntu

sudo apt-get install python3 sudo apt-get install pip3 sudo pip3 instali mysql-konektilon

Ni kreas MySQL-datumbazon, alŝutas la rubejon pydhcp.sql en ĝin kaj agordas la agordan dosieron.

Agordo

Ĉiuj servilaj agordoj estas en xml-dosiero. Referenca dosiero:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 lokagastiganto testo testo pydhcp option_8.8.8.8_hex:sw_port82:1:20 option_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 elektu ip, maskon, enkursigilon, dns de uzantoj kie upper(mac)=supro('{option_3_AgentRemoteId_hex}') kaj upper(port)=upper('{option_1_AgentCircuitId_port_hex}') elektu ip, maskon, enkursigilon, dns de uzantoj kie upper(mac)=upper('{sw_mac}') kaj upper(port)=upper('{sw_port82}') elektu ip, maskon, enkursigilon, dns de uzantoj kie upper(mac)=upper('{ClientMacAddress}') enigu en historion (id, dt, mac, ip, komento) valoroj (nulo, nun (), '{ClientMacAddress}', '{RequestedIpAddress}', 'DHCPACK/INFORM')

Nun pli detale pri la etikedoj:

La sekcio dhcpserver priskribas la bazajn agordojn por lanĉi la servilon, nome:

  • gastiganto - kian IP-adreson la servilo aŭskultas ĉe la haveno 67
  • broadcast - kiu ip estas la elsendo por DHCPOFFER kaj DHCPACK
  • DHCPServer - kio estas la ip de la DHCP-servilo
  • LeaseTime liztempo de la eldonita IP-adreso
  • ThreadLimit - kiom da fadenoj funkcias samtempe por prilabori envenantajn UDP-pakojn sur la haveno 67. Ĝi supozeble helpas pri altŝarĝaj projektoj 😉
  • defaultMask,defaultRouter,defaultDNS - kio estas ofertita al la abonanto defaŭlte se IP troviĝas en la datumbazo, sed kromaj parametroj ne estas specifitaj por ĝi

mysql sekcio:

gastiganto, uzantnomo, pasvorto, baznomo - ĉio parolas por si mem. Proksimuma datumbaza strukturo estas afiŝita GitHub

Demandsekcio: petoj por ricevi OFERTON/ACK estas priskribitaj ĉi tie:

  • offer_count — la nombro da linioj kun petoj kiuj resendas rezulton kiel ip, masko, enkursigilo, dns
  • offer_n — demanda ĉeno. Se reveno estas malplena, tiam plenumas la sekvan oferpeton
  • history_sql - demando kiu skribas, ekzemple, al la "historio de rajtigo" por abonanto

Petoj povas inkluzivi ajnajn variablojn de la opciosekcio aŭ opciojn de la DHCP-protokolo.

Sekcio de opcioj. Ĉi tie ĝi fariĝas pli interesa. Ĉi tie ni povas krei variablojn, kiujn ni povas uzi poste en la demanda sekcio.

Ekzemple:

option_82_hex:sw_port1:20:22

, ĉi tiu komandlinio prenas la tutan linion kiu venis en la DHCP-peta opcio 82, en heksformato, en la intervalo de 20 ĝis 22 bajtoj inkluzive kaj metas ĝin en la novan variablon sw_port1 (ŝanĝa haveno de kie venis la peto)

option_82_hex:sw_mac:26:40

, difinu la variablon sw_mac, prenante la deksanon el la intervalo 26:40

Vi povas vidi ĉiujn eblajn opciojn uzeblajn en demandoj lanĉante la servilon per la -d ŝaltilo. Ni vidos ion kiel ĉi tiu protokolo:

--a DHCPINFORM-pako alvenis sur havenon 67, de 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224c'764Adreso': 'ClientMacAddress': 'ClientByMacAddress': '00c'7 91%"Jxd5d' , ' HType': 'Ethernet', 'HostName': b'x0xa3xe5xa9xa8xa8-x43fx0.0.0.0a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouterDiscover': True, 'ReqList:SRouterRouter', 'ReqList:SRoute' 'ReqListSubnetM ask ': True, 'ReqListVendorSpecInfo': 5.0, 'RequestedIpAddress': '0025224', 'Vendor': b'MSFT 764', 'chaddr': '172.30.128.13ad00', '00.:172.30.114.25', '308.:6'. , 'flags': b'x1x82', 'giaddr': '12', 'gpoz': 12, 'hlen': 53, 'hops': 53, 'htype': 'MAC', 'magic_cookie': b'cx55Sc ', 'op': 'DHCPINFORM', 'option55': 60, 'option60': 61, 'option61': 82, 'option82': 82, 'option12': 01, 'option06': 00, ' option_04_byte': b'x00x01x00x06x02x08x00x06x00x1x9x2' b'x82x12010600040001000602080006001x589eXx2exb82xad', 'option_18_hex': '82 12_len': 01 06, 'option_00_str': "b'x04x00x01x00x06x02x08x00x06x00x1x9x2x768x0.0.0.0eXx001exb589xad'", 'result': False, 'sekundoj': 2, 'siaddr': '1', 'sw_mac': '06e89eb8ad', 'sw_port3': '897', 'xidbyte': b'

Sekve, ni povas envolvi ajnan variablon en {} kaj ĝi estos uzata en la SQL-demando.

Ni registru por historio, ke la kliento ricevis la IP-adreson:

DHCP+Mysql-servilo en Python

DHCP+Mysql-servilo en Python

Servilo starto

./pydhcpdb.py -d -c config.xml

— d konzola eligreĝimo DEBUG
- c <dosiernomo> agorda dosiero

Resumado

Kaj nun pli da detaloj pri efektivigo de la servilo en Python. Ĝi estas doloro. Python estis lernita sur la flugo. Multaj momentoj estas faritaj en la stilo de "ŭaŭ, iel mi igis ĝin funkcii." Tute ne optimumigita, kaj lasita en ĉi tiu formo ĉefe pro malmulta sperto en Python-disvolviĝo. Mi pritraktos la plej interesajn aspektojn de la servila efektivigo en "kodo".

Analizilo de XML-agorda dosiero

La norma Python-modulo xml.dom estas uzata. Ŝajnas simple, sed dum efektivigo estis rimarkebla manko de klara dokumentado kaj ekzemploj en la reto uzante ĉi tiun modulon.

    arbo = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") por elem en mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("gastiganto")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("uzantnomo")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName ("pasvorto")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("baznomo")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") por elem en dconfig: gconfig["broadcast"]=elem.getElementsByTagName("elsendo")[0]. firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("gastiganto")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName ("LeaseTime")[0].firstChild.data gconfig[" dhcp_ThreadLimit"]=int(elem.getElementsByTagName("ThreadLimit")[0].firstChild.data) gconfig["dhcp_Server"]=elem.getElementsByTagName("DHCPServer")[0].firstChild.data gconfig]["faultChild.data gconfig] =elem.getElementsByTagName ("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName ("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName ("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultRouter"]=ByTagName"] defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("demando") por elem en qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[1].firstChild.data por num en intervalo(int(gconfig["ofer_count"])): gconfig["offer_"+str(num+1)]=elem.getElementsByTagName("offer_"+str(num+0))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[XNUMX].firstChild.data options=tree.getElementsByTagName("opcioj") por elem en opcioj: node=elem.getElementsByTagName("opcio") por opcioj en nodo : opciojMod.append(options.firstChild.data)

Multfadenado

Strange, multifadenado en Python estas efektivigita tre klare kaj simple.

def PacketWork(data,addr): ... # efektivigo de analizado de la envenanta pako kaj respondado al ĝi ... dum True: data, addr = udp_socket.recvfrom(1024) # atendante la UDP-pakaĵeto thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # kiel ĝi venis - ni lanĉas la antaŭe difinitan PacketWork-funkcion en la fono kun parametroj dum threading.active_count() >gconfig["dhcp_ThreadLimit"]: tempo. sleep(1) # se la nombro Estas pli da fadenoj jam rulantaj ol en la agordoj, ni atendas ĝis estas malpli da ili

Ricevu/sendu DHCP-pakaĵon

Por kapti UDP-pakojn venantajn tra la retkarto, vi devas "levi" la ingon:

udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP) udp_socket.bind((gconfig["dhcp_gastiganto"],67))

, kie la flagoj estas:

  • AF_INET - signifas ke la adresformato estos IP: haveno. Povas esti ankaŭ AF_UNIX - kie la adreso estas donita per la dosiernomo.
  • SOCK_DGRAM - signifas, ke ni ne akceptas "krudan pakaĵon", sed tiun, kiu jam trapasis la fajroŝirmilon, kaj kun parte eltondita pako. Tiuj. ni ricevas nur UDP-pakaĵon sen la "fizika" komponanto de la UDP-pakaĵo. Se vi uzas la flagon SOCK_RAW, tiam vi ankaŭ devos analizi ĉi tiun "envolvaĵon".

Sendi paketon povas esti kiel elsendo:

                    udp_socket.setsockopt (socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #ŝanĝu la ingon al elsendo-reĝimo rz=udp_socket.sendto(packetack, (gconfig["elsendo"],68))

, kaj al la adreso "de kie venis la pako":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # ŝanĝu la ingon al pluraŭskultila reĝimo rz=udp_socket.sendto(packetack, addr)

, kie SOL_SOCKET signifas la "protokola nivelo" por agordi opciojn,

, SO_BROADCAST opcio ke la kaskpakaĵo estas "elsendo"

  ,SO_REUSEADDR opcio ŝanĝas la ingon al "multaj aŭskultantoj" reĝimo. En teorio, ĉi-kaze ĝi estas nenecesa, sed sur unu el la FreeBSD-serviloj, sur kiuj mi provis, la kodo ne funkciis sen ĉi tiu opcio.

Analizante DHCP-pakon

Ĉi tie mi tre ŝatis Python. Montriĝas, ke el la skatolo ĝi permesas vin esti sufiĉe fleksebla kun la bajtokodo. Permesante ĝin esti tre facile tradukita en dekumajn valorojn, ŝnurojn kaj deksanon - t.e. jen kion ni efektive bezonas por kompreni la strukturon de la pako. Do, ekzemple, vi povas akiri gamon da bajtoj en HEX kaj nur bajtojn:

    res["xidhex"]=datenoj[4:8].hex() res["xidbyte"]=datenoj[4:8]

, paku la bajtojn en strukturon:

res["flagoj"]=pack('BB',datenoj[10],datenoj[11])

Akiru IP de strukturo:

res["ciaddr"]=socket.inet_ntoa(pack('BBBB',datumoj[12],datumoj[13],datumoj[14],datumoj[15]));

Kaj inverse:

res=res+socket.inet_pton (socket.AF_INET, gconfig["dhcp_Server"])

Tio estas ĉio por nun 😉

fonto: www.habr.com

Aldoni komenton