DHCP+Mysql serveris Python

DHCP+Mysql serveris Python

Šio projekto tikslas buvo:

  • Mokymasis apie DHCP IPv4 tinkle
  • Mokymasis Python (šiek tiek daugiau nei nuo nulio 😉)
  • serverio pakeitimas DB2DHCP (mano šakutė), originalus čia, kurią vis sunkiau surinkti naujai OS. Ir man nepatinka, kad tai yra dvejetainis, kurio niekaip negalima „pakeisti dabar“
  • gauti veikiantį DHCP serverį su galimybe pasirinkti abonento IP adresą naudojant abonento mac arba komutatoriaus mac+prievado derinį (82 parinktis)
  • rašyti kitą dviratį (O, tai mano mėgstamiausia veikla)
  • gauti komentarų apie jūsų klubo darbą Habrahabr (arba dar geriau, kvietimą) 😉

Rezultatas: veikia 😉 Išbandyta FreeBSD ir Ubuntu OS. Teoriškai kodą galima paprašyti, kad jis veiktų bet kurioje OS, nes Atrodo, kad kode nėra jokių konkrečių įrišimų.
Atsargiai! Dar daug kas laukia.

Nuoroda į saugyklą mėgėjams "Liesti gyvas".

Diegimo, konfigūravimo ir „aparatinės įrangos tyrimo“ rezultato naudojimo procesas yra daug mažesnis, o tada šiek tiek teorijos apie DHCP protokolą. Sau pačiam. Ir istorijai 😉

Šiek tiek teorijos

Kas yra DHCP

Tai tinklo protokolas, leidžiantis įrenginiui sužinoti savo IP adresą (ir kitus parametrus, pvz., šliuzą, DNS ir kt.) iš DHCP serverio. Paketai keičiami naudojant UDP protokolą. Bendras įrenginio veikimo principas, kai prašoma tinklo parametrų, yra toks:

  1. Įrenginys (klientas) siunčia UDP transliavimo užklausą (DHCPDISCOVER) visame tinkle su prašymu „na, kas nors duok man IP adresą“. Be to, paprastai (bet ne visada) užklausa gaunama iš 68 prievado (šaltinis), o paskirties vieta yra 67 prievadas (paskirties vieta). Kai kurie įrenginiai taip pat siunčia paketus iš 67 prievado. Kliento įrenginio MAC adresas yra DHCPDISCOVER pakete.
  2. Visi tinkle esantys DHCP serveriai (o jų gali būti keli) sudaro DHCPOFFER pasiūlymą su tinklo nustatymais įrenginiui, kuris atsiuntė DHCPDISCOVER, ir taip pat transliuoja jį per tinklą. Identifikavimas, kam šis paketas skirtas, pagrįstas kliento MAC adresu, pateiktu anksčiau DHCPDISCOVER užklausoje.
  3. Klientas priima paketus su pasiūlymais dėl tinklo nustatymų, pasirenka patraukliausią (kriterijai gali skirtis, pvz., paketų pristatymo laikas, tarpinių maršrutų skaičius) ir pateikia „oficialią užklausą“ DHCPREQUEST su tinklo nustatymais. iš jam patinkančio DHCP serverio. Tokiu atveju paketas eina į konkretų DHCP serverį.
  4. DHCPREQUEST gavęs serveris siunčia DHCPACK formato paketą, kuriame dar kartą išvardija šiam klientui skirtus tinklo nustatymus

DHCP+Mysql serveris Python

Be to, yra DHCPINFORM paketai, kurie ateina iš kliento ir kurių tikslas yra informuoti DHCP serverį, kad „klientas gyvas“ ir naudoja išduotus tinklo nustatymus. Diegiant šį serverį į šiuos paketus nepaisoma.

Paketo formatas

Apskritai Ethernet paketo rėmelis atrodo maždaug taip:

DHCP+Mysql serveris Python

Mūsų atveju mes atsižvelgsime tik į duomenis tiesiai iš UDP paketo turinio, be OSI sluoksnio protokolo antraščių, būtent DHCP struktūrą:

DHCPDISCOVER

Taigi įrenginio IP adreso gavimo procesas prasideda DHCP klientui siunčiant transliavimo užklausą iš 68 prievado į 255.255.255.255:67. Šiame pakete klientas įtraukia savo MAC adresą ir tai, ką tiksliai jis nori gauti iš DHCP serverio. Pakuotės struktūra aprašyta toliau esančioje lentelėje.

DHCPDISCOVER paketų struktūros lentelė

Padėtis pakuotėje
Vertės pavadinimas
Pavyzdys
Įvadas
Baitas
Paaiškinimas

1
Įkrovos užklausa
1
Hex
1
Pranešimo tipas. 1 – užklausa iš kliento į serverį, 2 – atsakymas iš serverio klientui

2
Aparatūros tipas
1
Hex
1
Techninės įrangos adreso tipas, šiame protokole 1 – MAC

3
Aparatūros adresų ilgis
6
Hex
1
Įrenginio MAC adreso ilgis

4
Apyniai
1
Hex
1
Tarpinių maršrutų skaičius

5
Sandorio ID
23:cf:de:1d
Hex
4
Unikalus operacijos identifikatorius. Sugeneruoja klientas užklausos operacijos pradžioje

7
Praėjo antras
0
Hex
4
Laikas sekundėmis nuo adreso gavimo proceso pradžios

9
Batų vėliavėlės
0
Hex
2
Tam tikros vėliavėlės, kurias galima nustatyti, kad būtų rodomi protokolo parametrai

11
Kliento IP adresas
0.0.0.0
Linija
4
Kliento IP adresas (jei yra)

15
Jūsų kliento IP adresas
0.0.0.0
Linija
4
IP adresas, kurį siūlo serveris (jei yra)

19
Kitas serverio IP adresas
0.0.0.0
Linija
4
Serverio IP adresas (jei žinomas)

23
Perdavimo agento IP adresas
172.16.114.41
Linija
4
Perdavimo agento IP adresas (pavyzdžiui, jungiklis)

27
Kliento MAC adresas
14:d6:4d:a7:c9:55
Hex
6
Paketo siuntėjo (kliento) MAC adresas

31
Kliento aparatinės įrangos adresų užpildymas
 
Hex
10
Rezervuota vieta. Paprastai užpildytas nuliais

41
Serverio prieglobos pavadinimas
 
Linija
64
DHCP serverio pavadinimas. Paprastai neperduodamas

105
Įkrovos failo pavadinimas
 
Linija
128
Failo pavadinimas serveryje, kurį paleidžiant naudoja stotys be disko

235
Magiški sausainiai
63: 82: 53: 63
Hex
4
„Stebuklingas“ numeris, pagal kurį, įsk. galite nustatyti, kad šis paketas priklauso DHCP protokolui

DHCP parinktys. Gali eiti bet kokia tvarka

236
Pasirinkimo numeris
53
Gruodis
1
53 parinktis, kuri nurodo DHCP paketo tipą

1 – DHCPDISCOVER
3 – DHCPREQUEST
2 – DHCPOFFER
5 – DHCPACK
8 – DHCPINFORM

 
Pasirinkimo ilgis
1
Gruodis
1

 
Parinkties vertė
1
Gruodis
1

 
Pasirinkimo numeris
50
Gruodis
1
Kokį IP adresą klientas nori gauti?

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
172.16.134.61
Linija
4

 
Pasirinkimo numeris
55
 
1
Tinklo parametrai, kurių reikalauja klientas. Sudėtis gali skirtis

01 — tinklo kaukė
03 - Vartai
06 – DNS
oc – pagrindinio kompiuterio pavadinimas
0f – tinklo domeno pavadinimas
1c – transliacijos užklausos adresas (transliacija)
42 – TFTP serverio pavadinimas
79 – beklasis statinis maršrutas

 
Pasirinkimo ilgis
8
 
1

 
Parinkties vertė
01:03:06:0c:0f:1c:42:79
 
8

 
Pasirinkimo numeris
82
Gruodis
 
82 parinktis, kuri perduoda kartotuvo įrenginio MAC adresą ir kai kurias papildomas reikšmes.

Dažniausiai tai yra jungiklio prievadas, kuriame veikia galutinis DHCP klientas. Šioje parinktyje yra papildomų parametrų. Pirmas baitas yra "subparinkties" numeris, antrasis - jo ilgis, tada jo reikšmė.

Šiuo atveju 82 parinktyje papildomos parinktys yra įdėtos:
Agento grandinės ID = 00:04:00:01:00:04, kur paskutiniai du baitai yra DHCP kliento prievadas, iš kurio buvo gauta užklausa

Agent Remote ID = 00:06:c8:be:19:93:11:48 – DHCP kartotuvo įrenginio MAC adresas

 
Pasirinkimo ilgis
18
Gruodis
 

 
Parinkties vertė
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Pakuotės pabaiga
255
Gruodis
1
255 simbolizuoja paketo pabaigą

DHCP PASIŪLYMAS

Kai tik serveris gauna DHCPDISCOVER paketą ir pamato, kad gali pasiūlyti klientui ką nors iš prašomo, tada sugeneruoja jam atsakymą – DHCPDISCOVER. Atsakymas siunčiamas į uostą „iš kur atėjo“, transliacija, nes Šiuo metu klientas dar neturi IP adreso, todėl gali priimti paketą tik tada, kai jis siunčiamas transliacijos būdu. Klientas atpažįsta, kad tai jam skirtas paketas pagal jo MAC adresą pakete, taip pat operacijos numerį, kurį jis sugeneruoja kurdamas pirmąjį paketą.

DHCPOFFER paketų struktūros lentelė

Padėtis pakuotėje
Vertės pavadinimas (įprastas)
Pavyzdys
Įvadas
Baitas
Paaiškinimas

1
Įkrovos užklausa
1
Hex
1
Pranešimo tipas. 1 – užklausa iš kliento į serverį, 2 – atsakymas iš serverio klientui

2
Aparatūros tipas
1
Hex
1
Techninės įrangos adreso tipas, šiame protokole 1 – MAC

3
Aparatūros adresų ilgis
6
Hex
1
Įrenginio MAC adreso ilgis

4
Apyniai
1
Hex
1
Tarpinių maršrutų skaičius

5
Sandorio ID
23:cf:de:1d
Hex
4
Unikalus operacijos identifikatorius. Sugeneruoja klientas užklausos operacijos pradžioje

7
Praėjo antras
0
Hex
4
Laikas sekundėmis nuo adreso gavimo proceso pradžios

9
Batų vėliavėlės
0
Hex
2
Tam tikros vėliavėlės, kurias galima nustatyti, kad būtų rodomi protokolo parametrai. Šiuo atveju 0 reiškia Unicast užklausos tipą

11
Kliento IP adresas
0.0.0.0
Linija
4
Kliento IP adresas (jei yra)

15
Jūsų kliento IP adresas
172.16.134.61
Linija
4
IP adresas, kurį siūlo serveris (jei yra)

19
Kitas serverio IP adresas
0.0.0.0
Linija
4
Serverio IP adresas (jei žinomas)

23
Perdavimo agento IP adresas
172.16.114.41
Linija
4
Perdavimo agento IP adresas (pavyzdžiui, jungiklis)

27
Kliento MAC adresas
14:d6:4d:a7:c9:55
Hex
6
Paketo siuntėjo (kliento) MAC adresas

31
Kliento aparatinės įrangos adresų užpildymas
 
Hex
10
Rezervuota vieta. Paprastai užpildytas nuliais

41
Serverio prieglobos pavadinimas
 
Linija
64
DHCP serverio pavadinimas. Paprastai neperduodamas

105
Įkrovos failo pavadinimas
 
Linija
128
Failo pavadinimas serveryje, kurį paleidžiant naudoja stotys be disko

235
Magiški sausainiai
63: 82: 53: 63
Hex
4
„Stebuklingas“ numeris, pagal kurį, įsk. galite nustatyti, kad šis paketas priklauso DHCP protokolui

DHCP parinktys. Gali eiti bet kokia tvarka

236
Pasirinkimo numeris
53
Gruodis
1
53 parinktis, kuri apibrėžia DHCP 2 paketo tipą – DHCPOFFER

 
Pasirinkimo ilgis
1
Gruodis
1

 
Parinkties vertė
2
Gruodis
1

 
Pasirinkimo numeris
1
Gruodis
1
Galimybė pasiūlyti DHCP klientui tinklo kaukę

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
255.255.224.0
Linija
4

 
Pasirinkimo numeris
3
Gruodis
1
Galimybė pasiūlyti DHCP klientui numatytąjį šliuzą

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
172.16.12.1
Linija
4

 
Pasirinkimo numeris
6
Gruodis
1
Galimybė pasiūlyti DHCP DNS klientui

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
8.8.8.8
Linija
4

 
Pasirinkimo numeris
51
Gruodis
1
Išduotų tinklo parametrų gyvavimo laikas sekundėmis, po kurio DHCP klientas turi jų paprašyti dar kartą

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
86400
Gruodis
4

 
Pasirinkimo numeris
82
Gruodis
1
82 parinktis, pakartoja tai, kas buvo DHCPDISCOVER

 
Pasirinkimo ilgis
18
Gruodis
1

 
Parinkties vertė
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Gruodis
18

 
Pakuotės pabaiga
255
Gruodis
1
255 simbolizuoja paketo pabaigą

DHCPREQUEST

Klientas, gavęs DHCPOFFER, suformuoja tinklo parametrų paketą ne visiems tinkle esantiems DHCP serveriams, o tik vienam konkrečiam, kurio DHCPOFFER pasiūlymas jam „patiko“ labiausiai. „Patinka“ kriterijai gali būti skirtingi ir priklausyti nuo kliento DHCP diegimo. Užklausos gavėjas nurodomas naudojant DHCP serverio MAC adresą. Be to, klientas gali išsiųsti DHCPREQUEST paketą nesugeneravęs DHCPDISCOVER, jei serverio IP adresas jau buvo gautas anksčiau.

DHCPREQUEST paketų struktūros lentelė

Padėtis pakuotėje
Vertės pavadinimas (įprastas)
Pavyzdys
Įvadas
Baitas
Paaiškinimas

1
Įkrovos užklausa
1
Hex
1
Pranešimo tipas. 1 – užklausa iš kliento į serverį, 2 – atsakymas iš serverio klientui

2
Aparatūros tipas
1
Hex
1
Techninės įrangos adreso tipas, šiame protokole 1 – MAC

3
Aparatūros adresų ilgis
6
Hex
1
Įrenginio MAC adreso ilgis

4
Apyniai
1
Hex
1
Tarpinių maršrutų skaičius

5
Sandorio ID
23:cf:de:1d
Hex
4
Unikalus operacijos identifikatorius. Sugeneruoja klientas užklausos operacijos pradžioje

7
Praėjo antras
0
Hex
4
Laikas sekundėmis nuo adreso gavimo proceso pradžios

9
Batų vėliavėlės
8000
Hex
2
Tam tikros vėliavėlės, kurias galima nustatyti, kad būtų rodomi protokolo parametrai. Šiuo atveju nustatytas „transliavimas“.

11
Kliento IP adresas
0.0.0.0
Linija
4
Kliento IP adresas (jei yra)

15
Jūsų kliento IP adresas
172.16.134.61
Linija
4
IP adresas, kurį siūlo serveris (jei yra)

19
Kitas serverio IP adresas
0.0.0.0
Linija
4
Serverio IP adresas (jei žinomas)

23
Perdavimo agento IP adresas
172.16.114.41
Linija
4
Perdavimo agento IP adresas (pavyzdžiui, jungiklis)

27
Kliento MAC adresas
14:d6:4d:a7:c9:55
Hex
6
Paketo siuntėjo (kliento) MAC adresas

31
Kliento aparatinės įrangos adresų užpildymas
 
Hex
10
Rezervuota vieta. Paprastai užpildytas nuliais

41
Serverio prieglobos pavadinimas
 
Linija
64
DHCP serverio pavadinimas. Paprastai neperduodamas

105
Įkrovos failo pavadinimas
 
Linija
128
Failo pavadinimas serveryje, kurį paleidžiant naudoja stotys be disko

235
Magiški sausainiai
63: 82: 53: 63
Hex
4
„Stebuklingas“ numeris, pagal kurį, įsk. galite nustatyti, kad šis paketas priklauso DHCP protokolui

DHCP parinktys. Gali eiti bet kokia tvarka

236
Pasirinkimo numeris
53
Gruodis
3
53 parinktis, kuri apibrėžia 3 DHCP paketo tipą – DHCPREQUEST

 
Pasirinkimo ilgis
1
Gruodis
1

 
Parinkties vertė
3
Gruodis
1

 
Pasirinkimo numeris
61
Gruodis
1
Kliento ID: 01 (Ehernet) + kliento MAC adresas

 
Pasirinkimo ilgis
7
Gruodis
1

 
Parinkties vertė
01:2c:ab:25:ff:72:a6
Hex
7

 
Pasirinkimo numeris
60
Gruodis
 
„Pardavėjo klasės identifikatorius“. Mano atveju ji praneša apie DHCP kliento versiją. Galbūt kiti įrenginiai grąžina kažką kitokio. Pavyzdžiui, „Windows“ praneša apie MSFT 5.0

 
Pasirinkimo ilgis
11
Gruodis
 

 
Parinkties vertė
udhcp 0.9.8
Linija
 

 
Pasirinkimo numeris
55
 
1
Tinklo parametrai, kurių reikalauja klientas. Sudėtis gali skirtis

01 — tinklo kaukė
03 - Vartai
06 – DNS
oc – pagrindinio kompiuterio pavadinimas
0f – tinklo domeno pavadinimas
1c – transliacijos užklausos adresas (transliacija)
42 – TFTP serverio pavadinimas
79 – beklasis statinis maršrutas

 
Pasirinkimo ilgis
8
 
1

 
Parinkties vertė
01:03:06:0c:0f:1c:42:79
 
8

 
Pasirinkimo numeris
82
Gruodis
1
82 parinktis, pakartoja tai, kas buvo DHCPDISCOVER

 
Pasirinkimo ilgis
18
Gruodis
1

 
Parinkties vertė
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Gruodis
18

 
Pakuotės pabaiga
255
Gruodis
1
255 simbolizuoja paketo pabaigą

DHCPACK

Kaip patvirtinimą, kad „taip, tai yra jūsų IP adresas ir niekam kitam jo neišduosiu“ iš DHCP serverio, aptarnaujamas DHCPACK formato paketas iš serverio į klientą. Jis siunčiamas kaip ir kiti paketai. Nors toliau pateiktame DHCP serverio, įdiegto Python, kode tik tuo atveju dubliuoju bet kokią transliavimo užklausą, išsiųsdama paketą į konkretų kliento IP, jei jis jau žinomas. Be to, DHCP serveriui visiškai nerūpi, ar DHCPACK paketas pasiekė klientą. Jei klientas negauna DHCPACK, po kurio laiko jis tiesiog kartoja DHCPREQUEST

DHCPACK paketų struktūros lentelė

Padėtis pakuotėje
Vertės pavadinimas (įprastas)
Pavyzdys
Įvadas
Baitas
Paaiškinimas

1
Įkrovos užklausa
2
Hex
1
Pranešimo tipas. 1 – užklausa iš kliento į serverį, 2 – atsakymas iš serverio klientui

2
Aparatūros tipas
1
Hex
1
Techninės įrangos adreso tipas, šiame protokole 1 – MAC

3
Aparatūros adresų ilgis
6
Hex
1
Įrenginio MAC adreso ilgis

4
Apyniai
1
Hex
1
Tarpinių maršrutų skaičius

5
Sandorio ID
23:cf:de:1d
Hex
4
Unikalus operacijos identifikatorius. Sugeneruoja klientas užklausos operacijos pradžioje

7
Praėjo antras
0
Hex
4
Laikas sekundėmis nuo adreso gavimo proceso pradžios

9
Batų vėliavėlės
8000
Hex
2
Tam tikros vėliavėlės, kurias galima nustatyti, kad būtų rodomi protokolo parametrai. Šiuo atveju nustatytas „transliavimas“.

11
Kliento IP adresas
0.0.0.0
Linija
4
Kliento IP adresas (jei yra)

15
Jūsų kliento IP adresas
172.16.134.61
Linija
4
IP adresas, kurį siūlo serveris (jei yra)

19
Kitas serverio IP adresas
0.0.0.0
Linija
4
Serverio IP adresas (jei žinomas)

23
Perdavimo agento IP adresas
172.16.114.41
Linija
4
Perdavimo agento IP adresas (pavyzdžiui, jungiklis)

27
Kliento MAC adresas
14:d6:4d:a7:c9:55
Hex
6
Paketo siuntėjo (kliento) MAC adresas

31
Kliento aparatinės įrangos adresų užpildymas
 
Hex
10
Rezervuota vieta. Paprastai užpildytas nuliais

41
Serverio prieglobos pavadinimas
 
Linija
64
DHCP serverio pavadinimas. Paprastai neperduodamas

105
Įkrovos failo pavadinimas
 
Linija
128
Failo pavadinimas serveryje, kurį paleidžiant naudoja stotys be disko

235
Magiški sausainiai
63: 82: 53: 63
Hex
4
„Stebuklingas“ numeris, pagal kurį, įsk. galite nustatyti, kad šis paketas priklauso DHCP protokolui

DHCP parinktys. Gali eiti bet kokia tvarka

236
Pasirinkimo numeris
53
Gruodis
3
53 parinktis, kuri apibrėžia 5 DHCP paketo tipą – DHCPACK

 
Pasirinkimo ilgis
1
Gruodis
1

 
Parinkties vertė
5
Gruodis
1

 
Pasirinkimo numeris
1
Gruodis
1
Galimybė pasiūlyti DHCP klientui tinklo kaukę

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
255.255.224.0
Linija
4

 
Pasirinkimo numeris
3
Gruodis
1
Galimybė pasiūlyti DHCP klientui numatytąjį šliuzą

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
172.16.12.1
Linija
4

 
Pasirinkimo numeris
6
Gruodis
1
Galimybė pasiūlyti DHCP DNS klientui

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
8.8.8.8
Linija
4

 
Pasirinkimo numeris
51
Gruodis
1
Išduotų tinklo parametrų gyvavimo laikas sekundėmis, po kurio DHCP klientas turi jų paprašyti dar kartą

 
Pasirinkimo ilgis
4
Gruodis
1

 
Parinkties vertė
86400
Gruodis
4

 
Pasirinkimo numeris
82
Gruodis
1
82 parinktis, pakartoja tai, kas buvo DHCPDISCOVER

 
Pasirinkimo ilgis
18
Gruodis
1

 
Parinkties vertė
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Gruodis
18

 
Pakuotės pabaiga
255
Gruodis
1
255 simbolizuoja paketo pabaigą

Montavimas

Diegimas iš tikrųjų susideda iš darbui reikalingų python modulių įdiegimo. Daroma prielaida, kad MySQL jau įdiegtas ir sukonfigūruotas.

FreeBSD

pkg įdiegti python3 python3 -m securepip pip3 įdiegti mysql jungtį

ubuntu

sudo apt-get install python3 sudo apt-get install pip3 sudo pip3 install mysql-connector

Sukuriame MySQL duomenų bazę, įkeliame į ją pydhcp.sql dump ir sukonfigūruojame konfigūracijos failą.

Konfigūravimas

