DHCP + Mysql սերվեր Python-ում

DHCP + Mysql սերվեր Python-ում

Այս նախագծի նպատակն էր.

  • Իմանալով DHCP-ի մասին IPv4 ցանցում
  • Սովորել Python (մի փոքր ավելին, քան զրոյից 😉)
  • սերվերի փոխարինում DB2DHCP (իմ պատառաքաղ), օրիգինալ այստեղ, որն ավելի ու ավելի դժվար է դառնում նոր ՕՀ-ի համար հավաքելը։ Եվ ինձ դուր չի գալիս, որ դա երկուական է, որը «հենց հիմա փոխելու» հնարավորություն չկա
  • ստանալով աշխատող DHCP սերվեր՝ բաժանորդի IP հասցեն ընտրելու ունակությամբ՝ օգտագործելով բաժանորդի mac կամ անջատիչ mac+port համակցությունը (տարբերակ 82)
  • մեկ այլ հեծանիվ գրել (Օ՜, սա իմ սիրելի զբաղմունքն է)
  • ստանալով մեկնաբանություններ քո ակումբային ձեռքի մասին Habrahabr-ում (կամ ավելի լավ՝ հրավեր) 😉

Արդյունք. այն աշխատում է 😉 Փորձարկվել է FreeBSD-ի և Ubuntu OS-ի վրա: Տեսականորեն, կոդը կարող է պահանջվել աշխատել ցանկացած ՕՀ-ի ներքո, քանի որ Կարծես թե օրենսգրքում հատուկ կապեր չկան:
Զգույշ. Շատ ավելին է սպասվում:

Հղում դեպի շտեմարան սիրողականների համար «կենդանի դիպչել».

«Սարքաշարի ուսումնասիրության» արդյունքի տեղադրման, կազմաձևման և օգտագործման գործընթացը շատ ավելի ցածր է, իսկ հետո մի փոքր տեսություն DHCP արձանագրության մասին: Ինձ համար. Եվ պատմության համար 😉

Մի փոքր տեսություն

Ինչ է DHCP-ն

Սա ցանցային արձանագրություն է, որը թույլ է տալիս սարքին պարզել իր IP հասցեն (և այլ պարամետրեր, ինչպիսիք են gateway, DNS և այլն) DHCP սերվերից: Փաթեթները փոխանակվում են UDP արձանագրության միջոցով: Ցանցի պարամետրերը պահանջելիս սարքի շահագործման ընդհանուր սկզբունքը հետևյալն է.

  1. Սարքը (հաճախորդը) ուղարկում է UDP հեռարձակման հարցում (DHCPDISCOVER) ամբողջ ցանցով՝ «դե ինչ-որ մեկն ինձ IP հասցե տա» խնդրանքով։ Ավելին, սովորաբար (բայց ոչ միշտ) հարցումը կատարվում է 68-րդ նավահանգստից (աղբյուր), իսկ նպատակակետը 67-րդ նավահանգիստն է (նպատակակետ): Որոշ սարքեր նաև փաթեթներ են ուղարկում 67 պորտից: Հաճախորդի սարքի MAC հասցեն ներառված է DHCPDISCOVER փաթեթի ներսում:
  2. Ցանցում տեղակայված բոլոր DHCP սերվերները (և դրանք կարող են լինել մի քանիսը) կազմում են DHCPOFFER առաջարկ՝ ցանցային կարգավորումներով DHCPDISCOVER ուղարկած սարքի համար, ինչպես նաև հեռարձակում են այն ցանցով: Նույնականացումը, թե ում համար է այս փաթեթը նախատեսված, հիմնված է հաճախորդի MAC հասցեի վրա, որը տրամադրվել է ավելի վաղ DHCPDISCOVER հարցումում:
  3. Հաճախորդը ընդունում է փաթեթներ ցանցի կարգավորումների առաջարկներով, ընտրում է ամենագրավիչը (չափանիշները կարող են տարբեր լինել, օրինակ՝ փաթեթների առաքման ժամանակը, միջանկյալ երթուղիների քանակը) և կատարում է «պաշտոնական հարցում» DHCPREQUEST ցանցի կարգավորումներով։ DHCP սերվերից, որը նա սիրում է: Այս դեպքում փաթեթը գնում է կոնկրետ DHCP սերվեր:
  4. DHCPREQUEST ստացած սերվերը ուղարկում է DHCPACK ձևաչափի փաթեթ, որում ևս մեկ անգամ թվարկում է այս հաճախորդի համար նախատեսված ցանցի կարգավորումները:

DHCP + Mysql սերվեր Python-ում

Բացի այդ, կան DHCPINFORM փաթեթներ, որոնք գալիս են հաճախորդից, և որոնց նպատակն է տեղեկացնել DHCP սերվերին, որ «հաճախորդը ողջ է» և օգտագործում է թողարկված ցանցի կարգավորումները: Այս սերվերի ներդրման ժամանակ այս փաթեթներն անտեսվում են:

Փաթեթի ձևաչափ

Ընդհանուր առմամբ, Ethernet փաթեթի շրջանակն այսպիսի տեսք ունի.

DHCP + Mysql սերվեր Python-ում

Մեր դեպքում մենք կդիտարկենք միայն տվյալները անմիջապես UDP փաթեթի բովանդակությունից, առանց OSI շերտի արձանագրության վերնագրերի, մասնավորապես DHCP կառուցվածքի.

DHCPDISCOVER

Այսպիսով, սարքի համար IP հասցե ստանալու գործընթացը սկսվում է նրանից, որ DHCP հաճախորդը հեռարձակման հարցում է ուղարկում 68 նավահանգստից 255.255.255.255:67 համարին: Այս փաթեթում հաճախորդը ներառում է իր MAC հասցեն, ինչպես նաև այն, ինչ նա ցանկանում է ստանալ DHCP սերվերից: Փաթեթի կառուցվածքը նկարագրված է ստորև բերված աղյուսակում:

DHCPDISCOVER փաթեթի կառուցվածքի աղյուսակ

Դիրքը փաթեթում
Արժեքի անվանումը
Օրինակ
Ներածություն
Բայթ
Բացատրություն

1
Boot Request
1
Hex
1
Հաղորդագրության տեսակը. 1 - հարցում հաճախորդից սերվեր, 2 - պատասխան սերվերից հաճախորդ

2
Սարքավորման տեսակը
1
Hex
1
Սարքավորման հասցեի տեսակը, այս արձանագրության մեջ 1 - MAC

3
Սարքավորումների հասցեների երկարությունը
6
Hex
1
Սարքի MAC հասցեի երկարությունը

4
Hops
1
Hex
1
Միջանկյալ երթուղիների քանակը

5
Գործարքի ID
23:cf:de:1d
Hex
4
Գործարքի եզակի նույնացուցիչ: Հաճախորդի կողմից ստեղծվել է հարցման գործողության սկզբում

7
Երկրորդն անցավ
0
Hex
4
Ժամանակը վայրկյաններով՝ հասցե ստանալու գործընթացի սկզբից

9
Կոշիկի դրոշներ
0
Hex
2
Որոշ դրոշներ, որոնք կարող են սահմանվել արձանագրության պարամետրերը ցույց տալու համար

11
Հաճախորդի IP հասցե
0.0.0.0
Լարային
4
Հաճախորդի IP հասցե (եթե այդպիսիք կան)

15
Ձեր հաճախորդի IP հասցեն
0.0.0.0
Լարային
4
Սերվերի կողմից առաջարկվող IP հասցե (եթե առկա է)

19
Հաջորդ սերվերի IP հասցեն
0.0.0.0
Լարային
4
Սերվերի IP հասցե (եթե հայտնի է)

23
Ռելե գործակալի IP հասցե
172.16.114.41
Լարային
4
Ռելե գործակալի IP հասցեն (օրինակ՝ անջատիչ)

27
Հաճախորդի MAC հասցեն
14:d6:4d:a7:c9:55
Hex
6
Փաթեթ ուղարկողի (հաճախորդի) MAC հասցեն

31
Հաճախորդի ապարատային հասցեի լրացում
 
Hex
10
Պահպանված նստատեղ. Սովորաբար լցված են զրոներով

41
Սերվերի հյուրընկալողի անունը
 
Լարային
64
DHCP սերվերի անունը. Սովորաբար չի փոխանցվում

105
Boot ֆայլի անունը
 
Լարային
128
Ֆայլի անունը սերվերի վրա, որն օգտագործվում է առանց սկավառակի կայանների կողմից բեռնման ժամանակ

235
Կախարդական թխվածքաբլիթներ
63- ը, 82- ը, 53- ը, 63- ը
Hex
4
«Magic» համարը, ըստ որի, ներառյալ. Դուք կարող եք որոշել, որ այս փաթեթը պատկանում է DHCP արձանագրությանը

DHCP ընտրանքներ. Կարող է գնալ ցանկացած կարգով

236
Տարբերակի համարը
53
dec
1
Տարբերակ 53, որը սահմանում է DHCP փաթեթի տեսակը

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

 
Տարբերակի երկարությունը
1
dec
1

 
Ընտրանքի արժեքը
1
dec
1

 
Տարբերակի համարը
50
dec
1
Ի՞նչ IP հասցե է ցանկանում ստանալ հաճախորդը:

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
172.16.134.61
Լարային
4

 
Տարբերակի համարը
55
 
1
Հաճախորդի կողմից պահանջվող ցանցի պարամետրերը: Կազմը կարող է տարբեր լինել

01 — Ցանցային դիմակ
03 - Դարպաս
06 - DNS
oc — հյուրընկալողի անուն
0f - ցանցի տիրույթի անուն
1c - հեռարձակման հարցման հասցեն (հեռարձակում)
42 - TFTP սերվերի անունը
79 - Անդաս ստատիկ երթուղի

 
Տարբերակի երկարությունը
8
 
1

 
Ընտրանքի արժեքը
01:03:06:0c:0f:1c:42:79
 
8

 
Տարբերակի համարը
82
dec
 
Տարբերակ 82, որը փոխանցում է կրկնող սարքի MAC հասցեն և որոշ լրացուցիչ արժեքներ:

Ամենից հաճախ սա անջատիչի նավահանգիստն է, որի վրա աշխատում է վերջնական DHCP հաճախորդը: Այս տարբերակը պարունակում է լրացուցիչ պարամետրեր: Առաջին բայթը «ենթածրագրի» թիվն է, երկրորդը՝ դրա երկարությունը, ապա արժեքը:

Այս դեպքում 82-րդ տարբերակում ենթատարբերակները տեղադրված են.
Agent Circuit ID = 00:04:00:01:00:04, որտեղ վերջին երկու բայթերը DHCP հաճախորդի պորտն են, որտեղից ստացվել է հարցումը:

Agent Remote ID = 00:06:c8:be:19:93:11:48 - DHCP կրկնող սարքի MAC հասցեն

 
Տարբերակի երկարությունը
18
dec
 

 
Ընտրանքի արժեքը
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Hex
 

 
Փաթեթի ավարտը
255
dec
1
255-ը խորհրդանշում է փաթեթի ավարտը

DHCPOFFER

Հենց որ սերվերը ստանում է DHCPDISCOVER փաթեթը և եթե տեսնում է, որ կարող է հաճախորդին առաջարկել ինչ-որ բան պահանջվածից, ապա դրա համար պատասխան է առաջացնում՝ DHCPDISCOVER: Պատասխանն ուղարկվում է նավահանգիստ «որտեղից այն եկել է», հեռարձակմամբ, քանի որ այս պահին հաճախորդը դեռ չունի IP հասցե, հետևաբար այն կարող է ընդունել փաթեթը միայն եթե այն ուղարկվում է հեռարձակմամբ: Հաճախորդը ընդունում է, որ սա իր համար փաթեթ է իր MAC հասցեով փաթեթի ներսում, ինչպես նաև գործարքի համարով, որը նա ստեղծում է առաջին փաթեթի ստեղծման պահին:

DHCPOFFER փաթեթի կառուցվածքի աղյուսակ

Դիրքը փաթեթում
Արժեքի անվանումը (ընդհանուր)
Օրինակ
Ներածություն
Բայթ
Բացատրություն

1
Boot Request
1
Hex
1
Հաղորդագրության տեսակը. 1 - հարցում հաճախորդից սերվեր, 2 - պատասխան սերվերից հաճախորդ

2
Սարքավորման տեսակը
1
Hex
1
Սարքավորման հասցեի տեսակը, այս արձանագրության մեջ 1 - MAC

3
Սարքավորումների հասցեների երկարությունը
6
Hex
1
Սարքի MAC հասցեի երկարությունը

4
Hops
1
Hex
1
Միջանկյալ երթուղիների քանակը

5
Գործարքի ID
23:cf:de:1d
Hex
4
Գործարքի եզակի նույնացուցիչ: Հաճախորդի կողմից ստեղծվել է հարցման գործողության սկզբում

7
Երկրորդն անցավ
0
Hex
4
Ժամանակը վայրկյաններով՝ հասցե ստանալու գործընթացի սկզբից

9
Կոշիկի դրոշներ
0
Hex
2
Որոշ դրոշներ, որոնք կարող են սահմանվել արձանագրության պարամետրերը ցույց տալու համար: Այս դեպքում 0-ը նշանակում է Unicast հարցման տեսակը

11
Հաճախորդի IP հասցե
0.0.0.0
Լարային
4
Հաճախորդի IP հասցե (եթե այդպիսիք կան)

15
Ձեր հաճախորդի IP հասցեն
172.16.134.61
Լարային
4
Սերվերի կողմից առաջարկվող IP հասցե (եթե առկա է)

19
Հաջորդ սերվերի IP հասցեն
0.0.0.0
Լարային
4
Սերվերի IP հասցե (եթե հայտնի է)

23
Ռելե գործակալի IP հասցե
172.16.114.41
Լարային
4
Ռելե գործակալի IP հասցեն (օրինակ՝ անջատիչ)

27
Հաճախորդի MAC հասցեն
14:d6:4d:a7:c9:55
Hex
6
Փաթեթ ուղարկողի (հաճախորդի) MAC հասցեն

31
Հաճախորդի ապարատային հասցեի լրացում
 
Hex
10
Պահպանված նստատեղ. Սովորաբար լցված են զրոներով

41
Սերվերի հյուրընկալողի անունը
 
Լարային
64
DHCP սերվերի անունը. Սովորաբար չի փոխանցվում

105
Boot ֆայլի անունը
 
Լարային
128
Ֆայլի անունը սերվերի վրա, որն օգտագործվում է առանց սկավառակի կայանների կողմից բեռնման ժամանակ

235
Կախարդական թխվածքաբլիթներ
63- ը, 82- ը, 53- ը, 63- ը
Hex
4
«Magic» համարը, ըստ որի, ներառյալ. Դուք կարող եք որոշել, որ այս փաթեթը պատկանում է DHCP արձանագրությանը

DHCP ընտրանքներ. Կարող է գնալ ցանկացած կարգով

236
Տարբերակի համարը
53
dec
1
Տարբերակ 53, որը սահմանում է DHCP 2 փաթեթի տեսակը՝ DHCPOFFER

 
Տարբերակի երկարությունը
1
dec
1

 
Ընտրանքի արժեքը
2
dec
1

 
Տարբերակի համարը
1
dec
1
DHCP հաճախորդին ցանցային դիմակ առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
255.255.224.0
Լարային
4

 
Տարբերակի համարը
3
dec
1
DHCP հաճախորդին լռելյայն դարպաս առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
172.16.12.1
Լարային
4

 
Տարբերակի համարը
6
dec
1
DNS հաճախորդին DHCP առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
8.8.8.8
Լարային
4

 
Տարբերակի համարը
51
dec
1
Թողարկված ցանցի պարամետրերի ժամկետը վայրկյաններով, որից հետո DHCP հաճախորդը պետք է նորից պահանջի դրանք

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
86400
dec
4

 
Տարբերակի համարը
82
dec
1
Տարբերակ 82, կրկնում է այն, ինչ եկել է DHCPDISCOVER-ում

 
Տարբերակի երկարությունը
18
dec
1

 
Ընտրանքի արժեքը
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
dec
18

 
Փաթեթի ավարտը
255
dec
1
255-ը խորհրդանշում է փաթեթի ավարտը

DHCPREQUEST

Այն բանից հետո, երբ հաճախորդը ստանում է DHCPOFFER, նա ձևավորում է փաթեթ, որը պահանջում է ցանցի պարամետրեր ոչ թե ցանցի բոլոր DHCP սերվերներին, այլ միայն մեկ կոնկրետ սերվերի, որի DHCPOFFER առաջարկն իրեն ամենաշատը «հավանել է»: «Նման» չափանիշները կարող են տարբեր լինել և կախված լինել հաճախորդի DHCP-ի իրականացումից: Հարցման ստացողը նշվում է DHCP սերվերի MAC հասցեի միջոցով: Նաև DHCPREQUEST փաթեթը կարող է ուղարկվել հաճախորդի կողմից՝ առանց նախապես DHCPDISCOVER ստեղծելու, եթե սերվերի IP հասցեն արդեն ձեռք է բերվել նախկինում:

DHCPREQUEST Փաթեթի կառուցվածքի աղյուսակ

Դիրքը փաթեթում
Արժեքի անվանումը (ընդհանուր)
Օրինակ
Ներածություն
Բայթ
Բացատրություն

1
Boot Request
1
Hex
1
Հաղորդագրության տեսակը. 1 - հարցում հաճախորդից սերվեր, 2 - պատասխան սերվերից հաճախորդ

2
Սարքավորման տեսակը
1
Hex
1
Սարքավորման հասցեի տեսակը, այս արձանագրության մեջ 1 - MAC

3
Սարքավորումների հասցեների երկարությունը
6
Hex
1
Սարքի MAC հասցեի երկարությունը

4
Hops
1
Hex
1
Միջանկյալ երթուղիների քանակը

5
Գործարքի ID
23:cf:de:1d
Hex
4
Գործարքի եզակի նույնացուցիչ: Հաճախորդի կողմից ստեղծվել է հարցման գործողության սկզբում

7
Երկրորդն անցավ
0
Hex
4
Ժամանակը վայրկյաններով՝ հասցե ստանալու գործընթացի սկզբից

9
Կոշիկի դրոշներ
8000
Hex
2
Որոշ դրոշներ, որոնք կարող են սահմանվել արձանագրության պարամետրերը ցույց տալու համար: Այս դեպքում սահմանվում է «հեռարձակում»:

11
Հաճախորդի IP հասցե
0.0.0.0
Լարային
4
Հաճախորդի IP հասցե (եթե այդպիսիք կան)

15
Ձեր հաճախորդի IP հասցեն
172.16.134.61
Լարային
4
Սերվերի կողմից առաջարկվող IP հասցե (եթե առկա է)

19
Հաջորդ սերվերի IP հասցեն
0.0.0.0
Լարային
4
Սերվերի IP հասցե (եթե հայտնի է)

23
Ռելե գործակալի IP հասցե
172.16.114.41
Լարային
4
Ռելե գործակալի IP հասցեն (օրինակ՝ անջատիչ)

27
Հաճախորդի MAC հասցեն
14:d6:4d:a7:c9:55
Hex
6
Փաթեթ ուղարկողի (հաճախորդի) MAC հասցեն

31
Հաճախորդի ապարատային հասցեի լրացում
 
Hex
10
Պահպանված նստատեղ. Սովորաբար լցված են զրոներով

41
Սերվերի հյուրընկալողի անունը
 
Լարային
64
DHCP սերվերի անունը. Սովորաբար չի փոխանցվում

105
Boot ֆայլի անունը
 
Լարային
128
Ֆայլի անունը սերվերի վրա, որն օգտագործվում է առանց սկավառակի կայանների կողմից բեռնման ժամանակ

235
Կախարդական թխվածքաբլիթներ
63- ը, 82- ը, 53- ը, 63- ը
Hex
4
«Magic» համարը, ըստ որի, ներառյալ. Դուք կարող եք որոշել, որ այս փաթեթը պատկանում է DHCP արձանագրությանը

DHCP ընտրանքներ. Կարող է գնալ ցանկացած կարգով

236
Տարբերակի համարը
53
dec
3
Տարբերակ 53, որը սահմանում է DHCP փաթեթի 3-րդ տեսակը՝ DHCPREQUEST

 
Տարբերակի երկարությունը
1
dec
1

 
Ընտրանքի արժեքը
3
dec
1

 
Տարբերակի համարը
61
dec
1
Հաճախորդի ID՝ 01 (Ehernet-ի համար) + հաճախորդի MAC հասցե

 
Տարբերակի երկարությունը
7
dec
1

 
Ընտրանքի արժեքը
01:2c:ab:25:ff:72:a6
Hex
7

 
Տարբերակի համարը
60
dec
 
«Վաճառողի դասի նույնացուցիչ»: Իմ դեպքում, այն հաղորդում է DHCP հաճախորդի տարբերակը: Միգուցե այլ սարքերը այլ բան են վերադարձնում: Windows-ը, օրինակ, հաղորդում է MSFT 5.0

 
Տարբերակի երկարությունը
11
dec
 

 
Ընտրանքի արժեքը
ուղեկցորդ 0.9.8
Լարային
 

 
Տարբերակի համարը
55
 
1
Հաճախորդի կողմից պահանջվող ցանցի պարամետրերը: Կազմը կարող է տարբեր լինել

01 — Ցանցային դիմակ
03 - Դարպաս
06 - DNS
oc — հյուրընկալողի անուն
0f - ցանցի տիրույթի անուն
1c - հեռարձակման հարցման հասցեն (հեռարձակում)
42 - TFTP սերվերի անունը
79 - Անդաս ստատիկ երթուղի

 
Տարբերակի երկարությունը
8
 
1

 
Ընտրանքի արժեքը
01:03:06:0c:0f:1c:42:79
 
8

 
Տարբերակի համարը
82
dec
1
Տարբերակ 82, կրկնում է այն, ինչ եկել է DHCPDISCOVER-ում

 
Տարբերակի երկարությունը
18
dec
1

 
Ընտրանքի արժեքը
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
dec
18

 
Փաթեթի ավարտը
255
dec
1
255-ը խորհրդանշում է փաթեթի ավարտը

DHCPACK

Որպես հաստատում, որ «այո, դա ճիշտ է, սա ձեր IP հասցեն է, և ես այն ուրիշին չեմ տա» DHCP սերվերից, DHCPACK ձևաչափով փաթեթ սերվերից մինչև հաճախորդը ծառայում է: Այն ուղարկվում է հեռարձակման այնպես, ինչպես մյուս փաթեթները: Թեև Python-ում ներդրված DHCP սերվերի ստորև կոդում, ամեն դեպքում, ես կրկնօրինակում եմ ցանկացած հեռարձակման հարցում՝ ուղարկելով փաթեթ կոնկրետ հաճախորդի IP-ին, եթե այն արդեն հայտնի է: Ավելին, DHCP սերվերին ընդհանրապես չի հետաքրքրում, թե արդյոք DHCPACK փաթեթը հասել է հաճախորդին։ Եթե ​​հաճախորդը չի ստանում DHCPACK, ապա որոշ ժամանակ անց այն պարզապես կրկնում է DHCPREQUEST

DHCPACK փաթեթի կառուցվածքի աղյուսակ

Դիրքը փաթեթում
Արժեքի անվանումը (ընդհանուր)
Օրինակ
Ներածություն
Բայթ
Բացատրություն

1
Boot Request
2
Hex
1
Հաղորդագրության տեսակը. 1 - հարցում հաճախորդից սերվեր, 2 - պատասխան սերվերից հաճախորդ

2
Սարքավորման տեսակը
1
Hex
1
Սարքավորման հասցեի տեսակը, այս արձանագրության մեջ 1 - MAC

3
Սարքավորումների հասցեների երկարությունը
6
Hex
1
Սարքի MAC հասցեի երկարությունը

4
Hops
1
Hex
1
Միջանկյալ երթուղիների քանակը

5
Գործարքի ID
23:cf:de:1d
Hex
4
Գործարքի եզակի նույնացուցիչ: Հաճախորդի կողմից ստեղծվել է հարցման գործողության սկզբում

7
Երկրորդն անցավ
0
Hex
4
Ժամանակը վայրկյաններով՝ հասցե ստանալու գործընթացի սկզբից

9
Կոշիկի դրոշներ
8000
Hex
2
Որոշ դրոշներ, որոնք կարող են սահմանվել արձանագրության պարամետրերը ցույց տալու համար: Այս դեպքում սահմանվում է «հեռարձակում»:

11
Հաճախորդի IP հասցե
0.0.0.0
Լարային
4
Հաճախորդի IP հասցե (եթե այդպիսիք կան)

15
Ձեր հաճախորդի IP հասցեն
172.16.134.61
Լարային
4
Սերվերի կողմից առաջարկվող IP հասցե (եթե առկա է)

19
Հաջորդ սերվերի IP հասցեն
0.0.0.0
Լարային
4
Սերվերի IP հասցե (եթե հայտնի է)

23
Ռելե գործակալի IP հասցե
172.16.114.41
Լարային
4
Ռելե գործակալի IP հասցեն (օրինակ՝ անջատիչ)

27
Հաճախորդի MAC հասցեն
14:d6:4d:a7:c9:55
Hex
6
Փաթեթ ուղարկողի (հաճախորդի) MAC հասցեն

31
Հաճախորդի ապարատային հասցեի լրացում
 
Hex
10
Պահպանված նստատեղ. Սովորաբար լցված են զրոներով

41
Սերվերի հյուրընկալողի անունը
 
Լարային
64
DHCP սերվերի անունը. Սովորաբար չի փոխանցվում

105
Boot ֆայլի անունը
 
Լարային
128
Ֆայլի անունը սերվերի վրա, որն օգտագործվում է առանց սկավառակի կայանների կողմից բեռնման ժամանակ

235
Կախարդական թխվածքաբլիթներ
63- ը, 82- ը, 53- ը, 63- ը
Hex
4
«Magic» համարը, ըստ որի, ներառյալ. Դուք կարող եք որոշել, որ այս փաթեթը պատկանում է DHCP արձանագրությանը

DHCP ընտրանքներ. Կարող է գնալ ցանկացած կարգով

236
Տարբերակի համարը
53
dec
3
Տարբերակ 53, որը սահմանում է DHCP փաթեթի տեսակը 5 - DHCPACK

 
Տարբերակի երկարությունը
1
dec
1

 
Ընտրանքի արժեքը
5
dec
1

 
Տարբերակի համարը
1
dec
1
DHCP հաճախորդին ցանցային դիմակ առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
255.255.224.0
Լարային
4

 
Տարբերակի համարը
3
dec
1
DHCP հաճախորդին լռելյայն դարպաս առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
172.16.12.1
Լարային
4

 
Տարբերակի համարը
6
dec
1
DNS հաճախորդին DHCP առաջարկելու տարբերակ

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
8.8.8.8
Լարային
4

 
Տարբերակի համարը
51
dec
1
Թողարկված ցանցի պարամետրերի ժամկետը վայրկյաններով, որից հետո DHCP հաճախորդը պետք է նորից պահանջի դրանք

 
Տարբերակի երկարությունը
4
dec
1

 
Ընտրանքի արժեքը
86400
dec
4

 
Տարբերակի համարը
82
dec
1
Տարբերակ 82, կրկնում է այն, ինչ եկել է DHCPDISCOVER-ում

 
Տարբերակի երկարությունը
18
dec
1

 
Ընտրանքի արժեքը
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
dec
18

 
Փաթեթի ավարտը
255
dec
1
255-ը խորհրդանշում է փաթեթի ավարտը

Տեղակայում

Տեղադրումն իրականում բաղկացած է աշխատանքի համար անհրաժեշտ python մոդուլների տեղադրումից։ Ենթադրվում է, որ MySQL-ն արդեն տեղադրված և կազմաձևված է։

FreeBSD- ը

pkg տեղադրել python3 python3 -m surepip pip3 տեղադրել mysql-միակցիչ

Ubuntu

sudo apt-get տեղադրել python3 sudo apt-get տեղադրել pip3 sudo pip3 տեղադրել mysql-միակցիչ

Մենք ստեղծում ենք MySQL տվյալների բազա, վերբեռնում ենք pydhcp.sql աղբանոցը և կարգավորում ենք կազմաձևման ֆայլը:

Տեսիլ

Բոլոր սերվերի կարգավորումները գտնվում են xml ֆայլում: Հղման ֆայլ՝

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 փորձարկում փորձարկում 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 ընտրեք ip, դիմակ, երթուղիչ, dns օգտվողներից, որտեղ upper(mac)=upper('{option_3_AgentRemoteId_hex}') և upper(port)=upper('{option_1_AgentCircuitId_port_hex}') ընտրեք ip, դիմակ, երթուղիչ, dns օգտվողներից, որտեղ upper(mac)=upper('{sw_mac}') և upper(port)=upper('{sw_port82}') ընտրեք ip, դիմակ, երթուղիչ, dns օգտվողներից, որտեղ upper(mac)=upper('{ClientMacAddress}') մուտքագրեք պատմության մեջ (id, dt, mac, ip, մեկնաբանություն) արժեքները (null, now(), '{ClientMacAddress}', '{RequestedIpAddress}', 'DHCPACK/INFORM')

Այժմ ավելի մանրամասն պիտակների մասին.

dhcpserver բաժինը նկարագրում է սերվերը գործարկելու հիմնական պարամետրերը, մասնավորապես.

  • հոսթ – ինչ IP հասցե է լսում սերվերը 67-րդ նավահանգստում
  • հեռարձակում - որը ip-ն է DHCPOFFER-ի և DHCPACK-ի հեռարձակումը
  • DHCPServer - որն է DHCP սերվերի ip-ն
  • Թողարկված IP հասցեի LeaseTime վարձակալության ժամկետը
  • ThreadLimit - քանի շղթա միաժամանակ աշխատում է 67-րդ նավահանգստում մուտքային UDP փաթեթները մշակելու համար: Ենթադրվում է, որ այն կօգնի մեծ ծանրաբեռնված նախագծերին 😉
  • defaultMask,defaultRouter,defaultDNS - ինչ է առաջարկվում բաժանորդին լռելյայն, եթե տվյալների բազայում գտնվի IP, բայց դրա համար լրացուցիչ պարամետրեր նշված չեն:

mysql բաժին.

հյուրընկալող, օգտվողի անուն, գաղտնաբառ, բազային անուն - ամեն ինչ ինքնին խոսում է: Տեղադրված է տվյալների բազայի մոտավոր կառուցվածքը GitHub

Հարցման բաժին. ԱՌԱՋԱՐԿ/ԱԿՏ ստանալու հարցումները նկարագրված են այստեղ.

  • offer_count - հայտերով տողերի քանակը, որոնք վերադարձնում են արդյունք, ինչպիսիք են ip, դիմակ, երթուղիչ, dns
  • offer_n — հարցման տող: Եթե ​​վերադարձը դատարկ է, ապա կատարում է հետևյալ առաջարկի հարցումը
  • history_sql - հարցում, որը գրում է, օրինակ, «լիազորման պատմությանը» բաժանորդի համար

Հարցումները կարող են ներառել ընտրանքների բաժնի ցանկացած փոփոխական կամ DHCP արձանագրության տարբերակներ:

Ընտրանքներ բաժին. Այստեղ ավելի հետաքրքիր է դառնում: Այստեղ մենք կարող ենք ստեղծել փոփոխականներ, որոնք հետագայում կարող ենք օգտագործել հարցումների բաժնում։

Օրինակ `

option_82_hex:sw_port1:20:22

, այս հրամանի տողը վերցնում է ամբողջ տողը, որը եկել է DHCP հարցման տարբերակ 82, վեցանկյուն ձևաչափով, 20-ից 22 բայթ ներառյալ և դնում է նոր փոփոխական sw_port1 (անջատիչ նավահանգիստ, որտեղից եկել է հարցումը)

option_82_hex:sw_mac:26:40

, սահմանեք sw_mac փոփոխականը՝ վերցնելով վեցանկյունը 26:40 միջակայքից

Դուք կարող եք տեսնել բոլոր հնարավոր տարբերակները, որոնք կարող են օգտագործվել հարցումներում՝ գործարկելով սերվերը -d անջատիչով: Մենք կտեսնենք այսպիսի մատյան.

-- DHCPINFORM փաթեթը ժամանեց 67 նավահանգիստ, 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress', '0025224ClientMacAddress', '764ClientMacAddress', '00ClientMacAddress', '7y' 91 5%"Jxd0d" , 'HType': 'Ethernet', 'HostName': b'x3xa5xe9xa8xa8xa43-x0.0.0.0fx5.0a', 'ReqListDNS': True, 'ReqListDomainName': True, 'ReqListPerfowmRouterDiscover': TrueRuteReqListe, Ճիշտ է, 'ReqListSubnetM հարցում': Ճիշտ է, 'ReqListVendorSpecInfo': 0025224, 'RequestedIpAddress'՝ '764', 'Vendor': b'MSFT 172.30.128.13', 'chaddr': '00ad00', '172.30.114.25': '308': , 'դրոշակներ'՝ b'x6x1', 'giaddr': '82', 'gpoz': 12, 'hlen': 12, 'hops': 53, 'htype': 'MAC', 'magic_cookie': b'cx53Sc ', 'op': 'DHCPINFORM', 'option55': 55, 'option60': 60, 'option61': 61, 'option82': 82, 'option82': 12, 'Option01': 06, ' option_00_byte': b'x04x00x01x00x06x02x08x00x06x00x1x9' b'x2x82x12010600040001000602080006001eXx589exb2xad', 'option_82_hex': '18 _82_len': 12 01, 'option_06_str': "b'x00x04x00x01x00x06x02x08x00x06x00x1x9x2x768eXx0.0.0.0exb001xad'", 'արդյունք': Սխալ, 'վրկ' 589: 'siaddr'՝ '2', 'sw_mac': '1e06eb89ad', 'sw_port8': '3', 'xidbyte': b'

Համապատասխանաբար, մենք կարող ենք ցանկացած փոփոխական փաթաթել {}-ով և այն կօգտագործվի SQL հարցումում։

Եկեք արձանագրենք պատմության համար, որ հաճախորդը ստացել է IP հասցեն.

DHCP + Mysql սերվեր Python-ում

DHCP + Mysql սերվեր Python-ում

Սերվերի գործարկում

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

— d Վահանակով ելքային ռեժիմ DEBUG
- c <filename> կազմաձևման ֆայլ

Դեբրիֆինգ

Եվ հիմա ավելի շատ մանրամասներ Python-ում սերվերի ներդրման վերաբերյալ: Դա ցավ է։ Python-ը սովորել են թռիչքի ժամանակ: Շատ պահեր ստեղծված են «վայ, ինչ-որ կերպ ես դա աշխատեցրեցի» ոճով: Ընդհանրապես օպտիմիզացված չէ և մնացել է այս ձևով հիմնականում Python-ի մշակման փոքր փորձի պատճառով: Ես կանդրադառնամ սերվերի ներդրման ամենահետաքրքիր կողմերին «կոդով»:

XML կազմաձևման ֆայլերի վերլուծիչ

Օգտագործված է ստանդարտ Python մոդուլը xml.dom: Թվում է, թե պարզ է, բայց իրականացման ընթացքում այս մոդուլն օգտագործող ցանցում նկատելի էր հստակ փաստաթղթերի և օրինակների պակաս:

    ծառ = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") elem-ի համար mconfig. gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].data gconfig["mysql_username"]=elem.getElementsByTagName("username")[0].firstChild.data gconfig["mysql_password"]=elem.getElementsByTagName("password")[0].firstqlconfige"my =elem.getElementsByTagName("basename")[0].firstChild.data dconfig=tree.getElementsByTagName("dhcpserver") dconfig-ում էլեմի համար. gconfig["broadcast"]=elem.getElementsByTagName. firstChild.data gconfig["dhcp_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["dhcp_LeaseTime"]=elem.getElementsByTagName("LeaseTime")[0]config[g. dhcp_ThreadLimit"]=int(elem.getElementsByTagName("ThreadLimit")[0].firstChild.data) gconfig["dhcp_Server"]=elem.getElementsByTagName("DHCPServer")[0]configd]. =elem.getElementsByTagName("defaultMask")[0].firstChild.data gconfig["dhcp_defaultRouter"]=elem.getElementsByTagName("defaultRouter")[0].firstChild.data gconfig[seult.NSagt"deult. « defaultDNS")[0].firstChild.data qconfig=tree.getElementsByTagName("query") elem-ի համար qconfig-ում. gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.տվյալներ num-ի համար միջակայք(int(gconfig["offer_count"]): gconfig["offer_"+str(num+0)]=elem.getElementsByTagName("offer_"+str(num+1))[1].firstChild.data gconfig ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("options") էլեմի համար տարբերակներում. node=elem.getElementsByTagName") տարբերակների համար" : optionsMod.append(options.firstChild.data)

Multithreading

Բավական տարօրինակ է, բայց Python-ում բազմաթելերն իրականացվում է շատ պարզ և պարզ:

def PacketWork(data,addr): ... # մուտքային փաթեթի վերլուծության և դրան պատասխանելու իրականացում ... մինչդեռ True՝ data, addr = udp_socket.recvfrom(1024) # սպասում է UDP փաթեթի շարանը = threading.Thread( target=PacketWork , args=(data,addr,)).start() # ինչպես եղավ - մենք գործարկում ենք նախկինում սահմանված PacketWork ֆունկցիան ետին պլանում՝ threading.active_count() >gconfig["dhcp_ThreadLimit"]՝ ժամանակը: sleep(1) # եթե համարը Արդեն ավելի շատ թելեր կան, քան կարգավորումներում, մենք սպասում ենք, մինչև դրանք ավելի քիչ լինեն

Ստացեք/ուղարկեք DHCP փաթեթ

Ցանցային քարտով եկող UDP փաթեթները ընդհատելու համար հարկավոր է «բարձրացնել» վարդակը.

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

, որտեղ դրոշներն են.

  • AF_INET - նշանակում է, որ հասցեի ձևաչափը կլինի IP՝ պորտ: Կարող է լինել նաև AF_UNIX - որտեղ հասցեն տրվում է ֆայլի անունով:
  • SOCK_DGRAM - նշանակում է, որ մենք չենք ընդունում «հում փաթեթ», այլ այն, որն արդեն անցել է firewall-ով և մասամբ կտրված փաթեթով: Նրանք. մենք ստանում ենք միայն UDP փաթեթ՝ առանց UDP փաթեթի փաթեթավորման «ֆիզիկական» բաղադրիչի: Եթե ​​դուք օգտագործում եք SOCK_RAW դրոշը, ապա ձեզ նույնպես պետք է վերլուծել այս «փաթաթան»:

Փաթեթ ուղարկելը կարող է նմանվել հեռարձակման.

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #switch the socket to հեռարձակման ռեժիմ rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, և «որտեղից է փաթեթը եկել» հասցեին՝

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # միացրեք վարդակը բազմակի լսողների ռեժիմի rz=udp_socket.sendto(packetack, addr)

, որտեղ SOL_SOCKET նշանակում է «արձանագրության մակարդակ» ընտրանքների կարգավորման համար,

, SO_BROADCAST տարբերակ, որ սաղավարտի փաթեթը «հեռարձակվում է»

  SO_REUSEADDR տարբերակը միացնում է վարդակից «շատ լսողներ» ռեժիմի: Տեսականորեն, այս դեպքում դա ավելորդ է, բայց FreeBSD սերվերներից մեկում, որի վրա ես փորձարկել եմ, կոդը առանց այս տարբերակի չէր աշխատում։

DHCP փաթեթի վերլուծություն

Այստեղ ինձ շատ դուր եկավ Python-ը: Պարզվում է, որ արկղից դուրս այն թույլ է տալիս բավականին ճկուն լինել բայթկոդով։ Թույլ տալով, որ այն շատ հեշտությամբ թարգմանվի տասնորդական արժեքների, տողերի և վեցանկյունի, այսինքն. սա այն է, ինչ մենք իրականում պետք է հասկանանք փաթեթի կառուցվածքը: Այսպիսով, օրինակ, դուք կարող եք ստանալ մի շարք բայթեր HEX-ով և ընդամենը բայթերով.

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

, փաթեթավորեք բայթերը կառուցվածքի մեջ.

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

Ստացեք IP կառուցվածքից.

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

Եվ հակառակը.

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

Առայժմ այսքանը 😉

Source: www.habr.com

Добавить комментарий