
Selle projekti eesmÀrk oli:
- DHCP protokolli uurimine IPv4 vÔrgus
- Python'i Ă”ppimine (veidi rohkem kui nullist đ )
- serveri asendamine (minu fork), originaal , mida on ĂŒha raskem uue operatsioonisĂŒsteemi jaoks kokku panna. Ja ei meeldi, et binarni ei saa "otse praegu" asendada
- töökorras DHCP serveri saamine, mis vÔimaldab abonendi IP aadressi valimist abonendi MAC aadressi vÔi MAC-aadressi ja pordi (Option 82) sidumise pÔhjal.
- jÀrgmise jalgratta kirjutamine (O! see on minu lemmiktegevus)
- saada kukkumist oma oskamatuse tĂ”ttu HabrHabr'is (veel parem, kui kutse) đ
Tulemus: töötab đ Proovitud FreeBSD ja Ubuntu OS-iga. Teoreetiliselt saaks koodi kasutada mis tahes operatsioonisĂŒsteemis, kuna koodis ei tundu olevat spetsiifilisi seoseid.
Olge ettevaatlik! Edasi on palju.
Link hoidla jaoks neile, kes tahavad .
Installeerimise, seadistamise ja tulemuse kasutamise protsess "materjali Ă”ppimise" kohta on palju allpool, ning seejĂ€rel natuke teooriat DHCP protokolli kohta. Endale. Ja ajaloo jaoks đ
Veidi teooriat
Mis on DHCP
See on vĂ”rguprotokoll, mis vĂ”imaldab seadmel teada saada oma IP aadress (ja muid parameetreid nagu lĂŒĂŒs, DNS ja muud), DHCP serverilt. Pakettide vahetus toimub UDP protokolli kaudu. Ăldine tööprintsiip seadme, kui ta kĂŒsib vĂ”rgu parameetreid, on jĂ€rgmine:
- Seade (kliendi) saadab laialdaselt UDP pĂ€ringu (DHCPDISCOVER) ĂŒle terve vĂ”rgu, kĂŒsides "nii, keegi, andke mulle IP aadress". Tavaliselt (aga mitte alati) toimub pĂ€ring 68 porti lĂ€bi (allikas) ja sihtkoht on 67 port (sihtkoht). MĂ”ned seadmed saadavad pakette ka 67 porti kaudu. DHCPDISCOVER paketi sees on kliendi seadme MAC aadress.
- KĂ”ik DHCP serverid, mis asuvad vĂ”rgus (neid vĂ”ib olla mitu), koostavad seadme jaoks, kes lĂ€kitas DHCPDISCOVER'i, ettepaneku DHCPOFFER vĂ”rgu seadistustega ja saadavad selle laialdaselt ĂŒle vĂ”rgu. Paketi sihtkohta tuvastamine toimub varasemalt antud MAC aadressi pĂ”hjal, mis anti DHCPDISCOVER pĂ€ringu ajal.
- Klient vÔtab vastu pakette vÔrgu seadistuste ettepanekutega, valib kÔige sobivama (kriteeriumid vÔivad olla erinevad, nÀiteks ka paketi edastamise ajast, vahepealsetest marsruutidest) ja teeb meeldinud DHCP serverile "ametliku pÀringu" DHCPREQUEST koos vÔrgu seadistustega. Sel juhul lÀheb pakett juba konkreetsele DHCP serverile.
- Server, kes sai DHCPREQUEST'i, saadab paketi formaadis DHCPACK, kus loetletakse uuesti vÔrgu seadistused, mis on mÔeldud sellele kliendile.

Lisaks on olemas DHCPINFORM paketid, mis liiguvad kliendi poolt ja mille eesmÀrk on teavitada DHCP serverit, et "klient on elus" ja kasutab antud vÔrgu seadistusi. Selle serveri rakenduses need paketid ignoreeritakse.
Pakettide formaat
KokkuvÔttes nÀeb Etherneti paketi raam vÀlja ligikaudu selline:
![]()
KÀsitleme meie juhul ainult UDP paketi sisu, ilma OSI tasemete protokollide pÀiseid, nimelt DHCP struktuuri:
DHCPDISCOVER
Nii, protsess seadme IP aadressi saamiseks algab sellest, et DHCP klient saadab laialdaselt pÀringu port 68-le aadressile 255.255.255.255:67. Selles paketis hÔlmab klient oma MAC aadressi ning samuti, mida ta DHCP serverilt soovib. Paketi struktuur on allpool toodud tabelis.
DHCPDISCOVER paketi struktuuri tabel
Positsioon paketis
MÔiste
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, kĂ€esolevas protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahemarsruutide arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Ainulaadne tehingu identifikaator. Klient genereerib selle kĂŒsimise alguses.
7
Teine möödunud aeg
0
Hex
4
Aeg sekundites alates aadressi hankimise protsessi algusest
9
Bootp lipud
0
Hex
2
MÔned lipud, mis vÔivad olla paigaldatud, et mÀrkida protokolli parameetreid
11
Kliendi IP aadress
0.0.0.0
String
4
Kliendi IP aadress (kui on olemas)
15
Teie kliendi IP aadress
0.0.0.0
String
4
Serveri poolt ettenÀhtud IP aadress (kui on olemas)
19
JĂ€rgimise serveri IP aadress
0.0.0.0
String
4
Serveri IP aadress (kui on teada)
23
Edastaja IP aadress
172.16.114.41
String
4
Edastaja IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (kliendi)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
String
64
DHCP serveri nimi. Tavaliselt ei edastata
105
Boot faili nimi
Â
String
128
Faili nimi serveris, mida kasutatakse ketasteta jaamadelt kÀivitamiseks
235
Magic cookie
63:82:53:63
Hex
4
"Karmâ number, mille abil saab ka mÀÀrata, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
1
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi
1 â DHCPDISCOVER
3 â DHCPREQUEST
2 â DHCPOFFER
5 â DHCPACK
8 â DHCPINFORM
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
1
Dec
1
Â
Valiku number
50
Dec
1
Milline IP-aadress on kliendil soov saada
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.134.61
String
4
Â
Valiku number
55
Â
1
Kliendi poolt kĂŒsitud vĂ”rguparametrid. Koostis vĂ”ib olla erinev
01 â AlamvĂ”rgu mask
03 â LĂŒĂŒsi
06 â DNS
oc â Hostinimi
0f â vĂ”rgi domeeninimi
1c â Ăksikcasti aadress (broadcast)
42 â TFTP serveri nimi
79 â Ilma klassita staatiline marsruut
Â
Valiku pikkus
8
Â
1
Â
Valiku vÀÀrtus
01:03:06:0c:0f:1c:42:79
Â
8
Â
Valiku number
82
Dec
Â
Valik 82, kus edastatakse seadme MAC-aadress â edastaja ja mĂ”ned lisandvÀÀrtused.
Tavaliselt â lĂŒliti port, kus lĂ”ppkliendi DHCP töötab. Sel valikul on "peidetud" lisaparameetrid. Esimene bait â "alavaliku" number, teine ââtema pikkus, seejĂ€rel tema vÀÀrtus.
Selles valikus 82 on peidetud alavalikud:
Agent Circuit ID = 00:04:00:01:00:04, kus viimased kaks bait on DHCP kliendi port, kust pÀring tuli
Agent Remote ID = 00:06:c8:be:19:93:11:48 â edastaja DHCP seadme MAC-aadress
Â
Valiku pikkus
18
Dec
Â
Â
Valiku vÀÀrtus
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
Â
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPOFFER
Kuna server saab DHCPDISCOVER paki ja kui ta nĂ€eb, et ta suudab kliendile midagi pakkuda, moodustab ta vastuse â DHCPDISCOVER. Vastus saadetakse sadamasse "kust see tuli", laiemalt, kuna sel hetkel pole kliendil veel IP-aadressi, seega saab paketti vastu vĂ”tta ainult siis, kui see saadetakse laiale. Kliendi tuvastab, et see on tema pakett, MAC-aadressi ja samuti tehingu numbri jĂ€rgi, mille ta genereerib esimese paketi loomisel.
DHCPOFFER paketi struktuuri tabel
Positsioon paketis
Nime vÀÀrtus (ĂŒldiselt aktsepteeritud)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, kĂ€esolevas protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahemarsruutide arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Ainulaadne tehingu identifikaator. Klient genereerib selle kĂŒsimise alguses.
7
Teine möödunud aeg
0
Hex
4
Aeg sekundites alates aadressi hankimise protsessi algusest
9
Bootp lipud
0
Hex
2
MĂ”ned lipud, mis vĂ”ivad olla seadistatud, et nĂ€idata protokolli parameetreid. Antud juhul tĂ€hendab 0 kĂŒsimuse tĂŒĂŒpi Unicast
11
Kliendi IP aadress
0.0.0.0
String
4
Kliendi IP aadress (kui on olemas)
15
Teie kliendi IP aadress
172.16.134.61
String
4
Serveri poolt ettenÀhtud IP aadress (kui on olemas)
19
JĂ€rgimise serveri IP aadress
0.0.0.0
String
4
Serveri IP aadress (kui on teada)
23
Edastaja IP aadress
172.16.114.41
String
4
Edastaja IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (kliendi)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
String
64
DHCP serveri nimi. Tavaliselt ei edastata
105
Boot faili nimi
Â
String
128
Faili nimi serveris, mida kasutatakse ketasteta jaamadelt kÀivitamiseks
235
Magic cookie
63:82:53:63
Hex
4
"Karmâ number, mille abil saab ka mÀÀrata, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
1
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi 2 â DHCPOFFER
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
2
Dec
1
Â
Valiku number
1
Dec
1
Valik, mis pakub DHCP kliendile alamvÔrgu maski
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
255.255.224.0
String
4
Â
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaikimisi lĂŒĂŒsi
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.12.1
String
4
Â
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS-i
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
8.8.8.8
String
4
Â
Valiku number
51
Dec
1
Antud vĂ”rguparametrite kehtivusaeg sekundites, mille möödumisel DHCP klient peab taas kĂŒsima
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
86400
Dec
4
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER-ist
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPREQUEST
PĂ€rast seda, kui klient on saanud DHCPOFFER-i, moodustab ta paketi, et kĂŒsida vĂ”rguparametreid mitte enam kĂ”igilt DHCP serveritelt, vaid ainult ĂŒhelt konkreetselt, kelle DHCPOFFER pakkumine talle kĂ”ige rohkem "meeldis". Kriteeriumid, mis "meeldis" vĂ”ivad olla erinevad ja sĂ”ltuvad DHCP kliendi teostusest. Saaja MAC-aadressi kaudu mÀÀratakse, kes see server DHCP on. Samuti vĂ”ib DHCPREQUEST paketti saata klient ilma eelneva DHCPDISCOVER-i moodustamiseta, kui IP-aadress serverilt on juba varem saadud.
DHCPREQUEST paketi struktuuri tabel
Positsioon paketis
Nime vÀÀrtus (ĂŒldiselt aktsepteeritud)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
1
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, kĂ€esolevas protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahemarsruutide arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Ainulaadne tehingu identifikaator. Klient genereerib selle kĂŒsimise alguses.
7
Teine möödunud aeg
0
Hex
4
Aeg sekundites alates aadressi hankimise protsessi algusest
9
Bootp lipud
8000
Hex
2
MÔned lipud, mis vÔivad olla seadistatud, et nÀidata protokolli parameetreid. Antud juhul on seadistatud "laiali"
11
Kliendi IP aadress
0.0.0.0
String
4
Kliendi IP aadress (kui on olemas)
15
Teie kliendi IP aadress
172.16.134.61
String
4
Serveri poolt ettenÀhtud IP aadress (kui on olemas)
19
JĂ€rgimise serveri IP aadress
0.0.0.0
String
4
Serveri IP aadress (kui on teada)
23
Edastaja IP aadress
172.16.114.41
String
4
Edastaja IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (kliendi)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
String
64
DHCP serveri nimi. Tavaliselt ei edastata
105
Boot faili nimi
Â
String
128
Faili nimi serveris, mida kasutatakse ketasteta jaamadelt kÀivitamiseks
235
Magic cookie
63:82:53:63
Hex
4
"Karmâ number, mille abil saab ka mÀÀrata, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
3
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi 3 â DHCPREQUEST
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
3
Dec
1
Â
Valiku number
61
Dec
1
Kliendi identifikaator: 01 (Etherneti jaoks) + kliendi MAC-aadress
Â
Valiku pikkus
7
Dec
1
Â
Valiku vÀÀrtus
01:2c:ab:25:ff:72:a6
Hex
7
Â
Valiku number
60
Dec
Â
"Vendor class identifier". Minu juhul edastab see DHCP klienti versiooni. VÔimalik, et teised seadmed edastavad midagi muud. Windows nÀiteks teatab MSFT 5.0
Â
Valiku pikkus
11
Dec
Â
Â
Valiku vÀÀrtus
udhcp 0.9.8
String
Â
Â
Valiku number
55
Â
1
Kliendi poolt kĂŒsitud vĂ”rguparametrid. Koostis vĂ”ib olla erinev
01 â AlamvĂ”rgu mask
03 â LĂŒĂŒsi
06 â DNS
oc â Hostinimi
0f â vĂ”rgi domeeninimi
1c â Ăksikcasti aadress (broadcast)
42 â TFTP serveri nimi
79 â Ilma klassita staatiline marsruut
Â
Valiku pikkus
8
Â
1
Â
Valiku vÀÀrtus
01:03:06:0c:0f:1c:42:79
Â
8
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER-ist
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
DHCPACK
DHCP serveri poolt pakett DHCPACK kujul, mis kinnitab, et "jah, see on kindlasti sinu IP-aadress ja rohkem ma seda kellelegi ei anna", saadetakse laiale. Samuti nagu teised paketid, saadetakse see levis. Kuigi allolevas Pythonis rakendatud DHCP serveri koodis dubleerin igasuguste laiale suunatud pĂ€ringute korral paketi saatmist konkreetsele IP kliendile, kui see on juba teada. Ăkski DHCP server ei muretse, kas DHCPACK pakett jĂ”udis kliendini. Kui klient ei saa DHCPACK-i, korratakse mĂ”ne aja pĂ€rast DHCPREQUEST-i.
DHCPACK paketi struktuuri tabel
Positsioon paketis
Nime vÀÀrtus (ĂŒldiselt aktsepteeritud)
NĂ€ide
Vaade
Bait
Selgitus
1
Boot Request
2
Hex
1
SĂ”numi tĂŒĂŒp. 1 â pĂ€ring kliendilt serverile, 2 â vastus serverilt kliendile
2
Riistvara tĂŒĂŒp
1
Hex
1
Riistvara aadressi tĂŒĂŒp, kĂ€esolevas protokollis 1 â MAC
3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus
4
Hops
1
Hex
1
Vahemarsruutide arv
5
Tehingu ID
23:cf:de:1d
Hex
4
Ainulaadne tehingu identifikaator. Klient genereerib selle kĂŒsimise alguses.
7
Teine möödunud aeg
0
Hex
4
Aeg sekundites alates aadressi hankimise protsessi algusest
9
Bootp lipud
8000
Hex
2
MÔned lipud, mis vÔivad olla seadistatud, et nÀidata protokolli parameetreid. Antud juhul on seadistatud "laiali"
11
Kliendi IP aadress
0.0.0.0
String
4
Kliendi IP aadress (kui on olemas)
15
Teie kliendi IP aadress
172.16.134.61
String
4
Serveri poolt ettenÀhtud IP aadress (kui on olemas)
19
JĂ€rgimise serveri IP aadress
0.0.0.0
String
4
Serveri IP aadress (kui on teada)
23
Edastaja IP aadress
172.16.114.41
String
4
Edastaja IP aadress (nĂ€iteks lĂŒliti)
27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (kliendi)
31
Kliendi riistvara aadressi padjand
Â
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega
41
Serveri hostinimi
Â
String
64
DHCP serveri nimi. Tavaliselt ei edastata
105
Boot faili nimi
Â
String
128
Faili nimi serveris, mida kasutatakse ketasteta jaamadelt kÀivitamiseks
235
Magic cookie
63:82:53:63
Hex
4
"Karmâ number, mille abil saab ka mÀÀrata, et see pakett kuulub DHCP protokolli
DHCP valikud. Need vÔivad olla igas jÀrjekorras
236
Valiku number
53
Dec
3
Valik 53, mis mÀÀrab DHCP paketi tĂŒĂŒbi 5 â DHCPACK
Â
Valiku pikkus
1
Dec
1
Â
Valiku vÀÀrtus
5
Dec
1
Â
Valiku number
1
Dec
1
Valik, mis pakub DHCP kliendile alamvÔrgu maski
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
255.255.224.0
String
4
Â
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaikimisi lĂŒĂŒsi
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
172.16.12.1
String
4
Â
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS-i
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
8.8.8.8
String
4
Â
Valiku number
51
Dec
1
Antud vĂ”rguparametrite kehtivusaeg sekundites, mille möödumisel DHCP klient peab taas kĂŒsima
Â
Valiku pikkus
4
Dec
1
Â
Valiku vÀÀrtus
86400
Dec
4
Â
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER-ist
Â
Valiku pikkus
18
Dec
1
Â
Valiku vÀÀrtus
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Dec
18
Â
Paketi lÔpp
255
Dec
1
255 sĂŒmbolit tĂ€histab paketi lĂ”ppu
Installeerimine
Installeerimine seisneb tegelikult vajalike Python-moodulite installimises. Eeldatakse, et MySQL on juba installitud ja seadistatud.
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
Loome MySQL andmebaasi, laadime sellesse dumping faili pydhcp.sql, seadistame konfiguratsioonifaili.
Konfiguratsioon
KÔik serveri seaded on XML-formaadis failis. Viidatud fail:
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')NĂŒĂŒd natuke lĂ€hemalt siltide kohta:
dhcpserver sektsioon kirjeldab serveri kÀitamiseks vajalikke peamisi seadistusi, nimelt:
- host â milline IP aadress kuulab server 67. porti
- broadcast â milline IP on broidcast DHCPOFFER ja DHCPACK jaoks
- DHCPServer â mis IP on DHCP serveril
- LeaseTime â vĂ€ljastatud IP aadressi ĂŒĂŒriaeg
- ThreadLimit â kui palju samaaegselt vooge on aktiveeritud UDP pakettide töötlemiseks 67. porti. Eeldatakse, et see aitab kĂ”rge koormusega projektides đ
- defaultMask, defaultRouter, defaultDNS â see, mida pakutakse kliendile vaikimisi, kui IP on andmebaasis leitud, kuid lisaparameetreid ei ole mÀÀratud
mysql sektsioon:
host, username, password, basename â kĂ”ik rÀÀgib enda eest. Andmebaasi ligikaudne struktuur on postitatud
query sektsioon: siin kirjeldatakse pÀringute saamiseks OFFER/ACK:
- offer_count â ridade arv pĂ€ringutes, mis tagastavad tulemustena ip, mask, router, dns
- offer_n â pĂ€ringu rida. Kui tagastamine on tĂŒhi, siis teostatakse jĂ€rgmine pĂ€ring offer
- history_sql â pĂ€ring, mis kirjutab nĂ€iteks âautentimise ajaloosseâ vastavalt kliendile
PÀringutes vÔivad osaleda kÔik muutujad, mis on mÀÀratud options sektsioonis vÔi DHCP protokolli valikud.
options sektsioon. Siin on juba huvitavam. Siin saame luua muutujaid, mida saame hiljem kasutada query sektsioonis.
NĂ€iteks:
option_82_hex:sw_port1:20:22, see kÀsk vÔtab kogu rida, mis tuli DHCP pÀringus valikust 82, hex formaadis, vahemikus 20 kuni 22 baitide vahel ja salvestab selle uude muutujasse sw_port1 (switchi port, kust pÀring tuli)
option_82_hex:sw_mac:26:40, mÀÀratleme muutuja sw_mac, vÔttes hex vahemikust 26:40
KÔiki vÔimalikke valikuid, mida saab pÀringutes kasutada, saab nÀha serveri kÀivitamisel -d vÔtmega. NÀeme ligikaudu sellist logi:
--tuli DHCPINFORM pakk 67. porti, aadressilt 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'}Seega vÔime igasuguse muutuja asemel { } kasutada ja see kasutatakse SQL pÀringus.
Kinnitage ajaloo jaoks, et IP aadress, mille klient sai:


Serveri kÀivitamine
./pydhcpdb.py -d -c config.xml
â d - vĂ€ljundi reĆŸiim DEBUG
â c konfiguratsioonifail
KĂŒsimuste selgitamine
NĂŒĂŒd lĂ€hemalt serveri rakenduse kohta Pythonis. See on valus. Pythonit Ă”petati âlennulâ. Paljusid punkte on tehtud stiilis: âuhh, kuid midagi töötabâ. Need pole sugugi optimeeritud ja jĂ€etud selliseks peamiselt vĂ€hese Python arenduse kogemuse tĂ”ttu. JĂ€tkan kĂ”ige huvitavamate punktidega serveri rakendustes 'koodis'.
XML konfiguratsiooni faili parsija
Kasutatakse Python standardmodulit xml.dom. Tundub lihtne, kuid rakendamisel tundsin, et head dokumentatsiooni ja nÀiteid selle mooduli kasutamiseks veebis on vÀhe.
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)Mitme niidi olemasolu
Oma imelikul kombel on Pythonis mitmeharuline programmamine vÀga arusaadav ja lihtne.
def PacketWork(data, addr):
...
# saabumise paketi analĂŒĂŒsi ja sellele vastamise rakendamine
...
while True:
data, addr = udp_socket.recvfrom(1024) # ootame UDP paketti
thread = threading.Thread(target=PacketWork, args=(data, addr,)).start() # kui saabub, kÀivitame taustal eelnevalt mÀÀratud PacketWork funktsiooni parameetritega
while threading.active_count() > gconfig["dhcp_ThreadLimit"]:
time.sleep(1) # kui kÀivitatud lÔimede arv on suurem kui seadistustes, ootame kuni nende arv vÀhenebDHCP paketi vastuvÔtmine / saatmine
Kuna UDP pakettide tabamiseks, mis lÀbivad vÔrgukaarti, peab olema "soket" aktiveeritud:
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) udp_socket.bind((gconfig["dhcp_host"], 67))
, kus lipud:
- AF_INET â tĂ€hendab, et aadressi formaat on IP: port. Samuti vĂ”ib olla AF_UNIX â kus aadress mÀÀratakse faili nimega.
- SOCK_DGRAM â tĂ€hendab, et me ei vĂ”ta "toore paketti", vaid juba lĂ€bi tulemĂŒĂŒriga lĂ€bisĂ”idetud ja osaliselt kĂ€rbitud paketti. See tĂ€hendab, et saame ainult UDP paketti ilma "fĂŒĂŒsilise" UDP paketi ĂŒmbruseta. Kui kasutada lippu SOCK_RAW, tuleb samuti seda "ĂŒmbrust" analĂŒĂŒsida.
Paketis saatmine vÔib olla kas broidcastina:
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # lĂŒlitame soketi broidcasti saatmisreĆŸiimi
rz=udp_socket.sendto(packetack, (gconfig["broadcast"], 68)), samuti aadressile, "kust pakett tuli":
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # lĂŒlitame soketi "mitme kuulajaga" reĆŸiimi
rz=udp_socket.sendto(packetack, addr), kus SOL_SOCKET tĂ€hendab âprotokolli tasetâ, et seada valikuid,
, SO_BROADCAST valik, et pakett saadetakse âbroidcastinaâ
 , SO_REUSEADDR valik lĂŒlitab soketi âmitme kuulajaâ reĆŸiimisse. Teoreetiliselt ei ole see juhtumil vajalik, kuid ĂŒhel FreeBSD serveril, kus ma testisin, töötas kood ilma selle valikuta.
DHCP paketi analĂŒĂŒs
Siin hakkas mulle tĂ”eliselt meeldima Python. Selgub, et ta vĂ”imaldab ĂŒsna vabalt tegutseda bait-koodiga. Muutes selle vĂ€ga lihtsalt kĂŒmnendlikeks vÀÀrtusteks, ridadeks ja hex - see tĂ€hendab, et see on tĂ€pselt see, mida meil on vaja, et mĂ”ista paketi struktuuri. NĂ€iteks saabime kĂ€tte baitide vahemiku HEX ja lihtsalt baitidena:
res["xidhex"]=data[4:8].hex()
res["xidbyte"]=data[4:8], pakkida baitid struktuuri:
res["flags"]=pack('BB',data[10],data[11])Saada IP struktuurist:
res["ciaddr"]=socket.inet_ntoa(pack('BBBB',data[12],data[13],data[14],data[15]));Ja vastupidi:
res=res+socket.inet_pton(socket.AF_INET, gconfig["dhcp_Server"])
See ongi kĂ”ik đ
Allikas: habr.com
