خادم DHCP + Mysql في بيثون



الغرض من هذا المشروع هو:

  • تعلم DHCP عبر شبكة IPv4
  • تعلم بايثون (أكثر بقليل من الصفر ؛))
  • استبدال خادم DB2DHCP (شوكة بلدي) الأصلي هنا ، والذي يصعب تجميعه تحت نظام التشغيل الجديد. نعم ، وأنا لا أحب ذلك الثنائي ، وهو غير ممكن "التغيير في الوقت الحالي"
  • الحصول على خادم DHCP يعمل مع القدرة على تحديد عنوان IP الخاص بالمشترك عن طريق المشترك mac أو عن طريق مجموعة من مفاتيح mac + port (الخيار 82)
  • كتابة دراجة أخرى (أوه! هذا هو هوايتي المفضلة)
  • الحصول على luli حول الحول الخاص بك على Habrahabr (أو دعوة أفضل) ؛)

النتيجة: إنه يعمل ؛) تم اختباره على FreeBSD و Ubuntu OS. من الناحية النظرية ، يمكن طلب الرمز للعمل تحت أي نظام تشغيل ، لأنه لا توجد روابط محددة في الكود.
الحذر! أبعد من ذلك بكثير.

رابط إلى مستودع للجماهير "للمس على قيد الحياة" .

عملية تثبيت وتكوين واستخدام نتيجة "دراسة الأجهزة" أقل بكثير ، ومن ثم نظرية قليلة على بروتوكول DHCP. لنفسي وللقصة ؛)

قليلا من الناحية النظرية


ما هو DHCP؟


هذا هو بروتوكول شبكة يسمح للجهاز باكتشاف عنوان IP الخاص به (جيدًا ، معلمات أخرى مثل البوابة ، DNS ، إلخ) من خادم DHCP. يتم تبادل الحزم عبر UDP. المبدأ العام لتشغيل الجهاز عند طلب معلمات الشبكة هو كما يلي:

  1. يرسل الجهاز (العميل) طلب بث UDP (DHCPDISCOVER) عبر الشبكة مع الطلب ، "حسنًا ، شخص ما ، أعطني عنوان IP." عادةً (ولكن ليس دائمًا) يكون الطلب من المنفذ 68 (المصدر) ، والوجهة هي المنفذ 67 (الوجهة). تقوم بعض الأجهزة أيضًا بإرسال حزم من المنفذ 67. داخل حزمة DHCPDISCOVER ، يتم تضمين عنوان MAC لجهاز العميل.
  2. جميع خوادم DHCP الموجودة على الشبكة (وقد يكون هناك عدة) نموذج للجهاز الذي أرسل DHCPDISCOVER جملة DHCPOFFER مع إعدادات الشبكة ، كما يبثها عبر الشبكة. ينتقل تحديد هوية هذه الحزمة إلى عنوان MAC للعميل المقدم مسبقًا في طلب DHCPDISCOVER.
  3. يتلقى العميل الحزم مع عروض إعدادات الشبكة ، ويختار الأكثر جاذبية (يمكن أن تكون المعايير مختلفة ، على سبيل المثال ، بحلول وقت تسليم الحزمة ، وعدد الطرق الوسيطة) ، ويجعل خادم DHCP "يطلب رسميًا" DHCPREQUEST مع إعدادات الشبكة. في هذه الحالة ، تنتقل الحزمة إلى خادم DHCP معين.
  4. يرسل الخادم الذي تلقى DHCPREQUEST حزمة DHCPACK يسرد فيها مرة أخرى إعدادات الشبكة لهذا العميل



بالإضافة إلى ذلك ، هناك حزم DHCPINFORM تأتي من العميل ، والغرض منها هو إبلاغ خادم DHCP بأن "العميل على قيد الحياة" ويستخدم إعدادات الشبكة الصادرة. في تنفيذ هذا الخادم ، يتم تجاهل هذه الحزم.

تنسيق الحزمة



بشكل عام ، يبدو إطار حزم Ethernet كما يلي:



في حالتنا ، سننظر فقط في البيانات مباشرةً من محتويات حزمة UDP ، دون رؤوس بروتوكول طبقة OSI ، وهي بنية DHCP:

DHCPDISCOVER


لذلك ، تبدأ عملية الحصول على عنوان IP للجهاز بحقيقة أن عميل DHCP يرسل طلب بث من المنفذ 68 إلى 255.255.255.255:67. في هذه الحزمة ، يتضمن العميل عنوان MAC الخاص به ، وكذلك ما يريد تلقيه من خادم DHCP. ويرد وصف هيكل الحزمة في الجدول أدناه.

جدول بنية حزم DHCPDISCOVER
موقف حزمةاسم القيمةمثالفكرةبايتتوضيح
1طلب التمهيد1عرافة1نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل
2نوع الجهاز1عرافة1نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC
3طول adrees الأجهزة6عرافة1طول عنوان MAC للجهاز
4القفزات1عرافة1عدد الطرق الوسيطة
5معرف المعاملة23: راجع: de: 1dعرافة4معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب
7الثاني المنقضي0عرافة4الوقت بالثواني منذ بداية عملية الحصول على العنوان
9أعلام Bootp0عرافة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عرافة6عنوان MAC لمُرسِل الحزمة (العميل)
31حشوة عنوان جهاز العميلعرافة10مكان محجوز. عادة أصفار
41اسم مضيف الخادمصف64اسم خادم DHCP. عادة لا تنتقل
105اسم ملف التمهيدصف128اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد
235ملف تعريف الارتباط السحري63: 82: 53: 63عرافة4الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP
خيارات DHCP. يمكن أن تذهب في أي ترتيب
236رقم الخيار53ديسمبر1الخيار 53 الذي يحدد نوع حزمة DHCP

1 - DHCPDISCOVER
3 - DHCPREQUEST
2 - DHCPOFFER
5 - DHCPACK
8 - DHCPINFORM
طول الخيار1ديسمبر1
قيمة الخيار1ديسمبر1
رقم الخيار50ديسمبر1ما عنوان IP الذي يريد العميل استلامه؟
طول الخيار4ديسمبر1
قيمة الخيار172.16.134.61صف4
رقم الخيار551معلمات الشبكة المطلوبة من قبل العميل. التكوين قد يكون مختلفا

01 - قناع الشبكة
03 - بوابة
06 - DNS
اسم المضيف
0f - اسم مجال الشبكة
1C - عنوان طلب البث (البث)
42 - اسم خادم TFTP
79 - طريق ثابت بدون طبقات
طول الخيار81
قيمة الخيار01: 03: 06: 0c: 0f: 1c: 42: 798
رقم الخيار82ديسمبرالخيار 82 ، الذي يتم فيه إرسال عنوان MAC لجهاز التكرار وبعض القيم الإضافية.

غالبًا ما يكون منفذ التبديل الذي يعمل عليه عميل نهاية DHCP ، حيث يتم "تضمين" الخيارات الإضافية في هذا الخيار ، البايتة الأولى هي رقم "suboption" ، والثاني هو طوله ، ثم قيمته.

في هذه الحالة ، في الخيار 82 ، يتم تداخل الخيارات الفرعية:
معرف حلبة الوكيل = 00: 04: 00: 01: 00: 04 ، حيث آخر وحدتي بايت هما منفذ عميل DHCP الذي جاء منه الطلب

معرف العميل عن بُعد = 00: 06: c8: be: 19: 93: 11: 48 - عنوان MAC لجهاز ترحيل DHCP
طول الخيار18ديسمبر
قيمة الخيار01:06
00: 04: 00: 01: 00: 04
02:08
00: 06: c8: be: 19: 93: 11: 48
عرافة
نهاية الحزمة255ديسمبر1255 يرمز إلى نهاية الحزمة


DHCPOFFER


بمجرد أن يتلقى الخادم حزمة DHCPDISCOVER وإذا رأى أنه يمكن أن يقدم للعميل شيئًا من المطلوب ، فإنه يشكل استجابة لذلك - DHCPOFFER. يتم إرسال الجواب إلى المنفذ "من أين جاء" ، البث ، لأنه في هذه اللحظة ، ليس لدى العميل بعد عنوان IP ، لذلك ، لا يمكنه تلقي حزمة إلا إذا تم إرساله بالبث. يدرك العميل أنها عبارة عن حزمة له من قِبل لجنة الهدنة العسكرية على عنوانه داخل الحزمة ، وكذلك رقم المعاملة الذي ينشئه في وقت إنشاء الحزمة الأولى.

جدول هيكل الحزمة DHCPOFFER
موقف حزمةاسم القيمة (مشترك)مثالفكرةبايتتوضيح
1طلب التمهيد1عرافة1نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل
2نوع الجهاز1عرافة1نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC
3طول adrees الأجهزة6عرافة1طول عنوان MAC للجهاز
4القفزات1عرافة1عدد الطرق الوسيطة
5معرف المعاملة23: راجع: de: 1dعرافة4معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب
7الثاني المنقضي0عرافة4الوقت بالثواني منذ بداية عملية الحصول على العنوان
9أعلام Bootp0عرافة2بعض العلامات التي يمكن تعيينها كدليل على معلمات البروتوكول. في هذه الحالة ، يعني 0 نوع طلب البث الأحادي
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عرافة6عنوان MAC لمُرسِل الحزمة (العميل)
31حشوة عنوان جهاز العميلعرافة10مكان محجوز. عادة أصفار
41اسم مضيف الخادمصف64اسم خادم DHCP. عادة لا تنتقل
105اسم ملف التمهيدصف128اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد
235ملف تعريف الارتباط السحري63: 82: 53: 63عرافة4الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP
خيارات DHCP. يمكن أن تذهب في أي ترتيب
236رقم الخيار53ديسمبر1الخيار 53 الذي يحدد نوع حزمة DHCP 2 - DHCPOFFER
طول الخيار1ديسمبر1
قيمة الخيار2ديسمبر1
رقم الخيار1ديسمبر1خيار تقديم قناع شبكة عميل DHCP
طول الخيار4ديسمبر1
قيمة الخيار255.255.224.0صف4
رقم الخيار3ديسمبر1خيار تقديم العبارة الافتراضية عميل DHCP
طول الخيار4ديسمبر1
قيمة الخيار172.16.12.1صف4
رقم الخيار6ديسمبر1خيار تقديم DHCP إلى عميل DNS
طول الخيار4ديسمبر1
قيمة الخيار8.8.8.8صف4
رقم الخيار51ديسمبر1عمر معلمات الشبكة الصادرة بالثواني ، وبعد ذلك يجب على عميل DHCP طلبها مرة أخرى
طول الخيار4ديسمبر1
قيمة الخيار86400ديسمبر4
رقم الخيار82ديسمبر1الخيار 82 ، يكرر ما جاء في DHCPDISCOVER
طول الخيار18ديسمبر1
قيمة الخيار01: 08: 00: 06: 00
01: 01: 00: 00: 01
02: 06: 00: 03: 0f
26: 4 أيام: ec
ديسمبر18
نهاية الحزمة255ديسمبر1255 يرمز إلى نهاية الحزمة


DHCPREQUEST


بعد أن يتلقى العميل DHCPOFFER ، فإنه يشكل حزمة مع طلب لمعلمات الشبكة ليس لجميع خوادم DHCP في الشبكة ، ولكن فقط لخادم واحد محدد ، والذي اقترحه DHCPOFFER أكثر. يمكن أن تكون معايير "أعجبني" مختلفة وتعتمد على تنفيذ عميل DHCP. تتم الإشارة إلى مستلم الطلب باستخدام عنوان MAC لخادم DHCP. أيضًا ، يمكن إرسال حزمة DHCPREQUEST من قبل العميل دون تكوين DHCPDISCOVER مسبقًا ، إذا كان قد تم استلام عنوان IP الخاص بالخادم مسبقًا مسبقًا.

DHCPREQUEST جدول بنية الحزمة
موقف حزمةاسم القيمة (مشترك)مثالفكرةبايتتوضيح
1طلب التمهيد1عرافة1نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل
2نوع الجهاز1عرافة1نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC
3طول adrees الأجهزة6عرافة1طول عنوان MAC للجهاز
4القفزات1عرافة1عدد الطرق الوسيطة
5معرف المعاملة23: راجع: de: 1dعرافة4معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب
7الثاني المنقضي0عرافة4الوقت بالثواني منذ بداية عملية الحصول على العنوان
9أعلام Bootp8000عرافة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عرافة6عنوان MAC لمُرسِل الحزمة (العميل)
31حشوة عنوان جهاز العميلعرافة10مكان محجوز. عادة أصفار
41اسم مضيف الخادمصف64اسم خادم DHCP. عادة لا تنتقل
105اسم ملف التمهيدصف128اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد
235ملف تعريف الارتباط السحري63: 82: 53: 63عرافة4الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP
خيارات DHCP. يمكن أن تذهب في أي ترتيب
236رقم الخيار53ديسمبر3الخيار 53 الذي يحدد نوع حزمة DHCP 3 - DHCPREQUEST
طول الخيار1ديسمبر1
قيمة الخيار3ديسمبر1
رقم الخيار61ديسمبر1معرف العميل: 01 (لإيثرنت) + عنوان MAC للعميل
طول الخيار7ديسمبر1
قيمة الخيار01: 2c: ab: 25: ff: 72: a6عرافة7
رقم الخيار60ديسمبر"معرف فئة البائع." في حالتي ، يتم الإبلاغ عن إصدار عميل DHCP. ربما تقوم الأجهزة الأخرى بإرجاع شيء آخر. تقارير Windows على سبيل المثال MSFT 5.0
طول الخيار11ديسمبر
قيمة الخيارudhcp 0.9.8صف
رقم الخيار551معلمات الشبكة المطلوبة من قبل العميل. التكوين قد يكون مختلفا

01 - قناع الشبكة
03 - بوابة
06 - DNS
اسم المضيف
0f - اسم مجال الشبكة
1C - عنوان طلب البث (البث)
42 - اسم خادم TFTP
79 - طريق ثابت بدون طبقات
طول الخيار81
قيمة الخيار01: 03: 06: 0c: 0f: 1c: 42: 798
رقم الخيار82ديسمبر1الخيار 82 ، يكرر ما جاء في DHCPDISCOVER
طول الخيار18ديسمبر1
قيمة الخيار01: 08: 00: 06: 00
01: 01: 00: 00: 01
02: 06: 00: 03: 0f
26: 4 أيام: ec
ديسمبر18
نهاية الحزمة255ديسمبر1255 يرمز إلى نهاية الحزمة


DHCPACK


كتأكيد لحقيقة "نعم ، إنه عنوان IP الخاص بك ، ولن أعطيها لأي شخص آخر" من خادم DHCP ، هناك حزمة DHCPACK من الخادم إلى العميل. هو نفس بقية الحزم المرسلة للبث. على الرغم من أنه في التعليمة البرمجية أدناه الخاصة بخادم DHCP الذي تم تنفيذه في بيثون ، في الحال ، أنا أكرر أي طلب بث عن طريق إرسال حزمة إلى عنوان IP لعميل معين ، إذا كان معروفًا بالفعل. علاوة على ذلك ، لا يهم خادم DHCP على الإطلاق ما إذا كانت الحزمة DHCPACK قد وصلت إلى العميل. إذا لم يتلق العميل DHCPACK ، فحينئذٍ يكرر DHCPREQUEST

جدول هيكل حزم DHCPACK
موقف حزمةاسم القيمة (مشترك)مثالفكرةبايتتوضيح
1طلب التمهيد2عرافة1نوع الرسالة. 1 - طلب من عميل إلى خادم ، 2 - استجابة من خادم إلى عميل
2نوع الجهاز1عرافة1نوع عنوان الجهاز ، في هذا البروتوكول 1 - MAC
3طول adrees الأجهزة6عرافة1طول عنوان MAC للجهاز
4القفزات1عرافة1عدد الطرق الوسيطة
5معرف المعاملة23: راجع: de: 1dعرافة4معرف المعاملات الفريدة. تم إنشاؤها بواسطة العميل في بداية عملية الطلب
7الثاني المنقضي0عرافة4الوقت بالثواني منذ بداية عملية الحصول على العنوان
9أعلام Bootp8000عرافة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عرافة6عنوان MAC لمُرسِل الحزمة (العميل)
31حشوة عنوان جهاز العميلعرافة10مكان محجوز. عادة أصفار
41اسم مضيف الخادمصف64اسم خادم DHCP. عادة لا تنتقل
105اسم ملف التمهيدصف128اسم الملف على الخادم الذي تستخدمه المحطات الخالية من الأقراص أثناء التمهيد
235ملف تعريف الارتباط السحري63: 82: 53: 63عرافة4الرقم "السحري" الذي به يمكنك تحديد أن هذه الحزمة تنتمي إلى بروتوكول DHCP
خيارات DHCP. يمكن أن تذهب في أي ترتيب
236رقم الخيار53ديسمبر3الخيار 53 الذي يحدد نوع حزمة DHCP - DHCPACK
طول الخيار1ديسمبر1
قيمة الخيار5ديسمبر1
رقم الخيار1ديسمبر1خيار تقديم قناع شبكة عميل DHCP
طول الخيار4ديسمبر1
قيمة الخيار255.255.224.0صف4
رقم الخيار3ديسمبر1خيار تقديم العبارة الافتراضية عميل DHCP
طول الخيار4ديسمبر1
قيمة الخيار172.16.12.1صف4
رقم الخيار6ديسمبر1خيار تقديم DHCP إلى عميل DNS
طول الخيار4ديسمبر1
قيمة الخيار8.8.8.8صف4
رقم الخيار51ديسمبر1عمر معلمات الشبكة الصادرة بالثواني ، وبعد ذلك يجب على عميل DHCP طلبها مرة أخرى
طول الخيار4ديسمبر1
قيمة الخيار86400ديسمبر4
رقم الخيار82ديسمبر1الخيار 82 ، يكرر ما جاء في DHCPDISCOVER
طول الخيار18ديسمبر1
قيمة الخيار01: 08: 00: 06: 00
01: 01: 00: 00: 01
02: 06: 00: 03: 0f
26: 4 أيام: ec
ديسمبر18
نهاية الحزمة255ديسمبر1255 يرمز إلى نهاية الحزمة



تركيب


يتكون التثبيت بالفعل من تثبيت وحدات بيثون اللازمة لهذه المهمة. من المفترض أن MySQL قد تم تثبيته وتهيئته بالفعل.

فري


  pkg تثبيت python3
 python3 - م Enspip
 pip3 تثبيت mysql الموصل 

أوبونتو


  سودو الرابطة بين الحصول على تثبيت python3
 sudo الحصول على تثبيت pip3
 sudo pip3 تثبيت mysql الموصل 

نقوم بإنشاء قاعدة بيانات MySQL ، وملء ملف التفريغ pydhcp.sql ، تكوين ملف التكوين.

ترتيب


جميع إعدادات الخادم في تنسيق ملف XML. الملف المرجعي:

  <؟ xml version = "1.0"؟>
 <التكوين>
     <Dhcpserver>
	 <host> 0.0.0.0 </host>
         <broadcast> 255.255.255.255 </broadcast>
         <DHCPServer> 192.168.0.71 </DHCPServer>
	 <LeaseTime> 8600 </LeaseTime>
	 <ThreadLimit> 1 </ThreadLimit>
         <defaultMask> 255.255.255.0 </defaultMask>
         <defaultRouter> 192.168.0.1 </defaultRouter>
         <defaultDNS> 8.8.8.8 </defaultDNS>
     </ Dhcpserver>
     <ماي>
         <host> المضيف المحلي </ المضيف>
	 <username> test </username>
	 <password> test </password>
	 <اسم الملف> pydhcp </basename>
     </ ماي>
     <خيارات>
        <option> option_82_hex: sw_port1: 20:22 </option>       
        <option> option_82_hex: sw_port2: 16:18 </option>       
        <option> option_82_hex: sw_mac: 26: 40 </option>
     </ خيارات>    
     <سؤال>
         <offer_count> 3 </offer_count>
	 <offer_1> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث upper (mac) = upper ('{option_82_AgentRemoteId_hex}') و upper (port) = upper ('{option_82_AgentCircuitId_port_hex}') </offer_1>
         <offer_2> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث العلوي (mac) = العلوي ('{sw_mac}') والأعلى (منفذ) = العلوي ('{sw_port2}') </offer_2>
         <offer_3> حدد ip ، وقناع ، وجهاز التوجيه ، ونظام أسماء النطاقات من المستخدمين حيث upper (mac) = upper ('{ClientMacAddress}') </offer_3>
	 <history_sql> تضاف إلى قيم التاريخ (id ، dt ، mac ، ip ، comment) (خالية ، now () ، '{ClientMacAddress}' ، '{RequestedIpAddress}' ، 'DHCPACK / INFORM') </history_sql>
     </ استعلام>
 </ التكوين> 

الآن بمزيد من التفاصيل على العلامات:

يصف قسم dhcpserver الإعدادات الأساسية لبدء تشغيل الخادم ، وهي:
  • مضيف - عنوان IP الذي يستمع إليه الخادم على المنفذ 67
  • البث - الذي هو البث IP ل DHCPOFFER و DHCPACK
  • DHCPServer - ما هو الملكية الفكرية لخادم DHCP
  • LeaseTime وقت تأجير عنوان IP الصادر
  • ThreadLimit - كم عدد مؤشرات الترابط التي يتم تشغيلها في وقت واحد لمعالجة حزم UDP الواردة على المنفذ 67. من المفترض أن يساعد ذلك في المشروعات المحملة بدرجة عالية ؛)
  • defaultMask ، defaultRouter ، defaultDNS - ما يتم تقديمه للمشترك بشكل افتراضي إذا تم العثور على IP في قاعدة البيانات ، ولكن لم يتم تحديد معلمات إضافية له

ميسكل القسم:

المضيف ، اسم المستخدم ، كلمة المرور ، اسم الملف - كل شيء يتحدث عن نفسه. نموذج بنية قاعدة البيانات المنشورة على جيثب

قسم الاستعلامات: يصف هذا القسم طلبات العرض / ACK:

  • offer_count - عدد الأسطر مع الطلبات التي تُرجع نتيجة النموذج ip ، قناع ، جهاز التوجيه ، نظام أسماء النطاقات
  • 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 '\ x91 \ xa5 \ xe0 \ xa3 \ xa5 \ xa9- \ x8f \ x8a' ، ("172.30.114.25" ، 68)
 {'ClientMacAddress': '0025224ad764' ،
  'ClientMacAddressByte': b '\ x00٪ "J \ xd7d' ،
  "HType": "Ethernet" ،
  'HostName': b '\ x91 \ xa5 \ xe0 \ xa3 \ xa5 \ xa9- \ x8f \ x8a' ،
  "ReqListDNS": صحيح ،
  'ReqListDomainName': صحيح ،
  'ReqListPerfowmRouterDiscover': صحيح ،
  'ReqListRouter': صحيح ،
  'ReqListStaticRoute': صحيح ،
  'ReqListSubnetMask': صحيح ،
  'ReqListVendorSpecInfo': 43 ،
  'RequestedIpAddress': '0.0.0.0' ،
  "البائع": b'MSFT 5.0 '،
  'chaddr': '0025224ad764' ،
  "السدر": "172.30.128.13" ،
  "الأعلام": b '\ x00 \ x00' ،
  'giaddr': '172.30.114.25' ،
  "gpoz": 308 ،
  "hlen": 6 ،
  "القفزات": 1 ،
  'htype': 'MAC' ،
  'magic_cookie': b'c \ x82Sc '،
  "المرجع": "DHCPINFORM" ،
  "الخيار 12": 12 ،
  "الخيار 53": 53 ،
  الخيار 55: 55
  "الخيار 60": 60 ،
  "الخيار 61": 61 ،
  "الخيار 82": 82 ،
  'option_82_byte': b '\ x12 \ x01 \ x06 \ x00 \ x04 \ x00 \ x01 \ x00 \ x06 \ x02 \ x08 \ x00'
                    b '\ x06 \ x00 \ x1eX \ x9e \ xb2 \ xad' ،
  'option_82_hex': '12010600040001000602080006001e589eb2ad' ،
  'option_82_len': 18 ،
  'option_82_str': "b '\\ x12 \\ x01 \\ x06 \\ x00 \\ x04 \\ x00 \\ x01 \\ x00 \\ x06 \\ x02 \\ x08 \\ x08 \\ x00 \\ x06 \\ x00 \ \ x1eX \\ x9e \\ xb2 \\ xad '"،
  'النتيجة': خطأ ،
  ثوانى: 768
  'siaddr': '0.0.0.0' ،
  'sw_mac': '001e589eb2ad' ،
  'sw_port1': '06' ،
  'xidbyte': b '<\ x89} \ x8c' ،
  'xidhex': '3c897d8c' ،
  'yiaddr': '0.0.0.0'} 

وفقًا لذلك ، يمكننا التفاف أي متغير في {} وسيتم استخدامه في استعلام SQL.

دعنا نتعرف على السجل الذي تلقى فيه العميل عنوان IP:





بداية الخادم


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

- وضع الإخراج د إلى وحدة التحكم DEBUG
- ملف التكوين <file_name>

إستخلاص المعلومات


والآن أكثر على تنفيذ الخادم في بيثون. هذا ألم. بيثون درس على الطاير. تم صنع العديد من اللحظات بأسلوب: "واو ، لقد فعلت ما يعمل بطريقة ما." ليس الأمثل على الإطلاق ، ويترك في هذا النموذج ويرجع ذلك أساسا إلى الخبرة الصغيرة للتنمية في الثعبان. سوف أتحدث عن أكثر اللحظات إثارة للاهتمام في تنفيذ الخادم في "الكود".

محلل ملف تكوين XML


يتم استخدام وحدة Python القياسية xml.dom. يبدو الأمر بسيطًا ، لكن أثناء التنفيذ كان هناك نقص ملحوظ في الوثائق والأمثلة المعقولة على الشبكة باستخدام هذه الوحدة.

  tree = minidom.parse (gconfig ["config_file"])
     mconfig = tree.getElementsByTagName ("mysql")
     لـ elem في mconfig:        
         gconfig ["mysql_host"] = elem.getElementsByTagName ("host") [0] .firstChild.data      
         gconfig ["mysql_username"] = elem.getElementsByTagName ("اسم المستخدم") [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")
     ل elem في 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_defaultMask"] = elem.getElementsByTagName ("defaultMask") [0] .firstChild.data              
         gconfig ["dhcp_defaultRouter"] = elem.getElementsByTagName ("defaultRouter") [0] .firstChild.data              
         gconfig ["dhcp_defaultDNS"] = elem.getElementsByTagName ("defaultDNS") [0] .firstChild.data              
     qconfig = tree.getElementsByTagName ("استعلام")
     عن العلم في qconfig:  
         gconfig ["offer_count"] = elem.getElementsByTagName ("offer_count") [0] .firstChild.data                          
         بالنسبة إلى 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                          
     خيارات = tree.getElementsByTagName ("خيارات")       
     للعنصر في الخيارات:          
         عقدة = elem.getElementsByTagName ("الخيار")
         للحصول على خيارات في العقدة:
             optionsMod.append (options.firstChild.data) 

خاصية تعدد


الغريب ، أن تعدد مؤشرات الترابط في بيثون يتم تنفيذه بوضوح شديد وبساطة.

  def PacketWork (البيانات ، addr): 
 ...
 # تنفيذ تحليل الحزمة المستلمة ، والإجابة عليها
 ...


 بينما صحيح:
     البيانات ، addr = udp_socket.recvfrom (1024) # انتظر حزمة UDP
     thread = threading.Thread (target = PacketWork، args = (data، addr،)). start () # كما جاء - قم بتشغيل الدالة PacketWork المحددة مسبقًا في الخلفية مع المعلمات
     أثناء threading.active_count ()> gconfig ["dhcp_ThreadLimit"]:
        time.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: port. ربما AF_UNIX - حيث يتم إعطاء العنوان بواسطة اسم الملف.
  • SOCK_DGRAM - يعني أننا لا نقبل "حزمة خام" ، ولكننا مررنا بالفعل من خلال جدار الحماية ، ومع الحزمة المقطوعة جزئيًا. أي نحصل على حزمة UDP فقط دون المكون "الفعلي" لبرنامج تغليف حزم UDP. إذا كنت تستخدم علامة SOCK_RAW ، فستظل بحاجة إلى تحليل هذه "المجموعة" أيضًا.

يمكن أن يكون إرسال الحزمة مثل البث:

  udp_socket.setsockopt (socket.SOL_SOCKET ، socket.SO_BROADCAST ، 1) # التبديل المقبس إلى وضع البث
                     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


هنا أحببت بيثون حقًا. اتضح من "المربع" أنه يسمح لك بسهولة التعامل مع الرمز البريدي. السماح بالبساطة في الترجمة إلى القيم العشرية والسلاسل والسداسية - أي ما نحتاج إليه فعلا لفهم بنية الحزمة. على سبيل المثال ، يمكنك الحصول على مجموعة من البايتات في HEX والبايتات فقط:

  الدقة ["xidhex"] = البيانات [4: 8] .hex ()
     الدقة ["xidbyte"] = البيانات [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: https://habr.com/ru/post/ar445338/


All Articles