Server DHCP+Mysql dengan Python

Server DHCP+Mysql dengan Python

Tujuan dari proyek ini adalah:

  • Belajar tentang DHCP pada jaringan IPv4
  • Belajar Python (sedikit lebih dari dari awal 😉)
  • penggantian server DB2DHCP (garpu saya), asli di sini, yang menjadi semakin sulit untuk dirakit untuk OS baru. Dan saya tidak suka bahwa ini adalah biner yang tidak ada cara untuk "mengubahnya sekarang"
  • mendapatkan server DHCP yang berfungsi dengan kemampuan untuk memilih alamat IP pelanggan menggunakan mac pelanggan atau kombinasi switch mac+port (Opsi 82)
  • menulis sepeda lain (Oh! ini aktivitas favoritku)
  • menerima komentar tentang sifat kidal Anda di Habrahabr (atau lebih baik lagi, undangan) 😉

Hasil: berhasil 😉 Diuji pada OS FreeBSD dan Ubuntu. Secara teoritis, kode tersebut dapat diminta untuk berfungsi di OS apa pun, karena Tampaknya tidak ada ikatan khusus dalam kode tersebut.
Dengan hati-hati! Masih banyak lagi yang akan datang.

Tautan ke repositori untuk amatir "sentuh hidup-hidup".

Proses instalasi, konfigurasi dan penggunaan hasil “mempelajari perangkat keras” jauh lebih rendah, dan kemudian sedikit teori tentang protokol DHCP. Untuk diriku. Dan untuk sejarah 😉

Sedikit teori

Apa itu DHCP

Ini adalah protokol jaringan yang memungkinkan perangkat mengetahui alamat IP-nya (dan parameter lain seperti gateway, DNS, dll.) dari server DHCP. Paket dipertukarkan menggunakan protokol UDP. Prinsip umum pengoperasian perangkat saat meminta parameter jaringan adalah sebagai berikut:

  1. Perangkat (klien) mengirimkan permintaan siaran UDP (DHCPDISCOVER) ke seluruh jaringan dengan permintaan “baiklah, seseorang memberi saya alamat IP.” Selain itu, biasanya (tetapi tidak selalu) permintaan terjadi dari port 68 (sumber), dan tujuannya adalah port 67 (tujuan). Beberapa perangkat juga mengirim paket dari port 67. Alamat MAC perangkat klien disertakan dalam paket DHCPDISCOVER.
  2. Semua server DHCP yang terletak di jaringan (dan mungkin ada beberapa di antaranya) membentuk penawaran DHCPOFFER dengan pengaturan jaringan untuk perangkat yang mengirim DHCPDISCOVER, dan juga menyiarkannya melalui jaringan. Identifikasi untuk siapa paket ini ditujukan berdasarkan alamat MAC klien yang diberikan sebelumnya dalam permintaan DHCPDISCOVER.
  3. Klien menerima paket dengan proposal untuk pengaturan jaringan, memilih yang paling menarik (kriteria mungkin berbeda, misalnya, waktu pengiriman paket, jumlah rute perantara), dan membuat "permintaan resmi" DHCPREQUEST dengan pengaturan jaringan dari server DHCP yang disukainya. Dalam hal ini, paket dikirim ke server DHCP tertentu.
  4. Server yang menerima DHCPREQUEST mengirimkan paket format DHCPACK, yang sekali lagi mencantumkan pengaturan jaringan yang ditujukan untuk klien ini

Server DHCP+Mysql dengan Python

Selain itu, ada paket DHCPINFORM yang berasal dari klien, dan tujuannya adalah untuk memberi tahu server DHCP bahwa “klien masih hidup” dan menggunakan pengaturan jaringan yang dikeluarkan. Dalam implementasi server ini, paket-paket ini diabaikan.

Format paket

Secara umum, frame paket Ethernet terlihat seperti ini:

Server DHCP+Mysql dengan Python

Dalam kasus kami, kami hanya akan mempertimbangkan data langsung dari isi paket UDP, tanpa header protokol lapisan OSI, yaitu struktur DHCP:

DHCP TEMUKAN

Jadi, proses mendapatkan alamat IP untuk suatu perangkat dimulai dengan klien DHCP mengirimkan permintaan siaran dari port 68 ke 255.255.255.255:67. Dalam paket ini, klien menyertakan alamat MAC-nya, serta apa sebenarnya yang ingin diterimanya dari server DHCP. Struktur paket dijelaskan pada tabel di bawah ini.

Tabel Struktur Paket DHCPDISCOVER

Posisi dalam paket
Nama nilai
Contoh
Pendahuluan
Byte
Klarifikasi

1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien

2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC

3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat

4
Hop
1
kutukan
1
Jumlah rute perantara

5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan

7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat

9
Bendera boot
0
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol

11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)

15
Alamat IP klien Anda
0.0.0.0
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)

19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)

23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)

27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)

31
Padding alamat perangkat keras klien
 
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol

41
Nama host server
 
Tali
64
Nama server DHCP. Biasanya tidak menular

105
Nama file boot
 
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting

235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP

Opsi DHCP. Bisa dalam urutan apa pun

236
Nomor opsi
53
Desember
1
Opsi 53, yang menentukan jenis paket DHCP

1 - PENEMUAN DHCPD
3 - PERMINTAAN DHC
2 - PENAWARAN DHC
5 - Paket DHC
8 - INFORMASI DHCP

 
Panjang opsi
1
Desember
1

 
Nilai opsi
1
Desember
1

 
Nomor opsi
50
Desember
1
Alamat IP apa yang ingin diterima klien?

 
Panjang opsi
4
Desember
1

 
Nilai opsi
172.16.134.61
Tali
4

 
Nomor opsi
55
 
1
Parameter jaringan yang diminta oleh klien. Komposisinya mungkin berbeda

01 — Masker jaringan
03 - Gerbang
06 -DNS
oc — Nama host
0f - nama domain jaringan
1c - alamat permintaan siaran (siaran)
42 - Nama server TFTP
79 - Rute Statis Tanpa Kelas

 
Panjang opsi
8
 
1

 
Nilai opsi
01:03:06:0c:0f:1c:42:79
 
8

 
Nomor opsi
82
Desember
 
Opsi 82, yang mengirimkan alamat MAC perangkat pengulang dan beberapa nilai tambahan.

Paling sering, ini adalah port switch di mana klien DHCP akhir berjalan. Opsi ini berisi parameter tambahan. Byte pertama adalah nomor "subopsi", yang kedua adalah panjangnya, lalu nilainya.

Dalam hal ini, pada opsi 82, sub-opsi disarangkan:
ID Sirkuit Agen = 00:04:00:01:00:04, dengan dua byte terakhir adalah port klien DHCP tempat permintaan datang

ID Jarak Jauh Agen = 00:06:c8:be:19:93:11:48 - Alamat MAC perangkat pengulang DHCP

 
Panjang opsi
18
Desember
 

 
Nilai opsi
01:06
00:04:00:01:00:04
02:08
00:06:c8:be:19:93:11:48
kutukan
 

 
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket

PENAWARAN DHCP

Segera setelah server menerima paket DHCPDISCOVER dan jika server melihat bahwa ia dapat menawarkan sesuatu kepada klien dari paket yang diminta, maka server akan menghasilkan respons untuk itu - DHCPDISCOVER. Responsnya dikirim ke port “dari mana asalnya”, melalui siaran, karena Saat ini klien belum memiliki alamat IP, oleh karena itu ia hanya dapat menerima paket jika dikirim melalui siaran. Klien mengenali bahwa ini adalah paket untuknya melalui alamat MAC-nya di dalam paket, serta nomor transaksi yang dia hasilkan pada saat paket pertama dibuat.

Tabel Struktur Paket DHCPOFFER

Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi

1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien

2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC

3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat

4
Hop
1
kutukan
1
Jumlah rute perantara

5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan

7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat

9
Bendera boot
0
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, 0 berarti jenis permintaan Unicast

11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)

15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)

19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)

23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)

27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)

31
Padding alamat perangkat keras klien
 
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol

41
Nama host server
 
Tali
64
Nama server DHCP. Biasanya tidak menular

105
Nama file boot
 
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting

235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP

Opsi DHCP. Bisa dalam urutan apa pun

236
Nomor opsi
53
Desember
1
Opsi 53, yang mendefinisikan jenis paket DHCP 2 - DHCPOFFER

 
Panjang opsi
1
Desember
1

 
Nilai opsi
2
Desember
1

 
Nomor opsi
1
Desember
1
Pilihan untuk menawarkan klien DHCP masker jaringan

 
Panjang opsi
4
Desember
1

 
Nilai opsi
255.255.224.0
Tali
4

 
Nomor opsi
3
Desember
1
Pilihan untuk menawarkan gateway default kepada klien DHCP

 
Panjang opsi
4
Desember
1

 
Nilai opsi
172.16.12.1
Tali
4

 
Nomor opsi
6
Desember
1
Pilihan untuk menawarkan DHCP ke klien DNS

 
Panjang opsi
4
Desember
1

 
Nilai opsi
8.8.8.8
Tali
4

 
Nomor opsi
51
Desember
1
Masa pakai parameter jaringan yang dikeluarkan dalam hitungan detik, setelah itu klien DHCP harus memintanya lagi

 
Panjang opsi
4
Desember
1

 
Nilai opsi
86400
Desember
4

 
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER

 
Panjang opsi
18
Desember
1

 
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18

 
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket

PERMINTAAN DHC

Setelah klien menerima DHCPOFFER, ia membentuk paket yang meminta parameter jaringan tidak ke semua server DHCP di jaringan, tetapi hanya ke satu server tertentu, yang penawaran DHCPOFFER-nya paling ia “sukai”. Kriteria "suka" bisa berbeda dan bergantung pada implementasi DHCP klien. Penerima permintaan ditentukan menggunakan alamat MAC server DHCP. Selain itu, paket DHCPREQUEST dapat dikirim oleh klien tanpa terlebih dahulu membuat DHCPDISCOVER, jika alamat IP server telah diperoleh sebelumnya.

Tabel Struktur Paket DHCPREQUEST

Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi

1
Permintaan Booting
1
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien

2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC

3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat

4
Hop
1
kutukan
1
Jumlah rute perantara

5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan

7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat

9
Bendera boot
8000
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, “siaran” diatur

11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)

15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)

19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)

23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)

27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)

31
Padding alamat perangkat keras klien
 
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol

41
Nama host server
 
Tali
64
Nama server DHCP. Biasanya tidak menular

105
Nama file boot
 
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting

235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP

Opsi DHCP. Bisa dalam urutan apa pun

236
Nomor opsi
53
Desember
3
Opsi 53, yang mendefinisikan paket DHCP tipe 3 - DHCPREQUEST

 
Panjang opsi
1
Desember
1

 
Nilai opsi
3
Desember
1

 
Nomor opsi
61
Desember
1
ID Klien: 01 (untuk Ehernet) + alamat MAC klien

 
Panjang opsi
7
Desember
1

 
Nilai opsi
01:2c:ab:25:ff:72:a6
kutukan
7

 
Nomor opsi
60
Desember
 
"Pengidentifikasi kelas vendor". Dalam kasus saya, ini melaporkan versi klien DHCP. Mungkin perangkat lain memberikan sesuatu yang berbeda. Windows misalnya melaporkan MSFT 5.0

 
Panjang opsi
11
Desember
 

 
Nilai opsi
udhcp 0.9.8
Tali
 

 
Nomor opsi
55
 
1
Parameter jaringan yang diminta oleh klien. Komposisinya mungkin berbeda

01 — Masker jaringan
03 - Gerbang
06 -DNS
oc — Nama host
0f - nama domain jaringan
1c - alamat permintaan siaran (siaran)
42 - Nama server TFTP
79 - Rute Statis Tanpa Kelas

 
Panjang opsi
8
 
1

 
Nilai opsi
01:03:06:0c:0f:1c:42:79
 
8

 
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER

 
Panjang opsi
18
Desember
1

 
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18

 
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket

DHCPACK

Sebagai konfirmasi bahwa “ya benar, ini adalah alamat IP Anda, dan saya tidak akan memberikannya kepada orang lain” dari server DHCP, paket dalam format DHCPACK dari server ke klien dilayani. Itu dikirim secara siaran seperti paket lainnya. Meskipun, dalam kode di bawah ini untuk server DHCP yang diimplementasikan dengan Python, untuk berjaga-jaga, saya menduplikasi permintaan siaran apa pun dengan mengirimkan paket ke IP klien tertentu, jika sudah diketahui. Selain itu, server DHCP tidak peduli sama sekali apakah paket DHCPACK telah sampai ke klien. Jika klien tidak menerima DHCPACK, maka setelah beberapa saat ia akan mengulangi DHCPREQUEST

Tabel Struktur Paket DHCPACK

Posisi dalam paket
Nama nilai (umum)
Contoh
Pendahuluan
Byte
Klarifikasi

1
Permintaan Booting
2
kutukan
1
Jenis pesan. 1 - permintaan dari klien ke server, 2 - respons dari server ke klien

2
Jenis perangkat keras
1
kutukan
1
Jenis alamat perangkat keras, dalam protokol ini 1 - MAC

3
Panjang alamat perangkat keras
6
kutukan
1
Panjang alamat MAC perangkat

4
Hop
1
kutukan
1
Jumlah rute perantara

5
ID Transaksi
23:lih:de:1d
kutukan
4
Pengidentifikasi transaksi unik. Dihasilkan oleh klien pada awal operasi permintaan

7
Waktu kedua telah berlalu
0
kutukan
4
Waktu dalam hitungan detik sejak awal proses mendapatkan alamat

9
Bendera boot
8000
kutukan
2
Bendera tertentu yang dapat diatur untuk menunjukkan parameter protokol. Dalam hal ini, “siaran” diatur

11
Alamat IP klien
0.0.0.0
Tali
4
Alamat IP klien (jika ada)

15
Alamat IP klien Anda
172.16.134.61
Tali
4
Alamat IP yang ditawarkan oleh server (jika tersedia)

19
Alamat IP server berikutnya
0.0.0.0
Tali
4
Alamat IP server (jika diketahui)

23
Alamat IP agen relai
172.16.114.41
Tali
4
Alamat IP agen relai (misalnya, sakelar)

27
Alamat MAC klien
14:d6:4d:a7:c9:55
kutukan
6
Alamat MAC pengirim paket (klien)

31
Padding alamat perangkat keras klien
 
kutukan
10
Kursi yang dipesan. Biasanya diisi dengan angka nol

41
Nama host server
 
Tali
64
Nama server DHCP. Biasanya tidak menular

105
Nama file boot
 
Tali
128
Nama file di server yang digunakan oleh stasiun tanpa disk saat booting

235
Kue ajaib
63: 82: 53: 63
kutukan
4
Nomor "ajaib", yang menurutnya, termasuk. Anda dapat menentukan bahwa paket ini milik protokol DHCP

Opsi DHCP. Bisa dalam urutan apa pun

236
Nomor opsi
53
Desember
3
Opsi 53, yang mendefinisikan paket DHCP tipe 5 - DHCPACK

 
Panjang opsi
1
Desember
1

 
Nilai opsi
5
Desember
1

 
Nomor opsi
1
Desember
1
Pilihan untuk menawarkan klien DHCP masker jaringan

 
Panjang opsi
4
Desember
1

 
Nilai opsi
255.255.224.0
Tali
4

 
Nomor opsi
3
Desember
1
Pilihan untuk menawarkan gateway default kepada klien DHCP

 
Panjang opsi
4
Desember
1

 
Nilai opsi
172.16.12.1
Tali
4

 
Nomor opsi
6
Desember
1
Pilihan untuk menawarkan DHCP ke klien DNS

 
Panjang opsi
4
Desember
1

 
Nilai opsi
8.8.8.8
Tali
4

 
Nomor opsi
51
Desember
1
Masa pakai parameter jaringan yang dikeluarkan dalam hitungan detik, setelah itu klien DHCP harus memintanya lagi

 
Panjang opsi
4
Desember
1

 
Nilai opsi
86400
Desember
4

 
Nomor opsi
82
Desember
1
Opsi 82, ulangi apa yang ada di DHCPDISCOVER

 
Panjang opsi
18
Desember
1

 
Nilai opsi
01:08:00:06:00
01:01:00:00:01
02:06:00:03:0f
26:4d:ec
Desember
18

 
Akhir paket
255
Desember
1
255 melambangkan akhir dari paket

Instalasi

Instalasi sebenarnya terdiri dari instalasi modul python yang diperlukan untuk bekerja. Diasumsikan MySQL sudah terinstal dan dikonfigurasi.

FreeBSD

pkg install python3 python3 -m surepip pip3 install mysql-connector

Ubuntu

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

Kami membuat database MySQL, mengunggah dump pydhcp.sql ke dalamnya, dan mengkonfigurasi file konfigurasi.

Konfigurasi

Semua pengaturan server ada dalam file xml. Berkas referensi:

1.0 0.0.0.0 255.255.255.255 192.168.0.71 8600 1 255.255.255.0 192.168.0.1 host lokal tes tes pydhcp opsi_8.8.8.8_hex:sw_port82:1:20 pilihan_22_hex:sw_port82:2:16 option_18_hex:sw_mac:82:26 40 pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{option_3_AgentRemoteId_hex}') dan upper(port)=upper('{option_1_AgentCircuitId_port_hex}') pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{sw_mac}') dan upper(port)=upper('{sw_port82}') pilih ip,mask,router,dns dari pengguna di mana upper(mac)=upper('{ClientMacAddress}') masukkan ke dalam nilai riwayat (id,dt,mac,ip,comment) (null,now(),'{ClientMacAddress}','{RequestedIpAddress}','DHCPACK/INFORM')

Sekarang lebih detail tentang tag:

Pada bagian dhcpserver menjelaskan tentang pengaturan dasar untuk memulai server, yaitu:

  • host - alamat IP apa yang didengarkan server pada port 67
  • siaran - ip mana yang disiarkan untuk DHCPOFFER dan DHCPACK
  • DHCPServer - apa ip server DHCP
  • LeaseTime waktu sewa dari alamat IP yang dikeluarkan
  • ThreadLimit - berapa banyak thread yang berjalan secara bersamaan untuk memproses paket UDP yang masuk pada port 67. Ini seharusnya membantu proyek dengan beban tinggi 😉
  • defaultMask,defaultRouter,defaultDNS - apa yang ditawarkan kepada pelanggan secara default jika IP ditemukan di database, tetapi parameter tambahan tidak ditentukan untuknya

bagian mysql:

host, nama pengguna, kata sandi, nama dasar - semuanya berbicara sendiri. Perkiraan struktur database diposting GitHub

Bagian kueri: permintaan untuk menerima PENAWARAN/ACK dijelaskan di sini:

  • offer_count — jumlah baris dengan permintaan yang mengembalikan hasil seperti ip,mask,router,dns
  • offer_n — string kueri. Jika pengembalian kosong, maka jalankan permintaan penawaran berikut
  • history_sql - kueri yang menulis, misalnya, ke "riwayat otorisasi" untuk pelanggan

Permintaan dapat menyertakan variabel apa pun dari bagian opsi atau opsi dari protokol DHCP.

Bagian opsi. Di sinilah hal menjadi lebih menarik. Di sini kita bisa membuat variabel yang nantinya bisa kita gunakan di bagian query.

Sebagai contoh:

option_82_hex:sw_port1:20:22

, baris perintah ini mengambil seluruh baris yang datang dalam opsi permintaan DHCP 82, dalam format hex, dalam kisaran dari 20 hingga 22 byte inklusif dan memasukkannya ke dalam variabel baru sw_port1 (beralih port dari mana permintaan datang)

option_82_hex:sw_mac:26:40

, tentukan variabel sw_mac, ambil hex dari rentang 26:40

Anda dapat melihat semua kemungkinan opsi yang dapat digunakan dalam kueri dengan memulai server dengan tombol -d. Kita akan melihat sesuatu seperti log ini:

--paket DHCPINFORM tiba di port 67, dari 0025224ad764 , b'x91xa5xe0xa3xa5xa9-x8fx8a' , ('172.30.114.25', 68) {'ClientMacAddress': '0025224ad764', 'ClientMacAddressByte': b'x00 7%"Jxd 91d' , ' HType': 'Ethernet', 'HostName': b'x5xa0xe3xa5xa9xa8-x8fx43a', 'ReqListDNS': Benar, 'ReqListDomainName': Benar, 'ReqListPerfowmRouterDiscover': Benar, 'ReqListRouter': Benar, 'ReqListStaticRoute': Benar, 'ReqListSubnetM tanya ': Benar, 'ReqListVendorSpecInfo': 0.0.0.0, 'RequestedIpAddress': '5.0', 'Vendor': b'MSFT 0025224', 'chaddr': '764ad172.30.128.13', 'ciaddr': '00' , 'bendera': b'x00x172.30.114.25', 'giaddr': '308', 'gpoz': 6, 'hlen': 1, 'hops': 82, 'htype': 'MAC', 'magic_cookie': b'cx12Sc ', 'op': 'DHCPINFORM', 'option12': 53, 'option53': 55, 'option55': 60, 'option60': 61, 'option61': 82, 'option82': 82, ' option_12_byte': b'x01x06x00x04x00x01x00x06x02x08x00x06' b'x00x1x9eXx2exb82xad', 'option_12010600040001000602080006001_hex': '589e2eb82ad', 'option_ 18_len': 82 12, 'option_01_str': "b'x06x00x04x00x01x00x06x02x08x00x06x00x1x9x2eXx768exb0.0.0.0xad'", 'hasil': Salah, 'detik': 001, 'siaddr': '589', 'sw_mac': '2e1eb06ad', 'sw_port89': '8', 'xidbyte': b'

Oleh karena itu, kita bisa menggabungkan variabel apa pun dalam {} dan variabel tersebut akan digunakan dalam kueri SQL.

Mari kita catat riwayat bahwa klien menerima alamat IP:

Server DHCP+Mysql dengan Python

Server DHCP+Mysql dengan Python

Server mulai

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

— d mode keluaran konsol DEBUG
- c file konfigurasi <nama file>

Tanya jawab

Dan sekarang detail lebih lanjut tentang implementasi server dengan Python. Ini menyakitkan. Python dipelajari dengan cepat. Banyak momen yang dibuat dengan gaya “wow, entah bagaimana saya berhasil.” Tidak dioptimalkan sama sekali, dan dibiarkan dalam bentuk ini terutama karena sedikit pengalaman dalam pengembangan Python. Saya akan membahas aspek paling menarik dari implementasi server dalam "kode".

Pengurai file konfigurasi XML

Modul Python standar xml.dom digunakan. Tampaknya sederhana, tetapi selama implementasi terdapat kurangnya dokumentasi dan contoh yang jelas di jaringan yang menggunakan modul ini.

    tree = minidom.parse(gconfig["config_file"]) mconfig=tree.getElementsByTagName("mysql") untuk elem di mconfig: gconfig["mysql_host"]=elem.getElementsByTagName("host")[0].firstChild.data gconfig["mysql_username"]=elem.getElementsByTagName("username")[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") untuk elem di 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("query") untuk elem di qconfig: gconfig["offer_count"]=elem.getElementsByTagName("offer_count")[0].firstChild.data untuk num in rentang(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 options=tree.getElementsByTagName("options") untuk elem dalam opsi: node=elem.getElementsByTagName("option") untuk opsi dalam node : optionsMod.append(options.firstChild.data)

Multithread

Anehnya, multithreading dengan Python diimplementasikan dengan sangat jelas dan sederhana.

def PacketWork(data,addr): ... # implementasi parsing paket masuk dan meresponnya... while True: data, addr = udp_socket.recvfrom(1024) # menunggu paket UDP thread = threading.Thread( target=PacketWork , args=(data,addr,)).start() # yang muncul - kami meluncurkan fungsi PacketWork yang telah ditentukan sebelumnya di latar belakang dengan parameter saat threading.active_count() >gconfig["dhcp_ThreadLimit"]: waktu. tidur(1) # jika jumlah thread yang berjalan lebih banyak daripada yang ada di pengaturan, kita tunggu hingga jumlahnya lebih sedikit

Menerima/mengirim paket DHCP

Untuk mencegat paket UDP yang datang melalui kartu jaringan, Anda perlu “menaikkan” soket:

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

, di mana benderanya berada:

  • AF_INET - berarti format alamatnya adalah IP: port. Mungkin juga ada AF_UNIX - yang alamatnya diberikan berdasarkan nama file.
  • SOCK_DGRAM - berarti kami tidak menerima "paket mentah", tetapi paket yang telah melewati firewall, dan dengan paket yang dipotong sebagian. Itu. kami hanya menerima paket UDP tanpa komponen “fisik” dari pembungkus paket UDP. Jika Anda menggunakan flag SOCK_RAW, Anda juga perlu mengurai “wrapper” ini.

Mengirim paket bisa seperti siaran:

                    udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #alihkan soket ke mode siaran rz=udp_socket.sendto(packetack, (gconfig["broadcast"],68))

, dan ke alamat “dari mana paket itu berasal”:

                        udp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # alihkan soket ke mode multi-listener rz=udp_socket.sendto(packetack, addr)

, di mana SOL_SOCKET berarti “tingkat protokol” untuk opsi pengaturan,

, SO_BROADCAST pilihan paket helmnya adalah “broadcast”

  , Opsi SO_REUSEADDR mengalihkan soket ke mode "banyak pendengar". Secara teori, hal ini tidak diperlukan dalam kasus ini, tetapi pada salah satu server FreeBSD yang saya uji, kode tidak akan berfungsi tanpa opsi ini.

Mengurai paket DHCP

Di sinilah saya sangat menyukai Python. Ternyata di luar kotak itu memungkinkan Anda menjadi cukup fleksibel dengan bytecode. Memungkinkannya untuk dengan mudah diterjemahkan ke dalam nilai desimal, string dan hex - mis. inilah yang sebenarnya kita perlukan untuk memahami struktur paket. Jadi, misalnya, Anda bisa mendapatkan rentang byte dalam HEX dan hanya byte:

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

, kemas byte ke dalam struktur:

res["bendera"]=paket('BB',data[10],data[11])

Dapatkan IP dari struktur:

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

Dan sebaliknya:

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

Itu saja untuk saat ini 😉

Sumber: www.habr.com

Tambah komentar