DHCP+Mysql server Pythonis

DHCP+Mysql server Pythonis

Selle projekti eesmÀrk oli:

  • DHCP protokolli uurimine IPv4 vĂ”rgus
  • Python'i Ă”ppimine (veidi rohkem kui nullist 😉 )
  • serveri asendamine DB2DHCP (minu fork), originaal siit, 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 "elusat" puudutada.

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:

  1. 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.
  2. 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.
  3. 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.
  4. Server, kes sai DHCPREQUEST'i, saadab paketi formaadis DHCPACK, kus loetletakse uuesti vÔrgu seadistused, mis on mÔeldud sellele kliendile.

DHCP+Mysql server Pythonis

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:

DHCP+Mysql server Pythonis

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 GitHub

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:

DHCP+Mysql server Pythonis

DHCP+Mysql server Pythonis

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Àheneb

DHCP 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

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster