Python'da DHCP+Mysql sunucusu

Python'da DHCP+Mysql sunucusu

Bu projenin amacı şuydu:

  • IPv4 ağında DHCP'yi öğrenme
  • Python'u öğrenmek (sıfırdan biraz daha fazlası 😉)
  • sunucu değişimi DB2DHCP (çatalım), orijinal burada, yeni işletim sistemi için bir araya getirilmesi giderek daha zor hale geliyor. Ve bunun "şu anda değiştirmenin" hiçbir yolu olmayan bir ikili sistem olmasından hoşlanmıyorum
  • abonenin mac'unu veya anahtar mac+port kombinasyonunu kullanarak abonenin IP adresini seçme yeteneğine sahip, çalışan bir DHCP sunucusu elde etmek (Seçenek 82)
  • başka bir bisiklet yazmak (Ah! bu benim en sevdiğim aktivite)
  • Habrahabr'da sopalı tavrınız hakkında yorumlar alıyorum (ya da daha iyisi bir davet) 😉

Sonuç: çalışıyor 😉 FreeBSD ve Ubuntu işletim sistemi üzerinde test edilmiştir. Teorik olarak kodun herhangi bir işletim sistemi altında çalışması istenebilir çünkü Kodda belirli bir bağlama yok gibi görünüyor.
Dikkatlice! Daha gelecek çok şey var.

Amatörler için depoya bağlantı "canlıya dokunmak".

"Donanımı incelemenin" sonucunu kurma, yapılandırma ve kullanma süreci çok daha düşüktür ve ardından DHCP protokolü hakkında küçük bir teori. Kendim için. Ve tarih adına 😉

Küçük bir teori

DHCP nedir

Bu, bir cihazın IP adresini (ve ağ geçidi, DNS vb. gibi diğer parametreleri) bir DHCP sunucusundan bulmasına olanak tanıyan bir ağ protokolüdür. Paketler UDP protokolü kullanılarak değiştirilir. Ağ parametreleri istenirken cihazın genel çalışma prensibi aşağıdaki gibidir:

  1. Cihaz (istemci), ağ üzerinden "biri bana bir IP adresi versin" isteğiyle bir UDP yayın isteği (DHCPDISCOVER) gönderir. Ayrıca, genellikle (ancak her zaman değil) istek 68 numaralı bağlantı noktasından (kaynak) gelir ve hedef, 67 numaralı bağlantı noktasıdır (hedef). Bazı cihazlar ayrıca 67 numaralı bağlantı noktasından da paket gönderir. İstemci aygıtının MAC adresi DHCPDISCOVER paketinin içinde bulunur.
  2. Ağda bulunan tüm DHCP sunucuları (ve birkaç tane olabilir), DHCPDISCOVER'ı gönderen cihaz için ağ ayarlarıyla birlikte bir DHCPOFFER teklifi oluşturur ve bunu ağ üzerinden de yayınlar. Bu paketin kime yönelik olduğunun belirlenmesi, DHCPDISCOVER isteğinde daha önce sağlanan istemcinin MAC adresine dayanmaktadır.
  3. İstemci, ağ ayarları önerileri içeren paketleri kabul eder, en çekici olanı seçer (kriterler farklı olabilir, örneğin paket teslim süresi, ara yol sayısı) ve ağ ayarlarıyla birlikte "resmi bir istek" DHCPREQUEST yapar beğendiği DHCP sunucusundan. Bu durumda paket belirli bir DHCP sunucusuna gider.
  4. DHCPREQUEST'i alan sunucu, bu istemciye yönelik ağ ayarlarını bir kez daha listeleyen DHCPACK biçiminde bir paket gönderir.

Python'da DHCP+Mysql sunucusu

Ayrıca istemciden gelen DHCPINFORM paketleri de vardır ve amacı DHCP sunucusuna "istemcinin hayatta olduğunu" ve verilen ağ ayarlarını kullandığını bildirmektir. Bu sunucunun uygulamasında bu paketler göz ardı edilir.

Paket formatı

Genel olarak bir Ethernet paket çerçevesi şuna benzer:

Python'da DHCP+Mysql sunucusu

Bizim durumumuzda, OSI katmanı protokol başlıkları, yani DHCP yapısı olmadan, yalnızca doğrudan UDP paketinin içeriğindeki verileri ele alacağız:

DHCPKEŞFEDİN

Yani bir cihaza IP adresi alma süreci DHCP istemcisinin 68 numaralı porttan 255.255.255.255:67’ye yayın isteği göndermesiyle başlar. Bu pakette istemci, MAC adresinin yanı sıra DHCP sunucusundan tam olarak ne almak istediğini de içerir. Paket yapısı aşağıdaki tabloda açıklanmıştır.

DHCPDISCOVER Paket Yapı Tablosu

Paketteki konum
Değer adı
Örnek
Представление
Bayt
Açıklama

1
Önyükleme İsteği
1
Büyü
1
Mesaj tipi. 1 - istemciden sunucuya istek, 2 - sunucudan istemciye yanıt

2
donanım türü
1
Büyü
1
Bu protokoldeki donanım adresi türü 1 - MAC

3
Donanım adreslerinin uzunluğu
6
Büyü
1
Cihaz MAC adresi uzunluğu

4
Hops
1
Büyü
1
Ara rota sayısı

5
İşlem Kimliği
23:cf:de:1d
Büyü
4
Benzersiz işlem tanımlayıcısı. İstemci tarafından istek işleminin başlangıcında oluşturulur

7
Geçen saniye
0
Büyü
4
Adres alma sürecinin başlangıcından itibaren saniye cinsinden süre

9
Önyükleme bayrakları
0
Büyü
2
Protokol parametrelerini belirtmek için ayarlanabilen belirli bayraklar

11
İstemci IP adresi
0.0.0.0
Hat
4
İstemci IP adresi (varsa)

15
İstemci IP adresiniz
0.0.0.0
Hat
4
Sunucu tarafından sunulan IP adresi (varsa)

19
Sonraki sunucu IP adresi
0.0.0.0
Hat
4
Sunucu IP adresi (biliniyorsa)

23
Aktarma aracısının IP adresi
172.16.114.41
Hat
4
Aktarma aracısının IP adresi (örneğin bir anahtar)

27
İstemci MAC adresi
14:d6:4d:a7:c9:55
Büyü
6
Paket gönderenin (istemci) MAC adresi

31
İstemci donanım adresi dolgusu
 
Büyü
10
Rezerve koltuk. Genellikle sıfırlarla doldurulur

41
Sunucu ana bilgisayar adı
 
Hat
64
DHCP sunucu adı. Genellikle iletilmez

105
Önyükleme dosyası adı
 
Hat
128
Disksiz istasyonların önyükleme sırasında kullandığı sunucudaki dosya adı

235
Sihirli kurabiyeler
63: 82: 53: 63
Büyü
4
Buna göre "Sihirli" sayı dahil. bu paketin DHCP protokolüne ait olduğunu belirleyebilirsiniz

DHCP seçenekleri. Herhangi bir sırayla gidebilir

236
Seçenek numarası
53
Aralık
1
DHCP paket tipini belirten Seçenek 53

1 - DHCPDISCOVER
3 - DHCPREQUEST
2 - DHCP TEKLİFİ
5 -DHCPACK
8 - DHCP BİLGİSİ

 
Seçenek uzunluğu
1
Aralık
1

 
Opsiyon değeri
1
Aralık
1

 
Seçenek numarası
50
Aralık
1
İstemci hangi IP adresini almak istiyor?

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
172.16.134.61
Hat
4

 
Seçenek numarası
55
 
1
İstemci tarafından talep edilen ağ parametreleri. Kompozisyon değişebilir

01 — Ağ maskesi
03 - Ağ Geçidi
06 - DNS'ler
oc — Ana bilgisayar adı
0f - ağ alan adı
1c - yayın isteğinin adresi (yayın)
42 - TFTP sunucu adı
79 - Sınıfsız Statik Rota

 
Seçenek uzunluğu
8
 
1

 
Opsiyon değeri
01:03:06:0c:0f:1c:42:79
 
8

 
Seçenek numarası
82
Aralık
 
Tekrarlayıcı cihazın MAC adresini ve bazı ek değerleri ileten Seçenek 82.

Çoğu zaman bu, uç DHCP istemcisinin çalıştığı anahtarın bağlantı noktasıdır.Bu seçenek ek parametreler içerir.İlk bayt "alt seçeneğin" numarası, ikincisi uzunluğu ve ardından değeridir.

Bu durumda seçenek 82'de alt seçenekler iç içe geçmiştir:
Ajan Devre Kimliği = 00:04:00:01:00:04; burada son iki bayt, isteğin geldiği DHCP istemci bağlantı noktasıdır

Agent Remote ID = 00:06:c8:be:19:93:11:48 - DHCP yineleyici aygıtının MAC adresi

 
Seçenek uzunluğu
18
Aralık
 

 
Opsiyon değeri
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
Büyü
 

 
Paket sonu
255
Aralık
1
255 paketin sonunu simgeliyor

DHCP TEKLİFİ

Sunucu DHCPDISCOVER paketini alır almaz ve istemciye istenen paketten bir şey sunabileceğini görürse, bunun için bir yanıt oluşturur - DHCPDISCOVER. Yanıt yayın yoluyla “geldiği yerden” bağlantı noktasına gönderilir çünkü şu anda istemcinin henüz bir IP adresi yoktur, bu nedenle paketi yalnızca yayın yoluyla gönderilirse kabul edebilir. Müşteri bunun kendisi için bir paket olduğunu, paketin içindeki MAC adresinden ve ilk paketi oluşturduğu anda oluşturduğu işlem numarasından anlar.

DHCPOFFER Paket Yapı Tablosu

Paketteki konum
Değerin adı (ortak)
Örnek
Представление
Bayt
Açıklama

1
Önyükleme İsteği
1
Büyü
1
Mesaj tipi. 1 - istemciden sunucuya istek, 2 - sunucudan istemciye yanıt

2
donanım türü
1
Büyü
1
Bu protokoldeki donanım adresi türü 1 - MAC

3
Donanım adreslerinin uzunluğu
6
Büyü
1
Cihaz MAC adresi uzunluğu

4
Hops
1
Büyü
1
Ara rota sayısı

5
İşlem Kimliği
23:cf:de:1d
Büyü
4
Benzersiz işlem tanımlayıcısı. İstemci tarafından istek işleminin başlangıcında oluşturulur

7
Geçen saniye
0
Büyü
4
Adres alma sürecinin başlangıcından itibaren saniye cinsinden süre

9
Önyükleme bayrakları
0
Büyü
2
Protokol parametrelerini belirtmek için ayarlanabilen belirli bayraklar. Bu durumda 0, Tek noktaya yayın istek türü anlamına gelir

11
İstemci IP adresi
0.0.0.0
Hat
4
İstemci IP adresi (varsa)

15
İstemci IP adresiniz
172.16.134.61
Hat
4
Sunucu tarafından sunulan IP adresi (varsa)

19
Sonraki sunucu IP adresi
0.0.0.0
Hat
4
Sunucu IP adresi (biliniyorsa)

23
Aktarma aracısının IP adresi
172.16.114.41
Hat
4
Aktarma aracısının IP adresi (örneğin bir anahtar)

27
İstemci MAC adresi
14:d6:4d:a7:c9:55
Büyü
6
Paket gönderenin (istemci) MAC adresi

31
İstemci donanım adresi dolgusu
 
Büyü
10
Rezerve koltuk. Genellikle sıfırlarla doldurulur

41
Sunucu ana bilgisayar adı
 
Hat
64
DHCP sunucu adı. Genellikle iletilmez

105
Önyükleme dosyası adı
 
Hat
128
Disksiz istasyonların önyükleme sırasında kullandığı sunucudaki dosya adı

235
Sihirli kurabiyeler
63: 82: 53: 63
Büyü
4
Buna göre "Sihirli" sayı dahil. bu paketin DHCP protokolüne ait olduğunu belirleyebilirsiniz

DHCP seçenekleri. Herhangi bir sırayla gidebilir

236
Seçenek numarası
53
Aralık
1
DHCP 53 paket türünü tanımlayan Seçenek 2 - DHCPOFFER

 
Seçenek uzunluğu
1
Aralık
1

 
Opsiyon değeri
2
Aralık
1

 
Seçenek numarası
1
Aralık
1
DHCP istemcisine bir ağ maskesi sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
255.255.224.0
Hat
4

 
Seçenek numarası
3
Aralık
1
DHCP istemcisine varsayılan bir ağ geçidi sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
172.16.12.1
Hat
4

 
Seçenek numarası
6
Aralık
1
DNS istemcisine DHCP sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
8.8.8.8
Hat
4

 
Seçenek numarası
51
Aralık
1
Verilen ağ parametrelerinin saniye cinsinden ömrü; bunun ardından DHCP istemcisinin bunları tekrar istemesi gerekir

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
86400
Aralık
4

 
Seçenek numarası
82
Aralık
1
Seçenek 82, DHCPDISCOVER'da gelenleri tekrarlıyor

 
Seçenek uzunluğu
18
Aralık
1

 
Opsiyon değeri
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Aralık
18

 
Paket sonu
255
Aralık
1
255 paketin sonunu simgeliyor

DHCPİSTEĞİ

Müşteri DHCPOFFER'ı aldıktan sonra, ağdaki tüm DHCP sunucularına değil, yalnızca DHCPOFFER teklifini en çok "beğendiği" belirli bir sunucuya ağ parametreleri isteyen bir paket oluşturur. "Beğenme" kriterleri farklı olabilir ve müşterinin DHCP uygulamasına bağlı olabilir. İsteğin alıcısı, DHCP sunucusunun MAC adresi kullanılarak belirtilir. Ayrıca, sunucunun IP adresi daha önce alınmışsa, önce DHCPDISCOVER oluşturulmadan istemci tarafından bir DHCPREQUEST paketi gönderilebilir.

DHCPREQUEST Paket Yapı Tablosu

Paketteki konum
Değerin adı (ortak)
Örnek
Представление
Bayt
Açıklama

1
Önyükleme İsteği
1
Büyü
1
Mesaj tipi. 1 - istemciden sunucuya istek, 2 - sunucudan istemciye yanıt

2
donanım türü
1
Büyü
1
Bu protokoldeki donanım adresi türü 1 - MAC

3
Donanım adreslerinin uzunluğu
6
Büyü
1
Cihaz MAC adresi uzunluğu

4
Hops
1
Büyü
1
Ara rota sayısı

5
İşlem Kimliği
23:cf:de:1d
Büyü
4
Benzersiz işlem tanımlayıcısı. İstemci tarafından istek işleminin başlangıcında oluşturulur

7
Geçen saniye
0
Büyü
4
Adres alma sürecinin başlangıcından itibaren saniye cinsinden süre

9
Önyükleme bayrakları
8000
Büyü
2
Protokol parametrelerini belirtmek için ayarlanabilen belirli bayraklar. Bu durumda “yayın” ayarlıdır

11
İstemci IP adresi
0.0.0.0
Hat
4
İstemci IP adresi (varsa)

15
İstemci IP adresiniz
172.16.134.61
Hat
4
Sunucu tarafından sunulan IP adresi (varsa)

19
Sonraki sunucu IP adresi
0.0.0.0
Hat
4
Sunucu IP adresi (biliniyorsa)

23
Aktarma aracısının IP adresi
172.16.114.41
Hat
4
Aktarma aracısının IP adresi (örneğin bir anahtar)

27
İstemci MAC adresi
14:d6:4d:a7:c9:55
Büyü
6
Paket gönderenin (istemci) MAC adresi

31
İstemci donanım adresi dolgusu
 
Büyü
10
Rezerve koltuk. Genellikle sıfırlarla doldurulur

41
Sunucu ana bilgisayar adı
 
Hat
64
DHCP sunucu adı. Genellikle iletilmez

105
Önyükleme dosyası adı
 
Hat
128
Disksiz istasyonların önyükleme sırasında kullandığı sunucudaki dosya adı

235
Sihirli kurabiyeler
63: 82: 53: 63
Büyü
4
Buna göre "Sihirli" sayı dahil. bu paketin DHCP protokolüne ait olduğunu belirleyebilirsiniz

DHCP seçenekleri. Herhangi bir sırayla gidebilir

236
Seçenek numarası
53
Aralık
3
DHCP paket tipi 53'ü tanımlayan Seçenek 3 - DHCPREQUEST

 
Seçenek uzunluğu
1
Aralık
1

 
Opsiyon değeri
3
Aralık
1

 
Seçenek numarası
61
Aralık
1
İstemci Kimliği: 01 (Ehernet için) + istemci MAC adresi

 
Seçenek uzunluğu
7
Aralık
1

 
Opsiyon değeri
01:2c:ab:25:ff:72:a6
Büyü
7

 
Seçenek numarası
60
Aralık
 
"Satıcı sınıfı tanımlayıcısı". Benim durumumda DHCP istemci sürümünü rapor ediyor. Belki diğer cihazlar farklı bir şey döndürür. Örneğin Windows MSFT 5.0'ı rapor ediyor

 
Seçenek uzunluğu
11
Aralık
 

 
Opsiyon değeri
uhcp 0.9.8
Hat
 

 
Seçenek numarası
55
 
1
İstemci tarafından talep edilen ağ parametreleri. Kompozisyon değişebilir

01 — Ağ maskesi
03 - Ağ Geçidi
06 - DNS'ler
oc — Ana bilgisayar adı
0f - ağ alan adı
1c - yayın isteğinin adresi (yayın)
42 - TFTP sunucu adı
79 - Sınıfsız Statik Rota

 
Seçenek uzunluğu
8
 
1

 
Opsiyon değeri
01:03:06:0c:0f:1c:42:79
 
8

 
Seçenek numarası
82
Aralık
1
Seçenek 82, DHCPDISCOVER'da gelenleri tekrarlıyor

 
Seçenek uzunluğu
18
Aralık
1

 
Opsiyon değeri
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Aralık
18

 
Paket sonu
255
Aralık
1
255 paketin sonunu simgeliyor

DHCPACK

DHCP sunucusundan “evet doğru, bu sizin IP adresiniz ve bunu başkasına vermeyeceğim” onayı olarak sunucudan istemciye DHCPACK formatında bir paket hizmet verir. Diğer paketler gibi yayın olarak gönderilir. Bununla birlikte, Python'da uygulanan bir DHCP sunucusu için aşağıdaki kodda, her ihtimale karşı, önceden biliniyorsa, belirli bir istemci IP'sine bir paket göndererek herhangi bir yayın isteğini kopyalarım. Üstelik DHCP sunucusu, DHCPACK paketinin istemciye ulaşıp ulaşmadığını hiç umursamaz. İstemci DHCPACK'i almazsa, bir süre sonra DHCPREQUEST'i tekrarlar.

DHCPACK Paket Yapı Tablosu

Paketteki konum
Değerin adı (ortak)
Örnek
Представление
Bayt
Açıklama

1
Önyükleme İsteği
2
Büyü
1
Mesaj tipi. 1 - istemciden sunucuya istek, 2 - sunucudan istemciye yanıt

2
donanım türü
1
Büyü
1
Bu protokoldeki donanım adresi türü 1 - MAC

3
Donanım adreslerinin uzunluğu
6
Büyü
1
Cihaz MAC adresi uzunluğu

4
Hops
1
Büyü
1
Ara rota sayısı

5
İşlem Kimliği
23:cf:de:1d
Büyü
4
Benzersiz işlem tanımlayıcısı. İstemci tarafından istek işleminin başlangıcında oluşturulur

7
Geçen saniye
0
Büyü
4
Adres alma sürecinin başlangıcından itibaren saniye cinsinden süre

9
Önyükleme bayrakları
8000
Büyü
2
Protokol parametrelerini belirtmek için ayarlanabilen belirli bayraklar. Bu durumda “yayın” ayarlıdır

11
İstemci IP adresi
0.0.0.0
Hat
4
İstemci IP adresi (varsa)

15
İstemci IP adresiniz
172.16.134.61
Hat
4
Sunucu tarafından sunulan IP adresi (varsa)

19
Sonraki sunucu IP adresi
0.0.0.0
Hat
4
Sunucu IP adresi (biliniyorsa)

23
Aktarma aracısının IP adresi
172.16.114.41
Hat
4
Aktarma aracısının IP adresi (örneğin bir anahtar)

27
İstemci MAC adresi
14:d6:4d:a7:c9:55
Büyü
6
Paket gönderenin (istemci) MAC adresi

31
İstemci donanım adresi dolgusu
 
Büyü
10
Rezerve koltuk. Genellikle sıfırlarla doldurulur

41
Sunucu ana bilgisayar adı
 
Hat
64
DHCP sunucu adı. Genellikle iletilmez

105
Önyükleme dosyası adı
 
Hat
128
Disksiz istasyonların önyükleme sırasında kullandığı sunucudaki dosya adı

235
Sihirli kurabiyeler
63: 82: 53: 63
Büyü
4
Buna göre "Sihirli" sayı dahil. bu paketin DHCP protokolüne ait olduğunu belirleyebilirsiniz

DHCP seçenekleri. Herhangi bir sırayla gidebilir

236
Seçenek numarası
53
Aralık
3
DHCP paket tipini tanımlayan Seçenek 53 5 - DHCPACK

 
Seçenek uzunluğu
1
Aralık
1

 
Opsiyon değeri
5
Aralık
1

 
Seçenek numarası
1
Aralık
1
DHCP istemcisine bir ağ maskesi sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
255.255.224.0
Hat
4

 
Seçenek numarası
3
Aralık
1
DHCP istemcisine varsayılan bir ağ geçidi sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
172.16.12.1
Hat
4

 
Seçenek numarası
6
Aralık
1
DNS istemcisine DHCP sunma seçeneği

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
8.8.8.8
Hat
4

 
Seçenek numarası
51
Aralık
1
Verilen ağ parametrelerinin saniye cinsinden ömrü; bunun ardından DHCP istemcisinin bunları tekrar istemesi gerekir

 
Seçenek uzunluğu
4
Aralık
1

 
Opsiyon değeri
86400
Aralık
4

 
Seçenek numarası
82
Aralık
1
Seçenek 82, DHCPDISCOVER'da gelenleri tekrarlıyor

 
Seçenek uzunluğu
18
Aralık
1

 
Opsiyon değeri
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Aralık
18

 
Paket sonu
255
Aralık
1
255 paketin sonunu simgeliyor

Montaj

Kurulum aslında iş için gerekli olan python modüllerinin kurulmasından ibarettir. MySQL'in zaten kurulu ve yapılandırılmış olduğu varsayılmaktadır.

FreeBSD

pkg python3'ü kurun python3 -m surepip pip3 mysql-konektörünü kurun

Ubuntu

sudo apt-get install python3 sudo apt-get install pip3 sudo pip3 mysql bağlayıcıyı kur

Bir MySQL veritabanı oluşturuyoruz, pydhcp.sql dökümünü buraya yüklüyoruz ve yapılandırma dosyasını yapılandırıyoruz.

Yapılandırma

Tüm sunucu ayarları bir xml dosyasındadır. Referans dosyası:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 yerel ana bilgisayar Ölçek Ölçek pydhcp seçenek_8.8.8.8_hex:sw_port82:1:20 seçenek_22_hex:sw_port82:2:16 seçenek_18_hex:sw_mac:82:26 40 Upper(mac)=upper('{option_3_AgentRemoteId_hex}') ve Upper(port)=upper('{option_1_AgentCircuitId_port_hex}') olduğu kullanıcılardan ip,mask,router,dns seçin Upper(mac)=upper('{sw_mac}') ve Upper(port)=upper('{sw_port82}') olan kullanıcılardan ip,mask,router,dns seçin Upper(mac)=upper('{ClientMacAddress}') olan kullanıcılardan ip,mask,yönlendirici,dns seçin geçmişe (id,dt,mac,ip,comment) değerleri ekleyin (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Şimdi etiketler hakkında daha ayrıntılı olarak:

Dhcpserver bölümü, sunucuyu başlatmak için temel ayarları açıklar:

  • ana bilgisayar - sunucunun 67 numaralı bağlantı noktasında dinlediği IP adresi
  • yayın - DHCPOFFER ve DHCPACK'in yayını hangi iptir?
  • DHCPServer - DHCP sunucusunun ip'si nedir
  • Verilen IP adresinin LeaseTime kiralama süresi
  • ThreadLimit - 67 numaralı bağlantı noktasında gelen UDP paketlerini işlemek için aynı anda kaç iş parçacığının çalıştığı. Yüksek yüklü projelere yardımcı olması gerekiyor 😉
  • defaultMask,defaultRouter,defaultDNS - veritabanında bir IP bulunursa, ancak bunun için ek parametreler belirtilmemişse aboneye varsayılan olarak sunulan şey

MySQL bölümü:

ana bilgisayar, kullanıcı adı, şifre, taban adı - her şey kendi adına konuşuyor. Yaklaşık bir veritabanı yapısı şu adreste yayınlanmıştır: GitHub

Sorgu bölümü: TEKLİF/ACK alma talepleri burada açıklanmaktadır:

  • Offer_count — ip,mask,yönlendirici,dns gibi bir sonuç döndüren isteklere sahip satır sayısı
  • Offer_n — sorgu dizesi. Return boşsa aşağıdaki teklif isteğini yürütür
  • History_sql - örneğin bir abonenin "yetkilendirme geçmişine" yazan bir sorgu

İstekler, seçenekler bölümündeki herhangi bir değişkeni veya DHCP protokolündeki seçenekleri içerebilir.

Seçenekler bölümü. İşte burası daha da ilginçleşiyor. Burada daha sonra sorgulama kısmında kullanabileceğimiz değişkenler oluşturabiliriz.

Örneğin:

option_82_hex:sw_port1:20:22

, bu komut satırı, DHCP istek seçeneği 82'de gelen satırın tamamını onaltılık formatta, 20 ila 22 bayt aralığında alır ve onu yeni sw_port1 değişkenine (isteğin geldiği yerdeki anahtar bağlantı noktası) koyar.

option_82_hex:sw_mac:26:40

26:40 aralığından hex değerini alarak sw_mac değişkenini tanımlayın

Sunucuyu -d anahtarı ile başlatarak sorgularda kullanılabilecek tüm olası seçenekleri görebilirsiniz. Bu günlüğe benzer bir şey göreceğiz:

--67ad0025224 , b'x764xa91xe5xa0xa3xa5-x9fx8a' , ('8', 172.30.114.25) {'ClientMacAddress': '68ad0025224', 'ClientMacAddressByte': b'x764% "Jx adresinden 00 numaralı bağlantı noktasına bir DHCPINFORM paketi geldi d7d', ' HType': 'Ethernet', 'HostName': b'x91xa5xe0xa3xa5xa9-x8fx8a', 'ReqListDNS': Doğru, 'ReqListDomainName': Doğru, 'ReqListPerfowmRouterDiscover': Doğru, 'ReqListRouter': Doğru, 'ReqListStaticRoute': Doğru, ' ReqListSubnetMask ': True, 'ReqListVendorSpecInfo': 43, 'RequestedIpAddress': '0.0.0.0', 'Vendor': b'MSFT 5.0', 'chaddr': '0025224ad764', 'ciaddr': '172.30.128.13', ' flags ': b'x00x00', 'giaddr': '172.30.114.25', 'gpoz': 308, 'hlen': 6, 'hops': 1, 'htype': 'MAC', 'magic_cookie': b' cx82Sc ', 'op': 'DHCPINFORM', 'option12': 12, 'option53': 53, 'option55': 55, 'option60': 60, 'option61': 61, 'option82': 82, 'option_82_byte' : b'x12x01x06x00x04x00x01x00x06x02x08x00' b'x06x00x1eXx9exb2xad', 'option_82_hex': '12010600040001000602080006001e589eb2ad', 'option_82_len': 18 , 'option_82_str': "b'x12x01x06x00x04x00x01x00x06x02x08x00x06x00x1eXx9exb2xad'", 'result': False, 'secs': 768, 'siaddr' : '0.0.0.0', 'sw_mac': '001e589eb2ad', 'sw_port1': '06', 'xidbyte': b'

Buna göre herhangi bir değişkeni {} içine sarabiliriz ve bu, SQL sorgusunda kullanılacaktır.

İstemcinin IP adresini aldığını geçmişe kaydedelim:

Python'da DHCP+Mysql sunucusu

Python'da DHCP+Mysql sunucusu

Sunucu başlangıcı

./pydhcpdb.py -d -c yapılandırma.xml

— d konsol çıkış modu DEBUG
- c <dosya adı> yapılandırma dosyası

Bilgi alma

Ve şimdi sunucunun Python'da uygulanmasına ilişkin daha fazla ayrıntı. Bu bir acı. Python anında öğrenildi. Pek çok an "vay be, bir şekilde başardım" tarzında yapılıyor. Hiç optimize edilmedi ve Python geliştirmedeki az deneyim nedeniyle bu formda bırakıldı. Sunucu uygulamasının en ilginç yönleri üzerinde “kod” bölümünde duracağım.

XML yapılandırma dosyası ayrıştırıcısı

Standart Python modülü xml.dom kullanılır. Basit görünüyor, ancak uygulama sırasında bu modülü kullanan ağda gözle görülür net dokümantasyon ve örnekler eksikliği vardı.

    ağaç = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") mconfig'deki öğe için: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("kullanıcı adı")[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") dconfig içindeki öğe için: 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("query") qconfig içindeki öğe için: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data içindeki sayı için range(int(gconfig["offer_count"])): gconfig["offer_"+str(num+1)]=elem.getElementsByTagName("offer_"+str(num+1))[0].firstChild.data gconfig Seçeneklerdeki öğe için ["history_sql"]=elem.getElementsByTagName("history_sql")[0].firstChild.data options=tree.getElementsByTagName("options"): düğümdeki seçenekler için node=elem.getElementsByTagName("option") : optionsMod.append(options.firstChild.data)

Çoklu kullanım

İşin tuhafı, Python'da çoklu iş parçacığı kullanımı çok açık ve basit bir şekilde uygulanıyor.

def PacketWork(data,addr): ... # gelen paketi ayrıştırma ve ona yanıt verme uygulaması ... while True: data, addr = udp_socket.recvfrom(1024) # UDP paket iş parçacığını bekliyor = threading.Thread( target=PacketWork , args=(data,addr,)).start() # geldiği gibi - threading.active_count() >gconfig["dhcp_ThreadLimit"]: time sırasında önceden tanımlanmış PacketWork fonksiyonunu arka planda parametrelerle başlatırız. uyku(1) # eğer sayı Ayarlarda olduğundan daha fazla iş parçacığı zaten çalışıyorsa, daha azı olana kadar bekleriz

DHCP paketini al/gönder

Ağ kartından gelen UDP paketlerini engellemek için soketi "yükseltmeniz" gerekir:

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

, bayrakların olduğu yer:

  • AF_INET - adres formatının IP: port olacağı anlamına gelir. Adresin dosya adına göre verildiği AF_UNIX de olabilir.
  • SOCK_DGRAM - "ham paketi" kabul etmediğimiz, ancak zaten güvenlik duvarından geçmiş ve kısmen kesilmiş bir paketi kabul ettiğimiz anlamına gelir. Onlar. UDP paket sarmalayıcısının "fiziksel" bileşeni olmadan yalnızca bir UDP paketi alıyoruz. SOCK_RAW bayrağını kullanırsanız, bu "sarmalayıcıyı" da ayrıştırmanız gerekecektir.

Paket göndermek yayına benzeyebilir:

                    udp_socket.setsockopt(socket.SOL_SOCKET, soket.SO_BROADCAST, 1) #soketi yayın moduna geçirin rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

ve "paketin geldiği yer" adresine:

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # soketi çoklu dinleyici moduna geçir rz=udp_socket.sendto(packetack, addr)

SOL_SOCKET, seçenekleri ayarlamak için "protokol düzeyi" anlamına gelir;

, SO_BROADCAST seçeneği kask paketinin “yayın” olduğunu gösterir

  ,SO_REUSEADDR seçeneği soketi “çok dinleyici” moduna geçirir. Teorik olarak bu durumda gereksizdir, ancak test ettiğim FreeBSD sunucularından birinde kod bu seçenek olmadan çalışmadı.

DHCP paketini ayrıştırma

Python'u gerçekten sevdiğim yer burası. Bayt kodu konusunda oldukça esnek olmanızı sağladığı ortaya çıktı. Ondalık değerlere, dizelere ve onaltılık değerlere çok kolay bir şekilde çevrilmesine izin vermek - yani. aslında paketin yapısını anlamamız gereken şey budur. Örneğin, HEX'te bir bayt aralığı ve yalnızca bayt elde edebilirsiniz:

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

baytları bir yapıya paketleyin:

res["flags"]=paket('BB',veri[10],veri[11])

Yapıdan IP alın:

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

Ve tam tersi:

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

Şimdilik bu kadar 😉

Kaynak: habr.com

Yorum ekle