DHCP+Mysql-bediener in Python

DHCP+Mysql-bediener in Python

Die doel van hierdie projek was:

  • Leer oor DHCP op 'n IPv4-netwerk
  • Leer Python ('n bietjie meer as van nuuts af 😉)
  • bediener vervanging DB2DHCP (my vurk), oorspronklike hier, wat al hoe moeiliker word om vir die nuwe bedryfstelsel saam te stel. En ek hou nie daarvan dat dit 'n binêre is dat daar geen manier is om "nou te verander nie"
  • verkryging van 'n werkende DHCP-bediener met die vermoë om 'n intekenaar se IP-adres te kies deur die intekenaar se Mac of skakel Mac+poort kombinasie te gebruik (Opsie 82)
  • nog 'n fiets skryf (O! dit is my gunsteling aktiwiteit)
  • ontvang opmerkings oor jou klubhandigheid op Habrahabr (of beter nog, 'n uitnodiging) 😉

Resultaat: dit werk 😉 Getoets op FreeBSD en Ubuntu OS. Teoreties kan die kode gevra word om onder enige bedryfstelsel te werk, want Dit lyk asof daar geen spesifieke bindings in die kode is nie.
Versigtig! Daar is nog baie om te kom.

Skakel na bewaarplek vir amateurs "raak lewendig".

Die proses van installering, konfigurasie en gebruik van die resultaat van "bestudering van die hardeware" is baie laer, en dan 'n bietjie teorie oor die DHCP-protokol. Vir myself. En vir geskiedenis 😉

'n Bietjie teorie

Wat is DHCP

Dit is 'n netwerkprotokol wat 'n toestel toelaat om sy IP-adres (en ander parameters soos poort, DNS, ens.) van 'n DHCP-bediener uit te vind. Pakkies word uitgeruil met behulp van die UDP-protokol. Die algemene beginsel van werking van die toestel wanneer netwerkparameters versoek word, is soos volg:

  1. Die toestel (kliënt) stuur 'n UDP-uitsaaiversoek (DHCPDISCOVER) deur die netwerk met die versoek "wel, iemand gee vir my 'n IP-adres." Boonop kom die versoek gewoonlik (maar nie altyd nie) vanaf poort 68 (bron), en die bestemming is poort 67 (bestemming). Sommige toestelle stuur ook pakkies vanaf poort 67. Die MAC-adres van die kliënttoestel is in die DHCPDISCOVER-pakkie ingesluit.
  2. Alle DHCP-bedieners wat op die netwerk geleë is (en daar kan verskeie van hulle wees) vorm 'n DHCPOFFER-aanbieding met netwerkinstellings vir die toestel wat DHCPDISCOVER gestuur het, en saai dit ook oor die netwerk uit. Identifikasie van vir wie hierdie pakkie bedoel is, is gebaseer op die MAC-adres van die kliënt wat vroeër in die DHCPDISCOVER-versoek verskaf is.
  3. Die kliënt aanvaar pakkies met voorstelle vir netwerkinstellings, kies die aantreklikste een (die kriteria kan verskil, byvoorbeeld die tyd van pakkie aflewering, die aantal tussenroetes), en rig 'n "amptelike versoek" DHCPREQUEST met die netwerkinstellings vanaf die DHCP-bediener waarvan dit hou. In hierdie geval gaan die pakkie na 'n spesifieke DHCP-bediener.
  4. Die bediener wat die DHCPREQUEST ontvang het, stuur 'n DHCPACK-formaat pakkie, waarin dit weereens die netwerkinstellings wat vir hierdie kliënt bedoel is, lys

DHCP+Mysql-bediener in Python

Daarbenewens is daar DHCPINFORM-pakkies wat van die kliënt af kom, en die doel daarvan is om die DHCP-bediener in te lig dat die "kliënt lewendig is" en die uitgereikte netwerkinstellings gebruik. In hierdie bediener se implementering word hierdie pakkies geïgnoreer.

Pakketformaat

Oor die algemeen lyk 'n Ethernet-pakkieraam so iets:

DHCP+Mysql-bediener in Python

In ons geval sal ons slegs die data direk vanaf die inhoud van die UDP-pakkie oorweeg, sonder OSI-laagprotokolopskrifte, naamlik die DHCP-struktuur:

DHCP ONTDEK

Dus, die proses om 'n IP-adres vir 'n toestel te verkry, begin met die DHCP-kliënt wat 'n uitsaaiversoek vanaf poort 68 na 255.255.255.255:67 stuur. In hierdie pakket sluit die kliënt sy MAC-adres in, sowel as wat dit presies van die DHCP-bediener wil ontvang. Die pakketstruktuur word in die tabel hieronder beskryf.

DHCPDISCOVER Pakkiestruktuurtabel

Posisie in die pakkie
Waarde naam
Voorbeeld
idee
Byte
Verduideliking

1
Opstartversoek
1
Hex
1
Soort boodskap. 1 - versoek van kliënt tot bediener, 2 - reaksie van bediener tot kliënt

2
Hardeware tipe
1
Hex
1
Tipe hardeware-adres, in hierdie protokol 1 - MAC

3
Lengte van hardeware-adresse
6
Hex
1
Toestel MAC-adres lengte

4
Hop
1
Hex
1
Aantal intermediêre roetes

5
Transaksie ID
23:cf:de:1d
Hex
4
Unieke transaksie-identifiseerder. Gegenereer deur die kliënt aan die begin van 'n versoekoperasie

7
Tweede het verloop
0
Hex
4
Tyd in sekondes vanaf die begin van die proses om 'n adres te verkry

9
Boot vlae
0
Hex
2
Sekere vlae wat gestel kan word om protokolparameters aan te dui

11
Kliënt IP-adres
0.0.0.0
ry
4
Kliënt IP-adres (indien enige)

15
Jou kliënt IP-adres
0.0.0.0
ry
4
IP-adres aangebied deur die bediener (indien beskikbaar)

19
Volgende bediener IP-adres
0.0.0.0
ry
4
Bediener IP-adres (indien bekend)

23
Aflosagent se IP-adres
172.16.114.41
ry
4
IP-adres van die aflosagent (byvoorbeeld 'n skakelaar)

27
Kliënt MAC-adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres van die pakkiesender (kliënt)

31
Kliënt hardeware adres opvulling
 
Hex
10
Gereserveerde sitplek. Gewoonlik gevul met nulle

41
Bedienergasheernaam
 
ry
64
DHCP bediener naam. Gewoonlik nie oorgedra nie

105
Boot lêer naam
 
ry
128
Lêernaam op die bediener wat deur skyflose stasies gebruik word tydens selflaai

235
Magiese koekies
63: 82: 53: 63
Hex
4
"Magic" nommer, waarvolgens, inkl. jy kan bepaal dat hierdie pakkie aan die DHCP-protokol behoort

DHCP opsies. Kan in enige volgorde gaan

236
Opsie nommer
53
Desember
1
Opsie 53, wat die DHCP-pakkietipe spesifiseer

1 - DHCP ONTDEK
3 - DHCPREQUEST
2 - DHCP AANBIEDING
5 - DHCPACK
8 - DHCPINFORM

 
Opsie lengte
1
Desember
1

 
Opsie waarde
1
Desember
1

 
Opsie nommer
50
Desember
1
Watter IP-adres wil die kliënt ontvang?

 
Opsie lengte
4
Desember
1

 
Opsie waarde
172.16.134.61
ry
4

 
Opsie nommer
55
 
1
Netwerkparameters versoek deur die kliënt. Samestelling kan verskil

01 - Netwerkmasker
03 - Poort
06 - DNS
oc — Gasheernaam
0f - netwerk domeinnaam
1c - adres van uitsaaiversoek (uitsending)
42 - TFTP-bedienernaam
79 - Klaslose statiese roete

 
Opsie lengte
8
 
1

 
Opsie waarde
01:03:06:0c:0f:1c:42:79
 
8

 
Opsie nommer
82
Desember
 
Opsie 82, wat die MAC-adres van die herhalertoestel en 'n paar bykomende waardes oordra.

Dikwels is dit die poort van die skakelaar waarop die eind-DHCP-kliënt loop. Hierdie opsie bevat bykomende parameters. Die eerste greep is die nommer van die "subopsie", die tweede is sy lengte, dan sy waarde.

In hierdie geval, in opsie 82, word die sub-opsies geneste:
Agentkring-ID = 00:04:00:01:00:04, waar die laaste twee grepe die DHCP-kliëntpoort is waaruit die versoek gekom het

Agent Remote ID = 00:06:c8:be:19:93:11:48 - MAC-adres van die DHCP-herhalertoestel

 
Opsie lengte
18
Desember
 

 
Opsie waarde
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Einde van pakket
255
Desember
1
255 simboliseer die einde van die pakkie

DHCP AANBIEDING

Sodra die bediener die DHCPDISCOVER-pakkie ontvang en as dit sien dat dit die kliënt iets van die versoekte een kan bied, genereer dit 'n reaksie daarvoor - DHCPDISCOVER. Die reaksie word na die hawe gestuur "vanwaar dit gekom het", per uitsending, want op hierdie oomblik het die kliënt nog nie 'n IP-adres nie, daarom kan dit slegs die pakkie aanvaar as dit per uitsending gestuur word. Die kliënt herken dat dit 'n pakket vir hom is aan sy MAC-adres binne die pakket, sowel as die transaksienommer wat hy genereer wanneer die eerste pakket geskep word.

DHCPOFFER Pakkiestruktuurtabel

Posisie in die pakkie
Naam van waarde (algemeen)
Voorbeeld
idee
Byte
Verduideliking

1
Opstartversoek
1
Hex
1
Soort boodskap. 1 - versoek van kliënt tot bediener, 2 - reaksie van bediener tot kliënt

2
Hardeware tipe
1
Hex
1
Tipe hardeware-adres, in hierdie protokol 1 - MAC

3
Lengte van hardeware-adresse
6
Hex
1
Toestel MAC-adres lengte

4
Hop
1
Hex
1
Aantal intermediêre roetes

5
Transaksie ID
23:cf:de:1d
Hex
4
Unieke transaksie-identifiseerder. Gegenereer deur die kliënt aan die begin van 'n versoekoperasie

7
Tweede het verloop
0
Hex
4
Tyd in sekondes vanaf die begin van die proses om 'n adres te verkry

9
Boot vlae
0
Hex
2
Sekere vlae wat gestel kan word om protokolparameters aan te dui. In hierdie geval beteken 0 die Unicast-versoektipe

11
Kliënt IP-adres
0.0.0.0
ry
4
Kliënt IP-adres (indien enige)

15
Jou kliënt IP-adres
172.16.134.61
ry
4
IP-adres aangebied deur die bediener (indien beskikbaar)

19
Volgende bediener IP-adres
0.0.0.0
ry
4
Bediener IP-adres (indien bekend)

23
Aflosagent se IP-adres
172.16.114.41
ry
4
IP-adres van die aflosagent (byvoorbeeld 'n skakelaar)

27
Kliënt MAC-adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres van die pakkiesender (kliënt)

31
Kliënt hardeware adres opvulling
 
Hex
10
Gereserveerde sitplek. Gewoonlik gevul met nulle

41
Bedienergasheernaam
 
ry
64
DHCP bediener naam. Gewoonlik nie oorgedra nie

105
Boot lêer naam
 
ry
128
Lêernaam op die bediener wat deur skyflose stasies gebruik word tydens selflaai

235
Magiese koekies
63: 82: 53: 63
Hex
4
"Magic" nommer, waarvolgens, inkl. jy kan bepaal dat hierdie pakkie aan die DHCP-protokol behoort

DHCP opsies. Kan in enige volgorde gaan

236
Opsie nommer
53
Desember
1
Opsie 53, wat die DHCP 2 pakkie tipe definieer - DHCPOFFER

 
Opsie lengte
1
Desember
1

 
Opsie waarde
2
Desember
1

 
Opsie nommer
1
Desember
1
Opsie om die DHCP-kliënt 'n netwerkmasker aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
255.255.224.0
ry
4

 
Opsie nommer
3
Desember
1
Opsie om die DHCP-kliënt 'n verstekpoort aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
172.16.12.1
ry
4

 
Opsie nommer
6
Desember
1
Opsie om DHCP aan DNS-kliënt aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
8.8.8.8
ry
4

 
Opsie nommer
51
Desember
1
Die leeftyd van die uitgereikte netwerkparameters in sekondes, waarna die DHCP-kliënt dit weer moet versoek

 
Opsie lengte
4
Desember
1

 
Opsie waarde
86400
Desember
4

 
Opsie nommer
82
Desember
1
Opsie 82, herhaal wat in DHCPDISCOVER gekom het

 
Opsie lengte
18
Desember
1

 
Opsie waarde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
Desember
18

 
Einde van pakket
255
Desember
1
255 simboliseer die einde van die pakkie

DHCVERSOEK

Nadat die kliënt DHCPOFFER ontvang het, vorm hy 'n pakkie wat netwerkparameters versoek, nie aan alle DHCP-bedieners op die netwerk nie, maar slegs na een spesifieke een, wie se DHCPOFFER-aanbod hy die meeste "van gehou" het. Die "soos"-kriteria kan anders wees en afhang van die kliënt se DHCP-implementering. Die ontvanger van die versoek word gespesifiseer deur die MAC-adres van die DHCP-bediener te gebruik. 'n DHCPREQUEST-pakkie kan ook deur die kliënt gestuur word sonder om eers DHCPDISCOVER te genereer, as die bediener se IP-adres reeds voorheen verkry is.

DHCPREQUEST Pakketstruktuurtabel

Posisie in die pakkie
Naam van waarde (algemeen)
Voorbeeld
idee
Byte
Verduideliking

1
Opstartversoek
1
Hex
1
Soort boodskap. 1 - versoek van kliënt tot bediener, 2 - reaksie van bediener tot kliënt

2
Hardeware tipe
1
Hex
1
Tipe hardeware-adres, in hierdie protokol 1 - MAC

3
Lengte van hardeware-adresse
6
Hex
1
Toestel MAC-adres lengte

4
Hop
1
Hex
1
Aantal intermediêre roetes

5
Transaksie ID
23:cf:de:1d
Hex
4
Unieke transaksie-identifiseerder. Gegenereer deur die kliënt aan die begin van 'n versoekoperasie

7
Tweede het verloop
0
Hex
4
Tyd in sekondes vanaf die begin van die proses om 'n adres te verkry

9
Boot vlae
8000
Hex
2
Sekere vlae wat gestel kan word om protokolparameters aan te dui. In hierdie geval is "uitsending" gestel

11
Kliënt IP-adres
0.0.0.0
ry
4
Kliënt IP-adres (indien enige)

15
Jou kliënt IP-adres
172.16.134.61
ry
4
IP-adres aangebied deur die bediener (indien beskikbaar)

19
Volgende bediener IP-adres
0.0.0.0
ry
4
Bediener IP-adres (indien bekend)

23
Aflosagent se IP-adres
172.16.114.41
ry
4
IP-adres van die aflosagent (byvoorbeeld 'n skakelaar)

27
Kliënt MAC-adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres van die pakkiesender (kliënt)

31
Kliënt hardeware adres opvulling
 
Hex
10
Gereserveerde sitplek. Gewoonlik gevul met nulle

41
Bedienergasheernaam
 
ry
64
DHCP bediener naam. Gewoonlik nie oorgedra nie

105
Boot lêer naam
 
ry
128
Lêernaam op die bediener wat deur skyflose stasies gebruik word tydens selflaai

235
Magiese koekies
63: 82: 53: 63
Hex
4
"Magic" nommer, waarvolgens, inkl. jy kan bepaal dat hierdie pakkie aan die DHCP-protokol behoort

DHCP opsies. Kan in enige volgorde gaan

236
Opsie nommer
53
Desember
3
Opsie 53, wat die DHCP-pakkietipe 3 - DHCPREQUEST definieer

 
Opsie lengte
1
Desember
1

 
Opsie waarde
3
Desember
1

 
Opsie nommer
61
Desember
1
Kliënt ID: 01 (vir Ehernet) + kliënt MAC adres

 
Opsie lengte
7
Desember
1

 
Opsie waarde
01:2c:ab:25:ff:72:a6
Hex
7

 
Opsie nommer
60
Desember
 
"Verskafferklasidentifiseerder". In my geval rapporteer dit die DHCP-kliëntweergawe. Miskien gee ander toestelle iets anders terug. Windows rapporteer byvoorbeeld MSFT 5.0

 
Opsie lengte
11
Desember
 

 
Opsie waarde
udhcp 0.9.8
ry
 

 
Opsie nommer
55
 
1
Netwerkparameters versoek deur die kliënt. Samestelling kan verskil

01 - Netwerkmasker
03 - Poort
06 - DNS
oc — Gasheernaam
0f - netwerk domeinnaam
1c - adres van uitsaaiversoek (uitsending)
42 - TFTP-bedienernaam
79 - Klaslose statiese roete

 
Opsie lengte
8
 
1

 
Opsie waarde
01:03:06:0c:0f:1c:42:79
 
8

 
Opsie nommer
82
Desember
1
Opsie 82, herhaal wat in DHCPDISCOVER gekom het

 
Opsie lengte
18
Desember
1

 
Opsie waarde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
Desember
18

 
Einde van pakket
255
Desember
1
255 simboliseer die einde van die pakkie

DHCPACK

As bevestiging dat "ja, dit is reg, dit is jou IP-adres, en ek sal dit aan niemand anders gee nie" vanaf die DHCP-bediener, dien 'n pakkie in DHCPACK-formaat van die bediener na die kliënt. Dit word uitgesaai net soos ander pakkies. Alhoewel, in die kode hieronder vir 'n DHCP-bediener wat in Python geïmplementeer is, vir ingeval, dupliseer ek enige uitsaaiversoek deur 'n pakkie na 'n spesifieke kliënt-IP te stuur, as dit reeds bekend is. Boonop gee die DHCP-bediener glad nie om of die DHCPACK-pakkie die kliënt bereik het nie. As die kliënt nie DHCPACK ontvang nie, herhaal dit na 'n rukkie eenvoudig DHCPREQUEST

DHCPACK Pakkie Struktuur Tabel

Posisie in die pakkie
Naam van waarde (algemeen)
Voorbeeld
idee
Byte
Verduideliking

1
Opstartversoek
2
Hex
1
Soort boodskap. 1 - versoek van kliënt tot bediener, 2 - reaksie van bediener tot kliënt

2
Hardeware tipe
1
Hex
1
Tipe hardeware-adres, in hierdie protokol 1 - MAC

3
Lengte van hardeware-adresse
6
Hex
1
Toestel MAC-adres lengte

4
Hop
1
Hex
1
Aantal intermediêre roetes

5
Transaksie ID
23:cf:de:1d
Hex
4
Unieke transaksie-identifiseerder. Gegenereer deur die kliënt aan die begin van 'n versoekoperasie

7
Tweede het verloop
0
Hex
4
Tyd in sekondes vanaf die begin van die proses om 'n adres te verkry

9
Boot vlae
8000
Hex
2
Sekere vlae wat gestel kan word om protokolparameters aan te dui. In hierdie geval is "uitsending" gestel

11
Kliënt IP-adres
0.0.0.0
ry
4
Kliënt IP-adres (indien enige)

15
Jou kliënt IP-adres
172.16.134.61
ry
4
IP-adres aangebied deur die bediener (indien beskikbaar)

19
Volgende bediener IP-adres
0.0.0.0
ry
4
Bediener IP-adres (indien bekend)

23
Aflosagent se IP-adres
172.16.114.41
ry
4
IP-adres van die aflosagent (byvoorbeeld 'n skakelaar)

27
Kliënt MAC-adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres van die pakkiesender (kliënt)

31
Kliënt hardeware adres opvulling
 
Hex
10
Gereserveerde sitplek. Gewoonlik gevul met nulle

41
Bedienergasheernaam
 
ry
64
DHCP bediener naam. Gewoonlik nie oorgedra nie

105
Boot lêer naam
 
ry
128
Lêernaam op die bediener wat deur skyflose stasies gebruik word tydens selflaai

235
Magiese koekies
63: 82: 53: 63
Hex
4
"Magic" nommer, waarvolgens, inkl. jy kan bepaal dat hierdie pakkie aan die DHCP-protokol behoort

DHCP opsies. Kan in enige volgorde gaan

236
Opsie nommer
53
Desember
3
Opsie 53, wat die DHCP-pakkietipe 5 - DHCPACK definieer

 
Opsie lengte
1
Desember
1

 
Opsie waarde
5
Desember
1

 
Opsie nommer
1
Desember
1
Opsie om die DHCP-kliënt 'n netwerkmasker aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
255.255.224.0
ry
4

 
Opsie nommer
3
Desember
1
Opsie om die DHCP-kliënt 'n verstekpoort aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
172.16.12.1
ry
4

 
Opsie nommer
6
Desember
1
Opsie om DHCP aan DNS-kliënt aan te bied

 
Opsie lengte
4
Desember
1

 
Opsie waarde
8.8.8.8
ry
4

 
Opsie nommer
51
Desember
1
Die leeftyd van die uitgereikte netwerkparameters in sekondes, waarna die DHCP-kliënt dit weer moet versoek

 
Opsie lengte
4
Desember
1

 
Opsie waarde
86400
Desember
4

 
Opsie nommer
82
Desember
1
Opsie 82, herhaal wat in DHCPDISCOVER gekom het

 
Opsie lengte
18
Desember
1

 
Opsie waarde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ek
Desember
18

 
Einde van pakket
255
Desember
1
255 simboliseer die einde van die pakkie

installasie

Die installasie bestaan ​​eintlik uit die installering van die python-modules wat nodig is vir werk. Daar word aanvaar dat MySQL reeds geïnstalleer en gekonfigureer is.

FreeBSD

pkg installeer python3 python3 -m surepip pip3 installeer mysql-connector

Ubuntu

sudo apt-get installeer python3 sudo apt-get installeer pip3 sudo pip3 installeer mysql-connector

Ons skep 'n MySQL-databasis, laai die pydhcp.sql-storting daarin op en stel die konfigurasielêer op.

opset

Alle bedienerinstellings is in 'n xml-lêer. Verwysingslêer:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 plaaslike gasheer toets toets pydhcp option_8.8.8.8_hex:sw_port82:1:20 option_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 kies ip,masker,router,dns van gebruikers waar upper(mac)=upper('{option_3_AgentRemoteId_hex}') en upper(port)=upper('{option_1_AgentCircuitId_port_hex}') kies ip,masker,router,dns van gebruikers waar upper(mac)=upper('{sw_mac}') en upper(port)=upper('{sw_port82}') kies ip,masker,router,dns van gebruikers waar upper(mac)=upper('{ClientMacAddress}') voeg waardes in geskiedenis (id,dt,mac,ip,comment) in (nul,nou(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Nou in meer besonderhede oor die etikette:

Die dhcpserver-afdeling beskryf die basiese instellings om die bediener te begin, naamlik:

  • gasheer - na watter IP-adres luister die bediener op poort 67
  • uitsaai - watter ip is die uitsending vir DHCPOFFER en DHCPACK
  • DHCPServer - wat is die ip van die DHCP-bediener
  • LeaseTime-huurtyd van die uitgereikte IP-adres
  • ThreadLimit - hoeveel drade loop gelyktydig om inkomende UDP-pakkies op poort 67 te verwerk. Dit is veronderstel om te help met hoëladingsprojekte 😉
  • defaultMask,defaultRouter,defaultDNS - wat by verstek aan die intekenaar aangebied word as 'n IP in die databasis gevind word, maar bykomende parameters word nie daarvoor gespesifiseer nie

mysql afdeling:

gasheer, gebruikersnaam, wagwoord, basisnaam - alles spreek vanself. 'n Geskatte databasisstruktuur word op geplaas GitHub

Navrae-afdeling: versoeke vir die ontvangs van AANBOD/ACK word hier beskryf:

  • offer_count — die aantal reëls met versoeke wat 'n resultaat soos ip,mask,router,dns terugstuur
  • offer_n — navraagstring. As teruggawe leeg is, voer dan die volgende aanbodversoek uit
  • history_sql - 'n navraag wat byvoorbeeld na die "magtigingsgeskiedenis" vir 'n intekenaar skryf

Versoeke kan enige veranderlikes van die opsie-afdeling of opsies van die DHCP-protokol insluit.

Opsies afdeling. Dit is waar dit meer interessant word. Hier kan ons veranderlikes skep wat ons later in die navraagafdeling kan gebruik.

Byvoorbeeld:

option_82_hex:sw_port1:20:22

, neem hierdie opdragreël die hele reël wat in die DHCP-versoekopsie 82 gekom het, in hekshoekformaat, in die reeks van 20 tot 22 grepe en plaas dit in die nuwe veranderlike sw_port1 (skakel poort van waar die versoek gekom het)

option_82_hex:sw_mac:26:40

, definieer die sw_mac-veranderlike, neem die hex uit die reeks 26:40

U kan al die moontlike opsies sien wat in navrae gebruik kan word deur die bediener met die -d-skakelaar te begin. Ons sal iets soos hierdie log sien:

--'n DHCPINFORM-pakkie het op poort 67 aangekom, vanaf 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': 'B'ClientMacAddress': '0025224'Address': '764'Mac': '00'Mac 7 91%"Jxd5d" , 'HType': 'Ethernet', 'Hostname': B'x0xa3xe5xa9xa8xa8-X43fx0.0.0.0a ',' Reqlistdns ': True,' reqlistdomainname ': true,' reqlistperfowmrouterDiscover ':' True, 'reqlistRouter': true, 'true,' reqlistStaticrOpTe ': 'ReqListSubnetM ask': True, 'ReqListVendorSpecInfo': 5.0, 'RequestedIpAddress': '0025224', 'Vendor': b'MSFT 764', 'chaddr': '172.30.128.13ad00', 'ciaddr'.00'.172.30.114.25'308'. , 'vlae': b'x6x1', 'giaddr': '82', 'gpoz': 12, 'hlen': 12, 'hops': 53, 'htype': 'MAC', 'magic_cookie': b'cx53Sc ', 'op': 'DHCPINFORM', 'option55': 55, 'option60': 60, 'option61': 61, 'option82': 82, 'option82': 12, 'option01': 06, ' option_00_byte': b'x04x00x01x00x06x02x08x00x06x00x1x9' b'x2x82x12010600040001000602080006001eXx589exb2xad', 'option_82_hex': '18e _82_len': 12 01, 'option_06_str': "b'x00x04x00x01x00x06x02x08x00x06x00x1x9x2x768eXx0.0.0.0exb001xad'", 'resultaat': False, 'secs': 589 'siaddr': '2', 'sw_mac': '1e06eb89ad', 'sw_port8': '3', 'xidbyte': b'

Gevolglik kan ons enige veranderlike in {} omvou en dit sal in die SQL-navraag gebruik word.

Kom ons teken vir geskiedenis aan dat die kliënt die IP-adres ontvang het:

DHCP+Mysql-bediener in Python

DHCP+Mysql-bediener in Python

Bediener begin

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

— d konsole-uitsetmodus DEBUG
- c <lêernaam> konfigurasielêer

ontlonting

En nou meer besonderhede oor die implementering van die bediener in Python. Dit is 'n pyn. Python is op die vlieg geleer. Baie oomblikke word gemaak in die styl van "sjoe, op een of ander manier het ek dit laat werk." Glad nie geoptimaliseer nie, en in hierdie vorm gelaat hoofsaaklik as gevolg van min ervaring in Python-ontwikkeling. Ek sal stilstaan ​​by die interessantste aspekte van die bedienerimplementering in "kode".

XML konfigurasie lêer ontleder

Die standaard Python-module xml.dom word gebruik. Dit lyk eenvoudig, maar tydens implementering was daar 'n merkbare gebrek aan duidelike dokumentasie en voorbeelde op die netwerk wat hierdie module gebruik.

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") vir elem in mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("gasheer")[0].firstChild. gconfig["mysql_username"]=elem.getElementsByTagName("gebruikersnaam")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("wagwoord")[0].firstChild.data gconfig_basenameq]l_basenameq] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") vir elem in dconfig: gconfig["broadcast"]=elem.getElementsByTagName("uitsaai")[0]. firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("gasheer")[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"]defaultMacskp_default =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultDgetElement"]=eBlemyTagElement defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") vir elem in qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data vir num in reeks(int(gconfig["aanbod_telling"])): gconfig["aanbod_"+str(num+1)]=elem.getElementsByTagName("aanbieding_"+str(num+1))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("options") vir elem in opsies: node=elem.getElementsByTagName("opsie") vir opsies in node : optionsMod.append(options.firstChild.data)

Multithreading

Vreemd genoeg word multithreading in Python baie duidelik en eenvoudig geïmplementeer.

def PacketWork(data,addr): ... # implementering van die ontleding van die inkomende pakkie en daarop reageer ... terwyl True: data, addr = udp_socket.recvfrom(1024) # wag vir die UDP-pakketdraad = threading.Thread( target=PacketWork , args=(data,addr,)).start() # soos dit gekom het - ons begin die voorheen gedefinieerde PacketWork-funksie op die agtergrond met parameters terwyl threading.active_count() >gconfig["dhcp_ThreadLimit"]: tyd. slaap(1) # as die nommer Daar is meer drade wat reeds loop as in die instellings, ons wag totdat daar minder van hulle is

Ontvang/stuur DHCP-pakkie

Om UDP-pakkies wat deur die netwerkkaart kom, te onderskep, moet jy die sok "lig":

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

, waar die vlae is:

  • AF_INET - beteken dat die adresformaat IP:poort sal wees. Daar kan ook AF_UNIX wees - waar die adres deur die lêernaam gegee word.
  • SOCK_DGRAM - beteken dat ons nie 'n "rou pakkie" aanvaar nie, maar een wat reeds deur die firewall gegaan het, en met 'n gedeeltelik afgesnyde pakkie. Dié. ons ontvang slegs 'n UDP-pakkie sonder die "fisiese" komponent van die UDP-pakkie-omhulsel. As jy die SOCK_RAW vlag gebruik, sal jy ook hierdie "wrapper" moet ontleed.

Om 'n pakkie te stuur kan soos 'n uitsending wees:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #skakel die sok na uitsaaimodus rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, en na die adres "waar die pakkie vandaan gekom het":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # skakel die sok oor na multiluister-modus rz=udp_socket.sendto(packetack, addr)

, waar SOL_SOCKET die "protokolvlak" beteken vir die instelling van opsies,

, SO_BROADCAST opsie dat die helmpakket "uitgesaai" word

  ,SO_REUSEADDR opsie skakel die sok na "baie luisteraars" af. In teorie is dit in hierdie geval onnodig, maar op een van die FreeBSD-bedieners waarop ek getoets het, het die kode nie sonder hierdie opsie gewerk nie.

Ontleding van 'n DHCP-pakkie

Dit is waar ek baie van Python gehou het. Dit blyk dat dit jou uit die boks toelaat om redelik buigsaam te wees met die greepkode. Laat toe dat dit baie maklik in desimale waardes, stringe en heks vertaal kan word - d.w.s. dit is wat ons eintlik nodig het om die struktuur van die pakket te verstaan. So, byvoorbeeld, kan jy 'n reeks grepe in HEX kry en net grepe:

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

, pak die grepe in 'n struktuur:

res["vlae"]=pak('BB',data[10],data[11])

Kry IP vanaf struktuur:

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

En omgekeerd:

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

Dis al vir nou 😉

Bron: will.com

Voeg 'n opmerking