DHCP+MySQL server në Python

DHCP+MySQL server në Python

Qëllimi i këtij projekti ishte:

  • Studimi i protokollit DHCP nĂ« punĂ«n me rrjetin IPv4
  • Studimi i Python (pak mĂ« shumĂ« se nga fillimi 😉 )
  • zĂ«vendĂ«simi i serverit DB2DHCP (forku im), origjinali kĂ«tu, i cili bĂ«het gjithnjĂ« e mĂ« e vĂ«shtirĂ« tĂ« ndĂ«rtohet pĂ«r sistemet e reja operative. Madje, nuk mĂ« pĂ«lqen qĂ« ekzekutuesi, i cili nuk ka mundĂ«si "ta ndĂ«rroni menjĂ«herĂ«"
  • marrja e njĂ« serveri DHCP funksional me mundĂ«sinĂ« e marrjes sĂ« IP adresĂ«s sĂ« abonentit sipas mac adresĂ«s sĂ« abonentit apo lidhjes mac tĂ« switch-it + port (Opsioni 82)
  • shkrimi i njĂ« biçiklete tĂ« re (O! kjo Ă«shtĂ« aktiviteti im i preferuar)
  • marrja e kritika pĂ«r neglizhencĂ«n time nĂ« HabrHabr (e preferuara Ă«shtĂ« njĂ« ftesĂ«) 😉

Rezultati: punon 😉 Testuar nĂ« OS FreeBSD dhe Ubuntu. Teoretikisht, mund tĂ« kĂ«rkohet qĂ« kodi tĂ« punojĂ« pĂ«r çdo OS, pasi nuk ka lidhje specifike nĂ« kod.
Kujdes! Më poshtë ka shumë.

Lidhja me depo për adhuruesit "të prekësh në jet".

Procesi i instalimit, konfigurimit dhe pĂ«rdorimit tĂ« rezultatit "tĂ« studimit tĂ« materies" Ă«shtĂ« shumĂ« poshtĂ«, dhe mĂ« pas pak teori pĂ«r protokollin DHCP. PĂ«r vete. Dhe pĂ«r historinĂ« 😉

Pak teori

ÇfarĂ« Ă«shtĂ« DHCP

Ky është një protokoll rrjetesh që lejon një aparat të mësojë IP adresën e tij (dhe parametra të tjerë si gateway, DNS etj.) nga serveri DHCP. Shkëmbimi i paketeve bëhet përmes protokolit UDP. Parimi i përgjithshëm i punës së aparatit kur kërkon parametrat e rrjetit është si në vijim:

  1. Aparati (klienti) shpërndan një kërkesë UDP të gjerë (DHCPDISCOVER) në të gjithë rrjetin me kërkesën "cilido, më jepni një IP adresë". Zakonisht (por jo gjithmonë), kërkesa ndodh nga porta 68 (burimi), dhe destinimi është porta 67 (destinacioni). Disa aparate dërgojnë paketa edhe nga porta 67. Brenda paketës DHCPDISCOVER është përfshirë adresa MAC e aparatit klient.
  2. Të gjithë serverat DHCP, që ndodhen në rrjet (dhe mund të ketë disa), formulojnë për aparatin që dërgoi DHCPDISCOVER, një ofertë DHCPOFFER me cilësimet e rrjetit, dhe gjithashtu e dërgojnë atë në mënyrë të gjerë në rrjet. Identifikimi se për kë është për këtë paketë bëhet përmes adresës MAC të klientit, e cila është dhënë më parë në kërkesën DHCPDISCOVER.
  3. Klienti pranon paketat me propozime për konfigurimet e rrjetit, zgjedh paketën më tërheqëse (kriteret mund të jenë të ndryshme, përfshirë edhe kohën e dërgesës së paketës, numrin e rrugëve ndërmjetëse), dhe bën një "kërkesë zyrtare" DHCPREQUEST me konfigurimet e rrjetit për serverin DHCP që i pëlqen. Në këtë rast, paketa shkon tashmë për te një server specifik DHCP.
  4. Serveri që merr DHCPREQUEST dërgon një paketë në formatin DHCPACK, në të cilën përmend sërish konfigurimet e rrjetit të destinuara për këtë klient.

DHCP+MySQL server në Python

Për më tepër, ka paketa DHCPINFORM që dërgohen nga klienti, dhe qëllimi i tyre është të informojnë serverin DHCP se "klienti është aktiv" dhe po përdor konfigurimet e dhëna të rrjetit. Në realizimin e këtij serveri, këto paketa injorohen.

Formati i paketimeve

Në përgjithësi, fushat e paketa Ethernet duken afërsisht kështu:

DHCP+MySQL server në Python

Në rastin tonë, ne do të shqyrtojmë vetëm të dhënat e përmbajtjes së paketës UDP, pa tituj të protokolleve të niveleve OSI, konkretisht strukturën DHCP:

DHCPDISCOVER

Pra, procesi i marrjes së një adrese IP për pajisjen fillon me atë që klienti DHCP dërgon një kërkesë të gjerë nga porta 68 në 255.255.255.255:67. Në këtë paketë, klienti përfshin adresën e tij MAC, si dhe çfarë dëshiron të marrë nga serveri DHCP. Struktura e paketës përshkruhet në formën e tabelës më poshtë.

Tabelë e strukturës së paketës DHCPDISCOVER

Pozita në paketë
Emri i vlerës
Shembulli
Përfaqësimi
Bytes
Shpjegimi

1
Kërkesa Boot
1
Hex
1
Tipi i mesazhit. 1 - kërkesë nga klienti për serverin, 2 - përgjigje nga serveri për klientin

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

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

4
Hops
1
Hex
1
Numri i rrugëve ndërmjetëse

5
ID i Transaksionit
23:cf:de:1d
Hex
4
Identifikues unik i transaksionit. Klienti e gjeneron në fillim të procesit të kërkesës

7
Sekondi të kaluara
0
Hex
4
Koha në sekonda që nga fillimi i procesit të marrjes së adresës

9
Flagat e Bootp
0
Hex
2
Disa flag, që mund të vendosen për të treguar parametrat e protokollit

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

15
Adresa IP e klientit tuaj
0.0.0.0
String
4
Adresa IP e propozuar nga serveri (nëse ka)

19
Adresa IP e serverit të ardhshëm
0.0.0.0
String
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit të rinisjes
172.16.114.41
String
4
Adresa IP e agjentit të rinisjes (për shembull switch)

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

31
Përmasat e adresës së harduerit të klientit
 
Hex
10
Hapësirë e rezervuar. Zakonisht mbushet me zero

41
Emri i serverit
 
String
64
Emri i serverit DHCP. Zakonisht nuk dërgohet

105
Emri i skedarit të boot
 
String
128
Emri i skedarit në server, i përdorur nga stacionet pa disqe gjatë ngarkimit

235
Magic cookie
63:82:53:63
Hex
4
Numri "magjik", me të cilin gjithashtu mund të përcaktohet se ky paket i përket protokollit DHCP

Opsionet DHCP. Mund të shfaqen në çdo rend

236
Numri i opsionit
53
Dec
1
Opsioni 53, që përcakton tipin e paketës DHCP

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

 
Gjatësia e opsionit
1
Dec
1

 
Vlera e opsionit
1
Dec
1

 
Numri i opsionit
50
Dec
1
Cila IP adresë dëshiron të marrë klienti

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
172.16.134.61
String
4

 
Numri i opsionit
55
 
1
Parametrat rrjetore të kërkuar nga klienti. Strukturat mund të jenë të ndryshme

01 — MaskĂ« rrjeti
03 — Gjenerator
06 — DNS
oc — Emri i hostit
0f — emri i domenit tĂ« rrjetit
1c — adresa e kĂ«rkesĂ«s sĂ« shumicĂ«s (broadcast)
42 — emri i serverit TFTP
79 — Rruga Statike pa Klasa

 
Gjatësia e opsionit
8
 
1

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

 
Numri i opsionit
82
Dec
 
Opsioni 82, në të cilin transmetohet adresa MAC e pajisjes - retransmetues dhe disa vlera shtesë.

mĂ« sĂ« shumti — porta e switch-it ku punon klienti pĂ«rfundimtar DHCP NĂ« kĂ«tĂ« opsion janĂ« "injektuar" parameter tĂ« tjerĂ«. Bytes i parĂ« — numri i "nĂ«opsionit", i dyti gjatĂ«sia e saj, pastaj vlera e saj.

