Server DHCP asli menggunakan bash

Saya suka mengotomatiskan proses dan menulis sepeda motor saya sendiri untuk mempelajari materi ini atau itu. Tujuan baru saya adalah server DHCP, yang akan mengeluarkan alamat di jaringan kecil sehingga konfigurasi awal peralatan dapat dibuat.

Pada artikel ini saya akan berbicara sedikit tentang protokol DHCP dan beberapa seluk-beluk dari bash.



Hasil akhir


Mari kita mulai dari akhir, sehingga jelas apa yang kita perjuangkan.

Demonstrasi kerja:



Repositori dengan skrip: firemoon777 / bash-dhcp-server

Masalah awal


Konfigurasi yang saya butuhkan dilakukan dengan cara ini: kita terhubung langsung melalui kabel twisted pair ke peralatan, mengeluarkan alamat sementara melalui DHCP, dan mengkonfigurasinya dengan skrip yang sudah dibuat. Dan sepuluh hingga dua puluh kali berturut-turut.

Bagi banyak orang, server-isc-dhcp yang terkenal melakukan tugasnya dengan sempurna, tetapi, sayangnya, itu tidak memberi tahu skrip saya bahwa alamat tersebut dikeluarkan, jadi Anda harus memblokir eksekusi sampai alamat tersebut dikeluarkan.

Solusinya, tampaknya, adalah di permukaan: ping sampai biru di wajah, sampai peralatan merespons:

while ! ping -c1 -W1 "$DHCP" | grep -q "time=" do echo "Waiting for $DHCP..." done 

Tetapi keputusan ini jelas tidak memiliki petualangan.

Bagian teoretis


Memperoleh alamat dengan satu server DHCP



Protokol DHCP berfungsi melalui UDP pada port 67 dan 68. Server selalu berfungsi hanya pada 67, dan klien hanya pada 68. Karena klien tidak memiliki alamat (memiliki alamat 0.0.0.0), paket DHCP disiarkan. Yaitu klien selalu mengirim paket ke alamat 255.255.255.255:67 dari alamat 0.0.0.0:68, dan server mengirim dari alamatnya: 67 ke alamat 255.255.255.255.255:68.

Klien menerima alamat dalam empat paket ( DORA ):

  1. Klien mencari tahu di mana server DHCP ( D iscover)
  2. Server merespons dan menawarkan alamatnya ( O ffer)
  3. Klien meminta alamat yang diusulkan dari server tertentu ( R equest)
  4. Server setuju dan mengeluarkan alamat ( A ck)

Secara visual, skema dapat direpresentasikan sebagai berikut:



Memperoleh alamat dengan beberapa server DHCP



Ketika klien mengirim Discover, semua server yang dapat mendengar mengirim Penawaran mereka ke klien. Tetapi klien harus memilih satu. Pilihan klien diumumkan dalam pesan Permintaan dengan opsi 54 (server DHCP), yang berisi alamat IP dari server DHCP yang disukai. Meskipun Permintaan juga dikirimkan kepada semua orang di jaringan, hanya server DHCP yang IP-nya ditentukan dalam opsi 54 yang akan merespons.



Isi paket DHCP


Paket DHCP terdiri dari dua bagian: konstanta, ukuran 236 byte, dan variabel yang membawa opsi (Opsi DHCP).

Tabel dengan semua bidang paket DHCP dari Wikipedia
LapanganDeskripsiPanjang (dalam byte)
op
Jenis pesan. Misalnya, dapat mengambil nilai: BOOTREQUEST (0x01, permintaan dari klien ke server) dan BOOTREPLY (0x02, respons dari server ke klien).
1
htype
Jenis alamat perangkat keras. Nilai yang valid untuk bidang ini didefinisikan dalam RFC 1700 Assigned Numbers. Misalnya, untuk alamat MAC Ethernet, bidang ini disetel ke 0x01.
1
hlen
Panjang alamat perangkat keras dalam byte. Alamat MAC Ethernet adalah 0x06.
1
hop
Jumlah router perantara (yang disebut agen relai DHCP ) yang dilaluinya pesan tersebut. Klien menetapkan bidang ini ke 0x00.
1
xid
Pengidentifikasi transaksi unik sebesar 4 byte yang dihasilkan oleh klien pada awal proses mendapatkan alamat.
4
dtk
Waktu dalam detik sejak dimulainya proses mendapatkan alamat. Mungkin tidak digunakan (dalam hal ini diatur ke 0x0000).
2
bendera
Field untuk flag adalah parameter khusus dari protokol DHCP.
2
ciaddr
Alamat IP klien. Itu diisi hanya jika klien sudah memiliki alamat IP sendiri dan mampu menanggapi permintaan ARP (ini dimungkinkan jika klien melakukan prosedur untuk memperbarui alamat setelah masa sewa berakhir).
4
yiaddr
Alamat IP klien baru yang diusulkan oleh server.
4
siaddr
Alamat IP server. Kembali dalam klausa DHCP (lihat di bawah).
4
giaddr
Alamat IP agen relai, jika ada yang terlibat dalam proses pengiriman pesan DHCP ke server.
4
chaddr
Alamat perangkat keras (biasanya alamat MAC) klien.
16
sname
Nama server opsional sebagai string yang diakhiri dengan nol.
64
file
Nama file server opsional yang digunakan oleh stasiun kerja tanpa disk saat mengunduh dari jarak jauh. Seperti halnya sname , ia direpresentasikan sebagai string yang diakhiri dengan null.
128
opsi
Bidang opsi DHCP . Berbagai opsi konfigurasi tambahan ditunjukkan di sini. Pada awal bidang ini, empat byte khusus dengan nilai 99, 130, 83, 99 ("angka ajaib") ditunjukkan, memungkinkan server untuk menentukan keberadaan bidang ini. Bidang memiliki panjang variabel, tetapi klien DHCP harus siap untuk menerima pesan DHCP 576-byte (dalam pesan ini, bidang opsi panjangnya 340 byte).
variabel


Daftar semua opsi DHCP di RFC 2132

Opsi DHCP dikodekan sebagai berikut:
NomorPanjangnyaData

Misalnya, parameter 3 (gateway yang diusulkan) dengan nilai 10.0.0.1:
3410001

Jika Anda perlu melewati beberapa parameter, panjang parameter akan meningkat.
Misalnya, dalam parameter 6 (server DNS) kami akan mengirimkan dua alamat (1.1.1.1 dan 8.8.4.4):
6811118844

Tanda akhir bidang opsi adalah parameter dengan angka 255 (0xFF) dan panjang 0.

Paling sering, klien menempatkan parameter 55 (daftar parameter yang ingin ia terima sebagai respons) di DHCP Discover, namun, kami memiliki hak untuk memberinya bukan semua yang ia minta.

Bagian praktis


Pada awalnya direncanakan untuk menulis server dalam beberapa bahasa yang lebih cocok (C) untuk ini, namun, itu akan menjadi biasa dan sederhana. Entah menulis skrip yang akan mengambil alih fungsi server dhcp.

Penyederhanaan


Karena server yang dikembangkan seharusnya digunakan dalam jaringan dua node yang terhubung oleh sebuah tambalan, penyederhanaan berikut diadopsi:

  • dijamin bahwa satu klien di jaringan;
  • dijamin tidak ada lagi server dhcp di jaringan
  • inisiator memutuskan alamat mana yang akan diterbitkan
  • Rilis DHCP dan Penurunan DHCP diabaikan

Pendengar


Pertama-tama, Anda perlu belajar cara menerima paket. Ini membutuhkan pendengar simpatik yang bersertifikat , misalnya, nc. Tetapi tidak setiap nc cocok untuk tujuan ini. OpenBSD netcat 1.130 dari Debian cocok, tetapi 1,105 dengan Ubuntu hilang. Jalankan nc untuk mendengarkan semua paket UDP yang tiba di port 67.

 nc -l 0.0.0.0 -up 67 -w0 

Netcat OpenBSD juga diperlukan karena saklar -w dengan nilai 0. Setelah menerima satu paket (UDP Broadcast), nc tradisional tidak menerima lebih banyak paket, tetapi tidak berakhir.

Penanganan byte mentah


Dalam shell, sangat sulit untuk bekerja dengan karakter yang tidak dapat dicetak, seperti karakter nol: itu hanya mengabaikannya. Paket DHCP berisi banyak byte 0x00 (misalnya, bidang file). Solusi untuk masalah ini datang dalam bentuk hex-dump:

  nc -l 0.0.0.0 -up 67 -w0 | stdbuf -o0 od -v -w1 -t x1 -An 

Satu byte per baris, tanpa mengeluarkan alamat, tanpa melewatkan byte duplikat. Anda juga dapat membumbui stdbuf -o0 sehingga output tidak buffered.

Menerima, menyimpan, dan memproses paket


Dari perintah od stdout, byte diambil oleh perintah read dan ditambahkan ke array.

 msg=() for i in {0..235}; do read -r tmp msg[$i]=$tmp done 

Meskipun semua nilai ditransmisikan dalam notasi heksadesimal, nomor Opsi DHCP dan panjang opsi paling baik ditampilkan pada layar / dalam log dalam bentuk desimal biasa. Untuk melakukan ini, Anda dapat menggunakan bash'a entri pendek:

 $ op=AC $ echo $((16#$op)) 172 

Paket yang diterima diedit sesuai dengan jenis permintaan (Temukan atau Permintaan) dan dikirim kembali.

Tanggapan


Namun, mengirim paket bukanlah tugas yang mudah. Pertama, Anda perlu mengkonversi byte dari dump ke byte mentah dan mengirim semuanya sekaligus dengan satu paket.

Konversi dapat dilakukan dengan utilitas printf menggunakan urutan melarikan diri. Dan agar tidak ada yang hilang, segera tulis byte ke sebuah file.

 #   >/tmp/dhcp.payload #     for i in ${msg[*]}; do printf "\x$i" >> /tmp/dhcp.payload done 

Netcat OpenBSD juga digunakan untuk pengiriman. Namun, jika versi 1.105 dengan Ubuntu cocok sebagai pendengar, itu tidak cocok untuk menyiarkan pesan UDP: kami mendapatkan protokol tidak ada kesalahan.

 cat /tmp/dhcp.payload | nc -ub 255.255.255.255 68 -s $SERVER -p 67 -w0 

Switch -b memungkinkan pesan siaran dikirim, dan ini adalah alasan kedua mengapa server harus dijalankan dari bawah superuser.

Apa batasannya?


Server DHCP ini dirancang dengan penyederhanaan seperti satu klien di jaringan. Namun, ini akan bekerja dengan beberapa klien. Dapatkan saja alamat tercepat.



Kesimpulan


Walaupun skrip bash hampir tidak bisa disebut bahasa pemrograman lengkap, namun, dengan keinginan yang sesuai, Anda bahkan dapat menyelesaikan masalah seperti mengeluarkan alamat IP pada jaringan tanpa menggunakan perangkat lunak yang dirancang khusus untuk ini. Dan memecahkan masalah spesifik tidak hanya membawa kegembiraan, tetapi juga pengetahuan baru yang terbuka pada saat solusi.

Sumber


  1. DHCP - Wikipedia
  2. Parameter DHCP dan BOOTP - IANA

Source: https://habr.com/ru/post/id435148/


All Articles