DHCP+Mysql-tsjinner yn Python

DHCP+Mysql-tsjinner yn Python

It doel fan dit projekt wie:

  • Learje oer DHCP op in IPv4-netwurk
  • Python leare (in bytsje mear dan fanôf it begjin 😉)
  • tsjinner ferfanging DB2DHCP (myn foarke), oarspronklik hjir, dy't hieltyd dreger wurdt om te sammeljen foar it nije OS. En ik hâld der net fan dat it binêr is dat d'r gjin manier is om "op it stuit te feroarjen"
  • it krijen fan in wurkjende DHCP-tsjinner mei de mooglikheid om it IP-adres fan 'e abonnee te selektearjen mei de mac fan' e abonnee of wikselje mac + poarte kombinaasje (Opsje 82)
  • in oare fyts skriuwe (Oh! dit is myn favorite aktiviteit)
  • opmerkings ûntfange oer jo klup-handedness op Habrahabr (of better noch, in útnoeging) 😉

Resultaat: it wurket 😉 Teste op FreeBSD en Ubuntu OS. Teoretysk kin de koade frege wurde om te wurkjen ûnder elke OS, om't D'r lykje gjin spesifike bindingen te wêzen yn 'e koade.
Foarsichtich! Der komt noch folle mear.

Link nei repository foar amateurs "libben oanreitsje".

It proses fan it ynstallearjen, konfigurearjen en brûken fan it resultaat fan "stúdzje de hardware" is folle leger, en dan in bytsje teory oer it DHCP-protokol. Foar mysels. En foar skiednis 😉

In bytsje teory

Wat is DHCP

Dit is in netwurkprotokol wêrmei in apparaat syn IP-adres (en oare parameters lykas gateway, DNS, ensfh.) fan in DHCP-tsjinner kin fine. Pakketten wurde útwiksele mei it UDP-protokol. It algemiene prinsipe fan wurking fan it apparaat by it oanfreegjen fan netwurkparameters is as folget:

  1. It apparaat (kliïnt) stjoert in UDP-útstjoerfersyk (DHCPDISCOVER) troch it heule netwurk mei it fersyk "goed, immen jou my in IP-adres." Boppedat, meastal (mar net altyd) it fersyk komt fan haven 68 (boarne), en de bestimming is haven 67 (bestimming). Guon apparaten stjoere ek pakketten fan poarte 67. It MAC-adres fan it kliïntapparaat is opnommen yn it DHCPDISCOVER-pakket.
  2. Alle DHCP tsjinners leit op it netwurk (en der kin wêze ferskate fan harren) foarmje in DHCPOFFER oanbod mei netwurk ynstellings foar it apparaat dat stjoerde DHCPDISCOVER, en ek útstjoere it oer it netwurk. Identifikaasje fan wa't dit pakket is bedoeld foar is basearre op it MAC-adres fan 'e kliïnt earder levere yn it DHCPDISCOVER-fersyk.
  3. De kliïnt akseptearret pakketten mei útstellen foar netwurkynstellingen, selekteart de meast oantreklike (de kritearia kinne oars wêze, bygelyks de tiid fan pakketlevering, it oantal tuskenrûtes), en makket in "offisjele fersyk" DHCPREQUEST mei de netwurkynstellingen fan 'e DHCP-tsjinner dy't it liket. Yn dit gefal giet it pakket nei in spesifike DHCP-tsjinner.
  4. De tsjinner dy't de DHCPREQUEST ûntfong stjoert in pakket fan DHCPACK-formaat, wêryn't it nochris de netwurkynstellingen foar dizze kliïnt oantsjutte

DHCP+Mysql-tsjinner yn Python

Derneist binne d'r DHCPINFORM-pakketten dy't fan 'e kliïnt komme, en it doel dêrfan is om de DHCP-tsjinner te ynformearjen dat de "kliïnt libbet" en de útjûne netwurkynstellingen brûkt. By de ymplemintaasje fan dizze tsjinner wurde dizze pakketten negearre.

Pakketformaat

Yn 't algemien sjocht in Ethernet-pakketframe der sa út:

DHCP+Mysql-tsjinner yn Python

Yn ús gefal sille wy allinich de gegevens direkt beskôgje fan 'e ynhâld fan it UDP-pakket, sûnder OSI-laachprotokolkopteksten, nammentlik de DHCP-struktuer:

DHCP DISCOVER

Dat, it proses fan it krijen fan in IP-adres foar in apparaat begjint mei de DHCP-kliïnt dy't in útstjoerfersyk ferstjoert fan poarte 68 nei 255.255.255.255:67. Yn dit pakket omfettet de kliïnt syn MAC-adres, lykas wat it krekt wol ûntfange fan 'e DHCP-tsjinner. De pakketstruktuer wurdt beskreaun yn 'e tabel hjirûnder.

DHCPDISCOVER Packet Struktuer Tabel

Posysje yn it pakket
Wearde namme
Foarbyld:
Ynlieding
Byte
Taljochting

1
Boot Fersyk
1
Hex
1
Berjochttype. 1 - fersyk fan kliïnt nei tsjinner, 2 - antwurd fan tsjinner nei kliïnt

2
Hardware type
1
Hex
1
Soart hardware adres, yn dit protokol 1 - MAC

3
Hardware adressen lingte
6
Hex
1
Apparaat MAC adres lingte

4
Hops
1
Hex
1
Oantal tuskenlizzende rûtes

5
Transaksje ID
23:cf:de:1d
Hex
4
Unike transaksje identifier. Generearre troch de klant oan it begjin fan in fersyk operaasje

7
Twadde ferrûn
0
Hex
4
Tiid yn sekonden fan it begjin fan it proses fan it krijen fan in adres

9
Boot flaggen
0
Hex
2
Bepaalde flaggen dy't kinne wurde ynsteld om protokol parameters oan te jaan

11
Client IP-adres
0.0.0.0
String
4
Client IP-adres (as ien)

15
Jo klant IP-adres
0.0.0.0
String
4
IP-adres oanbean troch de tsjinner (as beskikber)

19
Folgjende tsjinner IP-adres
0.0.0.0
String
4
Server IP-adres (as bekend)

23
Relay agent IP-adres
172.16.114.41
String
4
IP-adres fan 'e relay-agent (bygelyks in switch)

27
Client MAC adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres fan de pakketstjoerder (kliïnt)

31
Client hardware adres padding
 
Hex
10
Reservearre sit. Meastal fol mei nullen

41
Tsjinner host namme
 
String
64
DHCP tsjinner namme. Gewoanlik net oerdroegen

105
Boot triemnamme
 
String
128
Bestânsnamme op de tsjinner brûkt troch diskless stasjons by it opstarten

235
Magic cookies
63: 82: 53: 63
Hex
4
"Magic" nûmer, neffens hokker, incl. jo kinne bepale dat dit pakket heart ta it DHCP-protokol

DHCP opsjes. Kin gean yn elke folchoarder

236
Opsje nûmer
53
Jan
1
Opsje 53, dy't it DHCP-pakkettype spesifisearret

1 - DHCPDISCOVER
3 - DHCPREQUEST
2 - DHCPOFFER
5 - DHCPACK
8 - DHCPINFORM

 
Opsje lingte
1
Jan
1

 
Opsje wearde
1
Jan
1

 
Opsje nûmer
50
Jan
1
Hokker IP-adres wol de kliïnt ûntfange?

 
Opsje lingte
4
Jan
1

 
Opsje wearde
172.16.134.61
String
4

 
Opsje nûmer
55
 
1
Netwurk parameters oanfrege troch de klant. Gearstalling kin ferskille

01 - Netwurkmasker
03 - Gateway
06 - DNS
oc - Hostnamme
0f - netwurk domeinnamme
1c - adres fan útstjoerfersyk (útstjoering)
42 - TFTP-tsjinnernamme
79 - Classless Static Route

 
Opsje lingte
8
 
1

 
Opsje wearde
01:03:06:0c:0f:1c:42:79
 
8

 
Opsje nûmer
82
Jan
 
Opsje 82, dy't it MAC-adres fan it repeaterapparaat en wat ekstra wearden trochstjoert.

Meastentiids is dit de poarte fan 'e skeakel wêrop de ein fan' e DHCP-kliïnt rint. Dizze opsje befettet ekstra parameters. De earste byte is it nûmer fan 'e "subopsje", de twadde is de lingte, dan de wearde.

Yn dit gefal, yn opsje 82, binne de sub-opsjes nestele:
Agent Circuit ID = 00:04:00:01:00:04, wêr't de lêste twa bytes de DHCP-kliïntpoarte binne wêrfan it fersyk kaam

Agent Remote ID = 00:06:c8:be:19:93:11:48 - MAC-adres fan it DHCP-repeaterapparaat

 
Opsje lingte
18
Jan
 

 
Opsje wearde
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Ein fan pakket
255
Jan
1
255 symbolisearret it ein fan it pakket

DHCPOFFER

Sadree't de tsjinner it DHCPDISCOVER-pakket ûntfangt en as it sjocht dat it de kliïnt wat kin biede fan 'e frege, dan genereart it in antwurd foar it - DHCPDISCOVER. It antwurd wurdt stjoerd nei de haven "fan wêr't it kaam", troch útstjoering, omdat op dit stuit hat de kliïnt noch gjin IP-adres, dêrom kin it it pakket allinich akseptearje as it troch útstjoering ferstjoerd wurdt. De kliïnt erkent dat dit in pakket foar him is troch syn MAC-adres yn it pakket, lykas ek it transaksjenûmer dat hy genereart op it momint dat it earste pakket wurdt oanmakke.

DHCPOFFER Packet Struktuer Tabel

Posysje yn it pakket
Namme fan wearde (mienskiplik)
Foarbyld:
Ynlieding
Byte
Taljochting

1
Boot Fersyk
1
Hex
1
Berjochttype. 1 - fersyk fan kliïnt nei tsjinner, 2 - antwurd fan tsjinner nei kliïnt

2
Hardware type
1
Hex
1
Soart hardware adres, yn dit protokol 1 - MAC

3
Hardware adressen lingte
6
Hex
1
Apparaat MAC adres lingte

4
Hops
1
Hex
1
Oantal tuskenlizzende rûtes

5
Transaksje ID
23:cf:de:1d
Hex
4
Unike transaksje identifier. Generearre troch de klant oan it begjin fan in fersyk operaasje

7
Twadde ferrûn
0
Hex
4
Tiid yn sekonden fan it begjin fan it proses fan it krijen fan in adres

9
Boot flaggen
0
Hex
2
Bepaalde flaggen dy't kinne wurde ynsteld om protokol parameters oan te jaan. Yn dit gefal betsjut 0 it Unicast-oanfraachtype

11
Client IP-adres
0.0.0.0
String
4
Client IP-adres (as ien)

15
Jo klant IP-adres
172.16.134.61
String
4
IP-adres oanbean troch de tsjinner (as beskikber)

19
Folgjende tsjinner IP-adres
0.0.0.0
String
4
Server IP-adres (as bekend)

23
Relay agent IP-adres
172.16.114.41
String
4
IP-adres fan 'e relay-agent (bygelyks in switch)

27
Client MAC adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres fan de pakketstjoerder (kliïnt)

31
Client hardware adres padding
 
Hex
10
Reservearre sit. Meastal fol mei nullen

41
Tsjinner host namme
 
String
64
DHCP tsjinner namme. Gewoanlik net oerdroegen

105
Boot triemnamme
 
String
128
Bestânsnamme op de tsjinner brûkt troch diskless stasjons by it opstarten

235
Magic cookies
63: 82: 53: 63
Hex
4
"Magic" nûmer, neffens hokker, incl. jo kinne bepale dat dit pakket heart ta it DHCP-protokol

DHCP opsjes. Kin gean yn elke folchoarder

236
Opsje nûmer
53
Jan
1
Opsje 53, dy't it DHCP 2-pakkettype definiearret - DHCPOFFER

 
Opsje lingte
1
Jan
1

 
Opsje wearde
2
Jan
1

 
Opsje nûmer
1
Jan
1
Opsje om de DHCP-kliïnt in netwurkmasker oan te bieden

 
Opsje lingte
4
Jan
1

 
Opsje wearde
255.255.224.0
String
4

 
Opsje nûmer
3
Jan
1
Opsje om de DHCP-kliïnt in standert gateway oan te bieden

 
Opsje lingte
4
Jan
1

 
Opsje wearde
172.16.12.1
String
4

 
Opsje nûmer
6
Jan
1
Opsje om DHCP oan te bieden oan DNS-kliïnt

 
Opsje lingte
4
Jan
1

 
Opsje wearde
8.8.8.8
String
4

 
Opsje nûmer
51
Jan
1
It libben fan 'e útjûne netwurkparameters yn sekonden, wêrnei't de DHCP-kliïnt se opnij moat oanfreegje

 
Opsje lingte
4
Jan
1

 
Opsje wearde
86400
Jan
4

 
Opsje nûmer
82
Jan
1
Opsje 82, werhellet wat kaam yn DHCPDISCOVER

 
Opsje lingte
18
Jan
1

 
Opsje wearde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:yk
Jan
18

 
Ein fan pakket
255
Jan
1
255 symbolisearret it ein fan it pakket

DHCPREQUEST

Nei't de kliïnt DHCPOFFER ûntfangt, foarmet hy in pakket dat netwurkparameters freget net oan alle DHCP-tsjinners op it netwurk, mar allinich nei ien spesifyk, waans DHCPOFFER-oanbod hy it meast "leafde". De "lykas" kritearia kinne oars wêze en binne ôfhinklik fan 'e DHCP-ymplemintaasje fan 'e kliïnt. De ûntfanger fan it fersyk wurdt oantsjutte mei it MAC-adres fan de DHCP-tsjinner. Ek kin in DHCPREQUEST-pakket troch de kliïnt stjoerd wurde sûnder earst DHCPDISCOVER te generearjen, as it IP-adres fan de tsjinner al earder is krigen.

DHCPREQUEST Packet Struktuer Tabel

Posysje yn it pakket
Namme fan wearde (mienskiplik)
Foarbyld:
Ynlieding
Byte
Taljochting

1
Boot Fersyk
1
Hex
1
Berjochttype. 1 - fersyk fan kliïnt nei tsjinner, 2 - antwurd fan tsjinner nei kliïnt

2
Hardware type
1
Hex
1
Soart hardware adres, yn dit protokol 1 - MAC

3
Hardware adressen lingte
6
Hex
1
Apparaat MAC adres lingte

4
Hops
1
Hex
1
Oantal tuskenlizzende rûtes

5
Transaksje ID
23:cf:de:1d
Hex
4
Unike transaksje identifier. Generearre troch de klant oan it begjin fan in fersyk operaasje

7
Twadde ferrûn
0
Hex
4
Tiid yn sekonden fan it begjin fan it proses fan it krijen fan in adres

9
Boot flaggen
8000
Hex
2
Bepaalde flaggen dy't kinne wurde ynsteld om protokol parameters oan te jaan. Yn dit gefal wurdt "útstjoering" ynsteld

11
Client IP-adres
0.0.0.0
String
4
Client IP-adres (as ien)

15
Jo klant IP-adres
172.16.134.61
String
4
IP-adres oanbean troch de tsjinner (as beskikber)

19
Folgjende tsjinner IP-adres
0.0.0.0
String
4
Server IP-adres (as bekend)

23
Relay agent IP-adres
172.16.114.41
String
4
IP-adres fan 'e relay-agent (bygelyks in switch)

27
Client MAC adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres fan de pakketstjoerder (kliïnt)

31
Client hardware adres padding
 
Hex
10
Reservearre sit. Meastal fol mei nullen

41
Tsjinner host namme
 
String
64
DHCP tsjinner namme. Gewoanlik net oerdroegen

105
Boot triemnamme
 
String
128
Bestânsnamme op de tsjinner brûkt troch diskless stasjons by it opstarten

235
Magic cookies
63: 82: 53: 63
Hex
4
"Magic" nûmer, neffens hokker, incl. jo kinne bepale dat dit pakket heart ta it DHCP-protokol

DHCP opsjes. Kin gean yn elke folchoarder

236
Opsje nûmer
53
Jan
3
Opsje 53, dy't it DHCP-pakkettype 3 definiearret - DHCPREQUEST

 
Opsje lingte
1
Jan
1

 
Opsje wearde
3
Jan
1

 
Opsje nûmer
61
Jan
1
Client ID: 01 (foar Ehernet) + client MAC adres

 
Opsje lingte
7
Jan
1

 
Opsje wearde
01:2c:ab:25:ff:72:a6
Hex
7

 
Opsje nûmer
60
Jan
 
"Vendor klasse identifier". Yn myn gefal rapportearret it de DHCP-kliïntferzje. Miskien jouwe oare apparaten wat oars werom. Windows meldt bygelyks MSFT 5.0

 
Opsje lingte
11
Jan
 

 
Opsje wearde
udhcp 0.9.8
String
 

 
Opsje nûmer
55
 
1
Netwurk parameters oanfrege troch de klant. Gearstalling kin ferskille

01 - Netwurkmasker
03 - Gateway
06 - DNS
oc - Hostnamme
0f - netwurk domeinnamme
1c - adres fan útstjoerfersyk (útstjoering)
42 - TFTP-tsjinnernamme
79 - Classless Static Route

 
Opsje lingte
8
 
1

 
Opsje wearde
01:03:06:0c:0f:1c:42:79
 
8

 
Opsje nûmer
82
Jan
1
Opsje 82, werhellet wat kaam yn DHCPDISCOVER

 
Opsje lingte
18
Jan
1

 
Opsje wearde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:yk
Jan
18

 
Ein fan pakket
255
Jan
1
255 symbolisearret it ein fan it pakket

DHCPACK

As befêstiging dat "ja, dat is rjocht, dit is jo IP-adres, en ik sil it net oan immen oars jaan" fan 'e DHCP-tsjinner, tsjinnet in pakket yn DHCPACK-formaat fan' e tsjinner nei de kliïnt. It wurdt útstjoerd krekt lykas oare pakketten. Hoewol, yn 'e koade hjirûnder foar in DHCP-tsjinner ymplementearre yn Python, foar it gefal, duplikearje ik elke útstjoerfersyk troch in pakket nei in spesifike client-IP te stjoeren, as it al bekend is. Boppedat makket de DHCP-tsjinner hielendal neat út oft it DHCPACK-pakket de kliïnt berikt hat. As de kliïnt gjin DHCPACK ûntfangt, dan werhellet it nei in skoft gewoan DHCPREQUEST

DHCPACK-pakketstruktuertabel

Posysje yn it pakket
Namme fan wearde (mienskiplik)
Foarbyld:
Ynlieding
Byte
Taljochting

1
Boot Fersyk
2
Hex
1
Berjochttype. 1 - fersyk fan kliïnt nei tsjinner, 2 - antwurd fan tsjinner nei kliïnt

2
Hardware type
1
Hex
1
Soart hardware adres, yn dit protokol 1 - MAC

3
Hardware adressen lingte
6
Hex
1
Apparaat MAC adres lingte

4
Hops
1
Hex
1
Oantal tuskenlizzende rûtes

5
Transaksje ID
23:cf:de:1d
Hex
4
Unike transaksje identifier. Generearre troch de klant oan it begjin fan in fersyk operaasje

7
Twadde ferrûn
0
Hex
4
Tiid yn sekonden fan it begjin fan it proses fan it krijen fan in adres

9
Boot flaggen
8000
Hex
2
Bepaalde flaggen dy't kinne wurde ynsteld om protokol parameters oan te jaan. Yn dit gefal wurdt "útstjoering" ynsteld

11
Client IP-adres
0.0.0.0
String
4
Client IP-adres (as ien)

15
Jo klant IP-adres
172.16.134.61
String
4
IP-adres oanbean troch de tsjinner (as beskikber)

19
Folgjende tsjinner IP-adres
0.0.0.0
String
4
Server IP-adres (as bekend)

23
Relay agent IP-adres
172.16.114.41
String
4
IP-adres fan 'e relay-agent (bygelyks in switch)

27
Client MAC adres
14:d6:4d:a7:c9:55
Hex
6
MAC-adres fan de pakketstjoerder (kliïnt)

31
Client hardware adres padding
 
Hex
10
Reservearre sit. Meastal fol mei nullen

41
Tsjinner host namme
 
String
64
DHCP tsjinner namme. Gewoanlik net oerdroegen

105
Boot triemnamme
 
String
128
Bestânsnamme op de tsjinner brûkt troch diskless stasjons by it opstarten

235
Magic cookies
63: 82: 53: 63
Hex
4
"Magic" nûmer, neffens hokker, incl. jo kinne bepale dat dit pakket heart ta it DHCP-protokol

DHCP opsjes. Kin gean yn elke folchoarder

236
Opsje nûmer
53
Jan
3
Opsje 53, dy't it DHCP-pakkettype 5 definiearret - DHCPACK

 
Opsje lingte
1
Jan
1

 
Opsje wearde
5
Jan
1

 
Opsje nûmer
1
Jan
1
Opsje om de DHCP-kliïnt in netwurkmasker oan te bieden

 
Opsje lingte
4
Jan
1

 
Opsje wearde
255.255.224.0
String
4

 
Opsje nûmer
3
Jan
1
Opsje om de DHCP-kliïnt in standert gateway oan te bieden

 
Opsje lingte
4
Jan
1

 
Opsje wearde
172.16.12.1
String
4

 
Opsje nûmer
6
Jan
1
Opsje om DHCP oan te bieden oan DNS-kliïnt

 
Opsje lingte
4
Jan
1

 
Opsje wearde
8.8.8.8
String
4

 
Opsje nûmer
51
Jan
1
It libben fan 'e útjûne netwurkparameters yn sekonden, wêrnei't de DHCP-kliïnt se opnij moat oanfreegje

 
Opsje lingte
4
Jan
1

 
Opsje wearde
86400
Jan
4

 
Opsje nûmer
82
Jan
1
Opsje 82, werhellet wat kaam yn DHCPDISCOVER

 
Opsje lingte
18
Jan
1

 
Opsje wearde
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:yk
Jan
18

 
Ein fan pakket
255
Jan
1
255 symbolisearret it ein fan it pakket

ynstelling

De ynstallaasje bestiet eins út it ynstallearjen fan de python-modules dy't nedich binne foar wurk. It wurdt oannommen dat MySQL al ynstallearre en konfigureare is.

FreeBSD

pkg ynstallearje python3 python3 -m surepip pip3 ynstallearje mysql-ferbining

ubuntu

sudo apt-get ynstallearje python3 sudo apt-get ynstallearje pip3 sudo pip3 ynstallearje mysql-ferbining

Wy meitsje in MySQL-database, upload de pydhcp.sql-dump deryn en konfigurearje it konfiguraasjetriem.

Konfiguraasje

Alle serverynstellingen binne yn in xml-bestân. Referinsjebestân:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 localhost 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 selektearje ip, masker, router, dns fan brûkers wêr't upper(mac)=upper('{option_3_AgentRemoteId_hex}') en upper(port)=upper('{option_1_AgentCircuitId_port_hex}') selektearje ip, masker, router, dns fan brûkers wêr't upper(mac)=upper('{sw_mac}') en upper(port)=upper('{sw_port82}') selektearje ip, masker, router, dns fan brûkers wêr't upper(mac)=upper('{ClientMacAddress}') ynfoegje yn skiednis (id,dt,mac,ip,comment) wearden (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

No yn mear detail oer de tags:

De dhcpserver-seksje beskriuwt de basisynstellingen foar it starten fan de tsjinner, nammentlik:

  • host - hokker IP-adres de tsjinner nei harket op poarte 67
  • broadcast - hokker ip is de útstjoering foar DHCPOFFER en DHCPACK
  • DHCPServer - wat is de ip fan 'e DHCP-tsjinner
  • LeaseTime lease tiid fan it útjûn IP-adres
  • ThreadLimit - hoefolle triedden rinne tagelyk om ynkommende UDP-pakketten te ferwurkjen op poarte 67. It soe helpe by projekten mei hege lading 😉
  • defaultMask,defaultRouter,defaultDNS - wat wurdt standert oanbean oan de abonnee as in IP is fûn yn 'e databank, mar ekstra parameters binne net spesifisearre foar it

mysql seksje:

host, brûkersnamme, wachtwurd, basisnamme - alles sprekt foar himsels. In ûngefear databankstruktuer wurdt pleatst op GitHub

Query seksje: oanfragen foar it ûntfangen fan OFFER / ACK wurde hjir beskreaun:

  • offer_count - it oantal rigels mei oanfragen dy't in resultaat weromjaan lykas ip,mask,router,dns
  • offer_n - query string. As werom is leech, dan fiert it folgjende oanbod fersyk
  • history_sql - in fraach dy't bygelyks skriuwt nei de "autorisaasjeskiednis" foar in abonnee

Oanfragen kinne alle fariabelen befetsje fan 'e opsjes seksje as opsjes fan it DHCP-protokol.

Opsjes seksje. Dit is wêr't it nijsgjirriger wurdt. Hjir kinne wy ​​fariabelen oanmeitsje dy't wy letter kinne brûke yn 'e query-seksje.

Bygelyks:

option_82_hex:sw_port1:20:22

, nimt dizze kommandorigel de hiele rigel dy't kaam yn 'e DHCP-fersykopsje 82, yn hex-formaat, yn it berik fan 20 oant 22 bytes ynklusyf en set it yn' e nije fariabele sw_port1 (skeakelje poarte fan wêr't it fersyk kaam)

option_82_hex:sw_mac:26:40

, definiearje de sw_mac fariabele, nimme de hex út it berik 26:40

Jo kinne alle mooglike opsjes sjen dy't brûkt wurde kinne yn queries troch de server te begjinnen mei de -d-skeakel. Wy sille wat sjen as dit log:

--in DHCPINFORM-pakket kaam oan op poarte 67, fan 0025224ad764, b'x91xa5xe0xa3xa5xa9-x8fx8a', ('172.30.114.25', 68) {'ClientMacAddress': '0025224', 764. % "Jxd00d", ' HType': 'Ethernet', 'HostName': b'x7xa91xe5xa0xa3xa5-x9fx8a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouterDiscover': True, 'ReqListRouteric: True, 'ReqListRouteric' ReqListSubnetMask ': True, 'ReqListVendorSpecInfo': 8, 'RequestedIpAddress': '43', 'Vendor': b'MSFT 0.0.0.0', 'chaddr': '5.0ad0025224', 'ciaddr': '764', '172.30.128.13. flaggen ': 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': '12010600040001000602080006001:'589:'2:'82:18:'82 12, 'option_01_str': "b'x06x00x04x00x01x00x06x02x08x00x06x00x1x9x2eXx768exb0.0.0.0xad'", 'resultaat': False, 'secs': 001, 'siaddr' : '589', 'sw_mac': '2e1eb06ad', 'sw_port89': '8', 'xidbyte': b'

Dêrtroch kinne wy ​​​​elke fariabele yn {} wrapje en it sil brûkt wurde yn 'e SQL-query.

Lit ús foar skiednis opnimme dat de kliïnt it IP-adres krige:

DHCP+Mysql-tsjinner yn Python

DHCP+Mysql-tsjinner yn Python

Server start

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

- d konsole útfier modus DEBUG
- c <triemnamme> konfiguraasjetriem

Debriefing

En no mear details oer it ymplementearjen fan de server yn Python. It is in pine. Python waard leard op 'e flecht. In protte mominten wurde makke yn 'e styl fan "wow, op ien of oare manier makke ik it wurk." Helemaal net optimalisearre, en ferliet yn dizze foarm benammen troch in bytsje ûnderfining yn Python-ûntwikkeling. Ik sil wenje op 'e meast nijsgjirrige aspekten fan' e tsjinner ymplemintaasje yn "koade".

XML konfiguraasje triem parser

De standert Python-module xml.dom wurdt brûkt. It liket ienfâldich, mar by ymplemintaasje wie d'r in merkber gebrek oan dúdlike dokumintaasje en foarbylden op it netwurk mei dizze module.

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") foar elem yn mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild. gconfig["mysql_username"]=elem.getElementsByTagName("brûkersnamme")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("wachtwurd")[0].firstChild.data gconfig_basenamesq]l =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") foar elem yn 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"]defaultMacsk" + defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") foar elem yn qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data foar num in range(int(gconfig["offer_count"])): gconfig["offer_"+str(num+0)]=elem.getElementsByTagName("offer_"+str(num+0))[1].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[1].firstChild.data options=tree.getElementsByTagName("opsjes") foar elem yn opsjes: node=elem.getElementsByTagName("opsje") foar opsjes yn node : optionsMod.append(options.firstChild.data)

Multithreading

Frjemd genôch is multithreading yn Python heul dúdlik en ienfâldich ymplementearre.

def PacketWork(data,addr): ... # ymplemintaasje fan it parsearjen fan it ynkommende pakket en dêrop reagearje ... wylst True: data, addr = udp_socket.recvfrom(1024) # wachtsjen op de UDP-pakketthread = threading.Thread( target=PacketWork, args=(data,addr,)).start() # as it kaam - wy starte de earder definieare PacketWork-funksje op 'e eftergrûn mei parameters wylst threading.active_count() >gconfig["dhcp_ThreadLimit"]: tiid. sliep(1) # as it nûmer D'r binne al mear diskusjes as yn 'e ynstellings, wy wachtsje oant d'r minder binne

DHCP-pakket ûntfange / ferstjoere

Om UDP-pakketten te ûnderskeppen dy't troch de netwurkkaart komme, moatte jo de socket "ferheegje":

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

, wêr't de flaggen binne:

  • AF_INET - betsjut dat it adresformaat IP: poarte sil wêze. D'r kin ek AF_UNIX wêze - wêr't it adres wurdt jûn troch de triemnamme.
  • SOCK_DGRAM - betsjut dat wy gjin "raw pakket" akseptearje, mar ien dy't al troch de firewall is trochjûn, en mei in foar in part ôfsnien pakket. Dy. wy ûntfange allinich in UDP-pakket sûnder de "fysike" komponint fan 'e UDP-pakket-wrapper. As jo ​​​​de SOCK_RAW-flagge brûke, dan moatte jo dizze "wrapper" ek parsearje.

It ferstjoeren fan in pakket kin wêze as in útstjoering:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #skeakelje de socket nei útstjoermodus rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, en nei it adres "wêr't it pakket wei kaam":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # skeakelje de socket nei multi-listener modus rz=udp_socket.sendto(packetack, addr)

, wêr't SOL_SOCKET it "protokolnivo" betsjut foar it ynstellen fan opsjes,

, SO_BROADCAST opsje dat it helmpakket "útstjoerd" is

  ,SO_REUSEADDR opsje skeakelt de socket nei "in protte harkers" modus. Yn teory is it yn dit gefal net nedich, mar op ien fan 'e FreeBSD-tsjinners wêrop ik hifke, wurke de koade net sûnder dizze opsje.

It parsearjen fan in DHCP-pakket

Dit is wêr ik echt leuk Python. It docht bliken dat it jo út 'e doaze frij fleksibel kinne wêze mei de bytekoade. Tastean dat it hiel maklik oerset wurde yn desimale wearden, snaren en hex - d.w.s. dit is wat wy eins moatte begripe de struktuer fan it pakket. Sa kinne jo bygelyks in berik fan bytes krije yn HEX en gewoan bytes:

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

, pak de bytes yn in struktuer:

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

Krij IP fan struktuer:

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

En oarsom:

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

Dat is alles foar no 😉

Boarne: www.habr.com

Add a comment