DHCP+Mysql poslužitelj u Pythonu

DHCP+Mysql poslužitelj u Pythonu

Svrha ovog projekta bila je:

  • Učenje o DHCP-u na IPv4 mreži
  • Učenje Pythona (malo više nego od nule 😉)
  • zamjena servera DB2DHCP (moja vilica), original здесь, koji postaje sve teže sastaviti za novi OS. I ne sviđa mi se što je to binarni zapis koji ne postoji način da se "odmah promijeni"
  • dobivanje radnog DHCP poslužitelja s mogućnošću odabira IP adrese pretplatnika pomoću kombinacije mac pretplatnika ili prekidača mac+port (opcija 82)
  • pisanje drugog bicikla (Oh! ovo je moja omiljena aktivnost)
  • primanje komentara o tvojoj klupskoj ruci na Habrahabru (ili još bolje, na poziv) 😉

Rezultat: radi 😉 Testirano na FreeBSD i Ubuntu OS. Teoretski, od koda se može tražiti da radi pod bilo kojim OS-om, jer Čini se da u kodu nema posebnih veza.
Pažljivo! Čeka nas još puno toga.

Link na repozitorij za amatere "dodirnuti živo".

Proces instaliranja, konfiguriranja i korištenja rezultat je "proučavanja hardvera" puno niži, a zatim malo teorije o DHCP protokolu. Za sebe. I za povijest 😉

Malo teorije

Što je DHCP

Ovo je mrežni protokol koji omogućuje uređaju da sazna svoju IP adresu (i druge parametre poput pristupnika, DNS-a itd.) od DHCP poslužitelja. Paketi se razmjenjuju pomoću UDP protokola. Opći princip rada uređaja pri traženju mrežnih parametara je sljedeći:

  1. Uređaj (klijent) šalje UDP zahtjev za emitiranjem (DHCPDISCOVER) kroz cijelu mrežu sa zahtjevom "dobro, neka mi netko da IP adresu." Štoviše, obično (ali ne uvijek) zahtjev dolazi s porta 68 (izvor), a odredište je port 67 (odredište). Neki uređaji također šalju pakete s porta 67. MAC adresa klijentskog uređaja uključena je u paket DHCPDISCOVER.
  2. Svi DHCP poslužitelji koji se nalaze na mreži (a može ih biti više) formiraju DHCPOFFER ponudu s mrežnim postavkama za uređaj koji je poslao DHCPDISCOVER, te je također emitiraju preko mreže. Identifikacija kome je ovaj paket namijenjen temelji se na MAC adresi klijenta navedenoj ranije u DHCPDISCOVER zahtjevu.
  3. Klijent prihvaća pakete s prijedlozima za mrežne postavke, odabire najatraktivnije (kriteriji mogu biti različiti, na primjer, vrijeme isporuke paketa, broj međuruta) i postavlja „službeni zahtjev“ DHCPREQUEST s mrežnim postavkama. s DHCP poslužitelja koji voli. U ovom slučaju paket ide na određeni DHCP poslužitelj.
  4. Poslužitelj koji je primio DHCPREQUEST šalje paket formata DHCPACK u kojem još jednom navodi mrežne postavke namijenjene ovom klijentu

DHCP+Mysql poslužitelj u Pythonu

Osim toga, tu su i DHCPINFORM paketi koji dolaze od klijenta, a čija je svrha obavijestiti DHCP server da je “klijent živ” i da koristi izdane mrežne postavke. U implementaciji ovog poslužitelja ti se paketi zanemaruju.

Format paketa

Općenito, okvir Ethernet paketa izgleda otprilike ovako:

DHCP+Mysql poslužitelj u Pythonu

U našem slučaju, razmotrit ćemo samo podatke izravno iz sadržaja UDP paketa, bez zaglavlja protokola OSI sloja, odnosno DHCP strukturu:

DHCPDICOVER

Dakle, proces dobivanja IP adrese za uređaj počinje tako što DHCP klijent šalje zahtjev za emitiranje s porta 68 na 255.255.255.255:67. U ovom paketu klijent uključuje svoju MAC adresu, kao i ono što točno želi primiti od DHCP poslužitelja. Struktura paketa opisana je u donjoj tablici.

DHCPDISCOVER Tablica strukture paketa

Pozicija u paketu
Naziv vrijednosti
Primjer
ideja
Bajt
razjašnjenje

1
Zahtjev za pokretanje
1
Hex
1
Vrsta poruke. 1 - zahtjev od klijenta do poslužitelja, 2 - odgovor od poslužitelja do klijenta

2
Vrsta hardvera
1
Hex
1
Vrsta hardverske adrese, u ovom protokolu 1 - MAC

3
Duljina hardverskih adresa
6
Hex
1
Duljina MAC adrese uređaja

4
Hmelj
1
Hex
1
Broj međuputova

5
ID transakcije
23:cf:de:1d
Hex
4
Jedinstveni identifikator transakcije. Generira klijent na početku operacije zahtjeva

7
Prošla je druga
0
Hex
4
Vrijeme u sekundama od početka procesa dobivanja adrese

9
Zastavice za čizme
0
Hex
2
Određene oznake koje se mogu postaviti za označavanje parametara protokola

11
IP adresa klijenta
0.0.0.0
red
4
IP adresa klijenta (ako postoji)

15
Vaša IP adresa klijenta
0.0.0.0
red
4
IP adresa koju nudi poslužitelj (ako je dostupna)

19
IP adresa sljedećeg poslužitelja
0.0.0.0
red
4
IP adresa poslužitelja (ako je poznata)

23
IP adresa relejnog agenta
172.16.114.41
red
4
IP adresa relejnog agenta (na primjer, prekidač)

27
MAC adresa klijenta
14:d6:4d:a7:c9:55
Hex
6
MAC adresa pošiljatelja paketa (klijenta)

31
Ispuna adrese hardvera klijenta
 
Hex
10
Rezervirano mjesto. Obično ispunjeno nulama

41
Naziv hosta poslužitelja
 
red
64
Naziv DHCP poslužitelja. Obično se ne prenosi

105
Naziv datoteke za pokretanje
 
red
128
Naziv datoteke na poslužitelju koji koriste stanice bez diska prilikom podizanja sustava

235
Čarobni kolačići
63: 82: 53: 63
Hex
4
“Magični” broj, prema kojem, uklj. možete utvrditi da ovaj paket pripada DHCP protokolu

DHCP opcije. Može ići bilo kojim redoslijedom

236
Broj opcije
53
prosinca
1
Opcija 53, koja specificira vrstu DHCP paketa

1 - DHCPDISCOVER
3 - DHC PREDUHTJEV
2 - DHCPPONUDA
5 - DHCPACK
8 - DHCPINFORM

 
Duljina opcije
1
prosinca
1

 
Vrijednost opcije
1
prosinca
1

 
Broj opcije
50
prosinca
1
Koju IP adresu klijent želi primiti?

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
172.16.134.61
red
4

 
Broj opcije
55
 
1
Parametri mreže koje zahtijeva klijent. Sastav može varirati

01 — Mrežna maska
03 - Prijelaz
06 - DNS
oc — Ime glavnog računala
0f - naziv mrežne domene
1c - adresa zahtjeva za emitiranje (emitiranje)
42 - Naziv TFTP poslužitelja
79 - Bezklasna statična ruta

 
Duljina opcije
8
 
1

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

 
Broj opcije
82
prosinca
 
Opcija 82, koja prenosi MAC adresu repetitorskog uređaja i neke dodatne vrijednosti.

Najčešće je to port preklopnika na kojem radi krajnji DHCP klijent.Ova opcija sadrži dodatne parametre.Prvi bajt je broj “podopcije”, drugi je njena dužina, zatim vrijednost.

U ovom slučaju, u opciji 82, podopcije su ugniježđene:
ID kruga agenta = 00:04:00:01:00:04, gdje su posljednja dva bajta port DHCP klijenta s kojeg je zahtjev došao

Agent Remote ID = 00:06:c8:be:19:93:11:48 - MAC adresa DHCP repetitorskog uređaja

 
Duljina opcije
18
prosinca
 

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

 
Kraj paketa
255
prosinca
1
255 simbolizira kraj paketa

DHCPPONUDA

Čim server primi DHCPDISCOVER paket i ako vidi da klijentu može ponuditi nešto od traženog, onda za to generira odgovor - DHCPDISCOVER. Odgovor se šalje na port "odakle je došao", emitiranjem, jer u ovom trenutku klijent još nema IP adresu, stoga može prihvatiti paket samo ako je poslan emitiranjem. Klijent prepoznaje da je to paket za njega po svojoj MAC adresi unutar paketa, kao i transakcijskom broju koji generira u trenutku kreiranja prvog paketa.

DHCPOFFER Tablica strukture paketa

Pozicija u paketu
Naziv vrijednosti (uobičajeno)
Primjer
ideja
Bajt
razjašnjenje

1
Zahtjev za pokretanje
1
Hex
1
Vrsta poruke. 1 - zahtjev od klijenta do poslužitelja, 2 - odgovor od poslužitelja do klijenta

2
Vrsta hardvera
1
Hex
1
Vrsta hardverske adrese, u ovom protokolu 1 - MAC

3
Duljina hardverskih adresa
6
Hex
1
Duljina MAC adrese uređaja

4
Hmelj
1
Hex
1
Broj međuputova

5
ID transakcije
23:cf:de:1d
Hex
4
Jedinstveni identifikator transakcije. Generira klijent na početku operacije zahtjeva

7
Prošla je druga
0
Hex
4
Vrijeme u sekundama od početka procesa dobivanja adrese

9
Zastavice za čizme
0
Hex
2
Određene oznake koje se mogu postaviti za označavanje parametara protokola. U ovom slučaju, 0 znači Unicast tip zahtjeva

11
IP adresa klijenta
0.0.0.0
red
4
IP adresa klijenta (ako postoji)

15
Vaša IP adresa klijenta
172.16.134.61
red
4
IP adresa koju nudi poslužitelj (ako je dostupna)

19
IP adresa sljedećeg poslužitelja
0.0.0.0
red
4
IP adresa poslužitelja (ako je poznata)

23
IP adresa relejnog agenta
172.16.114.41
red
4
IP adresa relejnog agenta (na primjer, prekidač)

27
MAC adresa klijenta
14:d6:4d:a7:c9:55
Hex
6
MAC adresa pošiljatelja paketa (klijenta)

31
Ispuna adrese hardvera klijenta
 
Hex
10
Rezervirano mjesto. Obično ispunjeno nulama

41
Naziv hosta poslužitelja
 
red
64
Naziv DHCP poslužitelja. Obično se ne prenosi

105
Naziv datoteke za pokretanje
 
red
128
Naziv datoteke na poslužitelju koji koriste stanice bez diska prilikom podizanja sustava

235
Čarobni kolačići
63: 82: 53: 63
Hex
4
“Magični” broj, prema kojem, uklj. možete utvrditi da ovaj paket pripada DHCP protokolu

DHCP opcije. Može ići bilo kojim redoslijedom

236
Broj opcije
53
prosinca
1
Opcija 53, koja definira DHCP 2 tip paketa - DHCPOFFER

 
Duljina opcije
1
prosinca
1

 
Vrijednost opcije
2
prosinca
1

 
Broj opcije
1
prosinca
1
Mogućnost da se DHCP klijentu ponudi mrežna maska

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
255.255.224.0
red
4

 
Broj opcije
3
prosinca
1
Mogućnost da se DHCP klijentu ponudi zadani pristupnik

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
172.16.12.1
red
4

 
Broj opcije
6
prosinca
1
Mogućnost ponude DHCP DNS klijentu

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
8.8.8.8
red
4

 
Broj opcije
51
prosinca
1
Životni vijek izdanih mrežnih parametara u sekundama, nakon čega ih DHCP klijent mora ponovno zatražiti

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
86400
prosinca
4

 
Broj opcije
82
prosinca
1
Opcija 82, ponavlja ono što je došlo u DHCPDISCOVER

 
Duljina opcije
18
prosinca
1

 
Vrijednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
prosinca
18

 
Kraj paketa
255
prosinca
1
255 simbolizira kraj paketa

DHCPPRIJAVA

Nakon što klijent primi DHCPOFFER, on formira paket tražeći mrežne parametre ne svim DHCP poslužiteljima na mreži, već samo jednom određenom, čija mu se DHCPOFFER ponuda najviše “sviđa”. Kriteriji "sviđa mi se" mogu biti različiti i ovise o klijentovoj implementaciji DHCP-a. Primatelj zahtjeva naveden je pomoću MAC adrese DHCP poslužitelja. Također, DHCPREQUEST paket može poslati klijent bez prethodnog generiranja DHCPDISCOVER, ako je IP adresa poslužitelja već prethodno dobivena.

DHCPREQUEST Tablica strukture paketa

Pozicija u paketu
Naziv vrijednosti (uobičajeno)
Primjer
ideja
Bajt
razjašnjenje

1
Zahtjev za pokretanje
1
Hex
1
Vrsta poruke. 1 - zahtjev od klijenta do poslužitelja, 2 - odgovor od poslužitelja do klijenta

2
Vrsta hardvera
1
Hex
1
Vrsta hardverske adrese, u ovom protokolu 1 - MAC

3
Duljina hardverskih adresa
6
Hex
1
Duljina MAC adrese uređaja

4
Hmelj
1
Hex
1
Broj međuputova

5
ID transakcije
23:cf:de:1d
Hex
4
Jedinstveni identifikator transakcije. Generira klijent na početku operacije zahtjeva

7
Prošla je druga
0
Hex
4
Vrijeme u sekundama od početka procesa dobivanja adrese

9
Zastavice za čizme
8000
Hex
2
Određene oznake koje se mogu postaviti za označavanje parametara protokola. U ovom slučaju postavljeno je "emitiranje".

11
IP adresa klijenta
0.0.0.0
red
4
IP adresa klijenta (ako postoji)

15
Vaša IP adresa klijenta
172.16.134.61
red
4
IP adresa koju nudi poslužitelj (ako je dostupna)

19
IP adresa sljedećeg poslužitelja
0.0.0.0
red
4
IP adresa poslužitelja (ako je poznata)

23
IP adresa relejnog agenta
172.16.114.41
red
4
IP adresa relejnog agenta (na primjer, prekidač)

27
MAC adresa klijenta
14:d6:4d:a7:c9:55
Hex
6
MAC adresa pošiljatelja paketa (klijenta)

31
Ispuna adrese hardvera klijenta
 
Hex
10
Rezervirano mjesto. Obično ispunjeno nulama

41
Naziv hosta poslužitelja
 
red
64
Naziv DHCP poslužitelja. Obično se ne prenosi

105
Naziv datoteke za pokretanje
 
red
128
Naziv datoteke na poslužitelju koji koriste stanice bez diska prilikom podizanja sustava

235
Čarobni kolačići
63: 82: 53: 63
Hex
4
“Magični” broj, prema kojem, uklj. možete utvrditi da ovaj paket pripada DHCP protokolu

DHCP opcije. Može ići bilo kojim redoslijedom

236
Broj opcije
53
prosinca
3
Opcija 53, koja definira DHCP tip paketa 3 - DHCPREQUEST

 
Duljina opcije
1
prosinca
1

 
Vrijednost opcije
3
prosinca
1

 
Broj opcije
61
prosinca
1
ID klijenta: 01 (za Ehernet) + MAC adresa klijenta

 
Duljina opcije
7
prosinca
1

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

 
Broj opcije
60
prosinca
 
"Identifikator klase dobavljača". U mom slučaju, javlja verziju DHCP klijenta. Možda drugi uređaji vraćaju nešto drugačije. Windows na primjer izvještava o MSFT 5.0

 
Duljina opcije
11
prosinca
 

 
Vrijednost opcije
udhcp 0.9.8
red
 

 
Broj opcije
55
 
1
Parametri mreže koje zahtijeva klijent. Sastav može varirati

01 — Mrežna maska
03 - Prijelaz
06 - DNS
oc — Ime glavnog računala
0f - naziv mrežne domene
1c - adresa zahtjeva za emitiranje (emitiranje)
42 - Naziv TFTP poslužitelja
79 - Bezklasna statična ruta

 
Duljina opcije
8
 
1

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

 
Broj opcije
82
prosinca
1
Opcija 82, ponavlja ono što je došlo u DHCPDISCOVER

 
Duljina opcije
18
prosinca
1

 
Vrijednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
prosinca
18

 
Kraj paketa
255
prosinca
1
255 simbolizira kraj paketa

DHCPACK

Kao potvrda da “da, tako je, ovo je vaša IP adresa i neću je dati nikome drugome” od DHCP poslužitelja služi paket u DHCPACK formatu od poslužitelja do klijenta. Šalje se emitirano kao i drugi paketi. Iako, u donjem kodu za DHCP poslužitelj implementiran u Pythonu, za svaki slučaj, dupliciram svaki zahtjev za emitiranje slanjem paketa na određenu IP adresu klijenta, ako je već poznata. Štoviše, DHCP poslužitelj uopće ne mari je li DHCPACK paket stigao do klijenta. Ako klijent ne primi DHCPACK, onda nakon nekog vremena jednostavno ponavlja DHCPREQUEST

DHCPACK tablica strukture paketa

Pozicija u paketu
Naziv vrijednosti (uobičajeno)
Primjer
ideja
Bajt
razjašnjenje

1
Zahtjev za pokretanje
2
Hex
1
Vrsta poruke. 1 - zahtjev od klijenta do poslužitelja, 2 - odgovor od poslužitelja do klijenta

2
Vrsta hardvera
1
Hex
1
Vrsta hardverske adrese, u ovom protokolu 1 - MAC

3
Duljina hardverskih adresa
6
Hex
1
Duljina MAC adrese uređaja

4
Hmelj
1
Hex
1
Broj međuputova

5
ID transakcije
23:cf:de:1d
Hex
4
Jedinstveni identifikator transakcije. Generira klijent na početku operacije zahtjeva

7
Prošla je druga
0
Hex
4
Vrijeme u sekundama od početka procesa dobivanja adrese

9
Zastavice za čizme
8000
Hex
2
Određene oznake koje se mogu postaviti za označavanje parametara protokola. U ovom slučaju postavljeno je "emitiranje".

11
IP adresa klijenta
0.0.0.0
red
4
IP adresa klijenta (ako postoji)

15
Vaša IP adresa klijenta
172.16.134.61
red
4
IP adresa koju nudi poslužitelj (ako je dostupna)

19
IP adresa sljedećeg poslužitelja
0.0.0.0
red
4
IP adresa poslužitelja (ako je poznata)

23
IP adresa relejnog agenta
172.16.114.41
red
4
IP adresa relejnog agenta (na primjer, prekidač)

27
MAC adresa klijenta
14:d6:4d:a7:c9:55
Hex
6
MAC adresa pošiljatelja paketa (klijenta)

31
Ispuna adrese hardvera klijenta
 
Hex
10
Rezervirano mjesto. Obično ispunjeno nulama

41
Naziv hosta poslužitelja
 
red
64
Naziv DHCP poslužitelja. Obično se ne prenosi

105
Naziv datoteke za pokretanje
 
red
128
Naziv datoteke na poslužitelju koji koriste stanice bez diska prilikom podizanja sustava

235
Čarobni kolačići
63: 82: 53: 63
Hex
4
“Magični” broj, prema kojem, uklj. možete utvrditi da ovaj paket pripada DHCP protokolu

DHCP opcije. Može ići bilo kojim redoslijedom

236
Broj opcije
53
prosinca
3
Opcija 53, koja definira DHCP paket tipa 5 - DHCPACK

 
Duljina opcije
1
prosinca
1

 
Vrijednost opcije
5
prosinca
1

 
Broj opcije
1
prosinca
1
Mogućnost da se DHCP klijentu ponudi mrežna maska

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
255.255.224.0
red
4

 
Broj opcije
3
prosinca
1
Mogućnost da se DHCP klijentu ponudi zadani pristupnik

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
172.16.12.1
red
4

 
Broj opcije
6
prosinca
1
Mogućnost ponude DHCP DNS klijentu

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
8.8.8.8
red
4

 
Broj opcije
51
prosinca
1
Životni vijek izdanih mrežnih parametara u sekundama, nakon čega ih DHCP klijent mora ponovno zatražiti

 
Duljina opcije
4
prosinca
1

 
Vrijednost opcije
86400
prosinca
4

 
Broj opcije
82
prosinca
1
Opcija 82, ponavlja ono što je došlo u DHCPDISCOVER

 
Duljina opcije
18
prosinca
1

 
Vrijednost opcije
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
prosinca
18

 
Kraj paketa
255
prosinca
1
255 simbolizira kraj paketa

Instalacija

Instalacija se zapravo sastoji od instaliranja python modula potrebnih za rad. Pretpostavlja se da je MySQL već instaliran i konfiguriran.

FreeBSD

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

Ubuntu

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

Stvaramo MySQL bazu podataka, učitavamo pydhcp.sql dump u nju i konfiguriramo konfiguracijsku datoteku.

Konfiguracija

Sve postavke poslužitelja nalaze se u xml datoteci. Referentna 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 domaćin test test pydhcp opcija_8.8.8.8_hex:sw_port82:1:20 opcija_22_hex:sw_port82:2:16 opcija_18_hex:sw_mac:82:26 40 odaberite ip,mask,router,dns od korisnika gdje je upper(mac)=upper('{option_3_AgentRemoteId_hex}') i upper(port)=upper('{option_1_AgentCircuitId_port_hex}') odaberite ip,mask,router,dns od korisnika gdje je upper(mac)=upper('{sw_mac}') i upper(port)=upper('{sw_port82}') odaberite ip,mask,router,dns od korisnika gdje je upper(mac)=upper('{ClientMacAddress}') umetnite u povijest (id,dt,mac,ip,comment) vrijednosti (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Sada detaljnije o oznakama:

Odjeljak dhcpserver opisuje osnovne postavke za pokretanje poslužitelja, naime:

  • host - koju IP adresu poslužitelj sluša na portu 67
  • emitiranje - koji ip je emitiranje za DHCPOFFER i DHCPACK
  • DHCPServer - koji je ip DHCP poslužitelja
  • LeaseTime vrijeme zakupa izdane IP adrese
  • ThreadLimit - koliko se niti radi istovremeno za obradu dolaznih UDP paketa na portu 67. Trebalo bi pomoći u projektima s velikim opterećenjem 😉
  • defaultMask,defaultRouter,defaultDNS - što se pretplatniku nudi prema zadanim postavkama ako je IP pronađen u bazi podataka, ali za njega nisu navedeni dodatni parametri

odjeljak mysql:

host, korisničko ime, lozinka, osnovno ime - sve govori za sebe. Približna struktura baze podataka objavljena je na GitHub

Odjeljak upita: ovdje su opisani zahtjevi za primanje PONUDE/ACK-a:

  • offer_count — broj redaka sa zahtjevima koji vraćaju rezultat poput ip,mask,router,dns
  • ponuda_n — niz upita. Ako je povrat prazan, tada se izvršava sljedeći zahtjev ponude
  • history_sql - upit koji upisuje, na primjer, u “povijest autorizacije” za pretplatnika

Zahtjevi mogu uključivati ​​bilo koje varijable iz odjeljka opcija ili opcije iz DHCP protokola.

Odjeljak s opcijama. Ovdje postaje još zanimljivije. Ovdje možemo stvoriti varijable koje kasnije možemo koristiti u odjeljku upita.

Na primjer:

option_82_hex:sw_port1:20:22

, ovaj naredbeni redak uzima cijeli redak koji je došao u opciji DHCP zahtjeva 82, u heksadecimalnom formatu, u rasponu od 20 do uključivo 22 bajta i stavlja ga u novu varijablu sw_port1 (sklopni port odakle je zahtjev došao)

option_82_hex:sw_mac:26:40

, definirajte varijablu sw_mac, uzimajući hex iz raspona 26:40

Sve moguće opcije koje se mogu koristiti u upitima možete vidjeti pokretanjem poslužitelja s prekidačem -d. Vidjet ćemo nešto poput ovog dnevnika:

--a DHCPINFORM paket je stigao na port 67, sa 0025224ad764, b'x91xa5xe0xa3xa5xa9-x8fx8a', ('172.30.114.25', 68) {'ClientMacAddress': '0025224ad764', 'ClientMacAddressBy te': b'x00 7%"Jxd91d' , 'HType': 'Ethernet', 'HostName': b'x5xa0xe3xa5xa9xa8-x8fx43a', 'ReqListDNS': Istina, 'ReqListDomainName': Istina, 'ReqListPerfowmRouterDiscover': Istina, 'ReqListRouter': Istina, 'ReqListStaticRoute ': Istina, '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', 'opcija12': 53, 'opcija53': 55, 'opcija55': 60, 'opcija60': 61, 'opcija61': 82, 'opcija82': 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': Netočno, 'sekundi': 001, 'siaddr': '589', 'sw_mac': '2e1eb06ad', 'sw_port89': '8', 'xidbyte': b'

U skladu s tim, možemo omotati bilo koju varijablu u {} i ona će se koristiti u SQL upitu.

Zabilježimo za povijest da je klijent primio IP adresu:

DHCP+Mysql poslužitelj u Pythonu

DHCP+Mysql poslužitelj u Pythonu

Pokretanje poslužitelja

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

— d način izlaza konzole DEBUG
- c <ime datoteke> konfiguracijska datoteka

Ispitivanje

A sada više detalja o implementaciji poslužitelja u Python. To je bol. Python se učio u hodu. Mnogi trenuci napravljeni su u stilu "vau, nekako sam uspio." Uopće nije optimiziran i ostao je u ovom obliku uglavnom zbog malog iskustva u razvoju Pythona. Zadržat ću se na najzanimljivijim aspektima implementacije poslužitelja u "kodu".

Parser XML konfiguracijske datoteke

Koristi se standardni Python modul xml.dom. Čini se jednostavno, no tijekom implementacije bio je primjetan nedostatak jasne dokumentacije i primjera na mreži koja koristi ovaj modul.

    stablo = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") za elem u 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") za elem u 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 u qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data za num u raspon(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 u opcijama: node=elem.getElementsByTagName("option") za opcije u čvoru : optionsMod.append(options.firstChild.data)

Višenitnost

Čudno, višenitnost u Pythonu implementirana je vrlo jasno i jednostavno.

def PacketWork(data,addr): ... # implementacija analiziranja dolaznog paketa i odgovaranja na njega ... while True: data, addr = udp_socket.recvfrom(1024) # čekanje UDP paketa thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # kako je došlo - pokrećemo prethodno definiranu PacketWork funkciju u pozadini s parametrima tijekom threadinga.active_count() >gconfig["dhcp_ThreadLimit"]: vrijeme. sleep(1) # ako je broj Već je pokrenuto više niti nego u postavkama, čekamo da ih bude manje

Primi/pošalji DHCP paket

Kako biste presreli UDP pakete koji dolaze kroz mrežnu karticu, morate "podići" utičnicu:

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

, gdje su zastave:

  • AF_INET - znači da će format adrese biti IP: port. Također može postojati AF_UNIX - gdje je adresa dana imenom datoteke.
  • SOCK_DGRAM - znači da ne prihvaćamo “raw paket”, već onaj koji je već prošao kroz vatrozid, te s djelomično trimiranim paketom. Oni. primamo samo UDP paket bez “fizičke” komponente omotača UDP paketa. Ako koristite oznaku SOCK_RAW, tada ćete također morati analizirati ovaj "omot".

Slanje paketa može biti poput emitiranja:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #prebacite utičnicu u način emitiranja rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, te na adresu “odakle je paket stigao”:

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # prebacivanje utičnice u način rada s više slušatelja rz=udp_socket.sendto(packetack, addr)

, gdje SOL_SOCKET znači "razina protokola" za opcije podešavanja,

, SO_BROADCAST opcija da je paket kacige "broadcast"

  ,SO_REUSEADDR opcija prebacuje utičnicu u način rada "mnogo slušatelja". U teoriji je u ovom slučaju nepotrebno, ali na jednom od FreeBSD poslužitelja na kojima sam testirao kod nije radio bez ove opcije.

Raščlanjivanje DHCP paketa

Ovdje mi se jako svidio Python. Ispada da vam izvan okvira omogućuje da budete prilično fleksibilni s bytecodeom. Omogućujući da se vrlo lako prevede u decimalne vrijednosti, nizove i hex - tj. to je ono što nam zapravo treba da bismo razumjeli strukturu paketa. Tako, na primjer, možete dobiti niz bajtova u HEX i samo bajtove:

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

, spakirajte bajtove u strukturu:

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

Dohvati IP iz strukture:

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

I obrnuto:

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

To je sve za sada 😉

Izvor: www.habr.com

Dodajte komentar