Visi serverio nustatymai yra xml faile. Nuorodos failas:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 vietinis šeimininkas bandymas bandymas 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 pasirinkite ip,mask,router,dns iš vartotojų, kur viršutinis(mac)=upper('{option_3_AgentRemoteId_hex}') ir viršutinis(prievadas)=upper('{option_1_AgentCircuitId_port_hex}') pasirinkite ip,mask,router,dns iš vartotojų, kur viršutinis(mac)=upper('{sw_mac}') ir viršutinis(prievadas)=upper('{sw_port82}') pasirinkite IP,mask,router,dns iš vartotojų, kur viršutinis(mac)=upper('{ClientMacAddress}') įterpti į istoriją (id,dt,mac,ip,comment) reikšmes (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Dabar išsamiau apie žymas:

Skyriuje dhcpserver aprašomi pagrindiniai serverio paleidimo parametrai, būtent:

  • host - kokio IP adreso serveris klauso 67 prievade
  • transliacija – kuris IP yra DHCPOFFER ir DHCPACK transliacija
  • DHCPServer - koks yra DHCP serverio IP
  • Suteikto IP adreso LeaseTime nuomos laikas
  • ThreadLimit – kiek gijų vienu metu veikia, kad apdorotų gaunamus UDP paketus per 67 prievadą. Tai turėtų padėti didelės apkrovos projektams 😉
  • defaultMask,defaultRouter,defaultDNS - kas pagal numatytuosius nustatymus siūloma abonentui, jei duomenų bazėje randamas IP, tačiau jam nenurodyti papildomi parametrai

mysql skyrius:

priegloba, vartotojo vardas, slaptažodis, bazinis vardas – viskas kalba už save. Apytikslė duomenų bazės struktūra paskelbta GitHub

Užklausos skiltis: užklausos gauti PASIŪLYMĄ / ACK aprašytos čia:

  • offer_count – eilučių su užklausomis, kurios pateikia rezultatą, pvz., ip, mask, maršrutizatorius, dns, skaičius
  • offer_n – užklausos eilutė. Jei grąžinimo laukas tuščias, įvykdoma ši pasiūlymo užklausa
  • history_sql – užklausa, kuri įrašo, pavyzdžiui, į prenumeratoriaus „autorizacijos istoriją“

Užklausos gali apimti bet kokius kintamuosius iš parinkčių skyriaus arba parinktis iš DHCP protokolo.

Parinkčių skyrius. Čia darosi įdomiau. Čia galime sukurti kintamuosius, kuriuos vėliau galėsime naudoti užklausos skiltyje.

Pavyzdžiui:

option_82_hex:sw_port1:20:22

, ši komandų eilutė paima visą eilutę, gautą DHCP užklausos parinktyje 82, šešioliktainiu formatu, diapazone nuo 20 iki 22 baitų imtinai, ir įdeda ją į naują kintamąjį sw_port1 (perjungti prievadą, iš kurio buvo gauta užklausa)

option_82_hex:sw_mac:26:40

, apibrėžkite sw_mac kintamąjį, paimdami šešioliktainį skaičių iš diapazono 26:40

Galite pamatyti visas galimas parinktis, kurias galima naudoti užklausose, paleidę serverį jungikliu -d. Pamatysime kažką panašaus į šį žurnalą:

--DHCPINFORM paketas atkeliavo į 67 prievadą iš 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress':'0025224'764Client00t'7'91Address':'5'0 b'x3% "Jxd5d", ' HType': 'Ethernet', 'HostName': b'x9xa8xe8xa43xa0.0.0.0xa5.0-x0025224fx764a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouter, TruterLeist, 'ReqListPerfowmRouter:'ReqLeist „StaticRoute“: tiesa, „ ReqListSubnetMask ': Tiesa, 'ReqListVendorSpecInfo': 172.30.128.13, 'RequestedIpAddress': '00', 'Pardavėjas': b'MSFT 00', 'chaddr': '172.30.114.25ad308', .'6ddr1':'.'.82 vėliavėlės ': b'x12x12', 'giaddr': '53', 'gpoz': 53, 'hlen': 55, 'hops': 55, 'htype': 'MAC', 'magic_cookie': b' cx60Sc ', 'op': 'DHCPINFORM', 'option60': 61, 'option61': 82, 'option82': 82, 'option12': 01, 'option06': 00, 'option04': 00, '_byte option'_01, '_ : b'x00x06x02x08x00x06x00x1x9x2x82x12010600040001000602080006001' b'x589x2x82eXx18exb82xad', 'option_12_hex': '01e_06 : 00, 'option_04_str': "b'x00x01x00x06x02x08x00x06x00x1x9x2x768x0.0.0.0x001eXx589exb2xad'", 'result': False, 'sec': 1',' : '06', 'sw_mac': '89e8eb3ad', 'sw_port897': '8', 'xidbyte': b'

Atitinkamai, bet kurį kintamąjį galime suvynioti į {} ir jis bus naudojamas SQL užklausoje.

Į istoriją įrašykime, kad klientas gavo IP adresą:

DHCP+Mysql serveris Python

DHCP+Mysql serveris Python

Serverio paleidimas

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

— d konsolės išvesties režimas DEBUG
- c <failo pavadinimas> konfigūracijos failas

Apklausa

O dabar daugiau informacijos apie serverio įdiegimą Python. Tai skausmas. Python buvo išmoktas skrendant. Daugelis akimirkų sukurtos „oho, kažkaip man pavyko tai padaryti“. Visai neoptimizuotas ir paliktas šioje formoje daugiausia dėl mažos Python kūrimo patirties. Prie įdomiausių serverio diegimo aspektų apsistosiu „kode“.

XML konfigūracijos failų analizatorius

Naudojamas standartinis Python modulis xml.dom. Atrodo paprasta, tačiau diegimo metu pastebimai trūko aiškios dokumentacijos ir pavyzdžių tinkle naudojant šį modulį.

    medis = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql"), skirtas elem in mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].fitstast gconfig["mysql_username"]=elem.getElementsByTagName("naudotojo vardas")[0].firstChild.data gconfig["mysql_slaptažodis"]=elem.getElementsByTagName("slaptažodis")[0].first"basanames] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver"), skirta elementui dconfig: gconfig["broadcast"]=elem.getElementsByTagcast.me" firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName("LeaseTime")[0]. dhcp_ThreadLimit"]=int(elem.getElementsByTagName("ThreadLimit")[0].firstChild.data) gconfig["dhcp_Server"]=elem.getElementsByTagName("DHCPServer")[0]. =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("užklausa") elementui qconfig: gconfig["offer_count"]=elem.getElementsByTagName("pasiūlymo_skaičius")[0].firstChild in. range(int(gconfig["pasiūlymų_skaičius"])): gconfig["pasiūlymo_"+str(num+0)]=elem.getElementsByTagName("pasiūlymo_"+str(num+1))[1].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("parinktys") elementui parinktyse: node=elem.getElementsByTagName("parinktis") parinkčių in node : optionsMod.append(options.firstChild.data)

Daugiagija

Kaip bebūtų keista, daugiagija Python yra įgyvendinta labai aiškiai ir paprastai.

def PacketWork(data,addr): ... # gaunamo paketo analizavimo ir atsakymo į jį įgyvendinimas... while True: data, addr = udp_socket.recvfrom(1024) # laukiama UDP paketo gijos = Thread (Thread) target=PacketWork , args=(data,addr,)).start() # kaip atsirado – paleidžiame anksčiau apibrėžtą PacketWork funkciją fone su parametrais, o threading.active_count() >gconfig["dhcp_ThreadLimit"]: laikas. sleep(1) # jei skaičius Jau veikia daugiau gijų nei nustatymuose, laukiame kol jų bus mažiau

Gauti / siųsti DHCP paketą

Norėdami perimti UDP paketus, ateinančius per tinklo plokštę, turite „pakelti“ lizdą:

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

, kur yra vėliavos:

  • AF_INET – reiškia, kad adreso formatas bus IP: prievadas. Taip pat gali būti AF_UNIX – kur adresas pateikiamas pagal failo pavadinimą.
  • SOCK_DGRAM - reiškia, kad mes priimame ne „neapdorotą paketą“, o tą, kuris jau praėjo per ugniasienę ir su iš dalies apkarpytu paketu. Tie. gauname tik UDP paketą be „fizinio“ UDP paketų įvyniojimo komponento. Jei naudojate SOCK_RAW vėliavėlę, taip pat turėsite išanalizuoti šį „įpakavimą“.

Paketo siuntimas gali būti kaip transliacija:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #perjunkite lizdą į transliacijos režimą rz=udp_socket.sendto(packetack, (gconfig["transliacija"],68))

ir adresu „iš kur atkeliavo siunta“:

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # perjungti lizdą į kelių klausytojų režimą rz=udp_socket.sendto(packetack, addr)

, kur SOL_SOCKET reiškia „protokolo lygį“ nustatant parinktis,

, SO_BROADCAST parinktis, kad šalmo paketas yra „transliuojamas“

  ,SO_REUSEADDR parinktis perjungia lizdą į „daug klausytojų“ režimą. Teoriškai šiuo atveju tai nereikalinga, tačiau viename iš FreeBSD serverių, kuriame išbandžiau, kodas be šios parinkties neveikė.

DHCP paketo analizavimas

Čia man labai patiko Python. Pasirodo, kad iš dėžutės tai leidžia jums būti gana lanksčiai su baito kodu. Leisdami jį labai lengvai išversti į dešimtaines reikšmes, eilutes ir šešioliktaines – t.y. tai iš tikrųjų reikia, kad suprastume paketo struktūrą. Taigi, pavyzdžiui, galite gauti baitų diapazoną HEX ir tik baitus:

    res["xidhex"]=duomenys[4:8].hex() res["xidbaitas"]=duomenys[4:8]

, supakuokite baitus į struktūrą:

res["flags"]=pack('BB',duomenys[10],duomenys[11])

Gaukite IP iš struktūros:

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

Ir atvirkščiai:

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

Kol kas tiek 😉

Šaltinis: www.habr.com

Добавить комментарий