Në këtë rast, në opsionin 82, janë injektuar nëopsione:
Agent Circuit ID = 00:04:00:01:00:04, ku dy bytes e fundit janë porta e klientit DHCP nga e cila erdhi kërkesa

Agent Remote ID = 00:06:c8:be:19:93:11:48 — adresa MAC e pajisjes retransmetuese DHCP

 
Gjatësia e opsionit
18
Dec
 

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

 
Përfundimi i paketës
255
Dec
1
255 simbolizon përfundimin e paketës

DHCPOFFER

Sapo serveri merr paketĂ«n DHCPDISCOVER dhe nĂ«se sheh se mund t’i ofrojĂ« klientit diçka nga e kĂ«rkuara, ai formon njĂ« pĂ«rgjigje pĂ«r tĂ« — DHCPDISCOVER. PĂ«rgjigja dĂ«rgohet nĂ« portin "nga e cila erdhi" si broadcast, pasi nĂ« kĂ«tĂ« moment, klienti ende nuk ka IP adresĂ«, kĂ«shtu qĂ« ai mund ta pranojĂ« paketĂ«n vetĂ«m nĂ«se Ă«shtĂ« dĂ«rguar si tĂ«rĂ«sisht. Klienti e njeh qĂ« kjo Ă«shtĂ« njĂ« paketĂ« pĂ«r tĂ« pĂ«rmes adresĂ«s sĂ« tij MAC nĂ« brendĂ«si tĂ« paketĂ«s, si dhe numrit tĂ« transaksionit, i cili gjenerohet nĂ« momentin e krijimit tĂ« paketĂ«s sĂ« parĂ«.

Tabela e strukturës së paketës DHCPOFFER

Pozita në paketë
Emri i vlerës (zakonisht e pranuar)
Shembulli
Përfaqësimi
Bytes
Shpjegimi

1
Kërkesa Boot
1
Hex
1
Tipi i mesazhit. 1 - kërkesë nga klienti për serverin, 2 - përgjigje nga serveri për klientin

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

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

4
Hops
1
Hex
1
Numri i rrugëve ndërmjetëse

5
ID i Transaksionit
23:cf:de:1d
Hex
4
Identifikues unik i transaksionit. Klienti e gjeneron në fillim të procesit të kërkesës

7
Sekondi të kaluara
0
Hex
4
Koha në sekonda që nga fillimi i procesit të marrjes së adresës

9
Flagat e Bootp
0
Hex
2
Disa flamuj, tĂ« cilat mund tĂ« vendosen si shenja tĂ« parametrave tĂ« protokollit. NĂ« kĂ«tĂ« rast, 0 — do tĂ« thotĂ« lloji i kĂ«rkesĂ«s Unicast

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

15
Adresa IP e klientit tuaj
172.16.134.61
String
4
Adresa IP e propozuar nga serveri (nëse ka)

19
Adresa IP e serverit të ardhshëm
0.0.0.0
String
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit të rinisjes
172.16.114.41
String
4
Adresa IP e agjentit të rinisjes (për shembull switch)

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

31
Përmasat e adresës së harduerit të klientit
 
Hex
10
Hapësirë e rezervuar. Zakonisht mbushet me zero

41
Emri i serverit
 
String
64
Emri i serverit DHCP. Zakonisht nuk dërgohet

105
Emri i skedarit të boot
 
String
128
Emri i skedarit në server, i përdorur nga stacionet pa disqe gjatë ngarkimit

235
Magic cookie
63:82:53:63
Hex
4
Numri "magjik", me të cilin gjithashtu mund të përcaktohet se ky paket i përket protokollit DHCP

Opsionet DHCP. Mund të shfaqen në çdo rend

