DHCP+Mysql-palvelin Pythonissa

DHCP+Mysql-palvelin Pythonissa

Tämän projektin tarkoitus oli:

  • Opi DHCP:stä IPv4-verkossa
  • Pythonin oppiminen (hieman enemmän kuin tyhjästä 😉)
  • palvelimen vaihto DB2DHCP (haarukkani), alkuperäinen täällä, jonka kokoaminen uutta käyttöjärjestelmää varten on yhä vaikeampaa. Ja en pidä siitä, että se on binääri, jota ei voi "muuttaa juuri nyt"
  • toimivan DHCP-palvelimen hankkiminen, jolla on mahdollisuus valita tilaajan IP-osoite käyttämällä tilaajan mac- tai kytkimen mac+portti-yhdistelmää (Vaihtoehto 82)
  • toisen pyörän kirjoittaminen (Oh! tämä on suosikkiharrastukseni)
  • saada kommentteja klubikätyydestäsi Habrahabrissa (tai vielä parempaa, kutsu) 😉

Tulos: toimii 😉 Testattu FreeBSD:llä ja Ubuntu OS:llä. Teoriassa koodia voidaan pyytää toimimaan missä tahansa käyttöjärjestelmässä, koska Koodissa ei näytä olevan erityisiä sidoksia.
Huolellisesti! Paljon on vielä tulossa.

Linkki amatöörien arkistoon "kosketa elossa".

Asennus-, konfigurointi- ja käyttöprosessi "laitteiston tutkimisen" tuloksena on paljon alhaisempi, ja sitten vähän teoriaa DHCP-protokollasta. Itselleni. Ja historialle 😉

Vähän teoriaa

Mikä on DHCP

Tämä on verkkoprotokolla, jonka avulla laite voi selvittää IP-osoitteensa (ja muut parametrit, kuten yhdyskäytävä, DNS jne.) DHCP-palvelimelta. Paketit vaihdetaan UDP-protokollaa käyttäen. Laitteen yleinen toimintaperiaate verkkoparametreja pyydettäessä on seuraava:

  1. Laite (asiakas) lähettää UDP-lähetyspyynnön (DHCPDISCOVER) koko verkkoon ja pyytää "no, anna joku IP-osoite". Lisäksi yleensä (mutta ei aina) pyyntö tulee portista 68 (lähde) ja kohde on portti 67 (kohde). Jotkut laitteet lähettävät paketteja myös portista 67. Asiakaslaitteen MAC-osoite sisältyy DHCPDISCOVER-pakettiin.
  2. Kaikki verkossa sijaitsevat DHCP-palvelimet (ja niitä voi olla useita) muodostavat DHCPOFFER-tarjouksen verkkoasetuksineen DHCPDISCOVERin lähettäneelle laitteelle ja lähettävät sen myös verkon yli. Tunnistus siitä, kenelle tämä paketti on tarkoitettu, perustuu aiemmin DHCPDISCOVER-pyynnössä annettuun asiakkaan MAC-osoitteeseen.
  3. Asiakas hyväksyy paketit verkkoasetusehdotuksineen, valitsee houkuttelevimman (kriteerit voivat olla erilaiset, esimerkiksi paketin toimitusaika, välireittien määrä) ja tekee "virallisen pyynnön" DHCPREQUEST verkkoasetuksista. DHCP-palvelimelta, josta se pitää. Tässä tapauksessa paketti menee tietylle DHCP-palvelimelle.
  4. DHCPREQUEST-pyynnön vastaanottanut palvelin lähettää DHCPACK-muotoisen paketin, jossa se listaa jälleen tälle asiakkaalle tarkoitetut verkkoasetukset.

DHCP+Mysql-palvelin Pythonissa

Lisäksi on olemassa asiakkaalta tulevia DHCPINFORM-paketteja, joiden tarkoituksena on ilmoittaa DHCP-palvelimelle, että "asiakas on elossa" ja käyttää annettuja verkkoasetuksia. Tämän palvelimen toteutuksessa nämä paketit ohitetaan.

Paketin muoto

Yleensä Ethernet-pakettikehys näyttää suunnilleen tältä:

DHCP+Mysql-palvelin Pythonissa

Tässä tapauksessa otamme huomioon vain tiedot suoraan UDP-paketin sisällöstä ilman OSI-kerroksen protokollaotsikoita, nimittäin DHCP-rakennetta:

DHCPDISCOVER

Joten IP-osoitteen hankintaprosessi laitteelle alkaa siitä, että DHCP-asiakas lähettää yleislähetyspyynnön portista 68 kohtaan 255.255.255.255:67. Tässä paketissa asiakas sisältää MAC-osoitteensa sekä sen, mitä se tarkalleen haluaa vastaanottaa DHCP-palvelimelta. Pakkauksen rakenne on kuvattu alla olevassa taulukossa.

DHCPDISCOVER-pakettirakennetaulukko

Sijainti pakkauksessa
Arvon nimi
Esimerkki
ajatus
tavu
Selvennys

1
Käynnistyspyyntö
1
Hex
1
Viestin tyyppi. 1 - pyyntö asiakkaalta palvelimelle, 2 - vastaus palvelimelta asiakkaalle

2
Laitteiston tyyppi
1
Hex
1
Laitteiston osoitteen tyyppi tässä protokollassa 1 - MAC

3
Laitteiston osoitteiden pituus
6
Hex
1
Laitteen MAC-osoitteen pituus

4
Humala
1
Hex
1
Välireittien lukumäärä

5
Transaktiotunnus
23:cf:de:1d
Hex
4
Ainutlaatuinen tapahtumatunnus. Asiakas luo pyyntötoiminnon alussa

7
Toinen kului
0
Hex
4
Aika sekunneissa osoitteenhakuprosessin alusta

9
Saappaiden liput
0
Hex
2
Tietyt liput, jotka voidaan asettaa osoittamaan protokollaparametreja

11
Asiakkaan IP-osoite
0.0.0.0
Linja
4
Asiakkaan IP-osoite (jos sellainen on)

15
Asiakkaasi IP-osoite
0.0.0.0
Linja
4
Palvelimen tarjoama IP-osoite (jos saatavilla)

19
Seuraavan palvelimen IP-osoite
0.0.0.0
Linja
4
Palvelimen IP-osoite (jos tiedossa)

23
Välitysagentin IP-osoite
172.16.114.41
Linja
4
Välitysagentin (esimerkiksi kytkimen) IP-osoite

27
Asiakkaan MAC-osoite
14:d6:4d:a7:c9:55
Hex
6
Paketin lähettäjän (asiakkaan) MAC-osoite

31
Asiakaslaitteiston osoitteen täyttö
 
Hex
10
Varattu paikka. Yleensä täytetään nollia

41
Palvelimen isäntänimi
 
Linja
64
DHCP-palvelimen nimi. Yleensä ei lähetetä

105
Käynnistystiedoston nimi
 
Linja
128
Tiedostonimi palvelimella, jota levyttömät asemat käyttävät käynnistettäessä

235
Maaginen eväste
63: 82: 53: 63
Hex
4
”Maginen” numero, jonka mukaan mm. voit määrittää, että tämä paketti kuuluu DHCP-protokollaan

DHCP-asetukset. Voi mennä missä järjestyksessä tahansa

236
Vaihtoehto numero
53
joulukuu
1
Vaihtoehto 53, joka määrittää DHCP-pakettityypin

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

 
Vaihtoehto pituus
1
joulukuu
1

 
Vaihtoehdon arvo
1
joulukuu
1

 
Vaihtoehto numero
50
joulukuu
1
Minkä IP-osoitteen asiakas haluaa saada?

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
172.16.134.61
Linja
4

 
Vaihtoehto numero
55
 
1
Asiakkaan pyytämät verkkoparametrit. Koostumus voi vaihdella

01 — Verkkomaski
03 - Yhdyskäytävä
06 - DNS
oc — Isäntänimi
0f - verkkotunnuksen nimi
1c - lähetyspyynnön osoite (lähetys)
42 - TFTP-palvelimen nimi
79 - Luokkaton staattinen reitti

 
Vaihtoehto pituus
8
 
1

 
Vaihtoehdon arvo
01:03:06:0c:0f:1c:42:79
 
8

 
Vaihtoehto numero
82
joulukuu
 
Vaihtoehto 82, joka lähettää toistinlaitteen MAC-osoitteen ja joitain lisäarvoja.

Useimmiten tämä on kytkimen portti, jossa loppu DHCP-asiakas toimii.Tämä vaihtoehto sisältää lisäparametreja.Ensimmäinen tavu on "alioption" numero, toinen sen pituus, sitten sen arvo.

Tässä tapauksessa vaihtoehdossa 82 alivaihtoehdot on sisäkkäin:
Agent Circuit ID = 00:04:00:01:00:04, jossa kaksi viimeistä tavua ovat DHCP-asiakasportti, josta pyyntö tuli

Agent Remote ID = 00:06:c8:be:19:93:11:48 - DHCP-toistinlaitteen MAC-osoite

 
Vaihtoehto pituus
18
joulukuu
 

 
Vaihtoehdon arvo
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Paketin loppu
255
joulukuu
1
255 symboloi paketin loppua

DHCPOFFER

Heti kun palvelin vastaanottaa DHCPDISCOVER-paketin ja jos se näkee voivansa tarjota asiakkaalle jotain pyydetystä paketista, se luo siihen vastauksen - DHCPDISCOVER. Vastaus lähetetään porttiin "mistä se tuli", yleislähetyksenä, koska Tällä hetkellä asiakkaalla ei vielä ole IP-osoitetta, joten se voi hyväksyä paketin vain, jos se lähetetään yleislähetyksenä. Asiakas tunnistaa tämän paketin hänelle paketin sisällä olevasta MAC-osoitteestaan ​​sekä tapahtumanumerosta, jonka hän luo ensimmäisen paketin luomisen yhteydessä.

DHCPOFFER-pakettirakennetaulukko

Sijainti pakkauksessa
Arvon nimi (yleinen)
Esimerkki
ajatus
tavu
Selvennys

1
Käynnistyspyyntö
1
Hex
1
Viestin tyyppi. 1 - pyyntö asiakkaalta palvelimelle, 2 - vastaus palvelimelta asiakkaalle

2
Laitteiston tyyppi
1
Hex
1
Laitteiston osoitteen tyyppi tässä protokollassa 1 - MAC

3
Laitteiston osoitteiden pituus
6
Hex
1
Laitteen MAC-osoitteen pituus

4
Humala
1
Hex
1
Välireittien lukumäärä

5
Transaktiotunnus
23:cf:de:1d
Hex
4
Ainutlaatuinen tapahtumatunnus. Asiakas luo pyyntötoiminnon alussa

7
Toinen kului
0
Hex
4
Aika sekunneissa osoitteenhakuprosessin alusta

9
Saappaiden liput
0
Hex
2
Tietyt liput, jotka voidaan asettaa osoittamaan protokollaparametreja. Tässä tapauksessa 0 tarkoittaa Unicast-pyyntötyyppiä

11
Asiakkaan IP-osoite
0.0.0.0
Linja
4
Asiakkaan IP-osoite (jos sellainen on)

15
Asiakkaasi IP-osoite
172.16.134.61
Linja
4
Palvelimen tarjoama IP-osoite (jos saatavilla)

19
Seuraavan palvelimen IP-osoite
0.0.0.0
Linja
4
Palvelimen IP-osoite (jos tiedossa)

23
Välitysagentin IP-osoite
172.16.114.41
Linja
4
Välitysagentin (esimerkiksi kytkimen) IP-osoite

27
Asiakkaan MAC-osoite
14:d6:4d:a7:c9:55
Hex
6
Paketin lähettäjän (asiakkaan) MAC-osoite

31
Asiakaslaitteiston osoitteen täyttö
 
Hex
10
Varattu paikka. Yleensä täytetään nollia

41
Palvelimen isäntänimi
 
Linja
64
DHCP-palvelimen nimi. Yleensä ei lähetetä

105
Käynnistystiedoston nimi
 
Linja
128
Tiedostonimi palvelimella, jota levyttömät asemat käyttävät käynnistettäessä

235
Maaginen eväste
63: 82: 53: 63
Hex
4
”Maginen” numero, jonka mukaan mm. voit määrittää, että tämä paketti kuuluu DHCP-protokollaan

DHCP-asetukset. Voi mennä missä järjestyksessä tahansa

236
Vaihtoehto numero
53
joulukuu
1
Vaihtoehto 53, joka määrittää DHCP 2 -pakettityypin - DHCPOFFER

 
Vaihtoehto pituus
1
joulukuu
1

 
Vaihtoehdon arvo
2
joulukuu
1

 
Vaihtoehto numero
1
joulukuu
1
Mahdollisuus tarjota DHCP-asiakkaalle verkkomaski

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
255.255.224.0
Linja
4

 
Vaihtoehto numero
3
joulukuu
1
Mahdollisuus tarjota DHCP-asiakkaalle oletusyhdyskäytävä

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
172.16.12.1
Linja
4

 
Vaihtoehto numero
6
joulukuu
1
Mahdollisuus tarjota DHCP DNS-asiakkaalle

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
8.8.8.8
Linja
4

 
Vaihtoehto numero
51
joulukuu
1
Annettujen verkkoparametrien käyttöikä sekunneissa, jonka jälkeen DHCP-asiakkaan on pyydettävä niitä uudelleen

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
86400
joulukuu
4

 
Vaihtoehto numero
82
joulukuu
1
Vaihtoehto 82, toistaa mitä tuli DHCPDISCOVERissa

 
Vaihtoehto pituus
18
joulukuu
1

 
Vaihtoehdon arvo
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
joulukuu
18

 
Paketin loppu
255
joulukuu
1
255 symboloi paketin loppua

DHCPREQUEST

Kun asiakas vastaanottaa DHCPOFFERin, hän muodostaa paketin, joka pyytää verkkoparametreja, ei kaikille verkon DHCP-palvelimille, vaan vain yhdelle tietylle, jonka DHCPOFFER-tarjouksesta hän "tykkäsi" eniten. "Tykkää"-kriteerit voivat olla erilaisia ​​ja riippuvat asiakkaan DHCP-toteutuksesta. Pyynnön vastaanottaja määritetään käyttämällä DHCP-palvelimen MAC-osoitetta. Asiakas voi myös lähettää DHCPREQUEST-paketin generoimatta ensin DHCPDISCOVERia, jos palvelimen IP-osoite on jo hankittu aiemmin.

DHCPREQUEST-pakettirakennetaulukko

Sijainti pakkauksessa
Arvon nimi (yleinen)
Esimerkki
ajatus
tavu
Selvennys

1
Käynnistyspyyntö
1
Hex
1
Viestin tyyppi. 1 - pyyntö asiakkaalta palvelimelle, 2 - vastaus palvelimelta asiakkaalle

2
Laitteiston tyyppi
1
Hex
1
Laitteiston osoitteen tyyppi tässä protokollassa 1 - MAC

3
Laitteiston osoitteiden pituus
6
Hex
1
Laitteen MAC-osoitteen pituus

4
Humala
1
Hex
1
Välireittien lukumäärä

5
Transaktiotunnus
23:cf:de:1d
Hex
4
Ainutlaatuinen tapahtumatunnus. Asiakas luo pyyntötoiminnon alussa

7
Toinen kului
0
Hex
4
Aika sekunneissa osoitteenhakuprosessin alusta

9
Saappaiden liput
8000
Hex
2
Tietyt liput, jotka voidaan asettaa osoittamaan protokollaparametreja. Tässä tapauksessa "lähetys" on asetettu

11
Asiakkaan IP-osoite
0.0.0.0
Linja
4
Asiakkaan IP-osoite (jos sellainen on)

15
Asiakkaasi IP-osoite
172.16.134.61
Linja
4
Palvelimen tarjoama IP-osoite (jos saatavilla)

19
Seuraavan palvelimen IP-osoite
0.0.0.0
Linja
4
Palvelimen IP-osoite (jos tiedossa)

23
Välitysagentin IP-osoite
172.16.114.41
Linja
4
Välitysagentin (esimerkiksi kytkimen) IP-osoite

27
Asiakkaan MAC-osoite
14:d6:4d:a7:c9:55
Hex
6
Paketin lähettäjän (asiakkaan) MAC-osoite

31
Asiakaslaitteiston osoitteen täyttö
 
Hex
10
Varattu paikka. Yleensä täytetään nollia

41
Palvelimen isäntänimi
 
Linja
64
DHCP-palvelimen nimi. Yleensä ei lähetetä

105
Käynnistystiedoston nimi
 
Linja
128
Tiedostonimi palvelimella, jota levyttömät asemat käyttävät käynnistettäessä

235
Maaginen eväste
63: 82: 53: 63
Hex
4
”Maginen” numero, jonka mukaan mm. voit määrittää, että tämä paketti kuuluu DHCP-protokollaan

DHCP-asetukset. Voi mennä missä järjestyksessä tahansa

236
Vaihtoehto numero
53
joulukuu
3
Vaihtoehto 53, joka määrittää DHCP-pakettityypin 3 - DHCPREQUEST

 
Vaihtoehto pituus
1
joulukuu
1

 
Vaihtoehdon arvo
3
joulukuu
1

 
Vaihtoehto numero
61
joulukuu
1
Asiakastunnus: 01 (Ehernetille) + asiakkaan MAC-osoite

 
Vaihtoehto pituus
7
joulukuu
1

 
Vaihtoehdon arvo
01:2c:ab:25:ff:72:a6
Hex
7

 
Vaihtoehto numero
60
joulukuu
 
"Toimittajan luokan tunniste". Minun tapauksessani se raportoi DHCP-asiakasversion. Ehkä muut laitteet palauttavat jotain erilaista. Esimerkiksi Windows raportoi MSFT 5.0:n

 
Vaihtoehto pituus
11
joulukuu
 

 
Vaihtoehdon arvo
udhcp 0.9.8
Linja
 

 
Vaihtoehto numero
55
 
1
Asiakkaan pyytämät verkkoparametrit. Koostumus voi vaihdella

01 — Verkkomaski
03 - Yhdyskäytävä
06 - DNS
oc — Isäntänimi
0f - verkkotunnuksen nimi
1c - lähetyspyynnön osoite (lähetys)
42 - TFTP-palvelimen nimi
79 - Luokkaton staattinen reitti

 
Vaihtoehto pituus
8
 
1

 
Vaihtoehdon arvo
01:03:06:0c:0f:1c:42:79
 
8

 
Vaihtoehto numero
82
joulukuu
1
Vaihtoehto 82, toistaa mitä tuli DHCPDISCOVERissa

 
Vaihtoehto pituus
18
joulukuu
1

 
Vaihtoehdon arvo
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
joulukuu
18

 
Paketin loppu
255
joulukuu
1
255 symboloi paketin loppua

DHCPACK

Vahvistukseksi "kyllä, se on oikein, tämä on IP-osoitteesi, enkä anna sitä kenellekään muulle" DHCP-palvelimelta, DHCPACK-muodossa oleva paketti palvelimelta asiakkaalle palvelee. Se lähetetään lähetyksenä kuten muutkin paketit. Vaikka alla olevassa Pythonissa toteutetun DHCP-palvelimen koodissa kopioin varmuuden vuoksi minkä tahansa yleislähetyspyynnön lähettämällä paketin tiettyyn asiakkaan IP-osoitteeseen, jos se on jo tiedossa. Lisäksi DHCP-palvelin ei välitä ollenkaan, onko DHCPACK-paketti saavuttanut asiakkaan. Jos asiakas ei vastaanota DHCPACK:ia, hetken kuluttua se yksinkertaisesti toistaa DHCPREQUESTin

DHCPACK-pakettirakennetaulukko

Sijainti pakkauksessa
Arvon nimi (yleinen)
Esimerkki
ajatus
tavu
Selvennys

1
Käynnistyspyyntö
2
Hex
1
Viestin tyyppi. 1 - pyyntö asiakkaalta palvelimelle, 2 - vastaus palvelimelta asiakkaalle

2
Laitteiston tyyppi
1
Hex
1
Laitteiston osoitteen tyyppi tässä protokollassa 1 - MAC

3
Laitteiston osoitteiden pituus
6
Hex
1
Laitteen MAC-osoitteen pituus

4
Humala
1
Hex
1
Välireittien lukumäärä

5
Transaktiotunnus
23:cf:de:1d
Hex
4
Ainutlaatuinen tapahtumatunnus. Asiakas luo pyyntötoiminnon alussa

7
Toinen kului
0
Hex
4
Aika sekunneissa osoitteenhakuprosessin alusta

9
Saappaiden liput
8000
Hex
2
Tietyt liput, jotka voidaan asettaa osoittamaan protokollaparametreja. Tässä tapauksessa "lähetys" on asetettu

11
Asiakkaan IP-osoite
0.0.0.0
Linja
4
Asiakkaan IP-osoite (jos sellainen on)

15
Asiakkaasi IP-osoite
172.16.134.61
Linja
4
Palvelimen tarjoama IP-osoite (jos saatavilla)

19
Seuraavan palvelimen IP-osoite
0.0.0.0
Linja
4
Palvelimen IP-osoite (jos tiedossa)

23
Välitysagentin IP-osoite
172.16.114.41
Linja
4
Välitysagentin (esimerkiksi kytkimen) IP-osoite

27
Asiakkaan MAC-osoite
14:d6:4d:a7:c9:55
Hex
6
Paketin lähettäjän (asiakkaan) MAC-osoite

31
Asiakaslaitteiston osoitteen täyttö
 
Hex
10
Varattu paikka. Yleensä täytetään nollia

41
Palvelimen isäntänimi
 
Linja
64
DHCP-palvelimen nimi. Yleensä ei lähetetä

105
Käynnistystiedoston nimi
 
Linja
128
Tiedostonimi palvelimella, jota levyttömät asemat käyttävät käynnistettäessä

235
Maaginen eväste
63: 82: 53: 63
Hex
4
”Maginen” numero, jonka mukaan mm. voit määrittää, että tämä paketti kuuluu DHCP-protokollaan

DHCP-asetukset. Voi mennä missä järjestyksessä tahansa

236
Vaihtoehto numero
53
joulukuu
3
Vaihtoehto 53, joka määrittää DHCP-pakettityypin 5 - DHCPACK

 
Vaihtoehto pituus
1
joulukuu
1

 
Vaihtoehdon arvo
5
joulukuu
1

 
Vaihtoehto numero
1
joulukuu
1
Mahdollisuus tarjota DHCP-asiakkaalle verkkomaski

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
255.255.224.0
Linja
4

 
Vaihtoehto numero
3
joulukuu
1
Mahdollisuus tarjota DHCP-asiakkaalle oletusyhdyskäytävä

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
172.16.12.1
Linja
4

 
Vaihtoehto numero
6
joulukuu
1
Mahdollisuus tarjota DHCP DNS-asiakkaalle

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
8.8.8.8
Linja
4

 
Vaihtoehto numero
51
joulukuu
1
Annettujen verkkoparametrien käyttöikä sekunneissa, jonka jälkeen DHCP-asiakkaan on pyydettävä niitä uudelleen

 
Vaihtoehto pituus
4
joulukuu
1

 
Vaihtoehdon arvo
86400
joulukuu
4

 
Vaihtoehto numero
82
joulukuu
1
Vaihtoehto 82, toistaa mitä tuli DHCPDISCOVERissa

 
Vaihtoehto pituus
18
joulukuu
1

 
Vaihtoehdon arvo
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
joulukuu
18

 
Paketin loppu
255
joulukuu
1
255 symboloi paketin loppua

Asennus

Asennus koostuu itse asiassa työhön tarvittavien python-moduulien asentamisesta. Oletetaan, että MySQL on jo asennettu ja määritetty.

FreeBSD

pkg asenna python3 python3 -m securepip pip3 asenna mysql-liitin

Ubuntu

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

Luomme MySQL-tietokannan, lataamme siihen pydhcp.sql-vedostiedoston ja määritämme asetustiedoston.

kokoonpano

Kaikki palvelinasetukset ovat xml-tiedostossa. Viitetiedosto:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 paikallinen isäntä testata testata 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 valitse ip,mask,router,dns käyttäjiltä, ​​joissa ylempi(mac)=upper('{option_3_AgentRemoteId_hex}') ja ylempi(port)=upper('{option_1_AgentCircuitId_port_hex}') valitse ip,mask,router,dns käyttäjiltä, ​​joissa ylempi(mac)=upper('{sw_mac}') ja ylempi(port)=upper('{sw_port82}') valitse ip,mask,router,dns käyttäjiltä, ​​joissa ylempi(mac)=upper('{ClientMacAddress}') lisää historiaan (id,dt,mac,ip,kommentti) arvot (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Nyt tarkemmin tunnisteista:

Dhcpserver-osiossa kuvataan perusasetukset palvelimen käynnistämiseksi, nimittäin:

  • isäntä - mitä IP-osoitetta palvelin kuuntelee portissa 67
  • broadcast - mikä IP on DHCPOFFER- ja DHCPACK-lähetys
  • DHCPServer - mikä on DHCP-palvelimen IP-osoite
  • Annetun IP-osoitteen LeaseTime-vuokra-aika
  • ThreadLimit - kuinka monta säiettä on käynnissä samanaikaisesti käsittelemään saapuvia UDP-paketteja portissa 67. Sen oletetaan auttavan korkean kuormituksen projekteissa 😉
  • defaultMask,defaultRouter,defaultDNS - mitä tilaajalle tarjotaan oletuksena, jos tietokannasta löytyy IP, mutta sille ei ole määritetty lisäparametreja

mysql-osio:

isäntä, käyttäjätunnus, salasana, perusnimi - kaikki puhuu puolestaan. Likimääräinen tietokantarakenne on julkaistu GitHub

Kyselyosio: TARJOUS/ACK-pyynnöt on kuvattu tässä:

  • offer_count — rivien määrä pyyntöillä, jotka palauttavat tuloksen, kuten ip,mask,router,dns
  • offer_n — kyselymerkkijono. Jos palautus on tyhjä, suorita seuraava tarjouspyyntö
  • history_sql - kysely, joka kirjoittaa esimerkiksi tilaajan "valtuutushistoriaan"

Pyynnöt voivat sisältää mitä tahansa muuttujia asetukset-osiosta tai vaihtoehtoja DHCP-protokollasta.

Asetukset-osio. Tästä se tulee mielenkiintoisemmaksi. Täällä voimme luoda muuttujia, joita voimme käyttää myöhemmin kyselyosassa.

Esimerkiksi:

option_82_hex:sw_port1:20:22

, tämä komentorivi ottaa koko rivin, joka tuli DHCP-pyyntövaihtoehdossa 82, heksadesimaalimuodossa, välillä 20–22 tavua ja sijoittaa sen uuteen muuttujaan sw_port1 (vaihtoportti, josta pyyntö tuli)

option_82_hex:sw_mac:26:40

, määritä sw_mac-muuttuja ottamalla heksadesimaaliarvo alueelta 26:40

Näet kaikki mahdolliset vaihtoehdot, joita voidaan käyttää kyselyissä käynnistämällä palvelimen -d-kytkimellä. Näemme jotain tämän kaltaista lokia:

--DHCPINFORM-paketti saapui porttiin 67, osoitteesta 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress'B,0025224'764CAddress'00t'y'7'91 ': b'x5 0%"Jxd3d" , ' HType': 'Ethernet', 'HostName': b'x5xa9xe8xa8xa43xa0.0.0.0-x5.0fx0025224a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouter, True, 'ReqListPerfowmRouter:'ReqList,Disco''Req ReqListStaticRoute': Totta, 'ReqListSubnetM ask ': True, 'ReqListVendorSpecInfo': 764, 'RequestedIpAddress': '172.30.128.13', 'Vendor': b'MSFT 00', 'chaddr': '00ad172.30.114.25'308'.6'ciad'1'.82. , 'liput ': b'x12x12', 'giaddr': '53', 'gpoz': 53, 'hlen': 55, 'hops': 55, 'htype': 'MAC', 'magic_cookie': b'cx60Sc ', 'op': 'DHCPINFORM', 'optio60': 61, 'optio61': 82, 'optio82': 82, 'optio12': 01, 'optio06': 00, 'optio04': 00 option_01_byte': b'x00x06x02x08x00x06x00x1x9x2x82x12010600040001000602080006001' b'x589x2x82eXx18exb82xad', 'optio_12_hex': '01 'option_06_len': 00 04, 'option_00_str': "b'x01x00x06x02x08x00x06x00x1x9x2x768x0.0.0.0x001x589eXx2exb1xad'", 'tulos': False,', '06se 'siaddr': '89', 'sw_mac': '8e3eb897ad', 'sw_port8': '0.0.0.0', 'xidbyte': b'

Vastaavasti voimme kääriä minkä tahansa muuttujan {}:ään ja sitä käytetään SQL-kyselyssä.

Tallennetaan historiaan, että asiakas sai IP-osoitteen:

DHCP+Mysql-palvelin Pythonissa

DHCP+Mysql-palvelin Pythonissa

Palvelimen käynnistys

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

— d konsolin lähtötila DEBUG
- c <tiedostonimi> määritystiedosto

jälkipuinti

Ja nyt lisätietoja palvelimen toteuttamisesta Pythonissa. Se on tuskaa. Python opittiin lennossa. Monet hetket on tehty tyyliin "vau, jotenkin sain sen toimimaan". Ei optimoitu ollenkaan ja jätettiin tähän muotoon lähinnä vähäisen Python-kehityskokemuksen vuoksi. Pysähdyn palvelimen toteutuksen mielenkiintoisimpiin puoliin "koodissa".

XML-määritystiedoston jäsentäjä

Käytössä on vakio Python-moduuli xml.dom. Se näyttää yksinkertaiselta, mutta toteutuksen aikana oli havaittavissa selkeän dokumentaation ja esimerkkien puute tätä moduulia käyttävästä verkossa.

    puu = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") elementille mconfig:ssa: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firtast gconfig["mysql_username"]=elem.getElementsByTagName("käyttäjänimi")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("salasana")[0].ensimmäinen"gconqlda["ensimmäinen lapsi] =elem.getElementsByTagName("perusnimi")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") dconfig-elementille: gconfig["broadcast"]=elem.getElementsByTagcast.") firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("isäntä")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName("LeaseTime")[0]. dhcp_threadlimit "] = int (elem.getElementsbytagname (" Threadlimit ") [0] .firstchild.data) gconfig [" dhcp_server "] = elem.getElementsbytagname (" dhcpserver "[0] .firstchild.data gconfig [") [0] .firstchild.data gconfig [") =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfigelem_s " defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("kysely") elementille qconfig: gconfig["offer_count"]=elem.getElementsByTagName("tarjousten_määrä")[0].firstChild in. range(int(gconfig["tarjousmäärä"])): gconfig["tarjous_"+str(num+1)]=elem.getElementsByTagName("tarjous"+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("optio") optioille in node : optionsMod.append(optiot.firstChild.data)

Monisäikeinen

Kummallista kyllä, monisäikeisyys Pythonissa on toteutettu erittäin selkeästi ja yksinkertaisesti.

def PacketWork(data,addr): ... # saapuvan paketin jäsentämisen ja siihen vastaamisen toteutus ... while True: data, addr = udp_socket.recvfrom(1024) # odottaa UDP-pakettia säie = threading.Thread( target=PacketWork , args=(data,addr,)).start() # sellaisena kuin se tuli - käynnistämme aiemmin määritellyn PacketWork-funktion taustalla parametreilla, kun threading.active_count() >gconfig["dhcp_ThreadLimit"]: aika. sleep(1) # jos numero On enemmän lankoja käynnissä kuin asetuksissa, odotamme kunnes niitä on vähemmän

Vastaanota/lähetä DHCP-paketti

Jotta voit siepata verkkokortin kautta tulevat UDP-paketit, sinun on "nostettava" liitäntä:

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

, missä liput ovat:

  • AF_INET - tarkoittaa, että osoitemuoto on IP: portti. Saattaa olla myös AF_UNIX - jossa osoite annetaan tiedoston nimellä.
  • SOCK_DGRAM - tarkoittaa, että emme hyväksy "raakapakettia", vaan sellaisen, joka on jo mennyt palomuurin läpi ja jossa on osittain leikattu paketti. Nuo. vastaanotamme vain UDP-paketin ilman UDP-pakettien kääreen "fyysistä" komponenttia. Jos käytät SOCK_RAW-lippua, sinun on myös jäsennettävä tämä "kääre".

Paketin lähettäminen voi olla kuin lähetys:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #vaihda socket lähetystilaan rz=udp_socket.sendto(packettack, (gconfig["broadcast"],68))

ja osoitteeseen "josta paketti tuli":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # vaihda socket usean kuuntelijan tilaan rz=udp_socket.sendto(packettack, addr)

, jossa SOL_SOCKET tarkoittaa asetusvaihtoehtojen "protokollatasoa",

, SO_BROADCAST vaihtoehto, että kypäräpaketti on "lähetys"

  ,SO_REUSEADDR vaihtoehto vaihtaa socketin "monet kuuntelijat" -tilaan. Teoriassa se on tarpeeton tässä tapauksessa, mutta yhdessä FreeBSD-palvelimista, jolla testasin, koodi ei toiminut ilman tätä vaihtoehtoa.

DHCP-paketin jäsentäminen

Täällä pidin todella Pythonista. Osoittautuu, että laatikosta otettuna voit olla melko joustava tavukoodin kanssa. Mahdollistaa sen erittäin helposti kääntämisen desimaaliarvoiksi, merkkijonoiksi ja heksadesimaaliarvoiksi - ts. tämä on se, mitä meidän itse asiassa tarvitsemme ymmärtääksemme paketin rakenteen. Joten esimerkiksi voit saada useita tavuja HEX-muodossa ja vain tavuja:

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

, pakkaa tavut rakenteeseen:

res["liput"]=paketti('BB',data[10],data[11])

Hanki IP rakenteesta:

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

Ja päinvastoin:

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

Siinä kaikki toistaiseksi 😉

Lähde: will.com

Lisää kommentti