DHCP+Mysql strežnik v Pythonu

DHCP+Mysql strežnik v Pythonu

Namen tega projekta je bil:

  • Spoznavanje DHCP v omrežju IPv4
  • Učenje Pythona (malo več kot od začetka 😉)
  • zamenjava strežnika DB2DHCP (moja vilica), original tukaj, ki ga je vedno težje sestaviti za novi OS. In ni mi všeč, da je dvojiška datoteka, ki je ni mogoče "takoj spremeniti"
  • pridobitev delujočega strežnika DHCP z možnostjo izbire naročnikovega naslova IP z uporabo naročnikovega maca ali kombinacije stikala mac+port (možnost 82)
  • pisanje drugega kolesa (Oh! to je moja najljubša dejavnost)
  • prejemanje komentarjev o vaši spretnosti s palico na Habrahabru (ali še bolje, povabilo) 😉

Rezultat: deluje 😉 Preizkušeno na FreeBSD in Ubuntu OS. Teoretično lahko zahtevamo, da koda deluje pod katerim koli OS, ker Zdi se, da v kodi ni posebnih vezav.
Previdno! Čaka nas še marsikaj.

Povezava do repozitorija za amaterje "dotakni se živega".

Postopek namestitve, konfiguracije in uporabe je rezultat "preučevanja strojne opreme" veliko nižji, nato pa malo teorije o protokolu DHCP. Zame. In za zgodovino 😉

Malo teorije

Kaj je DHCP

To je omrežni protokol, ki napravi omogoča, da iz strežnika DHCP ugotovi svoj naslov IP (in druge parametre, kot so prehod, DNS itd.). Paketi se izmenjujejo po protokolu UDP. Splošno načelo delovanja naprave pri zahtevanju omrežnih parametrov je naslednje:

  1. Naprava (odjemalec) pošlje zahtevo za oddajanje UDP (DHCPDISCOVER) po celotnem omrežju z zahtevo "no, nekdo mi da naslov IP." Poleg tega običajno (vendar ne vedno) zahteva poteka iz vrat 68 (vir), cilj pa je vrata 67 (cilj). Nekatere naprave pošiljajo pakete tudi iz vrat 67. Naslov MAC odjemalske naprave je vključen v paket DHCPDISCOVER.
  2. Vsi strežniki DHCP, ki se nahajajo v omrežju (in jih je lahko več), tvorijo ponudbo DHCPOFFER z omrežnimi nastavitvami za napravo, ki je poslala DHCPDISCOVER, in jo tudi oddajajo po omrežju. Identifikacija, komu je ta paket namenjen, temelji na naslovu MAC odjemalca, navedenem prej v zahtevi DHCPDISCOVER.
  3. Stranka sprejme pakete s predlogi omrežnih nastavitev, izbere najbolj privlačnega (kriteriji so lahko različni, na primer čas dostave paketa, število vmesnih poti) in naredi "uradno zahtevo" DHCPREQUEST z omrežnimi nastavitvami. s strežnika DHCP, ki mu je všeč. V tem primeru gre paket na določen strežnik DHCP.
  4. Strežnik, ki je prejel DHCPREQUEST, pošlje paket formata DHCPACK, v katerem ponovno izpiše omrežne nastavitve, namenjene temu odjemalcu.

DHCP+Mysql strežnik v Pythonu

Poleg tega obstajajo paketi DHCPINFORM, ki prihajajo od odjemalca in katerih namen je obvestiti DHCP strežnik, da je »odjemalec živ« in uporablja izdane omrežne nastavitve. V izvedbi tega strežnika so ti paketi prezrti.

Oblika paketa

Na splošno je paketni okvir Ethernet videti nekako takole:

DHCP+Mysql strežnik v Pythonu

V našem primeru bomo upoštevali samo podatke neposredno iz vsebine paketa UDP, brez glav protokola plasti OSI, in sicer strukturo DHCP:

DHCPDICOVER

Torej se postopek pridobivanja naslova IP za napravo začne tako, da odjemalec DHCP pošlje zahtevo za oddajanje iz vrat 68 na 255.255.255.255:67. V tem paketu odjemalec vključuje svoj naslov MAC in tudi, kaj točno želi prejeti od strežnika DHCP. Struktura paketa je opisana v spodnji tabeli.

Tabela strukture paketa DHCPDISCOVER

Položaj v paketu
Ime vrednosti
Primer
Uvod
Bajta
pojasnilo

1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca

2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC

3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave

4
Hmelj
1
Hex
1
Število vmesnih poti

5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve

7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova

9
Zastavice za zagon
0
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola

11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)

15
IP naslov vaše stranke
0.0.0.0
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)

19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)

23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)

27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)

31
Polnjenje naslova strojne opreme odjemalca
 
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami

41
Ime gostitelja strežnika
 
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša

105
Ime zagonske datoteke
 
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska

235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP

Možnosti DHCP. Lahko gre v poljubnem vrstnem redu

236
Številka možnosti
53
december
1
Možnost 53, ki določa vrsto paketa DHCP

1 - DHCPDISCOVER
3 - PREDZAHTEVA DHC
2 - DHCPPONUDBA
5 - DHCPACK
8 - DHCPINFORM

 
Dolžina možnosti
1
december
1

 
Vrednost opcije
1
december
1

 
Številka možnosti
50
december
1
Kateri IP naslov želi stranka prejeti?

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
172.16.134.61
Linija
4

 
Številka možnosti
55
 
1
Omrežni parametri, ki jih zahteva stranka. Sestava je lahko različna

01 — Omrežna maska
03 - Prehod
06 - DNS
oc — Ime gostitelja
0f - ime omrežne domene
1c - naslov zahteve za oddajanje (oddajanje)
42 - Ime strežnika TFTP
79 - Brezrazredna statična pot

 
Dolžina možnosti
8
 
1

 
Vrednost opcije
01:03:06:0c:0f:1c:42:79
 
8

 
Številka možnosti
82
december
 
Opcija 82, ki posreduje MAC naslov repetitorske naprave in nekaj dodatnih vrednosti.

Najpogosteje so to vrata stikala, na katerem teče končni odjemalec DHCP. Ta možnost vsebuje dodatne parametre. Prvi bajt je številka “podmožnosti”, drugi je njena dolžina, nato njena vrednost.

V tem primeru so v možnosti 82 podmožnosti ugnezdene:
ID vezja agenta = 00:04:00:01:00:04, kjer sta zadnja dva bajta vrata odjemalca DHCP, iz katerih je prišla zahteva

Agent Remote ID = 00:06:c8:be:19:93:11:48 - naslov MAC naprave ponavljalnika DHCP

 
Dolžina možnosti
18
december
 

 
Vrednost opcije
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Konec paketa
255
december
1
255 simbolizira konec paketa

DHCPPONUDBA

Takoj ko strežnik prejme paket DHCPDISCOVER in če vidi, da lahko odjemalcu ponudi nekaj od zahtevanega, potem zanj generira odgovor - DHCPDISCOVER. Odgovor se pošlje v vrata, "od koder je prišel", z oddajanjem, ker v tem trenutku odjemalec še nima naslova IP, zato lahko paket sprejme samo, če je poslan z oddajanjem. Naročnik prepozna, da je to paket zanj, po svojem MAC naslovu znotraj paketa ter transakcijski številki, ki jo generira ob kreiranju prvega paketa.

DHCPOFFER Strukturna tabela paketov

Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo

1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca

2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC

3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave

4
Hmelj
1
Hex
1
Število vmesnih poti

5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve

7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova

9
Zastavice za zagon
0
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru 0 pomeni vrsto zahteve Unicast

11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)

15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)

19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)

23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)

27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)

31
Polnjenje naslova strojne opreme odjemalca
 
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami

41
Ime gostitelja strežnika
 
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša

105
Ime zagonske datoteke
 
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska

235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP

Možnosti DHCP. Lahko gre v poljubnem vrstnem redu

236
Številka možnosti
53
december
1
Opcija 53, ki definira tip paketa DHCP 2 - DHCPOFFER

 
Dolžina možnosti
1
december
1

 
Vrednost opcije
2
december
1

 
Številka možnosti
1
december
1
Možnost, da odjemalcu DHCP ponudite omrežno masko

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
255.255.224.0
Linija
4

 
Številka možnosti
3
december
1
Možnost, da odjemalcu DHCP ponudite privzeti prehod

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
172.16.12.1
Linija
4

 
Številka možnosti
6
december
1
Možnost ponujanja DHCP odjemalcu DNS

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
8.8.8.8
Linija
4

 
Številka možnosti
51
december
1
Življenjska doba izdanih omrežnih parametrov v sekundah, po kateri jih mora odjemalec DHCP znova zahtevati

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
86400
december
4

 
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER

 
Dolžina možnosti
18
december
1

 
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18

 
Konec paketa
255
december
1
255 simbolizira konec paketa

DHCPREQUEST

Ko odjemalec prejme DHCPOFFER, oblikuje paket, ki zahteva omrežne parametre, ne do vseh DHCP strežnikov v omrežju, ampak le do enega določenega, katerega ponudba DHCPOFFER mu je najbolj »všeč«. Kriteriji »všeč mi je« so lahko različni in odvisni od odjemalčeve implementacije DHCP. Prejemnik zahteve je določen z naslovom MAC strežnika DHCP. Prav tako lahko odjemalec pošlje paket DHCPREQUEST brez predhodnega generiranja DHCPDISCOVER, če je bil naslov IP strežnika že prej pridobljen.

Tabela strukture paketa DHCPREQUEST

Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo

1
Zahteva za zagon
1
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca

2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC

3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave

4
Hmelj
1
Hex
1
Število vmesnih poti

5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve

7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova

9
Zastavice za zagon
8000
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru je nastavljeno »oddajanje«.

11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)

15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)

19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)

23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)

27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)

31
Polnjenje naslova strojne opreme odjemalca
 
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami

41
Ime gostitelja strežnika
 
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša

105
Ime zagonske datoteke
 
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska

235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP

Možnosti DHCP. Lahko gre v poljubnem vrstnem redu

236
Številka možnosti
53
december
3
Opcija 53, ki definira DHCP paket tipa 3 - DHCPREQUEST

 
Dolžina možnosti
1
december
1

 
Vrednost opcije
3
december
1

 
Številka možnosti
61
december
1
ID odjemalca: 01 (za Ehernet) + naslov MAC odjemalca

 
Dolžina možnosti
7
december
1

 
Vrednost opcije
01:2c:ab:25:ff:72:a6
Hex
7

 
Številka možnosti
60
december
 
"Identifikator razreda prodajalca". V mojem primeru sporoči različico odjemalca DHCP. Morda druge naprave vrnejo nekaj drugega. Windows na primer poroča o MSFT 5.0

 
Dolžina možnosti
11
december
 

 
Vrednost opcije
udhcp 0.9.8
Linija
 

 
Številka možnosti
55
 
1
Omrežni parametri, ki jih zahteva stranka. Sestava je lahko različna

01 — Omrežna maska
03 - Prehod
06 - DNS
oc — Ime gostitelja
0f - ime omrežne domene
1c - naslov zahteve za oddajanje (oddajanje)
42 - Ime strežnika TFTP
79 - Brezrazredna statična pot

 
Dolžina možnosti
8
 
1

 
Vrednost opcije
01:03:06:0c:0f:1c:42:79
 
8

 
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER

 
Dolžina možnosti
18
december
1

 
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18

 
Konec paketa
255
december
1
255 simbolizira konec paketa

DHCPACK

Kot potrditev, da "ja, tako je, to je vaš IP naslov in ne bom ga izdal nikomur drugemu" s strežnika DHCP služi paket v formatu DHCPACK od strežnika do odjemalca. Pošilja se v oddaji tako kot drugi paketi. Čeprav v spodnji kodi za strežnik DHCP, implementiran v Pythonu, za vsak slučaj podvojim vsako zahtevo za oddajanje tako, da pošljem paket na določen IP odjemalca, če je že znan. Poleg tega strežnika DHCP sploh ne zanima, ali je paket DHCPACK dosegel odjemalca. Če odjemalec ne prejme DHCPACK, čez nekaj časa preprosto ponovi DHCPREQUEST

Tabela strukture paketa DHCPACK

Položaj v paketu
Ime vrednosti (pogosto)
Primer
Uvod
Bajta
pojasnilo

1
Zahteva za zagon
2
Hex
1
Vrsta sporočila. 1 - zahteva od odjemalca do strežnika, 2 - odgovor od strežnika do odjemalca

2
Vrsta strojne opreme
1
Hex
1
Vrsta naslova strojne opreme, v tem protokolu 1 - MAC

3
Dolžina naslovov strojne opreme
6
Hex
1
Dolžina naslova MAC naprave

4
Hmelj
1
Hex
1
Število vmesnih poti

5
ID transakcije
23:cf:de:1d
Hex
4
Enolični identifikator transakcije. Ustvari odjemalec na začetku operacije zahteve

7
Pretečena sekunda
0
Hex
4
Čas v sekundah od začetka postopka pridobivanja naslova

9
Zastavice za zagon
8000
Hex
2
Nekatere zastavice, ki jih je mogoče nastaviti za označevanje parametrov protokola. V tem primeru je nastavljeno »oddajanje«.

11
IP naslov odjemalca
0.0.0.0
Linija
4
IP naslov odjemalca (če obstaja)

15
IP naslov vaše stranke
172.16.134.61
Linija
4
Naslov IP, ki ga ponuja strežnik (če je na voljo)

19
IP naslov naslednjega strežnika
0.0.0.0
Linija
4
Naslov IP strežnika (če je znan)

23
Naslov IP posrednika
172.16.114.41
Linija
4
IP naslov posrednika (na primer stikalo)

27
MAC naslov odjemalca
14:d6:4d:a7:c9:55
Hex
6
MAC naslov pošiljatelja paketa (odjemalec)

31
Polnjenje naslova strojne opreme odjemalca
 
Hex
10
Rezerviran sedež. Običajno napolnjena z ničlami

41
Ime gostitelja strežnika
 
Linija
64
Ime strežnika DHCP. Ponavadi se ne prenaša

105
Ime zagonske datoteke
 
Linija
128
Ime datoteke na strežniku, ki ga ob zagonu uporabljajo postaje brez diska

235
Čarobni piškoti
63: 82: 53: 63
Hex
4
“Magična” številka, po kateri vklj. lahko ugotovite, da ta paket pripada protokolu DHCP

Možnosti DHCP. Lahko gre v poljubnem vrstnem redu

236
Številka možnosti
53
december
3
Opcija 53, ki definira DHCP paket tipa 5 - DHCPACK

 
Dolžina možnosti
1
december
1

 
Vrednost opcije
5
december
1

 
Številka možnosti
1
december
1
Možnost, da odjemalcu DHCP ponudite omrežno masko

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
255.255.224.0
Linija
4

 
Številka možnosti
3
december
1
Možnost, da odjemalcu DHCP ponudite privzeti prehod

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
172.16.12.1
Linija
4

 
Številka možnosti
6
december
1
Možnost ponujanja DHCP odjemalcu DNS

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
8.8.8.8
Linija
4

 
Številka možnosti
51
december
1
Življenjska doba izdanih omrežnih parametrov v sekundah, po kateri jih mora odjemalec DHCP znova zahtevati

 
Dolžina možnosti
4
december
1

 
Vrednost opcije
86400
december
4

 
Številka možnosti
82
december
1
Možnost 82 ponavlja tisto, kar je prišlo v DHCPDISCOVER

 
Dolžina možnosti
18
december
1

 
Vrednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
december
18

 
Konec paketa
255
december
1
255 simbolizira konec paketa

Namestitev

Namestitev je pravzaprav sestavljena iz namestitve modulov python, potrebnih za delo. Predpostavlja se, da je MySQL že nameščen in konfiguriran.

FreeBSD

pkg namestite python3 python3 -m securepip pip3 namestite mysql-konektor

Ubuntu

sudo apt-get namestite python3 sudo apt-get namestite pip3 sudo pip3 namestite mysql-konektor

Ustvarimo bazo podatkov MySQL, vanjo naložimo dump pydhcp.sql in konfiguriramo konfiguracijsko datoteko.

Konfiguracija

Vse nastavitve strežnika so v datoteki xml. Referenčna datoteka:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 lokalni gostitelj test test pydhcp možnost_8.8.8.8_hex:sw_vrata82:1:20 možnost_22_hex:sw_port82:2:16 možnost_18_hex:sw_mac:82:26 40 izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{option_3_AgentRemoteId_hex}') in upper(port)=upper('{option_1_AgentCircuitId_port_hex}') izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{sw_mac}') in upper(port)=upper('{sw_port82}') izberite ip,mask,router,dns od uporabnikov, kjer je upper(mac)=upper('{ClientMacAddress}') vstavi v zgodovino (id,dt,mac,ip,comment) vrednosti (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Zdaj pa podrobneje o oznakah:

V razdelku dhcpserver so opisane osnovne nastavitve za zagon strežnika, in sicer:

  • gostitelj - kateri naslov IP strežnik posluša na vratih 67
  • oddajanje - kateri ip je oddajanje za DHCPOFFER in DHCPACK
  • DHCPServer - kakšen je ip strežnika DHCP
  • LeaseTime čas zakupa izdanega naslova IP
  • ThreadLimit - koliko niti se hkrati izvaja za obdelavo dohodnih paketov UDP na vratih 67. Pomagal naj bi pri visoko obremenjenih projektih 😉
  • defaultMask,defaultRouter,defaultDNS - kaj je privzeto ponujeno naročniku, če je IP najden v bazi podatkov, vendar zanj niso določeni dodatni parametri

razdelek mysql:

gostitelj, uporabniško ime, geslo, osnovno ime - vse govori samo zase. Približna struktura baze podatkov je objavljena na GitHub

Razdelek za poizvedbe: zahteve za prejem PONUDBE/ACK so opisane tukaj:

  • offer_count — število vrstic z zahtevami, ki vrnejo rezultat, kot je ip,mask,router,dns
  • offer_n — poizvedbeni niz. Če je vrnitev prazna, izvede naslednjo zahtevo za ponudbo
  • history_sql - poizvedba, ki piše na primer v "zgodovino avtorizacije" za naročnika

Zahteve lahko vključujejo poljubne spremenljivke iz razdelka z možnostmi ali možnosti iz protokola DHCP.

Razdelek z možnostmi. Tukaj postane bolj zanimivo. Tukaj lahko ustvarimo spremenljivke, ki jih lahko kasneje uporabimo v razdelku poizvedbe.

Na primer:

option_82_hex:sw_port1:20:22

, ta ukazna vrstica prevzame celotno vrstico, ki je prišla v možnosti zahteve DHCP 82, v šestnajstiškem formatu, v obsegu od 20 do vključno 22 bajtov, in jo postavi v novo spremenljivko sw_port1 (preklopna vrata, od koder je prišla zahteva)

option_82_hex:sw_mac:26:40

, definirajte spremenljivko sw_mac, pri čemer vzamete hex iz obsega 26:40

Vse možne možnosti, ki jih je mogoče uporabiti v poizvedbah, si lahko ogledate tako, da zaženete strežnik s stikalom -d. Videli bomo nekaj podobnega temu dnevniku:

--paket DHCPINFORM je prispel na vrata 67 iz 0025224ad764, b'x91xa5xe0xa3xa5xa9-x8fx8a', ('172.30.114.25', 68) {'ClientMacAddress': '0025224ad764', 'ClientMacAddressBy te': b'x00 7%"Jxd91d' , ' HType': 'Ethernet', 'HostName': b'x5xa0xe3xa5xa9xa8-x8fx43a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouterDiscover': True, 'ReqListRouter': True, 'ReqListStaticRoute ': Res je, 'ReqListSubnetM ask': True, 'ReqListVendorSpecInfo': 0.0.0.0, 'RequestedIpAddress': '5.0', 'Vendor': b'MSFT 0025224', 'chaddr': '764ad172.30.128.13', 'ciaddr': '00' , 'flags': b'x00x172.30.114.25', 'giaddr': '308', 'gpoz': 6, 'hlen': 1, 'hops': 82, 'htype': 'MAC', 'magic_cookie': b'cx12Sc ', 'op': 'DHCPINFORM', 'option12': 53, 'option53': 55, 'option55': 60, 'option60': 61, 'option61': 82, 'option82': 82, ' option_12_byte': b'x01x06x00x04x00x01x00x06x02x08x00x06' b'x00x1x9eXx2exb82xad', 'option_12010600040001000602080006001_hex': '589e2eb82ad', 'op tion_18_len': 82 12, 'option_01_str': "b'x06x00x04x00x01x00x06x02x08x00x06x00x1x9x2eXx768exb0.0.0.0xad'", 'rezultat': False, 'sekunde': 001, 'siaddr': '589', 'sw_mac': '2e1eb06ad', 'sw_port89': '8', 'xidbyte': b'

V skladu s tem lahko katero koli spremenljivko zavijemo v {} in ta bo uporabljena v poizvedbi SQL.

Zabeležimo v zgodovino, da je stranka prejela naslov IP:

DHCP+Mysql strežnik v Pythonu

DHCP+Mysql strežnik v Pythonu

Zagon strežnika

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

— d konzolni izhodni način DEBUG
- c <ime datoteke> konfiguracijska datoteka

Povzetek

In zdaj več podrobnosti o implementaciji strežnika v Python. To je bolečina. Pythona so se učili sproti. Veliko trenutkov je narejenih v slogu "vau, nekako mi je uspelo." Sploh ni optimiziran in ostal v tej obliki predvsem zaradi malo izkušenj z razvojem Pythona. O najbolj zanimivih vidikih implementacije strežnika se bom ustavil v "kodi".

Razčlenjevalnik konfiguracijske datoteke XML

Uporabljen je standardni modul Python xml.dom. Zdi se preprosto, vendar je bilo med izvajanjem opazno pomanjkanje jasne dokumentacije in primerov v omrežju, ki uporablja ta modul.

    drevo = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") za elem v mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("uporabniško ime")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("geslo")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") za elem v 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") za elem v qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data za num v obseg(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") za elem v možnostih: node=elem.getElementsByTagName("option") za možnosti v vozlišču : optionsMod.append(options.firstChild.data)

Večnitnost

Nenavadno je, da je večnitnost v Pythonu implementirana zelo jasno in preprosto.

def PacketWork(data,addr): ... # implementacija razčlenjevanja dohodnega paketa in odziva nanj ... while True: data, addr = udp_socket.recvfrom(1024) # čakanje na paket UDP thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # kot je prišlo - zaženemo predhodno definirano funkcijo PacketWork v ozadju s parametri med threading.active_count() >gconfig["dhcp_ThreadLimit"]: čas. sleep(1) # če je število Teče več niti kot v nastavitvah, počakamo, da jih je manj

Sprejmi/pošlji paket DHCP

Če želite prestreči pakete UDP, ki prihajajo skozi omrežno kartico, morate "dvigniti" vtičnico:

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

, kjer so zastave:

  • AF_INET - pomeni, da bo oblika naslova IP: vrata. Obstaja lahko tudi AF_UNIX - kjer je naslov podan z imenom datoteke.
  • SOCK_DGRAM - pomeni, da ne sprejmemo “surovega paketa”, ampak tistega, ki je že šel skozi požarni zid, in z delno obrezanim paketom. Tisti. prejmemo le paket UDP brez "fizične" komponente ovoja paketa UDP. Če uporabljate zastavico SOCK_RAW, boste morali razčleniti tudi ta »ovitek«.

Pošiljanje paketa je lahko kot oddaja:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #preklop vtičnice na način oddajanja rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, in na naslov "od kod prihaja paket":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # preklop vtičnice v način več poslušalcev rz=udp_socket.sendto(packetack, addr)

, pri čemer SOL_SOCKET pomeni "nivo protokola" za možnosti nastavitve,

, možnost SO_BROADCAST, da je paket čelade »oddajanje«

  ,SO_REUSEADDR možnost preklopi vtičnico v način "več poslušalcev". Teoretično je v tem primeru nepotreben, a na enem od strežnikov FreeBSD, na katerem sem testiral, koda brez te možnosti ni delovala.

Razčlenjevanje paketa DHCP

Tukaj mi je bil Python zelo všeč. Izkazalo se je, da takoj po namestitvi omogoča, da ste precej prilagodljivi z bajtno kodo. Omogoča zelo enostavno prevajanje v decimalne vrednosti, nize in šestnajstiške - tj. to je tisto, kar dejansko potrebujemo, da razumemo strukturo paketa. Tako lahko na primer dobite obseg bajtov v HEX in samo bajte:

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

, spakirajte bajte v strukturo:

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

Pridobi IP iz strukture:

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

In obratno:

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

To je zaenkrat vse 😉

Vir: www.habr.com

Dodaj komentar