DHCP+Mysql server sa Python

DHCP+Mysql server sa Python

Ang layunin ng proyektong ito ay:

  • Pag-aaral tungkol sa DHCP sa isang IPv4 network
  • Pag-aaral ng Python (higit pa sa simula 😉)
  • pagpapalit ng server DB2DHCP (aking tinidor), orihinal dito, na nagiging mas mahirap i-assemble para sa bagong OS. At hindi ko gusto na ito ay isang binary na walang paraan upang "magbago ngayon"
  • pagkuha ng gumaganang DHCP server na may kakayahang pumili ng IP address ng subscriber gamit ang mac ng subscriber o switch mac+port na kumbinasyon (Pagpipilian 82)
  • pagsulat ng isa pang bike (Oh! ito ang paborito kong aktibidad)
  • pagtanggap ng mga komento tungkol sa iyong pagiging kamay sa club sa Habrahabr (o mas mabuti pa, isang imbitasyon) 😉

Resulta: gumagana ito 😉 Nasubok sa FreeBSD at Ubuntu OS. Sa teoryang, ang code ay maaaring hilingin na gumana sa ilalim ng anumang OS, dahil Mukhang walang tiyak na mga binding sa code.
Mag-ingat! Marami pang darating.

Link sa repository para sa mga baguhan "hawakan ng buhay".

Ang proseso ng pag-install, pag-configure at paggamit ng resulta ng "pag-aaral ng hardware" ay mas mababa, at pagkatapos ay isang maliit na teorya tungkol sa DHCP protocol. Para sa sarili ko. At para sa kasaysayan 😉

Isang maliit na teorya

Ano ang DHCP

Ito ay isang network protocol na nagbibigay-daan sa isang device na malaman ang IP address nito (at iba pang mga parameter tulad ng gateway, DNS, atbp.) mula sa isang DHCP server. Ang mga packet ay ipinagpapalit gamit ang UDP protocol. Ang pangkalahatang prinsipyo ng pagpapatakbo ng device kapag humihiling ng mga parameter ng network ay ang mga sumusunod:

  1. Ang device (kliyente) ay nagpapadala ng kahilingan sa pag-broadcast ng UDP (DHCPDISCOVER) sa buong network na may kahilingang "well, may nagbigay sa akin ng IP address." Bukod dito, kadalasan (ngunit hindi palaging) ang kahilingan ay nangyayari mula sa port 68 (pinagmulan), at ang patutunguhan ay port 67 (destinasyon). Nagpapadala rin ang ilang device ng mga packet mula sa port 67. Ang MAC address ng client device ay kasama sa loob ng DHCPDISCOVER package.
  2. Ang lahat ng mga server ng DHCP na matatagpuan sa network (at maaaring marami sa kanila) ay bumubuo ng isang alok ng DHCPOFFER na may mga setting ng network para sa device na nagpadala ng DHCPDISCOVER, at nag-broadcast din nito sa network. Ang pagkakakilanlan kung kanino nilalayon ang packet na ito ay batay sa MAC address ng kliyente na ibinigay kanina sa kahilingan ng DHCPDISCOVER.
  3. Tumatanggap ang kliyente ng mga packet na may mga panukala para sa mga setting ng network, pinipili ang pinaka-kaakit-akit (maaaring iba ang pamantayan, halimbawa, ang oras ng paghahatid ng packet, ang bilang ng mga intermediate na ruta), at gumagawa ng "opisyal na kahilingan" na DHCPREQUEST sa mga setting ng network mula sa DHCP server na gusto nito. Sa kasong ito, ang packet ay mapupunta sa isang partikular na DHCP server.
  4. Ang server na nakatanggap ng DHCPREQUEST ay nagpapadala ng isang DHCPACK na format na packet, kung saan muli nitong inililista ang mga setting ng network na inilaan para sa kliyenteng ito.

DHCP+Mysql server sa Python

Bilang karagdagan, may mga DHCPINFORM packet na nagmumula sa kliyente, at ang layunin nito ay ipaalam sa DHCP server na ang "kliyente ay buhay" at ginagamit ang ibinigay na mga setting ng network. Sa pagpapatupad ng server na ito, binabalewala ang mga packet na ito.

Format ng package

Sa pangkalahatan, ganito ang hitsura ng isang Ethernet packet frame:

DHCP+Mysql server sa Python

Sa aming kaso, isasaalang-alang lamang namin ang data nang direkta mula sa mga nilalaman ng UDP packet, nang walang OSI layer protocol header, katulad ng istraktura ng DHCP:

DHCPDISCOVER

Kaya, ang proseso ng pagkuha ng IP address para sa isang device ay nagsisimula sa pagpapadala ng DHCP client ng kahilingan sa broadcast mula sa port 68 hanggang 255.255.255.255:67. Sa package na ito, kasama ng kliyente ang MAC address nito, gayundin ang eksaktong nais nitong matanggap mula sa DHCP server. Ang istraktura ng pakete ay inilarawan sa talahanayan sa ibaba.

DHCPDISCOVER Packet Structure Table

Posisyon sa pakete
Pangalan ng halaga
Halimbawa
Panimula
Byte
Linaw

1
Kahilingan sa Boot
1
Kulam
1
Uri ng mensahe. 1 - kahilingan mula sa kliyente patungo sa server, 2 - tugon mula sa server patungo sa kliyente

2
Uri ng hardware
1
Kulam
1
Uri ng address ng hardware, sa protocol na ito 1 - MAC

3
Haba ng mga address ng hardware
6
Kulam
1
Haba ng MAC address ng device

4
Hops
1
Kulam
1
Bilang ng mga intermediate na ruta

5
Transaksyon ID
23:cf:de:1d
Kulam
4
Natatanging identifier ng transaksyon. Binuo ng kliyente sa simula ng isang operasyon ng kahilingan

7
Lumipas ang pangalawa
0
Kulam
4
Oras sa mga segundo mula sa simula ng proseso ng pagkuha ng address

9
Mga flag ng boot
0
Kulam
2
Ilang mga flag na maaaring itakda upang ipahiwatig ang mga parameter ng protocol

11
IP address ng kliyente
0.0.0.0
Linya
4
IP address ng kliyente (kung mayroon man)

15
IP address ng iyong kliyente
0.0.0.0
Linya
4
IP address na inaalok ng server (kung magagamit)

19
Susunod na IP address ng server
0.0.0.0
Linya
4
IP address ng server (kung kilala)

23
IP address ng ahente ng relay
172.16.114.41
Linya
4
IP address ng relay agent (halimbawa, switch)

27
MAC address ng kliyente
14:d6:4d:a7:c9:55
Kulam
6
MAC address ng packet sender (client)

31
Padding ng address ng hardware ng kliyente
 
Kulam
10
Nakareserba ang upuan. Karaniwang puno ng mga zero

41
Pangalan ng host ng server
 
Linya
64
Pangalan ng DHCP server. Karaniwang hindi naipapasa

105
Pangalan ng boot file
 
Linya
128
Pangalan ng file sa server na ginagamit ng mga diskless na istasyon kapag nagbo-boot

235
Magic cookies
63: 82: 53: 63
Kulam
4
"Magic" na numero, ayon sa kung saan, kasama. maaari mong matukoy na ang packet na ito ay kabilang sa DHCP protocol

Mga pagpipilian sa DHCP. Maaaring pumunta sa anumang pagkakasunud-sunod

236
Numero ng opsyon
53
Disyembre
1
Opsyon 53, na tumutukoy sa uri ng packet ng DHCP

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

 
Haba ng opsyon
1
Disyembre
1

 
Halaga ng opsyon
1
Disyembre
1

 
Numero ng opsyon
50
Disyembre
1
Anong IP address ang gustong matanggap ng kliyente?

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
172.16.134.61
Linya
4

 
Numero ng opsyon
55
 
1
Mga parameter ng network na hiniling ng kliyente. Maaaring mag-iba ang komposisyon

01 — Network mask
03 - Gateway
06 - DNS
oc — Hostname
0f - pangalan ng domain ng network
1c - address ng kahilingan sa broadcast (broadcast)
42 - Pangalan ng server ng TFTP
79 - Walang Klase na Static na Ruta

 
Haba ng opsyon
8
 
1

 
Halaga ng opsyon
01:03:06:0c:0f:1c:42:79
 
8

 
Numero ng opsyon
82
Disyembre
 
Opsyon 82, na nagpapadala ng MAC address ng repeater device at ilang karagdagang value.

Kadalasan, ito ang port ng switch kung saan tumatakbo ang end DHCP client. Ang opsyong ito ay naglalaman ng mga karagdagang parameter. Ang unang byte ay ang bilang ng "suboption", ang pangalawa ay ang haba nito, pagkatapos ay ang halaga nito.

Sa kasong ito, sa opsyon 82, ang mga sub-option ay naka-nest:
Agent Circuit ID = 00:04:00:01:00:04, kung saan ang huling dalawang byte ay ang DHCP client port kung saan nanggaling ang kahilingan

Agent Remote ID = 00:06:c8:be:19:93:11:48 - MAC address ng DHCP repeater device

 
Haba ng opsyon
18
Disyembre
 

 
Halaga ng opsyon
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Kulam
 

 
Katapusan ng pakete
255
Disyembre
1
Ang 255 ay sumisimbolo sa dulo ng pakete

DHCPOFFER

Sa sandaling matanggap ng server ang DHCPDISCOVER packet at kung nakita nito na maaari itong mag-alok sa kliyente ng isang bagay mula sa hiniling, pagkatapos ay bubuo ito ng tugon para dito - DHCPDISCOVER. Ang tugon ay ipinadala sa port "mula sa kung saan ito nanggaling", sa pamamagitan ng broadcast, dahil sa sandaling ito, ang kliyente ay wala pang IP address, samakatuwid maaari lamang nitong tanggapin ang packet kung ito ay ipinadala sa pamamagitan ng broadcast. Kinikilala ng kliyente na ito ay isang package para sa kanya sa pamamagitan ng kanyang MAC address sa loob ng package, pati na rin ang numero ng transaksyon na kanyang nabuo sa oras na nilikha ang unang pakete.

Talahanayan ng Istraktura ng Packet ng DHCPOFFER

Posisyon sa pakete
Pangalan ng halaga (karaniwan)
Halimbawa
Panimula
Byte
Linaw

1
Kahilingan sa Boot
1
Kulam
1
Uri ng mensahe. 1 - kahilingan mula sa kliyente patungo sa server, 2 - tugon mula sa server patungo sa kliyente

2
Uri ng hardware
1
Kulam
1
Uri ng address ng hardware, sa protocol na ito 1 - MAC

3
Haba ng mga address ng hardware
6
Kulam
1
Haba ng MAC address ng device

4
Hops
1
Kulam
1
Bilang ng mga intermediate na ruta

5
Transaksyon ID
23:cf:de:1d
Kulam
4
Natatanging identifier ng transaksyon. Binuo ng kliyente sa simula ng isang operasyon ng kahilingan

7
Lumipas ang pangalawa
0
Kulam
4
Oras sa mga segundo mula sa simula ng proseso ng pagkuha ng address

9
Mga flag ng boot
0
Kulam
2
Ilang mga flag na maaaring itakda upang ipahiwatig ang mga parameter ng protocol. Sa kasong ito, ang ibig sabihin ng 0 ay ang uri ng kahilingan sa Unicast

11
IP address ng kliyente
0.0.0.0
Linya
4
IP address ng kliyente (kung mayroon man)

15
IP address ng iyong kliyente
172.16.134.61
Linya
4
IP address na inaalok ng server (kung magagamit)

19
Susunod na IP address ng server
0.0.0.0
Linya
4
IP address ng server (kung kilala)

23
IP address ng ahente ng relay
172.16.114.41
Linya
4
IP address ng relay agent (halimbawa, switch)

27
MAC address ng kliyente
14:d6:4d:a7:c9:55
Kulam
6
MAC address ng packet sender (client)

31
Padding ng address ng hardware ng kliyente
 
Kulam
10
Nakareserba ang upuan. Karaniwang puno ng mga zero

41
Pangalan ng host ng server
 
Linya
64
Pangalan ng DHCP server. Karaniwang hindi naipapasa

105
Pangalan ng boot file
 
Linya
128
Pangalan ng file sa server na ginagamit ng mga diskless na istasyon kapag nagbo-boot

235
Magic cookies
63: 82: 53: 63
Kulam
4
"Magic" na numero, ayon sa kung saan, kasama. maaari mong matukoy na ang packet na ito ay kabilang sa DHCP protocol

Mga pagpipilian sa DHCP. Maaaring pumunta sa anumang pagkakasunud-sunod