236
Numri i opsionit
53
Dec
1
Opsioni 53, qĂ« pĂ«rcakton tipin e paketĂ«s DHCP 2 — DHCPOFFER

 
Gjatësia e opsionit
1
Dec
1

 
Vlera e opsionit
2
Dec
1

 
Numri i opsionit
1
Dec
1
Opsioni që ofron klientit DHCP maskën e rrjetit

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
255.255.224.0
String
4

 
Numri i opsionit
3
Dec
1
Opsioni që ofron klientit DHCP portën e paracaktuar

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
172.16.12.1
String
4

 
Numri i opsionit
6
Dec
1
Opsioni që ofron klientit DHCP DNS

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
8.8.8.8
String
4

 
Numri i opsionit
51
Dec
1
Koha e jetĂ«s sĂ« parametrave tĂ« rrjetit tĂ« dhĂ«nĂ« nĂ« sekonda, pas sĂ« cilĂ«s klienti DHCP duhet t’i kĂ«rkojĂ« pĂ«rsĂ«ri

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
86400
Dec
4

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

 
Gjatësia e opsionit
18
Dec
1

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

 
Përfundimi i paketës
255
Dec
1
255 simbolizon përfundimin e paketës

DHCPREQUEST

Pas pas klienti të pranojë DHCPOFFER, ai formon një paketë me kërkesën për parametra rrjeti jo më për të gjithë serverët DHCP në rrjet, por vetëm për një të caktuar, oferta DHCPOFFER e të cilit i ka pëlqyer më shumë. Kriteret e "pëlqimit" mund të jenë të ndryshme dhe varen nga implementimi i klientit DHCP. Marrësi i kërkesës tregohet përmes adresës MAC të serverit DHCP. Po ashtu, paketa DHCPREQUEST mund të dërgohet nga klienti dhe pa formimin e mëparshëm DHCPDISCOVER, nëse adresa IP nga serveri ka qenë tashmë e marrë më herët.

Tabela e strukturës së paketës DHCPREQUEST

Pozita në paketë
Emri i vlerës (zakonisht e pranuar)
Shembulli
Përfaqësimi
Bytes
Shpjegimi

1
Kërkesa Boot
1
Hex
1
Tipi i mesazhit. 1 - kërkesë nga klienti për serverin, 2 - përgjigje nga serveri për klientin

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

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

4
Hops
1
Hex
1
Numri i rrugëve ndërmjetëse

5
ID i Transaksionit
23:cf:de:1d
Hex
4
Identifikues unik i transaksionit. Klienti e gjeneron në fillim të procesit të kërkesës

7
Sekondi të kaluara
0
Hex
4
Koha në sekonda që nga fillimi i procesit të marrjes së adresës

9
Flagat e Bootp
8000
Hex
2
Disa flagje, të cilat mund të vendosen si një tregues për parametrat e protokollit. Në këtë rast është vendosur "broadcast"

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

15
Adresa IP e klientit tuaj
172.16.134.61
String
4
Adresa IP e propozuar nga serveri (nëse ka)

19
Adresa IP e serverit të ardhshëm
0.0.0.0
String
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit të rinisjes
172.16.114.41
String
4
Adresa IP e agjentit të rinisjes (për shembull switch)

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

31
Përmasat e adresës së harduerit të klientit
 
Hex
10
Hapësirë e rezervuar. Zakonisht mbushet me zero

41
Emri i serverit
 
String
64
Emri i serverit DHCP. Zakonisht nuk dërgohet

105
Emri i skedarit të boot
 
String
128
Emri i skedarit në server, i përdorur nga stacionet pa disqe gjatë ngarkimit

235
Magic cookie
63:82:53:63
Hex
4
Numri "magjik", me të cilin gjithashtu mund të përcaktohet se ky paket i përket protokollit DHCP

Opsionet DHCP. Mund të shfaqen në çdo rend

236
Numri i opsionit
53
Dec
3
Opsioni 53, qĂ« pĂ«rcakton llojin e paketĂ«s DHCP 3 — DHCPREQUEST

 
Gjatësia e opsionit
1
Dec
1

 
Vlera e opsionit
3
Dec
1

 
Numri i opsionit
61
Dec
1
Identifikuesi i klientit: 01 (për Ethernet) + adresa MAC e klientit

 
Gjatësia e opsionit
7
Dec
1

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

 
Numri i opsionit
60
Dec
 
"Identifikuesi i klasës së shitësit". Në rastin tim njofton versionin e klientit DHCP. Mundësisht pajisje të tjera, kthejnë diçka tjetër. Windows për shembull raporton MSFT 5.0

 
Gjatësia e opsionit
11
Dec
 

 
Vlera e opsionit
udhcp 0.9.8
String
 

 
Numri i opsionit
55
 
1
Parametrat rrjetore të kërkuar nga klienti. Strukturat mund të jenë të ndryshme

01 — MaskĂ« rrjeti
03 — Gjenerator
06 — DNS
oc — Emri i hostit
0f — emri i domenit tĂ« rrjetit
1c — adresa e kĂ«rkesĂ«s sĂ« shumicĂ«s (broadcast)
42 — emri i serverit TFTP
79 — Rruga Statike pa Klasa

 
Gjatësia e opsionit
8
 
1

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

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

 
Gjatësia e opsionit
18
Dec
1

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

 
Përfundimi i paketës
255
Dec
1
255 simbolizon përfundimin e paketës

DHCPACK

Si një konfirmim që "po, me të vërtetë, kjo është adresa juaj IP, dhe nuk do ta jap më askujt" nga serveri DHCP, shërben paketa në formatin DHCPACK nga serveri për klientin. Ai, ashtu si dhe paketat e tjera dërgohet në mënyrë të gjitha. Megjithatë, në kodin e dhënë më poshtë të serverit DHCP të realizuar në Python, që dërgoj çdo kërkesë të gjeneruar në mënyrë të gjitha, duke dërguar paketën në një IP të caktuar të klientit, nëse tashmë është e njohur. Dhe serveri DHCP nuk shqetësohet aspak nëse paketa DHCPACK ka arritur te klienti. Nëse klienti nuk merr DHCPACK, atëherë pas një kohe të caktuar thjesht përsërit DHCPREQUEST

Tabela e strukturës së paketës DHCPACK

Pozita në paketë
Emri i vlerës (zakonisht e pranuar)
Shembulli
Përfaqësimi
Bytes
Shpjegimi

1
Kërkesa Boot
2
Hex
1
Tipi i mesazhit. 1 - kërkesë nga klienti për serverin, 2 - përgjigje nga serveri për klientin

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

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

4
Hops
1
Hex
1
Numri i rrugëve ndërmjetëse

5
ID i Transaksionit
23:cf:de:1d
Hex
4
Identifikues unik i transaksionit. Klienti e gjeneron në fillim të procesit të kërkesës

7
Sekondi të kaluara
0
Hex
4
Koha në sekonda që nga fillimi i procesit të marrjes së adresës

9
Flagat e Bootp
8000
Hex
2
Disa flagje, të cilat mund të vendosen si një tregues për parametrat e protokollit. Në këtë rast është vendosur "broadcast"

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

15
Adresa IP e klientit tuaj
172.16.134.61
String
4
Adresa IP e propozuar nga serveri (nëse ka)

19
Adresa IP e serverit të ardhshëm
0.0.0.0
String
4
Adresa IP e serverit (nëse dihet)

23
Adresa IP e agjentit të rinisjes
172.16.114.41
String
4
Adresa IP e agjentit të rinisjes (për shembull switch)

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

31
Përmasat e adresës së harduerit të klientit
 
Hex
10
Hapësirë e rezervuar. Zakonisht mbushet me zero

41
Emri i serverit
 
String
64
Emri i serverit DHCP. Zakonisht nuk dërgohet

105
Emri i skedarit të boot
 
String
128
Emri i skedarit në server, i përdorur nga stacionet pa disqe gjatë ngarkimit

235
Magic cookie
63:82:53:63
Hex
4
Numri "magjik", me të cilin gjithashtu mund të përcaktohet se ky paket i përket protokollit DHCP

Opsionet DHCP. Mund të shfaqen në çdo rend

236
Numri i opsionit
53
Dec
3
Opsioni 53, qĂ« pĂ«rcakton llojin e paketĂ«s DHCP 5 — DHCPACK

 
Gjatësia e opsionit
1
Dec
1

 
Vlera e opsionit
5
Dec
1

 
Numri i opsionit
1
Dec
1
Opsioni që ofron klientit DHCP maskën e rrjetit

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
255.255.224.0
String
4

 
Numri i opsionit
3
Dec
1
Opsioni që ofron klientit DHCP portën e paracaktuar

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
172.16.12.1
String
4

 
Numri i opsionit
6
Dec
1
Opsioni që ofron klientit DHCP DNS

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
8.8.8.8
String
4

 
Numri i opsionit
51
Dec
1
Koha e jetĂ«s sĂ« parametrave tĂ« rrjetit tĂ« dhĂ«nĂ« nĂ« sekonda, pas sĂ« cilĂ«s klienti DHCP duhet t’i kĂ«rkojĂ« pĂ«rsĂ«ri

 
Gjatësia e opsionit
4
Dec
1

 
Vlera e opsionit
86400
Dec
4

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

 
Gjatësia e opsionit
18
Dec
1

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

 
Përfundimi i paketës
255
Dec
1
255 simbolizon përfundimin e paketës

Instalimi

Instalimi në thelb përfshin instalimin e moduleve python të nevojshme për funksionimin. Supozon se MySQL është instaluar dhe konfiguruar tashmë.

FreeBSD

pkg install python3
python3 -m ensurepip
pip3 install mysql-connector

Ubuntu

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

Krijojmë BDb MySQL, ngarkojmë në të dump pydhcp.sql, konfigurimin e skedarit.

Konfigurimi

Të gjitha konfigurimet e serverit ndodhen në një skedar me format xml. Skedari referencë:

0.0.0.0
        255.255.255.255
        192.168.0.71
	8600
	1
        255.255.255.0
        192.168.0.1
        8.8.8.8
    
    
        localhost
	test
	test
	pydhcp
    
    
       option_82_hex:sw_port1:20:22       
       option_82_hex:sw_port2:16:18       
       option_82_hex:sw_mac:26:40
    
    
        3
	select ip,mask,router,dns from users where upper(mac)=upper('{option_82_AgentRemoteId_hex}') and upper(port)=upper('{option_82_AgentCircuitId_port_hex}')
        select ip,mask,router,dns from users where upper(mac)=upper('{sw_mac}') and upper(port)=upper('{sw_port2}')
        select ip,mask,router,dns from users where upper(mac)=upper('{ClientMacAddress}')
	insert into history (id,dt,mac,ip,comment) values (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Tani tani mbi etiketat:

Seksioni dhcpserver përshkruan parametrat kryesorë për aktivizimin e serverit, në veçanti:

  • host — cili IP adresĂ« dĂ«gjon serveri nĂ« portin 67
  • broadcast — cili IP Ă«shtĂ« bllokues pĂ«r DHCPOFFER dhe DHCPACK
  • DHCPServer — cili IP ka serveri DHCP
  • LeaseTime Ă«shtĂ« koha e qirasĂ« pĂ«r IP adresĂ«n e dhĂ«nĂ«
  • ThreadLimit — sa njĂ«si tĂ« njĂ«kohshme pĂ«rpunojnĂ« paketat UDP tĂ« marra nĂ« portin 67. Supozohet se ndihmon nĂ« projekte me ngarkesĂ« tĂ« lartĂ« 😉
  • defaultMask,defaultRouter,defaultDNS — ato qĂ« i ofrohen abonentit si parazgjedhje, nĂ«se IP-ja gjendet nĂ« bazĂ«, por parametrat e tjerĂ« pĂ«r tĂ« nuk janĂ« tĂ« pĂ«rcaktuar

Seksioni mysql:

host,username,password,basename  — gjithçka flet pĂ«r vete. StrukturĂ«n pĂ«rfundimtare tĂ« bazĂ«s sĂ« tĂ« dhĂ«nave e keni nĂ« GitHub

Seksioni query: këtu përshkruhen pyetjet për marrjen e OFFER/ACK:

  • offer_count — numri i rreshtave me pyetje qĂ« kthejnĂ« rezultat si ip,mask,router,dns
  • offer_n — rreshti i pyetjes. NĂ«se kthehet — bosh, atĂ«herĂ« realizon pyetjen e ardhshme offer
  • history_sql — pyetje qĂ« shĂ«non, pĂ«r shembull, nĂ« "historinĂ« e autorizimit" pĂ«r abonentin

Në pyetje mund të përfshihen çdo variabël nga seksioni options ose opsionet nga protokolli DHCP.

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

Për shembull:

option_82_hex:sw_port1:20:22

, kjo rresht komandë merr të gjithë rreshtin që ka ardhur në kërkesën DHCP në opsionin 82, në formatin hex, në një gamë nga byte 20 deri në 22 përfshirë dhe e vendos atë në një variabël të re sw_port1 (porta e switchit nga e cila erdhi kërkesa)

option_82_hex:sw_mac:26:40

, përcaktojmë variablën sw_mac, duke marrë hex nga gama 26:40

Të shikoni të gjitha opsionet e mundshme që mund të përdoren në kërkesa, mund të bëhet duke nisur serverin me çelësin -d. Do të shohim diçka të tillë në log:

--paketi DHCPINFORM ka ardhur në portin 67, nga 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68)
{'ClientMacAddress': '0025224ad764',
 'ClientMacAddressByte': b'x00%"Jxd7d',
 'HType': 'Ethernet',
 'HostName': b'x91xa5xe0xa3xa5xa9-x8fx8a',
 'ReqListDNS': True,
 'ReqListDomainName': True,
 'ReqListPerfowmRouterDiscover': True,
 'ReqListRouter': True,
 'ReqListStaticRoute': True,
 'ReqListSubnetMask': True,
 'ReqListVendorSpecInfo': 43,
 'RequestedIpAddress': '0.0.0.0',
 'Vendor': b'MSFT 5.0',
 'chaddr': '0025224ad764',
 'ciaddr': '172.30.128.13',
 'flags': b'x00x00',
 'giaddr': '172.30.114.25',
 'gpoz': 308,
 'hlen': 6,
 'hops': 1,
 'htype': 'MAC',
 'magic_cookie': b'cx82Sc',
 'op': 'DHCPINFORM',
 'option12': 12,
 'option53': 53,
 'option55': 55,
 'option60': 60,
 'option61': 61,
 'option82': 82,
 'option_82_byte': b'x12x01x06x00x04x00x01x00x06x02x08x00'
                   b'x06x00x1eXx9exb2xad',
 'option_82_hex': '12010600040001000602080006001e589eb2ad',
 'option_82_len': 18,
 'option_82_str': "b'x12x01x06x00x04x00x01x00x06x02x08x00x06x00x1eXx9exb2xad'",
 'result': False,
 'secs': 768,
 'siaddr': '0.0.0.0',
 'sw_mac': '001e589eb2ad',
 'sw_port1': '06',
 'xidbyte': b'<x89}x8c',
 'xidhex': '3c897d8c',
 'yiaddr': '0.0.0.0'}

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

Regjistrojmë për historinë që adresa IP që klienti mori:

DHCP+MySQL server në Python

DHCP+MySQL server në Python

Nisja e serverit

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

— d moda e daljes nĂ« konsolĂ« DEBUG
— c <emri_fajllit> fajlli i konfigurimit

Analiza e fluturimeve

Tani të flasim më në detaje mbi implementimin e serverit në Python. Kjo është një dhimbje. Python është studiuar 'në fluturim'. Më shumë momente janë bërë në stilin: 'ah, siç e bëra, funksionon'. Totalisht të pambrojtura, dhe janë lënë në këtë formë kryesisht për shkak të eksperiencës së vogël në zhvillimin në python. Do të ndalem në momentet më interesante të implementimit të serverit në 'kod'.

Parser i skedarit të konfigurimit XML

Përdoret moduli standard i Python xml.dom. Dukshëm dhe e thjeshtë, por gjatë implementimit ndiheshit ndjeshëm pa dokumentacion të dobishëm dhe shembuj në rrjet me përdorimin e këtij moduli.

    tree = minidom.parse(gconfig["config_file"])
    mconfig=tree.getElementsByTagName("mysql")
    for elem in mconfig:        
        gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data      
        gconfig["mysql_username"]=elem.getElementsByTagName("username")[0].firstChild.data      
        gconfig["mysql_password"]=elem.getElementsByTagName("password")[0].firstChild.data      
        gconfig["mysql_basename"]=elem.getElementsByTagName("basename")[0].firstChild.data      
    dconfig=tree.getElementsByTagName("dhcpserver")
    for elem in dconfig:        
        gconfig["broadcast"]=elem.getElementsByTagName("broadcast")[0].firstChild.data      
        gconfig["dhcp_host"]=elem.getElementsByTagName("host")[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["dhcp_defaultMask"]=elem.getElementsByTagName("defaultMask")[0].firstChild.data              
        gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data              
        gconfig["dhcp_defaultDNS"]=elem.getElementsByTagName("defaultDNS")[0].firstChild.data              
    qconfig=tree.getElementsByTagName("query")
    for elem in qconfig:  
        gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data                          
        for num in 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")       
    for elem in options:          
        node=elem.getElementsByTagName("option")
        for options in node:
            optionsMod.append(options.firstChild.data)

Multithreading

ÇuditĂ«risht, multithreading nĂ« Python Ă«shtĂ« realizuar nĂ« njĂ« mĂ«nyrĂ« shumĂ« tĂ« qartĂ« dhe tĂ« thjeshtĂ«.

def PacketWork(data, addr): 
...
# realizimi i analizës së paketës së ardhur dhe përgjigjes së saj
...


while True:
    data, addr = udp_socket.recvfrom(1024) # presim një paketë UDP
    thread = threading.Thread(target=PacketWork, args=(data, addr,)).start()	# sapo ka ardhur - fillojmë në mënyrë të pasme funksionin e caktuar më parë PacketWork me parametra
    while threading.active_count() > gconfig["dhcp_ThreadLimit"]:
       time.sleep(1) # nëse numri i driteve të nisura është më i madh se sa në vendosje, presim derisa të bëhet më i vogël

Pranimi/dërgimi i paketës DHCP

Për të kapur paketat UDP që kalojnë përmes kartës së rrjetit, duhet "të ngrihet" soketi:

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

, ku flamujt:

  • AF_INET — do tĂ« thotĂ« qĂ« formati i adresĂ«s do tĂ« jetĂ« IP: port. Mund tĂ« jetĂ« gjithashtu AF_UNIX — ku adresa jepet me emrin e skedarit.
  • SOCK_DGRAM — do tĂ« thotĂ«, se pranojmĂ« jo "paketĂ«n e papĂ«rpunuar", por njĂ« qĂ« tashmĂ« ka kaluar pĂ«rmes firewallit, dhe me paketĂ«n e prerĂ« pjesĂ«risht. KĂ«shtu, ne marrim vetĂ«m paketĂ«n UDP pa pĂ«rmbajtjen "fizike" tĂ« paketĂ«s UDP. NĂ«se pĂ«rdoret flamuri SOCK_RAW, atĂ«herĂ« do tĂ« duhet tĂ« analizojmĂ« edhe kĂ«tĂ« "pĂ«rmbajtje".

Dërgimi i paketës mund të jetë si broadcast:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # kalojmë soketin në modalitetin e dërgimit të bllokadës
                    rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, ashtu si dhe në adresën "nga ku erdhi paketa":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # kalojmë soketin në modalitetin "shumë dëgjues"
                        rz=udp_socket.sendto(packetack, addr)

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

, SO_BROADCAST është opsioni që paketa dërgohet "në bllok"

  , SO_REUSEADDR është opsioni që kalon soketin në modalitetin "shumë dëgjues". Idealisht nuk është e nevojshme në këtë rast, por në një nga serverët FreeBSD, ku kam testuar, pa këtë opsion kodi nuk punonte.

Analiza e paketës DHCP

KĂ«tu mĂ« pĂ«lqeu vĂ«rtet Python. TĂ« duket se nga "kuti" ai lejon tĂ« merremi shumĂ« lirisht me kodin byte. Duke e bĂ«rĂ« shumĂ« tĂ« thjeshtĂ« ta pĂ«rkthejmĂ« nĂ« vlera dhjetore, telash dhe hex — dmth. atĂ« qĂ« na nevojitet pĂ«r tĂ« kuptuar strukturĂ«n e paketĂ«s. KĂ«shtu, pĂ«r shembull, mund tĂ« marrim vargun e bajtave nĂ« HEX dhe thjesht bajtat:

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

, paketoni bajtat në strukturë:

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

Merrni IP-në nga struktura:

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

Dhe anasjelltas:

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

Kjo Ă«shtĂ« gjithçka 😉

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster