Servidor DHCP+Mysql en Python

Servidor DHCP+Mysql en Python

L'objectiu d'aquest projecte era:

  • Aprendre sobre DHCP en una xarxa IPv4
  • Aprenent Python (una mica més que des de zero 😉)
  • substitució del servidor DB2DHCP (la meva forquilla), original aquí, que és cada cop més difícil de muntar per al nou sistema operatiu. I no m'agrada que sigui un binari que no hi ha manera de "canviar ara mateix"
  • obtenir un servidor DHCP que funcioni amb la possibilitat de seleccionar l'adreça IP d'un subscriptor mitjançant la combinació de mac de l'abonat o canvi de mac+port (opció 82)
  • escriure una altra bicicleta (Oh! aquesta és la meva activitat preferida)
  • rebent comentaris sobre la teva participació en el club a Habrahabr (o millor encara, una invitació) 😉

Resultat: funciona 😉 Provat a FreeBSD i Ubuntu OS. Teòricament, es pot demanar que el codi funcioni amb qualsevol sistema operatiu, perquè Sembla que no hi ha enllaços específics al codi.
Amb compte! Hi ha molt més per venir.

Enllaç al repositori per a aficionats "tocar viu".

El procés d'instal·lació, configuració i ús del resultat d'"estudiar el maquinari" és molt inferior, i després una mica de teoria sobre el protocol DHCP. Per mi mateix. I per la història 😉

Una mica de teoria

Què és DHCP

Aquest és un protocol de xarxa que permet a un dispositiu esbrinar la seva adreça IP (i altres paràmetres com la passarel·la, el DNS, etc.) des d'un servidor DHCP. Els paquets s'intercanvien mitjançant el protocol UDP. El principi general de funcionament del dispositiu en sol·licitar paràmetres de xarxa és el següent:

  1. El dispositiu (client) envia una sol·licitud de difusió UDP (DHCPDISCOVER) a tota la xarxa amb la sol·licitud "bé, algú em doni una adreça IP". A més, normalment (però no sempre) la sol·licitud es produeix des del port 68 (font), i la destinació és el port 67 (destinació). Alguns dispositius també envien paquets des del port 67. L'adreça MAC del dispositiu client s'inclou dins del paquet DHCPDISCOVER.
  2. Tots els servidors DHCP situats a la xarxa (i pot ser que n'hi hagi diversos) formen una oferta DHCPOFFER amb la configuració de xarxa per al dispositiu que ha enviat DHCPDISCOVER i també l'emeten per la xarxa. La identificació de qui està destinat aquest paquet es basa en l'adreça MAC del client proporcionada anteriorment a la sol·licitud DHCPDISCOVER.
  3. El client accepta paquets amb propostes de configuració de xarxa, selecciona el més atractiu (els criteris poden ser diferents, per exemple, l'hora de lliurament del paquet, el nombre de rutes intermèdies) i fa una "sol·licitud oficial" DHCPREQUEST amb la configuració de la xarxa. des del servidor DHCP que li agrada. En aquest cas, el paquet va a un servidor DHCP específic.
  4. El servidor que va rebre la DHCPREQUEST envia un paquet en format DHCPACK, en el qual torna a enumerar la configuració de xarxa destinada a aquest client.

Servidor DHCP+Mysql en Python

A més, hi ha paquets DHCPINFORM que provenen del client, i la finalitat dels quals és informar al servidor DHCP que el "client està viu" i està utilitzant la configuració de xarxa emesa. En la implementació d'aquest servidor, aquests paquets s'ignoren.

Format de paquet

En general, una trama de paquets Ethernet té un aspecte semblant a això:

Servidor DHCP+Mysql en Python

En el nostre cas, considerarem només les dades directament del contingut del paquet UDP, sense capçaleres de protocol de capa OSI, és a dir, l'estructura DHCP:

DHCPDESCOBRIR

Per tant, el procés d'obtenció d'una adreça IP per a un dispositiu comença amb el client DHCP que envia una sol·licitud de difusió des del port 68 al 255.255.255.255:67. En aquest paquet, el client inclou la seva adreça MAC, així com el que vol rebre exactament del servidor DHCP. L'estructura del paquet es descriu a la taula següent.

Taula d'estructura de paquets DHCPDISCOVER

Posició al paquet
Nom del valor
Exemple
Introducció
Byte
Explicació

1
Sol·licitud d'arrencada
1
Malefici
1
Tipus de missatge. 1 - sol·licitud de client a servidor, 2 - resposta de servidor a client

2
Tipus de maquinari
1
Malefici
1
Tipus d'adreça de maquinari, en aquest protocol 1 - MAC

3
Longitud de les adreces de maquinari
6
Malefici
1
Longitud de l'adreça MAC del dispositiu

4
Llúpol
1
Malefici
1
Nombre de vies intermèdies

5
Identificador de transacció
23:cf:de:1d
Malefici
4
Identificador únic de transacció. Generat pel client a l'inici d'una operació de sol·licitud

7
Ha passat el segon
0
Malefici
4
Temps en segons des de l'inici del procés d'obtenció d'una adreça

9
Banderes d'arrencada
0
Malefici
2
Determinats indicadors que es poden configurar per indicar paràmetres de protocol

11
Adreça IP del client
0.0.0.0
Cadena
4
Adreça IP del client (si n'hi ha)

15
L'adreça IP del vostre client
0.0.0.0
Cadena
4
Adreça IP que ofereix el servidor (si està disponible)

19
Següent adreça IP del servidor
0.0.0.0
Cadena
4
Adreça IP del servidor (si es coneix)

23
Adreça IP de l'agent de retransmissió
172.16.114.41
Cadena
4
Adreça IP de l'agent de retransmissió (per exemple, un commutador)

27
Adreça MAC del client
14:d6:4d:a7:c9:55
Malefici
6
Adreça MAC del remitent del paquet (client)

31
Farciment d'adreces de maquinari del client
 
Malefici
10
Seient reservat. Normalment s'omple de zeros

41
Nom d'amfitrió del servidor
 
Cadena
64
Nom del servidor DHCP. Normalment no es transmet

105
Nom del fitxer d'arrencada
 
Cadena
128
Nom del fitxer al servidor utilitzat per les estacions sense disc quan arrenquen

235
Galetes màgiques
63: 82: 53: 63
Malefici
4
Número "màgic", segons el qual, incl. podeu determinar que aquest paquet pertany al protocol DHCP

Opcions de DHCP. Pot anar en qualsevol ordre

236
Número d'opció
53
desembre
1
Opció 53, que especifica el tipus de paquet DHCP

1 - DHCPDESCOBRIR
3 - SOL·LICITUD DHCP
2 - OFERTA DHCP
5 - DHCPACK
8 - DHCPINFORM

 
Longitud de l'opció
1
desembre
1

 
Valor de l'opció
1
desembre
1

 
Número d'opció
50
desembre
1
Quina adreça IP vol rebre el client?

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
172.16.134.61
Cadena
4

 
Número d'opció
55
 
1
Paràmetres de xarxa sol·licitats pel client. La composició pot variar

01 — Màscara de xarxa
03 - Porta d'entrada
06 - DNS
oc — Nom d'amfitrió
0f: nom de domini de xarxa
1c - adreça de la sol·licitud d'emissió (difusió)
42 - Nom del servidor TFTP
79 - Ruta estàtica sense classes

 
Longitud de l'opció
8
 
1

 
Valor de l'opció
01:03:06:0c:0f:1c:42:79
 
8

 
Número d'opció
82
desembre
 
Opció 82, que transmet l'adreça MAC del dispositiu repetidor i alguns valors addicionals.

Molt sovint, aquest és el port del commutador on s'executa el client DHCP final. Aquesta opció conté paràmetres addicionals. El primer byte és el número de la "subopció", el segon és la seva longitud i després el seu valor.

En aquest cas, a l'opció 82, les subopcions estan imbricades:
ID del circuit de l'agent = 00:04:00:01:00:04, on els dos últims bytes són el port de client DHCP des del qual prové la sol·licitud

ID de l'agent remot = 00:06:c8:be:19:93:11:48 - Adreça MAC del dispositiu repetidor DHCP

 
Longitud de l'opció
18
desembre
 

 
Valor de l'opció
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Malefici
 

 
Final del paquet
255
desembre
1
255 simbolitza el final del paquet

OFERTA DHCP

Tan bon punt el servidor rep el paquet DHCPDISCOVER i si veu que pot oferir al client alguna cosa del sol·licitat, genera una resposta per aquest: DHCPDISCOVER. La resposta s'envia al port "d'on va venir", per emissió, perquè en aquest moment, el client encara no té una adreça IP, per tant només pot acceptar el paquet si s'envia per difusió. El client reconeix que es tracta d'un paquet per a ell per la seva adreça MAC dins del paquet, així com pel número de transacció que genera en el moment en què es crea el primer paquet.

Taula d'estructura de paquets DHCPOFFER

Posició al paquet
Nom del valor (comú)
Exemple
Introducció
Byte
Explicació

1
Sol·licitud d'arrencada
1
Malefici
1
Tipus de missatge. 1 - sol·licitud de client a servidor, 2 - resposta de servidor a client

2
Tipus de maquinari
1
Malefici
1
Tipus d'adreça de maquinari, en aquest protocol 1 - MAC

3
Longitud de les adreces de maquinari
6
Malefici
1
Longitud de l'adreça MAC del dispositiu

4
Llúpol
1
Malefici
1
Nombre de vies intermèdies

5
Identificador de transacció
23:cf:de:1d
Malefici
4
Identificador únic de transacció. Generat pel client a l'inici d'una operació de sol·licitud

7
Ha passat el segon
0
Malefici
4
Temps en segons des de l'inici del procés d'obtenció d'una adreça

9
Banderes d'arrencada
0
Malefici
2
Determinats indicadors que es poden configurar per indicar paràmetres de protocol. En aquest cas, 0 significa el tipus de sol·licitud Unicast

11
Adreça IP del client
0.0.0.0
Cadena
4
Adreça IP del client (si n'hi ha)

15
L'adreça IP del vostre client
172.16.134.61
Cadena
4
Adreça IP que ofereix el servidor (si està disponible)

19
Següent adreça IP del servidor
0.0.0.0
Cadena
4
Adreça IP del servidor (si es coneix)

23
Adreça IP de l'agent de retransmissió
172.16.114.41
Cadena
4
Adreça IP de l'agent de retransmissió (per exemple, un commutador)

27
Adreça MAC del client
14:d6:4d:a7:c9:55
Malefici
6
Adreça MAC del remitent del paquet (client)

31
Farciment d'adreces de maquinari del client
 
Malefici
10
Seient reservat. Normalment s'omple de zeros

41
Nom d'amfitrió del servidor
 
Cadena
64
Nom del servidor DHCP. Normalment no es transmet

105
Nom del fitxer d'arrencada
 
Cadena
128
Nom del fitxer al servidor utilitzat per les estacions sense disc quan arrenquen

235
Galetes màgiques
63: 82: 53: 63
Malefici
4
Número "màgic", segons el qual, incl. podeu determinar que aquest paquet pertany al protocol DHCP

Opcions de DHCP. Pot anar en qualsevol ordre

236
Número d'opció
53
desembre
1
Opció 53, que defineix el tipus de paquet DHCP 2 - DHCPOFFER

 
Longitud de l'opció
1
desembre
1

 
Valor de l'opció
2
desembre
1

 
Número d'opció
1
desembre
1
Opció per oferir al client DHCP una màscara de xarxa

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
255.255.224.0
Cadena
4

 
Número d'opció
3
desembre
1
Opció per oferir al client DHCP una passarel·la per defecte

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
172.16.12.1
Cadena
4

 
Número d'opció
6
desembre
1
Opció per oferir DHCP al client DNS

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
8.8.8.8
Cadena
4

 
Número d'opció
51
desembre
1
La vida útil dels paràmetres de xarxa emesos en segons, després dels quals el client DHCP els ha de tornar a sol·licitar

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
86400
desembre
4

 
Número d'opció
82
desembre
1
L'opció 82, repeteix el que va venir a DHCPDISCOVER

 
Longitud de l'opció
18
desembre
1

 
Valor de l'opció
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
desembre
18

 
Final del paquet
255
desembre
1
255 simbolitza el final del paquet

SOL·LICITUD DE DHCP

Després que el client rep DHCPOFFER, forma un paquet demanant paràmetres de xarxa no a tots els servidors DHCP de la xarxa, sinó només a un en concret, l'oferta DHCPOFFER del qual li "agradava" més. Els criteris de "m'agrada" poden ser diferents i depenen de la implementació de DHCP del client. El destinatari de la sol·licitud s'especifica mitjançant l'adreça MAC del servidor DHCP. A més, el client pot enviar un paquet DHCPREQUEST sense generar prèviament DHCPDISCOVER, si l'adreça IP del servidor ja s'ha obtingut prèviament.

Taula d'estructura de paquets DHCPREQUEST

Posició al paquet
Nom del valor (comú)
Exemple
Introducció
Byte
Explicació

1
Sol·licitud d'arrencada
1
Malefici
1
Tipus de missatge. 1 - sol·licitud de client a servidor, 2 - resposta de servidor a client

2
Tipus de maquinari
1
Malefici
1
Tipus d'adreça de maquinari, en aquest protocol 1 - MAC

3
Longitud de les adreces de maquinari
6
Malefici
1
Longitud de l'adreça MAC del dispositiu

4
Llúpol
1
Malefici
1
Nombre de vies intermèdies

5
Identificador de transacció
23:cf:de:1d
Malefici
4
Identificador únic de transacció. Generat pel client a l'inici d'una operació de sol·licitud

7
Ha passat el segon
0
Malefici
4
Temps en segons des de l'inici del procés d'obtenció d'una adreça

9
Banderes d'arrencada
8000
Malefici
2
Determinats indicadors que es poden configurar per indicar paràmetres de protocol. En aquest cas, s'estableix "emissió".

11
Adreça IP del client
0.0.0.0
Cadena
4
Adreça IP del client (si n'hi ha)

15
L'adreça IP del vostre client
172.16.134.61
Cadena
4
Adreça IP que ofereix el servidor (si està disponible)

19
Següent adreça IP del servidor
0.0.0.0
Cadena
4
Adreça IP del servidor (si es coneix)

23
Adreça IP de l'agent de retransmissió
172.16.114.41
Cadena
4
Adreça IP de l'agent de retransmissió (per exemple, un commutador)

27
Adreça MAC del client
14:d6:4d:a7:c9:55
Malefici
6
Adreça MAC del remitent del paquet (client)

31
Farciment d'adreces de maquinari del client
 
Malefici
10
Seient reservat. Normalment s'omple de zeros

41
Nom d'amfitrió del servidor
 
Cadena
64
Nom del servidor DHCP. Normalment no es transmet

105
Nom del fitxer d'arrencada
 
Cadena
128
Nom del fitxer al servidor utilitzat per les estacions sense disc quan arrenquen

235
Galetes màgiques
63: 82: 53: 63
Malefici
4
Número "màgic", segons el qual, incl. podeu determinar que aquest paquet pertany al protocol DHCP

Opcions de DHCP. Pot anar en qualsevol ordre

236
Número d'opció
53
desembre
3
Opció 53, que defineix el tipus de paquet DHCP 3 - DHCPREQUEST

 
Longitud de l'opció
1
desembre
1

 
Valor de l'opció
3
desembre
1

 
Número d'opció
61
desembre
1
ID de client: 01 (per a Ehernet) + adreça MAC del client

 
Longitud de l'opció
7
desembre
1

 
Valor de l'opció
01:2c:ab:25:ff:72:a6
Malefici
7

 
Número d'opció
60
desembre
 
"Identificador de classe de proveïdor". En el meu cas, informa de la versió del client DHCP. Potser altres dispositius tornen alguna cosa diferent. Windows, per exemple, informa MSFT 5.0

 
Longitud de l'opció
11
desembre
 

 
Valor de l'opció
udhcp 0.9.8
Cadena
 

 
Número d'opció
55
 
1
Paràmetres de xarxa sol·licitats pel client. La composició pot variar

01 — Màscara de xarxa
03 - Porta d'entrada
06 - DNS
oc — Nom d'amfitrió
0f: nom de domini de xarxa
1c - adreça de la sol·licitud d'emissió (difusió)
42 - Nom del servidor TFTP
79 - Ruta estàtica sense classes

 
Longitud de l'opció
8
 
1

 
Valor de l'opció
01:03:06:0c:0f:1c:42:79
 
8

 
Número d'opció
82
desembre
1
L'opció 82, repeteix el que va venir a DHCPDISCOVER

 
Longitud de l'opció
18
desembre
1

 
Valor de l'opció
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
desembre
18

 
Final del paquet
255
desembre
1
255 simbolitza el final del paquet

DHCPACK

Com a confirmació que "sí, això és correcte, aquesta és la teva adreça IP i no la donaré a ningú més" des del servidor DHCP, serveix un paquet en format DHCPACK del servidor al client. S'envia emès igual que altres paquets. Tot i que, al codi següent per a un servidor DHCP implementat en Python, per si de cas, duplico qualsevol sol·licitud de difusió enviant un paquet a una IP de client específica, si ja se la coneix. A més, al servidor DHCP no li importa gens si el paquet DHCPACK ha arribat al client. Si el client no rep DHCPACK, després d'un temps simplement repeteix DHCPREQUEST

Taula d'estructura de paquets DHCPACK

Posició al paquet
Nom del valor (comú)
Exemple
Introducció
Byte
Explicació

1
Sol·licitud d'arrencada
2
Malefici
1
Tipus de missatge. 1 - sol·licitud de client a servidor, 2 - resposta de servidor a client

2
Tipus de maquinari
1
Malefici
1
Tipus d'adreça de maquinari, en aquest protocol 1 - MAC

3
Longitud de les adreces de maquinari
6
Malefici
1
Longitud de l'adreça MAC del dispositiu

4
Llúpol
1
Malefici
1
Nombre de vies intermèdies

5
Identificador de transacció
23:cf:de:1d
Malefici
4
Identificador únic de transacció. Generat pel client a l'inici d'una operació de sol·licitud

7
Ha passat el segon
0
Malefici
4
Temps en segons des de l'inici del procés d'obtenció d'una adreça

9
Banderes d'arrencada
8000
Malefici
2
Determinats indicadors que es poden configurar per indicar paràmetres de protocol. En aquest cas, s'estableix "emissió".

11
Adreça IP del client
0.0.0.0
Cadena
4
Adreça IP del client (si n'hi ha)

15
L'adreça IP del vostre client
172.16.134.61
Cadena
4
Adreça IP que ofereix el servidor (si està disponible)

19
Següent adreça IP del servidor
0.0.0.0
Cadena
4
Adreça IP del servidor (si es coneix)

23
Adreça IP de l'agent de retransmissió
172.16.114.41
Cadena
4
Adreça IP de l'agent de retransmissió (per exemple, un commutador)

27
Adreça MAC del client
14:d6:4d:a7:c9:55
Malefici
6
Adreça MAC del remitent del paquet (client)

31
Farciment d'adreces de maquinari del client
 
Malefici
10
Seient reservat. Normalment s'omple de zeros

41
Nom d'amfitrió del servidor
 
Cadena
64
Nom del servidor DHCP. Normalment no es transmet

105
Nom del fitxer d'arrencada
 
Cadena
128
Nom del fitxer al servidor utilitzat per les estacions sense disc quan arrenquen

235
Galetes màgiques
63: 82: 53: 63
Malefici
4
Número "màgic", segons el qual, incl. podeu determinar que aquest paquet pertany al protocol DHCP

Opcions de DHCP. Pot anar en qualsevol ordre

236
Número d'opció
53
desembre
3
Opció 53, que defineix el tipus de paquet DHCP 5 - DHCPACK

 
Longitud de l'opció
1
desembre
1

 
Valor de l'opció
5
desembre
1

 
Número d'opció
1
desembre
1
Opció per oferir al client DHCP una màscara de xarxa

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
255.255.224.0
Cadena
4

 
Número d'opció
3
desembre
1
Opció per oferir al client DHCP una passarel·la per defecte

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
172.16.12.1
Cadena
4

 
Número d'opció
6
desembre
1
Opció per oferir DHCP al client DNS

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
8.8.8.8
Cadena
4

 
Número d'opció
51
desembre
1
La vida útil dels paràmetres de xarxa emesos en segons, després dels quals el client DHCP els ha de tornar a sol·licitar

 
Longitud de l'opció
4
desembre
1

 
Valor de l'opció
86400
desembre
4

 
Número d'opció
82
desembre
1
L'opció 82, repeteix el que va venir a DHCPDISCOVER

 
Longitud de l'opció
18
desembre
1

 
Valor de l'opció
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
desembre
18

 
Final del paquet
255
desembre
1
255 simbolitza el final del paquet

Instal · lació

En realitat, la instal·lació consisteix a instal·lar els mòduls Python necessaris per al treball. Se suposa que MySQL ja està instal·lat i configurat.

FreeBSD

pkg instal·la python3 python3 -m assurepip pip3 instal·la mysql-connector

Ubuntu

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

Creem una base de dades MySQL, hi pengem el bolcat pydhcp.sql i configurem el fitxer de configuració.

Configuració

Tota la configuració del servidor es troba en un fitxer xml. Fitxer de referència:

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 prova prova 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 seleccioneu ip, màscara, encaminador, dns dels usuaris on upper(mac)=upper('{option_3_AgentRemoteId_hex}') i upper(port)=upper('{option_1_AgentCircuitId_port_hex}') seleccioneu ip, màscara, encaminador, dns dels usuaris on upper(mac)=upper('{sw_mac}') i upper(port)=upper('{sw_port82}') seleccioneu ip, màscara, encaminador, dns dels usuaris on upper(mac)=upper('{ClientMacAddress}') inseriu als valors de l'historial (id, dt, mac, ip, comentari) (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Ara amb més detall sobre les etiquetes:

La secció dhcpserver descriu la configuració bàsica per iniciar el servidor, és a dir:

  • host: quina adreça IP escolta el servidor al port 67
  • broadcast: quina ip és l'emissió per a DHCPOFFER i DHCPACK
  • DHCPServer: quina és la ip del servidor DHCP
  • LeaseTime temps d'arrendament de l'adreça IP emesa
  • ThreadLimit: quants fils s'executen simultàniament per processar els paquets UDP entrants al port 67. Se suposa que ajudarà en projectes de gran càrrega 😉
  • defaultMask,defaultRouter,defaultDNS: què s'ofereix al subscriptor de manera predeterminada si es troba una IP a la base de dades, però no s'especifiquen paràmetres addicionals per a aquesta

secció mysql:

host, nom d'usuari, contrasenya, nom base: tot parla per si sol. Es publica una estructura aproximada de la base de dades GitHub

Secció de consultes: les sol·licituds per rebre OFERTA/ACK es descriuen aquí:

  • offer_count — el nombre de línies amb sol·licituds que retornen un resultat com ip, mask, router, dns
  • offer_n — cadena de consulta. Si la devolució està buida, executa la següent sol·licitud d'oferta
  • history_sql: una consulta que escriu, per exemple, a l'"historial d'autoritzacions" d'un subscriptor

Les sol·licituds poden incloure qualsevol variable de la secció d'opcions o opcions del protocol DHCP.

Secció d'opcions. Aquí és on es fa més interessant. Aquí podem crear variables que podem utilitzar més endavant a la secció de consultes.

Per exemple:

option_82_hex:sw_port1:20:22

, aquesta línia d'ordres agafa tota la línia que va venir a l'opció de sol·licitud DHCP 82, en format hexadecimal, en el rang de 20 a 22 bytes inclosos i la posa a la nova variable sw_port1 (canvia el port d'on va venir la sol·licitud)

option_82_hex:sw_mac:26:40

, defineix la variable sw_mac, prenent l'hex de l'interval 26:40

Podeu veure totes les opcions possibles que es poden utilitzar en les consultes iniciant el servidor amb l'interruptor -d. Veurem alguna cosa com aquest registre:

--un paquet DHCPINFORM ha arribat al port 67, des de 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224MacAddress': '764:'Address': 'ClientMac': '00'7': Jxd91d', 'HType': 'Ethernet', 'HostName': b'x5xa0xe3xa5xa9xa8-x8fx43a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouterDiscover': True, 'ReqListSRouter', 'ReqListSRouter': ReqListSubnetMask ': True, 'ReqListVendorSpecInfo': 0.0.0.0, 'RequestedIpAddress': '5.0', 'Proveïdor': b'MSFT 0025224', 'chaddr': '764ad172.30.128.13', 'ciaddr..', '00':00 banderes ': b'x172.30.114.25x308', 'giaddr': '6', 'gpoz': 1, 'hlen': 82, 'hops': 12, 'htype': 'MAC', 'magic_cookie': b' cx12Sc ', 'op': 'DHCPINFORM', 'option53': 53, 'option55': 55, 'option60': 60, 'option61': 61, 'option82': 82, 'option82': 12, 'option_01_byte' : b'x06x00x04x00x01x00x06x02x08x00x06x00' b'x1x9x2eXx82exb12010600040001000602080006001xad', 'option_589_hex': '2', 'option_82_hex': '18 option_82_str': "b'x12x01x06x00x04x00x01x00x06x02x08x00x06x00x1eXx9exb2xad'", 'resultat': Fals, 'secs': 768, 'siaddr' : '0.0.0.0', 'sw_mac': '001e589eb2ad', 'sw_port1': '06', 'xidbyte': b'

En conseqüència, podem embolicar qualsevol variable a {} i s'utilitzarà a la consulta SQL.

Enregistrem per a l'historial que el client va rebre l'adreça IP:

Servidor DHCP+Mysql en Python

Servidor DHCP+Mysql en Python

Inici del servidor

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

— d mode de sortida de la consola DEBUG
- Fitxer de configuració c <nom del fitxer>

Debriefing

I ara més detalls sobre la implementació del servidor a Python. És un dolor. Python es va aprendre sobre la marxa. Molts moments es fan a l'estil de "wow, d'alguna manera ho vaig fer funcionar". No s'ha optimitzat gens, i es va deixar en aquesta forma principalment a causa de la poca experiència en el desenvolupament de Python. Em detendré en els aspectes més interessants de la implementació del servidor en "codi".

Analitzador de fitxers de configuració XML

S'utilitza el mòdul estàndard de Python xml.dom. Sembla senzill, però durant la implementació hi va haver una manca notable de documentació clara i exemples a la xarxa amb aquest mòdul.

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") per a l'element a mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("username")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("contrasenya")[0].firstChild.data gconfig["mysql_basename"] =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") per a l'element a dconfig: gconfig["broadcast"]=elem.getElementsByTagName("broadcast")[0]. firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("amfitrió")[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_defaultRouter"]meelement"ByTagTag"] defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("consulta") per a l'element a qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data per a num in rang(int(gconfig["offer_count"])): gconfig["offer_"+str(num+1)]=elem.getElementsByTagName("oferta_"+str(num+1))[0].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("opcions") per a l'element a les opcions: node=elem.getElementsByTagName("opció") per a les opcions del node : optionsMod.append(options.firstChild.data)

Multithreading

Curiosament, el multithreading a Python s'implementa de manera molt clara i senzilla.

def PacketWork(data,adr): ... # implementació d'analitzar el paquet entrant i respondre-hi... mentre que True: data, addr = udp_socket.recvfrom(1024) # esperant el fil del paquet UDP = threading.Thread( target=PacketWork , args=(data,addr,)).start() # tal com va venir - iniciem la funció PacketWork prèviament definida en segon pla amb paràmetres mentre threading.active_count() >gconfig["dhcp_ThreadLimit"]: time. sleep(1) # si el nombre Ja hi ha més fils en funcionament que a la configuració, esperem fins que n'hi hagi menys

Rebre/envia paquet DHCP

Per interceptar els paquets UDP que arriben a través de la targeta de xarxa, cal "aixecar" el sòcol:

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

, on les banderes són:

  • AF_INET - significa que el format d'adreça serà IP: port. També pot haver-hi AF_UNIX, on l'adreça ve donada pel nom del fitxer.
  • SOCK_DGRAM - significa que no acceptem un "paquet en brut", sinó un que ja ha passat pel tallafoc i amb un paquet parcialment retallat. Aquells. només rebem un paquet UDP sense el component "físic" de l'embolcall de paquets UDP. Si utilitzeu el senyalador SOCK_RAW, també haureu d'analitzar aquest "embolcall".

L'enviament d'un paquet pot ser com una emissió:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #canvia el sòcol al mode d'enviament d'emissió rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, i a l'adreça "d'on prové el paquet":

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # canvieu el socket al mode multi-escolta rz=udp_socket.sendto(packetack, addr)

, on SOL_SOCKET significa el "nivell de protocol" per configurar les opcions,

, opció SO_BROADCAST que el paquet del casc està "difusió"

  L'opció ,SO_REUSEADDR canvia el sòcol al mode "molts oients". En teoria, en aquest cas és innecessari, però en un dels servidors FreeBSD en què vaig provar, el codi no funcionava sense aquesta opció.

Analitzant un paquet DHCP

Aquí és on em va agradar molt Python. Resulta que fora de la caixa et permet ser bastant flexible amb el bytecode. Permet que es tradueixi molt fàcilment a valors decimals, cadenes i hexadecimals, és a dir. això és el que realment necessitem per entendre l'estructura del paquet. Així, per exemple, podeu obtenir un interval de bytes en HEX i només bytes:

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

, empaqueta els bytes en una estructura:

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

Obteniu IP de l'estructura:

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

I viceversa:

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

Això és tot per ara 😉

Font: www.habr.com

Afegeix comentari