236
Numero ng opsyon
53
Disyembre
1
Opsyon 53, na tumutukoy sa uri ng packet ng DHCP 2 - DHCPOFFER

 
Haba ng opsyon
1
Disyembre
1

 
Halaga ng opsyon
2
Disyembre
1

 
Numero ng opsyon
1
Disyembre
1
Opsyon na mag-alok sa DHCP client ng network mask

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
255.255.224.0
Linya
4

 
Numero ng opsyon
3
Disyembre
1
Opsyon na mag-alok sa DHCP client ng default na gateway

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
172.16.12.1
Linya
4

 
Numero ng opsyon
6
Disyembre
1
Opsyon na mag-alok ng DHCP sa DNS client

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
8.8.8.8
Linya
4

 
Numero ng opsyon
51
Disyembre
1
Ang tagal ng buhay ng ibinigay na mga parameter ng network sa ilang segundo, pagkatapos nito ay dapat hilingin muli ng DHCP client ang mga ito

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
86400
Disyembre
4

 
Numero ng opsyon
82
Disyembre
1
Opsyon 82, inuulit kung ano ang dumating sa DHCPDISCOVER

 
Haba ng opsyon
18
Disyembre
1

 
Halaga ng opsyon
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Disyembre
18

 
Katapusan ng pakete
255
Disyembre
1
Ang 255 ay sumisimbolo sa dulo ng pakete

DHCPREQUEST

Pagkatapos matanggap ng kliyente ang DHCPOFFER, bubuo siya ng isang packet na humihiling ng mga parameter ng network hindi sa lahat ng DHCP server sa network, ngunit sa isang partikular lamang, na ang alok ng DHCPOFFER ay "pinakagusto" niya. Maaaring iba ang pamantayang "like" at depende sa pagpapatupad ng DHCP ng kliyente. Ang tatanggap ng kahilingan ay tinukoy gamit ang MAC address ng DHCP server. Gayundin, ang isang DHCPREQUEST packet ay maaaring ipadala ng kliyente nang hindi muna bumubuo ng DHCPDISCOVER, kung ang IP address ng server ay nakuha na dati.

Talahanayan ng Istraktura ng Packet ng DHCPREQUEST

Posisyon sa pakete
Pangalan ng halaga (karaniwan)
Halimbawa
Panimula
Byte
Linaw

1
Kahilingan sa Boot
1
Kulam
1
Uri ng mensahe. 1 - kahilingan mula sa kliyente patungo sa server, 2 - tugon mula sa server patungo sa kliyente

2
Uri ng hardware
1
Kulam
1
Uri ng address ng hardware, sa protocol na ito 1 - MAC

3
Haba ng mga address ng hardware
6
Kulam
1
Haba ng MAC address ng device

4
Hops
1
Kulam
1
Bilang ng mga intermediate na ruta

5
Transaksyon ID
23:cf:de:1d
Kulam
4
Natatanging identifier ng transaksyon. Binuo ng kliyente sa simula ng isang operasyon ng kahilingan

7
Lumipas ang pangalawa
0
Kulam
4
Oras sa mga segundo mula sa simula ng proseso ng pagkuha ng address

9
Mga flag ng boot
8000
Kulam
2
Ilang mga flag na maaaring itakda upang ipahiwatig ang mga parameter ng protocol. Sa kasong ito, nakatakda ang "broadcast".

11
IP address ng kliyente
0.0.0.0
Linya
4
IP address ng kliyente (kung mayroon man)

15
IP address ng iyong kliyente
172.16.134.61
Linya
4
IP address na inaalok ng server (kung magagamit)

19
Susunod na IP address ng server
0.0.0.0
Linya
4
IP address ng server (kung kilala)

23
IP address ng ahente ng relay
172.16.114.41
Linya
4
IP address ng relay agent (halimbawa, switch)

27
MAC address ng kliyente
14:d6:4d:a7:c9:55
Kulam
6
MAC address ng packet sender (client)

31
Padding ng address ng hardware ng kliyente
 
Kulam
10
Nakareserba ang upuan. Karaniwang puno ng mga zero

41
Pangalan ng host ng server
 
Linya
64
Pangalan ng DHCP server. Karaniwang hindi naipapasa

105
Pangalan ng boot file
 
Linya
128
Pangalan ng file sa server na ginagamit ng mga diskless na istasyon kapag nagbo-boot

235
Magic cookies
63: 82: 53: 63
Kulam
4
"Magic" na numero, ayon sa kung saan, kasama. maaari mong matukoy na ang packet na ito ay kabilang sa DHCP protocol

Mga pagpipilian sa DHCP. Maaaring pumunta sa anumang pagkakasunud-sunod

236
Numero ng opsyon
53
Disyembre
3
Opsyon 53, na tumutukoy sa uri ng DHCP packet 3 - DHCPREQUEST

 
Haba ng opsyon
1
Disyembre
1

 
Halaga ng opsyon
3
Disyembre
1

 
Numero ng opsyon
61
Disyembre
1
Client ID: 01 (para sa Ehernet) + MAC address ng kliyente

 
Haba ng opsyon
7
Disyembre
1

 
Halaga ng opsyon
01:2c:ab:25:ff:72:a6
Kulam
7

 
Numero ng opsyon
60
Disyembre
 
"Identifier ng klase ng vendor". Sa aking kaso, iniuulat nito ang bersyon ng DHCP client. Marahil iba ang ibinabalik ng ibang mga device. Halimbawa, ang Windows ay nag-uulat ng MSFT 5.0

 
Haba ng opsyon
11
Disyembre
 

 
Halaga ng opsyon
udhcp 0.9.8
Linya
 

 
Numero ng opsyon
55
 
1
Mga parameter ng network na hiniling ng kliyente. Maaaring mag-iba ang komposisyon

01 — Network mask
03 - Gateway
06 - DNS
oc — Hostname
0f - pangalan ng domain ng network
1c - address ng kahilingan sa broadcast (broadcast)
42 - Pangalan ng server ng TFTP
79 - Walang Klase na Static na Ruta

 
Haba ng opsyon
8
 
1

 
Halaga ng opsyon
01:03:06:0c:0f:1c:42:79
 
8

 
Numero ng opsyon
82
Disyembre
1
Opsyon 82, inuulit kung ano ang dumating sa DHCPDISCOVER

 
Haba ng opsyon
18
Disyembre
1

 
Halaga ng opsyon
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Disyembre
18

 
Katapusan ng pakete
255
Disyembre
1
Ang 255 ay sumisimbolo sa dulo ng pakete

DHCPACK

Bilang kumpirmasyon na "oo, tama iyan, ito ang iyong IP address, at hindi ko ito ibibigay sa iba" mula sa DHCP server, isang packet sa DHCPACK na format mula sa server hanggang sa inihahatid ng kliyente. Ito ay ipinadala sa broadcast tulad ng iba pang mga packet. Bagaman, sa code sa ibaba para sa isang DHCP server na ipinatupad sa Python, kung sakali, duplicate ko ang anumang kahilingan sa broadcast sa pamamagitan ng pagpapadala ng isang packet sa isang partikular na IP ng kliyente, kung kilala na ito. Bukod dito, ang DHCP server ay walang pakialam kung ang DHCPACK packet ay nakarating sa kliyente. Kung ang kliyente ay hindi nakatanggap ng DHCPACK, pagkatapos ng ilang sandali ay inuulit lamang nito ang DHCPREQUEST

Talahanayan ng Istraktura ng Packet ng DHCPACK

Posisyon sa pakete
Pangalan ng halaga (karaniwan)
Halimbawa
Panimula
Byte
Linaw

1
Kahilingan sa Boot
2
Kulam
1
Uri ng mensahe. 1 - kahilingan mula sa kliyente patungo sa server, 2 - tugon mula sa server patungo sa kliyente

2
Uri ng hardware
1
Kulam
1
Uri ng address ng hardware, sa protocol na ito 1 - MAC

3
Haba ng mga address ng hardware
6
Kulam
1
Haba ng MAC address ng device

4
Hops
1
Kulam
1
Bilang ng mga intermediate na ruta

5
Transaksyon ID
23:cf:de:1d
Kulam
4
Natatanging identifier ng transaksyon. Binuo ng kliyente sa simula ng isang operasyon ng kahilingan

7
Lumipas ang pangalawa
0
Kulam
4
Oras sa mga segundo mula sa simula ng proseso ng pagkuha ng address

9
Mga flag ng boot
8000
Kulam
2
Ilang mga flag na maaaring itakda upang ipahiwatig ang mga parameter ng protocol. Sa kasong ito, nakatakda ang "broadcast".

