DHCP + MySQL server Pythonis

DHCP + MySQL server Pythonis

Selle projekti eesmÀrgiks oli:

  • DHCP protokolli uurimine IPv4 vĂ”rgus
  • Python'i Ă”ppimine (veidi rohkem kui nullist 😉 )
  • serveri asendamine DB2DHCP (minu fork), originaal siin, mille kokkupanemine uue operatsioonisĂŒsteemi jaoks muutub ĂŒha keerulisemaks. Ja ei meeldi, et binaarfaili ei ole vĂ”imalik "vahetada praegu"
  • töökorras DHCP serveri saamine, mis vĂ”imaldab IP aadressi valimist abonendi pĂ”hjal tema MAC aadressi vĂ”i MAC aadressi + porti kombinatsiooni (Valik 82) kaudu
  • jĂ€rgmise ratta kirjutamine (O! see on minu lemmiktegevus)
  • oma kohmakuse tĂ”ttu saanud kriitikat HabrHabr'is (vĂ”i veel parem - kutse) 😉

Tulemus: töötab 😉 Katsetatud FreeBSD ja Ubuntu operatsioonisĂŒsteemidel. Teoreetiliselt vĂ”iks koodi kĂ€itada igas operatsioonisĂŒsteemis, kuna koodis ei tundu olevat spetsiifilisi seoseid.
Kasutage ettevaatlikult! Edasi on palju.

Link teaduslikku repositooriumisse huvilistele "puudutada elusalt".

Installeerimise, seadistamise ja tulemuse kasutamise protsess "materjali uurimisest" on allpool, ja seejĂ€rel vĂ€ike teooria DHCP protokolli kohta. Endale. Ja ajaloo nimel 😉

Veidi teooriat

Mis on DHCP

See on vĂ”rgu protokoll, mis vĂ”imaldab seadmel teada saada oma IP aadressi (ja muid parameetreid nagu lĂŒĂŒs, DNS jne) DHCP serverilt. Pakettide vahetus toimub UDP protokolli kaudu. Seadme töö pĂ”himĂ”te vĂ”rgu parameetrite kĂŒsimisel on jĂ€rgmine:

  1. Seade (klient) saadab laienduslikku UDP pĂ€ringut (DHCPDISCOVER) lĂ€bi kogu vĂ”rgu kĂŒsimisega "kas keegi, andke mulle IP aadress". Tavaliselt (kuid mitte alati) toimub pĂ€ring 68 porti kaudu (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 (ja neid vÔib olla mitu), koostavad seadmele, kes saadab DHCPDISCOVER, DHCPOFFER pakkumise koos vÔrgu seadistustega, ja saadavad selle laiaulatuslikult vÔrku. Paketi identifitseerimine, kellele see pakett on mÔeldud, toimub eelnevalt DHCPDISCOVER pÀringus esitatud kliendi MAC aadressi pÔhjal.
  3. Kliendi seadmed saavad vÔrguseadistuste pakkumisi, valivad neist kÔige atraktiivsema (kriteeriumid vÔivad olla erinevad, sealhulgas pakkumise kohaletoimetamise aeg ja vahepeatuste arv) ja saadavad valitud DHCP serverile "ametliku pÀringu" DHCPREQUEST koos vÔrguseadistustega. Sel juhul suunatakse pakk juba konkreetsele DHCP serverile.
  4. Server, mis sai DHCPREQUEST-i, saadab paketi kujul DHCPACK, milles loetletakse uuesti vÔrguseadistused, mis on mÔeldud antud kliendile.

DHCP + MySQL server Pythonis

Lisaks on olemas DHCPINFORM paketid, mida saadetakse kliendi poolt, mille eesmÀrk on teavitada DHCP serverit, et "klient on elus" ja kasutab antud vÔrguseadistusi. Antud serveri rakenduses ignoreeritakse neid pakette.

Pakkide formaat

KokkuvÔttes nÀeb Etherneti paketi raam vÀlja umbes nii:

DHCP + MySQL server Pythonis

KĂ€esolevas juhul vaatame ainult UDP paketi sisu andmeid, ilma OSI taseme protokollide pealkirjadeta, nimelt DHCP struktuuri:

DHCPDISCOVER

Seega algab IP-aadressi saamise protsess seadme jaoks sellega, et DHCP klient saadab laialdaselt pÀringu pordilt 68 aadressile 255.255.255.255:67. Selles pakendis sisaldab klient oma MAC aadressi ja ka seda, mida ta soovib DHCP serverilt saada. Paketi struktuur on kirjeldatud allpool olevas tabelis.

DHCPDISCOVER paketi struktuuri tabel

Positsioon paketis
VÀÀrtuse nimi
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, selles protokollis 1 — MAC

3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus

4
Hops
1
Hex
1
Vahepeatuste arv

5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses

7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest

9
Bootp lipud
0
Hex
2
MÔned lipud, mida saab seadistada protokolli parameetrite nÀitamiseks

11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)

15
Teie kliendi IP aadress
0.0.0.0
Rida
4
IP aadress, mille server on pakkunud (kui on)

19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)

23
Ülekandeagendi IP aadress
172.16.114.41
Rida
4
Ülekandeagendi IP aadress (nĂ€iteks lĂŒliti)

27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)

31
Kliendi riistvara aadressi padjand
 
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega

41
Serveri hostinimi
 
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata

105
Boot failinimi
 
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel

235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, 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
Millise IP-aadressi soovib klient saada

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
172.16.134.61
Rida
4

 
Valiku number
55
 
1
Kliendi taotletavad vÔrgu parameetrid. Koostis vÔib olla erinev

01 — Alamside mask
03 — LĂŒkand
06 — DNS
oc — Hostinimi
0f — vĂ”rgu domeeninimi
1c — laiuskande aadress (broadcaster)
42 — TFTP serveri nimi
79 — MÀÀratlemata staatiline marsruut

 
Valiku pikkus
8
 
1

 
Valiku vÀÀrtus
01:03:06:0c:0f:1c:42:79
 
8

 
Valiku number
82
Dec
 
Valik 82, milles edastatakse seadme MAC-aadress — kordustootja ja mĂ”ned tĂ€iendavad vÀÀrtused.

Tavaliselt — lĂŒliti port, millel töötab lĂ”ppkliendi DHCP. Selle valiku sees on 'peidetud' tĂ€iendavad parameetrid. Esimene bait — 'alamvaliku' number, teine selle pikkus, seejĂ€rel selle vÀÀrtus.

Selles suhtes on valikus 82 peidetud alamvalikud:
Agent Circuit ID = 00:04:00:01:00:04, kus viimased kaks baidi on DHCP kliendi port, kust pÀring tuli

Agent Remote ID = 00:06:c8:be:19:93:11:48 — DHCP kordustootja 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

Niipea, kui server saab paketi DHCPDISCOVER ja nĂ€eb, et tal on vĂ”imalik kliendile pakkuda midagi taotletust, genereerib ta vastuse — DHCPDISCOVER. Vastus saadetakse porti, kust see tuli, broadcastina, kuna kliendil pole hetkel IP-aadressi ja seega saab ta paketti vastu vĂ”tta ainult siis, kui see saadetakse laiale ringile. Klient tuvastab, et see pakett on talle mĂ”eldud, tema MAC-aadressi ja tehingu numbri pĂ”hjal, mille ta genereerib esimese paketi loomise hetkel.

DHCPOFFER paketi struktuuri tabel

Positsioon paketis
VÀÀrtuse nimi (tavaline)
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, selles protokollis 1 — MAC

3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus

4
Hops
1
Hex
1
Vahepeatuste arv

5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses

7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest

9
Bootp lipud
0
Hex
2
MÔned lipud, mis vÔivad olla mÀÀratud protokolli parameetrite nÀitamiseks. Antud juhul tÀhendab 0 unicast'i pÀringut

11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)

15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)

19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)

23
Ülekandeagendi IP aadress
172.16.114.41
Rida
4
Ülekandeagendi IP aadress (nĂ€iteks lĂŒliti)

27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)

31
Kliendi riistvara aadressi padjand
 
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega

41
Serveri hostinimi
 
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata

105
Boot failinimi
 
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel

235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, 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 alamside maski

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
255.255.224.0
Rida
4

 
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaike lĂŒkandi

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
172.16.12.1
Rida
4

 
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
8.8.8.8
Rida
4

 
Valiku number
51
Dec
1
VÔrgu parameetrite kehtivusaeg sekundites, mille pÀrast peab DHCP klient taotlema neid uuesti

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
86400
Dec
4

 
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER'is

 
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, koostab ta paketi vĂ”rgu parameetrite taotlemiseks mitte kĂ”igilt DHCP serveritelt, vaid ainult ĂŒhe konkreetse serveri jaoks, kelle DHCPOFFER pakkumine talle kĂ”ige rohkem „meeldis“. Kriteeriumid „meeldimise“ jaoks vĂ”ivad olla erinevad ja sĂ”ltuvad DHCP kliendi teostusest. VastuvĂ”tja antakse teada DHCP serveri MAC-aadressi kaudu. Samuti vĂ”ib DHCPREQUEST pakett kliendi saadetud olla ka ilma eelneva DHCPDISCOVER-i vormistamiseta, kui IP-aadress serverilt on juba varem saadud.

DHCPREQUEST paketi struktuuri tabel

Positsioon paketis
VÀÀrtuse nimi (tavaline)
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, selles protokollis 1 — MAC

3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus

4
Hops
1
Hex
1
Vahepeatuste arv

5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses

7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest

9
Bootp lipud
8000
Hex
2
MĂ”ned lipud, mida saab seadistada, et nĂ€idata protokolli parameetreid. Antud juhul on seadistatud „broadcast“

11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)

15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)

19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)

23
Ülekandeagendi IP aadress
172.16.114.41
Rida
4
Ülekandeagendi IP aadress (nĂ€iteks lĂŒliti)

27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)

31
Kliendi riistvara aadressi padjand
 
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega

41
Serveri hostinimi
 
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata

105
Boot failinimi
 
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel

235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, 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ÀÀratleb 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 puhul teatab see DHCP kliendi versiooni. Teised seadmed vÔivad tagastada midagi muud. NÀiteks Windows teatab MSFT 5.0

 
Valiku pikkus
11
Dec
 

 
Valiku vÀÀrtus
udhcp 0.9.8
Rida
 

 
Valiku number
55
 
1
Kliendi taotletavad vÔrgu parameetrid. Koostis vÔib olla erinev

01 — Alamside mask
03 — LĂŒkand
06 — DNS
oc — Hostinimi
0f — vĂ”rgu domeeninimi
1c — laiuskande aadress (broadcaster)
42 — TFTP serveri nimi
79 — MÀÀratlemata 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'is

 
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

Kinnituseks, et "jah, see on sinu IP-aadress ja ma ei anna seda enam kellelegi", saadab DHCP server paketina DHCPACK kliendile. See saadetakse nagu kÔik teised paketid laialdaselt. Kuigi allpool toodud koodis on Pythonis implementeeritud DHCP server, dubleerin ma igaks juhuks iga laiaulatuslikku taotlust, saates paketi konkreetsele IP-aadressile, kui see on juba teada. Samuti ei huvita DHCP serverit, kas DHCPACK pakett jÔudis kliendile. Kui klient ei saa DHCPACK-i, kordab ta mÔne aja pÀrast lihtsalt DHCPREQUEST-i.

DHCPACK paketi struktuuri tabel

Positsioon paketis
VÀÀrtuse nimi (tavaline)
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, selles protokollis 1 — MAC

3
Riistvara aadressi pikkus
6
Hex
1
Seadme MAC aadressi pikkus

4
Hops
1
Hex
1
Vahepeatuste arv

5
Tehingu ID
23:cf:de:1d
Hex
4
Tehingu unikaalne identifikaator. Generatsioon toimub kliendi poolt pÀringu alguses

7
Kulu sekundites
0
Hex
4
Aeg sekundites alates aadressi saamise protsessi algusest

9
Bootp lipud
8000
Hex
2
MĂ”ned lipud, mida saab seadistada, et nĂ€idata protokolli parameetreid. Antud juhul on seadistatud „broadcast“

11
Kliendi IP aadress
0.0.0.0
Rida
4
Kliendi IP aadress (kui on)

15
Teie kliendi IP aadress
172.16.134.61
Rida
4
IP aadress, mille server on pakkunud (kui on)

19
JĂ€rgmise serveri IP aadress
0.0.0.0
Rida
4
Serveri IP aadress (kui teada)

23
Ülekandeagendi IP aadress
172.16.114.41
Rida
4
Ülekandeagendi IP aadress (nĂ€iteks lĂŒliti)

27
Kliendi MAC aadress
14:d6:4d:a7:c9:55
Hex
6
Paketi saatja MAC aadress (klient)

31
Kliendi riistvara aadressi padjand
 
Hex
10
Reserveeritud koht. Tavaliselt tÀidetud nullidega

41
Serveri hostinimi
 
Rida
64
DHCP serveri nimi. Tavernialt see tavaliselt ei edastata

105
Boot failinimi
 
Rida
128
Serveris failinimi, mida kasutatakse ketta vabadusjaamade kÀivitamisel

235
Magic cookie
63:82:53:63
Hex
4
«Magi» number, mille jÀrgi on vÔimalik tuvastada, 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ÀÀratleb 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 alamside maski

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
255.255.224.0
Rida
4

 
Valiku number
3
Dec
1
Valik, mis pakub DHCP kliendile vaike lĂŒkandi

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
172.16.12.1
Rida
4

 
Valiku number
6
Dec
1
Valik, mis pakub DHCP kliendile DNS

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
8.8.8.8
Rida
4

 
Valiku number
51
Dec
1
VÔrgu parameetrite kehtivusaeg sekundites, mille pÀrast peab DHCP klient taotlema neid uuesti

 
Valiku pikkus
4
Dec
1

 
Valiku vÀÀrtus
86400
Dec
4

 
Valiku number
82
Dec
1
Valik 82, kordab seda, mis tuli DHCPDISCOVER'is

 
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

Paigaldamine

Seadistamine 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

Loo MySQL andmebaas, lae sinna pydhcp.sql dump, seadista konfiguratsioonifail.

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 rÀÀgime lĂ€hemalt silte:

Sektsioon dhcpserver kirjeldab pÔhiseadeid serveri kÀivitamiseks, nimelt:

  • host — millist IP-aadressi server kuulab pordil 67
  • broadcast — milline IP on DHCPOFFER ja DHCPACK jaoks broidkast
  • DHCPServer — milline IP on DHCP serveril
  • LeaseTime on vĂ€lja antud IP-aadressi rentimise aeg
  • ThreadLimit — mitu samaaegset niiti on kĂ€imas UDP-pakettide töötlemiseks pordil 67. Eeldatakse, et see aitab kĂ”rgelt koormatud projektides 😉
  • defaultMask, defaultRouter, defaultDNS — see, mis pakutakse tellijale vaikimisi, kui IP on andmebaasis leitud, kuid tĂ€iendavad parameetrid tema jaoks pole mÀÀratud

Sektsioon mysql:

host, username, password, basename — kĂ”ik rÀÀgib enda eest. Andmebaasi ligikaudne struktuur on saadaval GitHub

Sektsioon query: siin kirjeldatakse pÀringuid OFFER/AACK saamiseks:

  • offer_count — ridade arv pĂ€ringutes, mis tagastavad tulemuse kujul ip, mask, router, dns
  • offer_n — pĂ€ringu rida. Kui tagastus on tĂŒhi, siis tĂ€idab jĂ€rgmise pĂ€ringu offer
  • history_sql — pĂ€ring, mis kirjutab nĂ€iteks »autentimise ajaloosse« tellija kohta

PÀringutes vÔivad osaleda kÔik muutujaid sektsioonist options vÔi DHCP protokolli vÔimalused.

Sektsioon options. Siin on juba huvitavam. Siin saame luua muutujaid, mida saame hiljem kasutada sektsioonis query.

NĂ€iteks:

option_82_hex:sw_port1:20:22

, see command line to take the entire line received in the DHCP request option 82, in hex format, in the range from bytes 20 to 22 inclusive and put it into a new variable sw_port1 (the switch port from which the request came)

option_82_hex:sw_mac:26:40

, define the variable sw_mac, taking hex from the range 26:40

You can see all possible options that can be used in requests by running the server with the -d key. We will see a log like this:

-- DHCPINFORM packet received on port 67, from 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'}

Therefore, we can wrap any variable in {} and it will be used in the SQL query.

We will record for the record that the client received the IP address:

DHCP + MySQL server Pythonis

DHCP + MySQL server Pythonis

Serveri kÀivitamine

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

— d mode displays DEBUG output to the console
— c <filename> configuration file

Flight analysis

Now, let's go into more detail about the implementation of the server in Python. It's a pain. Python was learned 'on the fly'. Many things were done in the style of: 'wow, I got it to work somehow'. It is not optimized at all and was left in this form mainly due to a lack of experience in Python development. I will focus on the most interesting aspects of the server implementation in the 'code'.

XML configuration file parser

The standard Python module xml.dom is used. It seems simple, but during the implementation, there was a noticeable lack of good documentation and examples online using this module.

    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)

Mitmekeelsus

Kuid ĂŒllatavalt on Pythonis mitmekeelsus hĂ€sti arusaadav ja lihtne.

def PacketWork(data,addr): 
...
# saabunud 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Ă”imed ĂŒletavad seadistustes mÀÀratud arvu, ootame, kuni neid on vĂ€hem

DHCP paketi vastuvÔtt/saatmine

Et UDP pakette, mis liiguvad vĂ”rkaartide kaudu, peeta kinni, tuleb „tĂ”sta” sokkel:

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 — see, et me ei saa "toores paketti", vaid juba pĂ€rast tulemusi lĂ€bi tulemĂŒĂŒri

Paketi saatmine vÔib toimuda nii broidcastina:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #lĂŒlitame socketi broidcast saatmise reĆŸiimi
                    rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, kui ka aadressile, "kust pakk tuli":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # lĂŒlitame socketi reĆŸiimi "palju kuulajaid"
                        rz=udp_socket.sendto(packetack, addr)

, kus SOL_SOCKET tÀhendab "protokolli taset" valikute seadmiseks,

, SO_BROADCAST valik, mis ĂŒtleb, et pakett saadetakse "broidcastina"

  , SO_REUSEADDR valik, mis lĂŒlitab socketi reĆŸiimi "palju kuulajaid". Ideaalis pole see antud juhul vajalik, kuid ĂŒhel FreeBSD serveril, kus testisin, ei töötanud see kood ilma selle valikuta.

DHCP paketi analĂŒĂŒs

Siin meeldis mulle tĂ”eliselt Python. Selgub, et "karbist" annab tema abil vĂ€ga vabalt töötada baitkoodiga. See vĂ”imaldab seda vĂ€ga lihtsalt tĂ”lkida kĂŒmnendvÀÀrtusteks, stringideks ja hex-ks — st seda, mida meil tĂ”eliselt vaja on, et mĂ”ista paketi struktuuri. NĂ€iteks saab saada baitide vahemiku HEX ja lihtsalt baitidena:

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

, pakkida baitide 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"])

Sellega on kĂ”ik 😉

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster