Serveri DHCP + Mysql në Python

Serveri DHCP + Mysql në Python

Qëllimi i këtij projekti ishte:

  • Mësoni rreth DHCP në një rrjet IPv4
  • Të mësosh Python (pak më shumë se nga e para 😉)
  • zëvendësimi i serverit DB2DHCP (piruni im), origjinal këtu, e cila po bëhet gjithnjë e më e vështirë për t'u montuar për sistemin operativ të ri. Dhe nuk më pëlqen që është një binar që nuk ka asnjë mënyrë për ta "ndryshuar tani"
  • marrja e një serveri DHCP funksional me aftësinë për të zgjedhur adresën IP të pajtimtarit duke përdorur mac-në e pajtimtarit ose kombinimin mac+port (Opsioni 82)
  • duke shkruar një biçikletë tjetër (Oh! ky është aktiviteti im i preferuar)
  • duke marrë komente në lidhje me dorëzimin e klubit në Habrahabr (ose më mirë akoma, një ftesë) 😉

Rezultati: funksionon 😉 Testuar në FreeBSD dhe Ubuntu OS. Teorikisht, kodi mund të kërkohet të funksionojë nën çdo OS, sepse Duket se nuk ka lidhje specifike në kod.
Me kujdes! Ka shumë të tjera për të ardhur.

Lidhje me depon për amatorë "prek i gjallë".

Procesi i instalimit, konfigurimit dhe përdorimit të rezultatit të "studimit të harduerit" është shumë më i ulët, dhe më pas një teori e vogël rreth protokollit DHCP. Për veten time. Dhe për historinë 😉

Pak teori

Çfarë është DHCP

Ky është një protokoll rrjeti që lejon një pajisje të zbulojë adresën e saj IP (dhe parametra të tjerë si gateway, DNS, etj.) nga një server DHCP. Paketat shkëmbehen duke përdorur protokollin UDP. Parimi i përgjithshëm i funksionimit të pajisjes kur kërkon parametrat e rrjetit është si më poshtë:

  1. Pajisja (klienti) dërgon një kërkesë për transmetim UDP (DHCPDISCOVER) në të gjithë rrjetin me kërkesën "epo, dikush më jep një adresë IP". Për më tepër, zakonisht (por jo gjithmonë) kërkesa ndodh nga porti 68 (burimi), dhe destinacioni është porti 67 (destinacioni). Disa pajisje dërgojnë gjithashtu pako nga porti 67. Adresa MAC e pajisjes së klientit përfshihet brenda paketës DHCPDISCOVER.
  2. Të gjithë serverët DHCP të vendosura në rrjet (dhe mund të ketë disa prej tyre) formojnë një ofertë DHCPOFFER me cilësimet e rrjetit për pajisjen që dërgoi DHCPDISCOVER, dhe gjithashtu e transmetojnë atë përmes rrjetit. Identifikimi se për kë është menduar kjo paketë bazohet në adresën MAC të klientit të dhënë më herët në kërkesën DHCPDISCOVER.
  3. Klienti pranon paketa me propozime për cilësimet e rrjetit, zgjedh atë më tërheqës (kriteret mund të jenë të ndryshme, për shembull, koha e dorëzimit të paketës, numri i rrugëve të ndërmjetme) dhe bën një "kërkesë zyrtare" DHCPREQUEST me cilësimet e rrjetit. nga serveri DHCP që i pëlqen. Në këtë rast, paketa shkon në një server specifik DHCP.
  4. Serveri që ka marrë DHCPREQUEST dërgon një paketë të formatit DHCPACK, në të cilën rendit edhe një herë cilësimet e rrjetit të destinuara për këtë klient

Serveri DHCP + Mysql në Python

Përveç kësaj, ka pako DHCPINFORM që vijnë nga klienti dhe qëllimi i të cilave është të informojnë serverin DHCP se "klienti është i gjallë" dhe po përdor cilësimet e lëshuara të rrjetit. Në zbatimin e këtij serveri, këto paketa nuk merren parasysh.

Formati i paketës

Në përgjithësi, një kornizë e paketave Ethernet duket diçka si kjo:

Serveri DHCP + Mysql në Python

Në rastin tonë, ne do të marrim parasysh vetëm të dhënat direkt nga përmbajtja e paketës UDP, pa titujt e protokollit të shtresës OSI, përkatësisht strukturën DHCP:

Zbulimi i DHCPD

Pra, procesi i marrjes së një adrese IP për një pajisje fillon me klientin DHCP që dërgon një kërkesë transmetimi nga porti 68 në 255.255.255.255:67. Në këtë paketë, klienti përfshin adresën e tij MAC, si dhe atë që saktësisht dëshiron të marrë nga serveri DHCP. Struktura e paketës përshkruhet në tabelën më poshtë.

Tabela e strukturës së paketës DHCPDISCOVER

Pozicioni në paketë
Emri i vlerës
Shembull
ide
bajt
Sqarim

1
Kërkesë për nisje
1
Magji
1
Lloji i mesazhit. 1 - kërkesë nga klienti në server, 2 - përgjigje nga serveri në klient

2
Lloji i harduerit
1
Magji
1
Lloji i adresës së harduerit, në këtë protokoll 1 - MAC

3
Gjatësia e adresave të harduerit
6
Magji
1
Gjatësia e adresës MAC të pajisjes

4
HOPS
1
Magji
1
Numri i rrugëve të ndërmjetme

5
ID e transaksionit
23:cf:de:1d
Magji
4
Identifikues unik i transaksionit. Gjeneruar nga klienti në fillim të një operacioni kërkese

7
E dyta ka kaluar
0
Magji
4
Koha në sekonda nga fillimi i procesit të marrjes së një adrese

9
Flamujt e çizmeve
0
Magji
2
Disa flamuj që mund të vendosen për të treguar parametrat e protokollit

11
Adresa IP e klientit
0.0.0.0
rresht
4
Adresa IP e klientit (nëse ka)

15
Adresa IP e klientit tuaj
0.0.0.0
rresht
4
Adresa IP e ofruar nga serveri (nëse është e disponueshme)

19
Adresa IP e serverit tjetër
0.0.0.0
rresht
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit transmetues
172.16.114.41
rresht
4
Adresa IP e agjentit rele (për shembull, një ndërprerës)

27
Adresa MAC e klientit
14:d6:4d:a7:c9:55
Magji
6
Adresa MAC e dërguesit të paketës (klientit)

31
Mbushja e adresës së harduerit të klientit
 
Magji
10
Vend i rezervuar. Zakonisht mbushet me zero

41
Emri i hostit të serverit
 
rresht
64
Emri i serverit DHCP. Zakonisht nuk transmetohet

105
Emri i skedarit të nisjes
 
rresht
128
Emri i skedarit në server që përdoret nga stacionet pa disk gjatë nisjes

235
Biskota magjike
63: 82: 53: 63
Magji
4
Numri "Magjik", sipas të cilit, përfshirë. ju mund të përcaktoni që kjo paketë i përket protokollit DHCP

Opsionet e DHCP. Mund të shkojë në çdo mënyrë

236
Numri i opsionit
53
Dhjetor
1
Opsioni 53, i cili specifikon llojin e paketës DHCP

1 - DHCPDISCOVER
3 - KËRKESË DHCP
2 - DHCPOFFER
5 - DHCPACK
8 - DHCPINFORM

 
Gjatësia e opsionit
1
Dhjetor
1

 
Vlera e opsionit
1
Dhjetor
1

 
Numri i opsionit
50
Dhjetor
1
Çfarë adrese IP dëshiron të marrë klienti?

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
172.16.134.61
rresht
4

 
Numri i opsionit
55
 
1
Parametrat e rrjetit të kërkuara nga klienti. Përbërja mund të ndryshojë

01 — Maska e rrjetit
03 - Porta
06 - DNS
oc - Emri i hostit
0f - emri i domenit të rrjetit
1c - adresa e kërkesës për transmetim (transmetim)
42 - Emri i serverit TFTP
79 - Rrugë statike pa klasë

 
Gjatësia e opsionit
8
 
1

 
Vlera e opsionit
01:03:06:0c:0f:1c:42:79
 
8

 
Numri i opsionit
82
Dhjetor
 
Opsioni 82, i cili transmeton adresën MAC të pajisjes përsëritëse dhe disa vlera shtesë.

Më shpesh, ky është porti i switch-it në të cilin funksionon klienti fundor DHCP. Ky opsion përmban parametra shtesë. Bajt i parë është numri i "nënopcionit", i dyti është gjatësia e tij, pastaj vlera e tij.

Në këtë rast, në opsionin 82, nën-opsionet janë të ndërthurura:
ID-ja e qarkut të agjentit = 00:04:00:01:00:04, ku dy bajtët e fundit janë porta e klientit DHCP nga erdhi kërkesa

ID-ja e largët e agjentit = 00:06:c8:be:19:93:11:48 - adresa MAC e pajisjes përsëritëse DHCP

 
Gjatësia e opsionit
18
Dhjetor
 

 
Vlera e opsionit
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Magji
 

 
Fundi i paketës
255
Dhjetor
1
255 simbolizon fundin e paketës

DHCPOFERA

Sapo serveri merr paketën DHCPDISCOVER dhe nëse sheh se mund t'i ofrojë klientit diçka nga ajo e kërkuar, atëherë gjeneron një përgjigje për të - DHCPDISCOVER. Përgjigja dërgohet në port “nga ka ardhur”, me transmetim, sepse në këtë moment, klienti nuk ka ende një adresë IP, prandaj mund ta pranojë paketën vetëm nëse dërgohet me transmetim. Klienti e njeh që kjo është një paketë për të nga adresa e tij MAC brenda paketës, si dhe numri i transaksionit që gjeneron në momentin kur krijohet paketa e parë.

Tabela e strukturës së paketës DHCPOFFER

Pozicioni në paketë
Emri i vlerës (i përbashkët)
Shembull
ide
bajt
Sqarim

1
Kërkesë për nisje
1
Magji
1
Lloji i mesazhit. 1 - kërkesë nga klienti në server, 2 - përgjigje nga serveri në klient

2
Lloji i harduerit
1
Magji
1
Lloji i adresës së harduerit, në këtë protokoll 1 - MAC

3
Gjatësia e adresave të harduerit
6
Magji
1
Gjatësia e adresës MAC të pajisjes

4
HOPS
1
Magji
1
Numri i rrugëve të ndërmjetme

5
ID e transaksionit
23:cf:de:1d
Magji
4
Identifikues unik i transaksionit. Gjeneruar nga klienti në fillim të një operacioni kërkese

7
E dyta ka kaluar
0
Magji
4
Koha në sekonda nga fillimi i procesit të marrjes së një adrese

9
Flamujt e çizmeve
0
Magji
2
Disa flamuj që mund të vendosen për të treguar parametrat e protokollit. Në këtë rast, 0 nënkupton llojin e kërkesës Unicast

11
Adresa IP e klientit
0.0.0.0
rresht
4
Adresa IP e klientit (nëse ka)

15
Adresa IP e klientit tuaj
172.16.134.61
rresht
4
Adresa IP e ofruar nga serveri (nëse është e disponueshme)

19
Adresa IP e serverit tjetër
0.0.0.0
rresht
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit transmetues
172.16.114.41
rresht
4
Adresa IP e agjentit rele (për shembull, një ndërprerës)

27
Adresa MAC e klientit
14:d6:4d:a7:c9:55
Magji
6
Adresa MAC e dërguesit të paketës (klientit)

31
Mbushja e adresës së harduerit të klientit
 
Magji
10
Vend i rezervuar. Zakonisht mbushet me zero

41
Emri i hostit të serverit
 
rresht
64
Emri i serverit DHCP. Zakonisht nuk transmetohet

105
Emri i skedarit të nisjes
 
rresht
128
Emri i skedarit në server që përdoret nga stacionet pa disk gjatë nisjes

235
Biskota magjike
63: 82: 53: 63
Magji
4
Numri "Magjik", sipas të cilit, përfshirë. ju mund të përcaktoni që kjo paketë i përket protokollit DHCP

Opsionet e DHCP. Mund të shkojë në çdo mënyrë

236
Numri i opsionit
53
Dhjetor
1
Opsioni 53, i cili përcakton llojin e paketës DHCP 2 - DHCPOFFER

 
Gjatësia e opsionit
1
Dhjetor
1

 
Vlera e opsionit
2
Dhjetor
1

 
Numri i opsionit
1
Dhjetor
1
Opsioni për t'i ofruar klientit DHCP një maskë rrjeti

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
255.255.224.0
rresht
4

 
Numri i opsionit
3
Dhjetor
1
Opsioni për t'i ofruar klientit DHCP një portë të paracaktuar

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
172.16.12.1
rresht
4

 
Numri i opsionit
6
Dhjetor
1
Opsioni për t'i ofruar DHCP klientit DNS

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
8.8.8.8
rresht
4

 
Numri i opsionit
51
Dhjetor
1
Jetëgjatësia e parametrave të rrjetit të lëshuar në sekonda, pas së cilës klienti DHCP duhet t'i kërkojë ato përsëri

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
86400
Dhjetor
4

 
Numri i opsionit
82
Dhjetor
1
Opsioni 82, përsërit atë që erdhi në DHCPDISCOVER

 
Gjatësia e opsionit
18
Dhjetor
1

 
Vlera e opsionit
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dhjetor
18

 
Fundi i paketës
255
Dhjetor
1
255 simbolizon fundin e paketës

DHCPREQUEST

Pasi klienti merr DHCPOFFER, ai formon një paketë që kërkon parametrat e rrjetit jo për të gjithë serverët DHCP në rrjet, por vetëm për një specifik, oferta e të cilit DHCPOFFER i "pëlqeu" më shumë. Kriteret "si" mund të jenë të ndryshme dhe varen nga zbatimi i DHCP i klientit. Marrësi i kërkesës specifikohet duke përdorur adresën MAC të serverit DHCP. Gjithashtu, një paketë DHCPREQUEST mund të dërgohet nga klienti pa gjeneruar më parë DHCPDISCOVER, nëse adresa IP e serverit tashmë është marrë më parë.

Tabela e strukturës së paketës DHCPREQUEST

Pozicioni në paketë
Emri i vlerës (i përbashkët)
Shembull
ide
bajt
Sqarim

1
Kërkesë për nisje
1
Magji
1
Lloji i mesazhit. 1 - kërkesë nga klienti në server, 2 - përgjigje nga serveri në klient

2
Lloji i harduerit
1
Magji
1
Lloji i adresës së harduerit, në këtë protokoll 1 - MAC

3
Gjatësia e adresave të harduerit
6
Magji
1
Gjatësia e adresës MAC të pajisjes

4
HOPS
1
Magji
1
Numri i rrugëve të ndërmjetme

5
ID e transaksionit
23:cf:de:1d
Magji
4
Identifikues unik i transaksionit. Gjeneruar nga klienti në fillim të një operacioni kërkese

7
E dyta ka kaluar
0
Magji
4
Koha në sekonda nga fillimi i procesit të marrjes së një adrese

9
Flamujt e çizmeve
8000
Magji
2
Disa flamuj që mund të vendosen për të treguar parametrat e protokollit. Në këtë rast, vendoset "transmetimi".

11
Adresa IP e klientit
0.0.0.0
rresht
4
Adresa IP e klientit (nëse ka)

15
Adresa IP e klientit tuaj
172.16.134.61
rresht
4
Adresa IP e ofruar nga serveri (nëse është e disponueshme)

19
Adresa IP e serverit tjetër
0.0.0.0
rresht
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit transmetues
172.16.114.41
rresht
4
Adresa IP e agjentit rele (për shembull, një ndërprerës)

27
Adresa MAC e klientit
14:d6:4d:a7:c9:55
Magji
6
Adresa MAC e dërguesit të paketës (klientit)

31
Mbushja e adresës së harduerit të klientit
 
Magji
10
Vend i rezervuar. Zakonisht mbushet me zero

41
Emri i hostit të serverit
 
rresht
64
Emri i serverit DHCP. Zakonisht nuk transmetohet

105
Emri i skedarit të nisjes
 
rresht
128
Emri i skedarit në server që përdoret nga stacionet pa disk gjatë nisjes

235
Biskota magjike
63: 82: 53: 63
Magji
4
Numri "Magjik", sipas të cilit, përfshirë. ju mund të përcaktoni që kjo paketë i përket protokollit DHCP

Opsionet e DHCP. Mund të shkojë në çdo mënyrë

236
Numri i opsionit
53
Dhjetor
3
Opsioni 53, i cili përcakton llojin e paketës DHCP 3 - DHCPREQUEST

 
Gjatësia e opsionit
1
Dhjetor
1

 
Vlera e opsionit
3
Dhjetor
1

 
Numri i opsionit
61
Dhjetor
1
ID-ja e klientit: 01 (për Ehernet) + adresa MAC e klientit

 
Gjatësia e opsionit
7
Dhjetor
1

 
Vlera e opsionit
01:2c:ab:25:ff:72:a6
Magji
7

 
Numri i opsionit
60
Dhjetor
 