11
IP address ng kliyente
0.0.0.0
Linya
4
IP address ng kliyente (kung mayroon man)

15
IP address ng iyong kliyente
172.16.134.61
Linya
4
IP address na inaalok ng server (kung magagamit)

19
Susunod na IP address ng server
0.0.0.0
Linya
4
IP address ng server (kung kilala)

23
IP address ng ahente ng relay
172.16.114.41
Linya
4
IP address ng relay agent (halimbawa, switch)

27
MAC address ng kliyente
14:d6:4d:a7:c9:55
Kulam
6
MAC address ng packet sender (client)

31
Padding ng address ng hardware ng kliyente
 
Kulam
10
Nakareserba ang upuan. Karaniwang puno ng mga zero

41
Pangalan ng host ng server
 
Linya
64
Pangalan ng DHCP server. Karaniwang hindi naipapasa

105
Pangalan ng boot file
 
Linya
128
Pangalan ng file sa server na ginagamit ng mga diskless na istasyon kapag nagbo-boot

235
Magic cookies
63: 82: 53: 63
Kulam
4
"Magic" na numero, ayon sa kung saan, kasama. maaari mong matukoy na ang packet na ito ay kabilang sa DHCP protocol

Mga pagpipilian sa DHCP. Maaaring pumunta sa anumang pagkakasunud-sunod

236
Numero ng opsyon
53
Disyembre
3
Opsyon 53, na tumutukoy sa uri ng DHCP packet 5 - DHCPACK

 
Haba ng opsyon
1
Disyembre
1

 
Halaga ng opsyon
5
Disyembre
1

 
Numero ng opsyon
1
Disyembre
1
Opsyon na mag-alok sa DHCP client ng network mask

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
255.255.224.0
Linya
4

 
Numero ng opsyon
3
Disyembre
1
Opsyon na mag-alok sa DHCP client ng default na gateway

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
172.16.12.1
Linya
4

 
Numero ng opsyon
6
Disyembre
1
Opsyon na mag-alok ng DHCP sa DNS client

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
8.8.8.8
Linya
4

 
Numero ng opsyon
51
Disyembre
1
Ang tagal ng buhay ng ibinigay na mga parameter ng network sa ilang segundo, pagkatapos nito ay dapat hilingin muli ng DHCP client ang mga ito

 
Haba ng opsyon
4
Disyembre
1

 
Halaga ng opsyon
86400
Disyembre
4

 
Numero ng opsyon
82
Disyembre
1
Opsyon 82, inuulit kung ano ang dumating sa DHCPDISCOVER

 
Haba ng opsyon
18
Disyembre
1

 
Halaga ng opsyon
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Disyembre
18

 
Katapusan ng pakete
255
Disyembre
1
Ang 255 ay sumisimbolo sa dulo ng pakete

Instalasyon

Ang pag-install ay talagang binubuo ng pag-install ng mga python module na kinakailangan para sa trabaho. Ipinapalagay na ang MySQL ay naka-install at naka-configure na.

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

Lumilikha kami ng MySQL database, i-upload ang pydhcp.sql dump dito, at i-configure ang configuration file.

Configuration

Ang lahat ng mga setting ng server ay nasa isang xml file. Reference file:

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 pagsusulit pagsusulit 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 piliin ang ip,mask,router,dns mula sa mga user kung saan upper(mac)=upper('{option_3_AgentRemoteId_hex}') at upper(port)=upper('{option_1_AgentCircuitId_port_hex}') piliin ang ip,mask,router,dns mula sa mga user kung saan ang upper(mac)=upper('{sw_mac}') at upper(port)=upper('{sw_port82}') piliin ang ip,mask,router,dns mula sa mga user kung saan upper(mac)=upper('{ClientMacAddress}') ipasok sa history (id,dt,mac,ip,comment) na mga halaga (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Ngayon sa higit pang detalye sa mga tag:

Ang seksyon ng dhcpserver ay naglalarawan ng mga pangunahing setting para sa pagsisimula ng server, katulad:

  • host - anong IP address ang pinapakinggan ng server sa port 67
  • broadcast - kung aling ip ang broadcast para sa DHCPOFFER at DHCPACK
  • DHCPServer - ano ang ip ng DHCP server
  • LeaseTime oras ng pag-upa ng ibinigay na IP address
  • ThreadLimit - kung gaano karaming mga thread ang tumatakbo nang sabay-sabay upang iproseso ang mga papasok na UDP packet sa port 67. Ito ay dapat na tumulong sa mga high-load na proyekto 😉
  • defaultMask,defaultRouter,defaultDNS - kung ano ang inaalok sa subscriber bilang default kung ang isang IP ay matatagpuan sa database, ngunit ang mga karagdagang parameter ay hindi tinukoy para dito

seksyon ng mysql:

host, username, password, basename - lahat ay nagsasalita para sa sarili nito. Ang isang tinatayang istraktura ng database ay nai-post sa GitHub

Seksyon ng query: ang mga kahilingan para sa pagtanggap ng OFFER/ACK ay inilarawan dito:

  • offer_count — ang bilang ng mga linya na may mga kahilingan na nagbabalik ng resulta tulad ng ip,mask,router,dns
  • offer_n — string ng query. Kung walang laman ang pagbabalik, pagkatapos ay isasagawa ang sumusunod na kahilingan sa alok
  • history_sql - isang query na nagsusulat, halimbawa, sa "kasaysayan ng pahintulot" para sa isang subscriber

Ang mga kahilingan ay maaaring magsama ng anumang mga variable mula sa seksyon ng mga opsyon o mga opsyon mula sa DHCP protocol.

Seksyon ng mga pagpipilian. Ito ay kung saan ito ay nagiging mas kawili-wili. Dito tayo makakagawa ng mga variable na magagamit natin mamaya sa seksyon ng query.

Halimbawa:

option_82_hex:sw_port1:20:22

, kinukuha ng command line na ito ang buong linya na dumating sa DHCP request option 82, sa hex na format, sa saklaw mula 20 hanggang 22 bytes kasama at inilalagay ito sa bagong variable na sw_port1 (lumipat sa port kung saan nanggaling ang kahilingan)

option_82_hex:sw_mac:26:40

, tukuyin ang variable na sw_mac, kunin ang hex mula sa hanay na 26:40

Makikita mo ang lahat ng posibleng opsyon na magagamit sa mga query sa pamamagitan ng pagsisimula sa server gamit ang -d switch. Makakakita tayo ng isang bagay tulad ng log na ito:

--isang DHCPINFORM packet ang dumating sa port 67, mula sa 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224'764ad00x7', 'BClientMacAddress': '91'5ad0x3 5d' , ' HType': 'Ethernet', 'HostName': b'x9xa8xe8xa43xa0.0.0.0xa5.0-x0025224fx764a', 'ReqListDNS': True, 'ReqListRomainName': True, 'ReqListPerfowmRouterDiscover': True, 'ReqListStatRouter': True, 'ReqListStatRouter': 'ReqListSubnetM ask ': True, 'ReqListVendorSpecInfo': 172.30.128.13, 'RequestedIpAddress': '00', 'Vendor': b'MSFT 00', 'chaddr': '172.30.114.25ad308', '6ad1', '82ad12', '12' , 'flags': b'x53x53', 'giaddr': '55', 'gpoz': 55, 'hlen': 60, 'hops': 60, 'htype': 'MAC', 'magic_cookie': b'cx61Sc ', 'op': 'DHCPINFORM', 'option61': 82, 'option82': 82, 'option12': 01, 'option06': 00, 'option04': 00, 'option01': 00, ' option_06_byte': b'x02x08x00x06x00x1x9x2x82x12010600040001000602080006001x589x2' b'x82x18x82eXx12exb01xad', 'option_06_hex': '00 tion_04_len': 00 01, 'option_00_str': "b'x06x02x08x00x06x00x1x9x2x768x0.0.0.0x001x589x2x1eXx06exb89xad'", 'result': False, 'secs,' 'siaddr': '8', 'sw_mac': '3e897eb8ad', 'sw_port0.0.0.0': 'XNUMX', 'xidbyte': b'

Alinsunod dito, maaari naming balutin ang anumang variable sa {} at ito ay gagamitin sa SQL query.

Itala natin para sa kasaysayan na natanggap ng kliyente ang IP address:

DHCP+Mysql server sa Python

DHCP+Mysql server sa Python

Pagsisimula ng server

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

— d console output mode DEBUG
- c <filename> configuration file

Pagdidiskusyon

At ngayon higit pang mga detalye sa pagpapatupad ng server sa Python. Ito ay isang sakit. Mabilis na natutunan ang sawa. Maraming mga sandali ang ginawa sa istilong "wow, kahit papaano nagawa ko itong gumana." Hindi na-optimize, at iniwan sa form na ito higit sa lahat dahil sa kaunting karanasan sa pagbuo ng Python. Tatalakayin ko ang mga pinaka-kagiliw-giliw na aspeto ng pagpapatupad ng server sa "code".

XML configuration file parser

Ang karaniwang Python module xml.dom ay ginagamit. Mukhang simple, ngunit sa panahon ng pagpapatupad ay may kapansin-pansing kakulangan ng malinaw na dokumentasyon at mga halimbawa sa network gamit ang modyul na ito.

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") para sa elem sa 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") para sa elem sa 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"_default =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig["dhcp_defaultDNS"]=elem.getNaElementsBy("defaultRouter") defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") para sa elem sa qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data para sa 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") para sa elem sa mga opsyon: node=elem.getElementsByTagName("option") para sa mga opsyon sa node : optionsMod.append(options.firstChild.data)

Multithreading

Kakatwa, ang multithreading sa Python ay ipinatupad nang napakalinaw at simple.

def PacketWork(data,addr): ... # pagpapatupad ng pag-parse ng papasok na packet at pagtugon dito ... habang True: data, addr = udp_socket.recvfrom(1024) # waiting for the UDP packet thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # as it came - inilunsad namin ang dating tinukoy na PacketWork function sa background na may mga parameter habang nag-thread.active_count() >gconfig["dhcp_ThreadLimit"]: oras. sleep(1) # kung ang numero Mayroong higit pang mga thread na tumatakbo na kaysa sa mga setting, maghihintay kami hanggang sa mas kaunti ang mga ito

Tumanggap/magpadala ng DHCP packet

Upang ma-intercept ang mga UDP packet na dumarating sa network card, kailangan mong "itaas" ang socket:

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

, kung saan ang mga flag ay:

  • AF_INET - nangangahulugan na ang format ng address ay magiging IP: port. Maaaring mayroon ding AF_UNIX - kung saan ang address ay ibinigay ng pangalan ng file.
  • SOCK_DGRAM - nangangahulugan na hindi kami tumatanggap ng "raw packet", ngunit isa na dumaan na sa firewall, at may bahagyang trimmed na packet. Yung. nakakatanggap lamang kami ng isang UDP packet na walang "pisikal" na bahagi ng UDP packet wrapper. Kung gagamitin mo ang bandila ng SOCK_RAW, kakailanganin mo ring i-parse ang "wrapper" na ito.

Ang pagpapadala ng packet ay maaaring parang broadcast:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #switch the socket to broadcast sending mode rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, at sa address na "kung saan nanggaling ang package":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # ilipat ang socket sa multi-listener mode rz=udp_socket.sendto(packetack, addr)

, kung saan ang SOL_SOCKET ay nangangahulugang ang "antas ng protocol" para sa mga pagpipilian sa pagtatakda,

, SO_BROADCAST na opsyon na ang helmet package ay "broadcast"

  , Ang opsyon ng SO_REUSEADDR ay inililipat ang socket sa mode na "maraming tagapakinig". Sa teorya, hindi kinakailangan sa kasong ito, ngunit sa isa sa mga server ng FreeBSD kung saan sinubukan ko, ang code ay hindi gumagana nang walang pagpipiliang ito.

Pag-parse ng DHCP packet

Dito ko talaga nagustuhan ang Python. Lumalabas na sa labas ng kahon ay nagbibigay-daan ito sa iyo na maging lubos na nababaluktot sa bytecode. Pagpapahintulot na ito ay napakadaling isalin sa mga decimal value, string at hex - i.e. ito ang talagang kailangan nating maunawaan ang istraktura ng pakete. Kaya, halimbawa, maaari kang makakuha ng isang hanay ng mga byte sa HEX at mga byte lang:

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

, i-pack ang mga byte sa isang istraktura:

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

Kumuha ng IP mula sa istraktura:

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

At kabaliktaran:

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

Yun lang muna 😉

Pinagmulan: www.habr.com

Magdagdag ng komento