"Identifikuesi i klasës së shitësit". Në rastin tim, ai raporton versionin e klientit DHCP. Ndoshta pajisjet e tjera kthejnë diçka ndryshe. Windows për shembull raporton MSFT 5.0

 
Gjatësia e opsionit
11
Dhjetor
 

 
Vlera e opsionit
udhcp 0.9.8
rresht
 

 
Numri i opsionit
55
 
1
Parametrat e rrjetit të kërkuara nga klienti. Përbërja mund të ndryshojë

01 — Maska e rrjetit
03 - Porta
06 - DNS
oc - Emri i hostit
0f - emri i domenit të rrjetit
1c - adresa e kërkesës për transmetim (transmetim)
42 - Emri i serverit TFTP
79 - Rrugë statike pa klasë

 
Gjatësia e opsionit
8
 
1

 
Vlera e opsionit
01:03:06:0c:0f:1c:42:79
 
8

 
Numri i opsionit
82
Dhjetor
1
Opsioni 82, përsërit atë që erdhi në DHCPDISCOVER

 
Gjatësia e opsionit
18
Dhjetor
1

 
Vlera e opsionit
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dhjetor
18

 
Fundi i paketës
255
Dhjetor
1
255 simbolizon fundin e paketës

DHCPACK

Si konfirmim që "po, ashtu është, kjo është adresa juaj IP dhe nuk do t'ia jap askujt tjetër" nga serveri DHCP, shërben një paketë në formatin DHCPACK nga serveri te klienti. Ai transmetohet ashtu si paketat e tjera. Megjithëse, në kodin e mëposhtëm për një server DHCP të implementuar në Python, për çdo rast, unë kopjoj çdo kërkesë transmetimi duke dërguar një paketë në një IP të klientit specifik, nëse tashmë dihet. Për më tepër, serverit DHCP nuk i intereson fare nëse paketa DHCPACK ka arritur te klienti. Nëse klienti nuk merr DHCPACK, atëherë pas një kohe ai thjesht përsërit DHCPREQUEST

Tabela e strukturës së paketës DHCPACK

Pozicioni në paketë
Emri i vlerës (i përbashkët)
Shembull
ide
bajt
Sqarim

1
Kërkesë për nisje
2
Magji
1
Lloji i mesazhit. 1 - kërkesë nga klienti në server, 2 - përgjigje nga serveri në klient

2
Lloji i harduerit
1
Magji
1
Lloji i adresës së harduerit, në këtë protokoll 1 - MAC

3
Gjatësia e adresave të harduerit
6
Magji
1
Gjatësia e adresës MAC të pajisjes

4
HOPS
1
Magji
1
Numri i rrugëve të ndërmjetme

5
ID e transaksionit
23:cf:de:1d
Magji
4
Identifikues unik i transaksionit. Gjeneruar nga klienti në fillim të një operacioni kërkese

7
E dyta ka kaluar
0
Magji
4
Koha në sekonda nga fillimi i procesit të marrjes së një adrese

9
Flamujt e çizmeve
8000
Magji
2
Disa flamuj që mund të vendosen për të treguar parametrat e protokollit. Në këtë rast, vendoset "transmetimi".

11
Adresa IP e klientit
0.0.0.0
rresht
4
Adresa IP e klientit (nëse ka)

15
Adresa IP e klientit tuaj
172.16.134.61
rresht
4
Adresa IP e ofruar nga serveri (nëse është e disponueshme)

19
Adresa IP e serverit tjetër
0.0.0.0
rresht
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit transmetues
172.16.114.41
rresht
4
Adresa IP e agjentit rele (për shembull, një ndërprerës)

27
Adresa MAC e klientit
14:d6:4d:a7:c9:55
Magji
6
Adresa MAC e dërguesit të paketës (klientit)

31
Mbushja e adresës së harduerit të klientit
 
Magji
10
Vend i rezervuar. Zakonisht mbushet me zero

41
Emri i hostit të serverit
 
rresht
64
Emri i serverit DHCP. Zakonisht nuk transmetohet

105
Emri i skedarit të nisjes
 
rresht
128
Emri i skedarit në server që përdoret nga stacionet pa disk gjatë nisjes

235
Biskota magjike
63: 82: 53: 63
Magji
4
Numri "Magjik", sipas të cilit, përfshirë. ju mund të përcaktoni që kjo paketë i përket protokollit DHCP

Opsionet e DHCP. Mund të shkojë në çdo mënyrë

236
Numri i opsionit
53
Dhjetor
3
Opsioni 53, i cili përcakton llojin e paketës DHCP 5 - DHCPACK

 
Gjatësia e opsionit
1
Dhjetor
1

 
Vlera e opsionit
5
Dhjetor
1

 
Numri i opsionit
1
Dhjetor
1
Opsioni për t'i ofruar klientit DHCP një maskë rrjeti

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
255.255.224.0
rresht
4

 
Numri i opsionit
3
Dhjetor
1
Opsioni për t'i ofruar klientit DHCP një portë të paracaktuar

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
172.16.12.1
rresht
4

 
Numri i opsionit
6
Dhjetor
1
Opsioni për t'i ofruar DHCP klientit DNS

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
8.8.8.8
rresht
4

 
Numri i opsionit
51
Dhjetor
1
Jetëgjatësia e parametrave të rrjetit të lëshuar në sekonda, pas së cilës klienti DHCP duhet t'i kërkojë ato përsëri

 
Gjatësia e opsionit
4
Dhjetor
1

 
Vlera e opsionit
86400
Dhjetor
4

 
Numri i opsionit
82
Dhjetor
1
Opsioni 82, përsërit atë që erdhi në DHCPDISCOVER

 
Gjatësia e opsionit
18
Dhjetor
1

 
Vlera e opsionit
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dhjetor
18

 
Fundi i paketës
255
Dhjetor
1
255 simbolizon fundin e paketës

Instalim

Instalimi në fakt konsiston në instalimin e moduleve python të nevojshme për punë. Supozohet se MySQL është instaluar dhe konfiguruar tashmë.

FreeBSD

pkg instaloni python3 python3 -m siguripip pip3 instaloni lidhësin mysql

Ubuntu

sudo apt-get instalo python3 sudo apt-get instalo pip3 sudo pip3 instalo lidhësin mysql

Ne krijojmë një bazë të dhënash MySQL, ngarkojmë skedarin pydhcp.sql në të dhe konfigurojmë skedarin e konfigurimit.

konfiguracion

Të gjitha cilësimet e serverit janë në një skedar xml. Skedari i referencës:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 localhost provë provë 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 zgjidhni ip, maskë, ruter, dns nga përdoruesit ku upper(mac)=upper('{option_3_AgentRemoteId_hex}') dhe upper(port)=upper('{option_1_AgentCircuitId_port_hex}') zgjidhni ip, maskë, ruter, dns nga përdoruesit ku upper(mac)=upper('{sw_mac}') dhe upper(port)=upper('{sw_port82}') zgjidhni ip, maskë, ruter, dns nga përdoruesit ku upper(mac)=upper ('{ClientMacAddress}') futni në histori (id, dt, mac, ip, koment) vlerat (null, tani(), '{ClientMacAddress}', '{RequestedIpAddress}', 'DHCPACK/INFORM')

Tani më në detaje mbi etiketat:

Seksioni dhcpserver përshkruan cilësimet bazë për fillimin e serverit, përkatësisht:

  • host - çfarë adrese IP dëgjon serveri në portin 67
  • transmetim - cila ip është transmetimi për DHCPOFFER dhe DHCPACK
  • DHCPServer - cila është ip-ja e serverit DHCP
  • Koha e qirasë LeaseTime e adresës IP të lëshuar
  • ThreadLimit - sa threads po funksionojnë njëkohësisht për të përpunuar paketat hyrëse UDP në portin 67. Supozohet të ndihmojë në projektet me ngarkesë të lartë 😉
  • defaultMask,defaultRouter,defaultDNS - çfarë i ofrohet pajtimtarit si parazgjedhje nëse një IP gjendet në bazën e të dhënave, por parametrat shtesë nuk janë specifikuar për të

seksioni mysql:

host, emri i përdoruesit, fjalëkalimi, emri bazë - gjithçka flet vetë. Një strukturë e përafërt e bazës së të dhënave është postuar në GitHub

Seksioni i pyetjeve: kërkesat për marrjen e OFERTËS/ACK përshkruhen këtu:

  • Oferta_count - numri i linjave me kërkesa që kthejnë një rezultat si ip, maskë, ruter, dns
  • Oferta_n — vargu i pyetjeve. Nëse kthimi është bosh, atëherë ekzekuton kërkesën e mëposhtme të ofertës
  • history_sql - një pyetje që shkruan, për shembull, në "historinë e autorizimit" për një pajtimtar

Kërkesat mund të përfshijnë çdo variabël nga seksioni i opsioneve ose opsione nga protokolli DHCP.

Seksioni i opsioneve. Këtu bëhet më interesante. Këtu mund të krijojmë variabla që mund t'i përdorim më vonë në seksionin e pyetjeve.

Për shembull:

option_82_hex:sw_port1:20:22

, kjo linjë komande merr të gjithë rreshtin që erdhi në opsionin e kërkesës DHCP 82, në format hex, në rangun nga 20 deri në 22 bajt përfshirëse dhe e vendos atë në variablin e ri sw_port1 (porta e ndërrimit nga erdhi kërkesa)

option_82_hex:sw_mac:26:40

, përcaktoni variablin sw_mac, duke marrë hex nga diapazoni 26:40

Ju mund të shihni të gjitha opsionet e mundshme që mund të përdoren në pyetje duke nisur serverin me çelësin -d. Do të shohim diçka si ky regjistër:

--një paketë DHCPINFORM mbërriti në portin 67, nga 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224ClientMacAddress': '764ClientMacAddress': '00ClientMacAddress': '7y' 91 5%"Jxd0d" , 'HType': 'Ethernet', 'HostName': b'x3xa5xe9xa8xa8xa43-x0.0.0.0fx5.0a', 'ReqListDNS': E vërtetë, 'ReqListDomainName': E vërtetë, 'ReqListPerfowmRouterDiscover': 'TrueqList'Router':TruetëRouter': e vertete, 'ReqListSubnetM pyet': E vërtetë, 'ReqListVendorSpecInfo': 0025224, 'RequestedIpAddress': '764', 'Shitësi': b'MSFT 172.30.128.13', 'chaddr': '00ad00', '172.30.114.25', '308. , 'flamujt': b'x6x1', 'giaddr': '82', 'gpoz': 12, 'hlen': 12, 'hops': 53, 'htype': 'MAC', 'cookie_magjike': b'cx53Sc ', 'op': 'DHCPINFORM', 'opsion55': 55, 'opsion60': 60, 'opsion61': 61, 'opsion82': 82, 'opsion82': 12, 'opsion01': 06, ' option_00_byte': b'x04x00x01x00x06x02x08x00x06x00x1x9' b'x2x82x12010600040001000602080006001eXx589exb2xad', 'option_82_hex': '18 _82_len': 12 01, 'option_06_str': "b'x00x04x00x01x00x06x02x08x00x06x00x1x9x2x768eXx0.0.0.0exb001xad", 'rezultati': False, 'seks': 589 'siaddr': '2', 'sw_mac': '1e06eb89ad', 'sw_port8': '3', 'xidbyte': b'

Prandaj, ne mund të mbështjellim çdo variabël në {} dhe do të përdoret në pyetjen SQL.

Le të regjistrojmë për historinë që klienti ka marrë adresën IP:

Serveri DHCP + Mysql në Python

Serveri DHCP + Mysql në Python

Fillimi i serverit

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

— d modaliteti i daljes së konsolës DEBUG
- c skedari i konfigurimit <emri i skedarit>

Debriefing

Dhe tani më shumë detaje mbi zbatimin e serverit në Python. Është një dhimbje. Python u mësua në fluturim. Shumë momente janë bërë në stilin e "wow, disi e bëra të funksionojë". Nuk është fare i optimizuar dhe është lënë në këtë formë kryesisht për shkak të pak përvojës në zhvillimin e Python. Unë do të ndalem në aspektet më interesante të zbatimit të serverit në "kodin".

Analizuesi i skedarëve të konfigurimit XML

Përdoret moduli standard Python xml.dom. Duket e thjeshtë, por gjatë zbatimit ka pasur një mungesë të dukshme të dokumentacionit dhe shembujve të qartë në rrjet duke përdorur këtë modul.

    pemë = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") për elementin në mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].datast gconfig["mysql_username"]=elem.getElementsByTagName("emri i përdoruesit")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("fjalëkalimi")[0].firstql"emri i fëmijës] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") për elementin në dconfig: gconfig["broadcast"]=elem.getElementsByTagName.]"(0)"me firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName("LeaseTime")[0]config[g. dhcp_ThreadLimit"]=int(elem.getElementsByTagName("ThreadLimit")[0].firstChild.data) gconfig["dhcp_Server"]=elem.getElementsByTagName("DHCPSserver")[0]Child]. =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig[element. " defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") për elementin në qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild in.të dhënat për num range(int(gconfig["offer_count"])): gconfig["offer_"+str(num+1)]=elem.getElementsByTagName("offer_"+str(num+1))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("options") për elementin në opsionet: node=elem.getElementsByTagName")(opsione : optionsMod.append(options.firstChild.data)

Multithreading

Mjaft e çuditshme, multithreading në Python zbatohet shumë qartë dhe thjesht.

def PacketWork(data,addr): ... # zbatimi i analizimit të paketës hyrëse dhe përgjigjes ndaj saj ... ndërsa E vërtetë: të dhëna, addr = udp_socket.recvfrom(1024) # në pritje të fillit të paketës UDP = threading.Thread( target=PacketWork , args=(data,addr,)).start() # siç erdhi - ne hapim funksionin e përcaktuar më parë PacketWork në sfond me parametra ndërsa threading.active_count() >gconfig["dhcp_ThreadLimit"]: koha. gjumë (1) # nëse numri Ka më shumë tema që po ekzekutohen sesa në cilësimet, presim derisa të ketë më pak prej tyre

Merrni/dërgoni paketën DHCP

Për të përgjuar paketat UDP që vijnë përmes kartës së rrjetit, duhet të "ngritni" prizën:

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

, ku flamujt janë:

  • AF_INET - do të thotë që formati i adresës do të jetë IP: port. Mund të ketë gjithashtu AF_UNIX - ku adresa jepet nga emri i skedarit.
  • SOCK_DGRAM - do të thotë që ne nuk pranojmë një "paketë të papërpunuar", por një që ka kaluar tashmë nëpër murin e zjarrit dhe me një paketë pjesërisht të shkurtuar. ato. ne marrim vetëm një pako UDP pa komponentin “fizik” të mbështjellësit të paketave UDP. Nëse përdorni flamurin SOCK_RAW, atëherë do t'ju duhet gjithashtu të analizoni këtë "mbështjellës".

Dërgimi i një pakete mund të jetë si një transmetim:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #kaloni prizën në modalitetin e transmetimit rz=udp_socket.sendto(packetack, (gconfig["transmetim"],68))

, dhe në adresën "nga erdhi paketa":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # kaloni prizën në modalitetin me shumë dëgjues rz=udp_socket.sendto(packetack, addr)

, ku SOL_SOCKET do të thotë "niveli i protokollit" për vendosjen e opsioneve,

, opsioni SO_BROADCAST që paketa e helmetës është "transmetuar"

  Opsioni SO_REUSEADDR e kalon prizën në modalitetin "shumë dëgjues". Në teori, është e panevojshme në këtë rast, por në një nga serverët FreeBSD në të cilin kam testuar, kodi nuk funksionoi pa këtë opsion.

Analiza e një pakete DHCP

Këtu më pëlqeu shumë Python. Rezulton se jashtë kutisë ju lejon të jeni mjaft fleksibël me bajtkodin. Duke e lejuar që të përkthehet shumë lehtë në vlera dhjetore, vargje dhe heks - d.m.th. kjo është ajo që ne në fakt na duhet për të kuptuar strukturën e paketës. Kështu, për shembull, mund të merrni një gamë bajtësh në HEX dhe vetëm bajt:

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

, paketoni bajtet në një strukturë:

res["flamujt"]=paketë('BB',të dhëna[10],të dhëna[11])

Merrni IP nga struktura:

res["ciaddr"]=socket.inet_ntoa(paketë('BBBB',të dhëna[12],të dhëna[13],të dhëna[14],të dhëna[15]));

Dhe anasjelltas:

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

Kjo është e gjitha për momentin 😉

Burimi: www.habr.com

Shto një koment