Serangan lapisan 7 pada situs antara lain serangan pada lapisan server web (nginx, apache, dll.) Dan serangan pada lapisan server aplikasi (php-fpm, nodejs, dll.), Yang biasanya terletak di belakang server proxy (nginx, apache , dll.). Dari perspektif protokol jaringan, keduanya adalah serangan lapisan aplikasi. Tetapi kami, dari sudut pandang praktis, perlu memisahkan kedua kasus ini. Server web (nginx, apache, dll.), Sebagai aturan, secara independen menyediakan file statis (gambar, gaya, skrip), dan permintaan proxy untuk konten dinamis ke server aplikasi (php-fpm, nodejs, dll.)). Permintaan inilah yang menjadi target serangan, karena, tidak seperti permintaan statis, server aplikasi saat membuat konten dinamis memerlukan beberapa kali lipat sumber daya sistem yang lebih terbatas, yang digunakan oleh penyerang.
Meski kedengarannya basi, untuk bertahan dari serangan, itu harus diidentifikasi terlebih dahulu. Faktanya, serangan DDoS tidak hanya dapat menyebabkan kegagalan situs, tetapi juga alasan lain yang terkait dengan kesalahan oleh pengembang dan administrator sistem. Untuk kenyamanan analisis, Anda perlu menambahkan parameter $ request_time ke format log nginx (maaf, saya tidak memiliki opsi dengan apache), dan mencatat permintaan ke server aplikasi dalam file terpisah:
log_format timed '$remote_addr - $remote_user [$time_local] '
'$host:$server_port "$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ($request_time s.)';
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
access_log /var/log/ngunx/application_access.log timed;
}
Setelah menerima log ke server aplikasi dalam file terpisah (tanpa log statik) dan dengan waktu permintaan dalam hitungan detik, Anda dapat dengan cepat mengidentifikasi saat serangan dimulai, saat jumlah permintaan dan waktu respons mulai meningkat tajam.
Setelah mengidentifikasi serangan tersebut, Anda dapat melanjutkan ke pertahanan.
Seringkali, administrator sistem mencoba melindungi situs dengan membatasi jumlah permintaan dari satu alamat IP. Untuk melakukan ini, gunakan 1) arahan nginx limit_req_zone ( lihat dokumentasi ), 2) fail2ban dan 3) iptables. Tentu saja, metode ini harus digunakan. Namun, metode perlindungan ini tidak efektif selama 10-15 tahun. Ada dua alasan untuk ini:
1) Lalu lintas yang dihasilkan oleh jaringan bot selama serangan di tingkat ke-7 mungkin lebih kecil volumenya daripada lalu lintas pengunjung situs biasa, karena pengunjung situs biasa memiliki satu permintaan "berat" ke server aplikasi (php-fpm , nodejs, dll.) Ada sekitar 100 permintaan "ringan" untuk mengunduh file statis yang dikirim oleh server web (nginx, apache, dll.). Iptables tidak melindungi permintaan tersebut, karena dapat membatasi lalu lintas hanya dengan indikator kuantitatif, dan tidak memperhitungkan pemisahan permintaan menjadi statika dan dinamika.
2) Alasan kedua adalah distribusi jaringan bot (huruf pertama adalah D dalam singkatan DDoS). Serangan tersebut biasanya melibatkan jaringan beberapa ribu bot. Mereka mampu membuat permintaan lebih jarang dari rata-rata pengguna. Biasanya, saat menyerang situs, penyerang secara empiris menghitung parameter limit_req_zone dan fail2ban. Dan mengkonfigurasi jaringan bot sehingga perlindungan ini tidak berfungsi. Seringkali, administrator sistem mulai meremehkan parameter ini, sehingga menonaktifkan klien nyata, sementara tidak banyak menghasilkan perlindungan dari bot.
Agar berhasil melindungi situs dari DDoS, semua cara perlindungan yang mungkin digunakan di server dalam kompleks harus digunakan. Dalam posting saya sebelumnya tentang topik ini, perlindungan DDoS di tingkat server webada link ke materi tentang cara mengkonfigurasi iptables, dan parameter kernel sistem apa yang perlu disesuaikan dengan nilai optimal (artinya, pertama-tama, jumlah file dan soket yang terbuka). Ini adalah prasyarat, perlu, tetapi bukan kondisi yang cukup untuk perlindungan dari bot.
Selain itu, perlu membangun perlindungan berdasarkan bot pendeteksi. Semua yang diperlukan untuk memahami mekanisme pendeteksian bot dijelaskan secara mendetail dalam artikel historis di Habré Modul nginx untuk memerangi DDoS oleh penulis kyprizel , dan diimplementasikan di pustaka penulis yang sama testcookie-nginx-module
Ini adalah perpustakaan C dan terus dikembangkan oleh komunitas kecil penulis. Mungkin, tidak semua administrator sistem siap untuk mengompilasi pustaka asing di server produksi. Jika Anda perlu membuat perubahan tambahan pada pekerjaan perpustakaan, maka ini sepenuhnya di luar cakupan administrator atau pengembang sistem biasa. Untungnya, sekarang ada fitur baru: bahasa scripting Lua yang dapat dijalankan di server nginx. Ada dua versi populer nginx dengan mesin skrip Lua bawaan: openresty, yang awalnya terinspirasi oleh Taobao, lalu Cloudfare, dan nginx-extras, yang disertakan dengan beberapa distribusi Linux, seperti Ubuntu. Kedua opsi menggunakan pustaka yang sama, jadi tidak ada bedanya mana yang akan digunakan.
Perlindungan bot dapat didasarkan pada penentuan kemampuan klien web untuk 1) mengeksekusi kode JavaScript, 2) melakukan pengalihan, dan 3) menyetel cookie. Dari semua metode ini, eksekusi kode JavaScript ternyata paling tidak menjanjikan, dan saya menolaknya, karena kode JavaScript tidak dieksekusi jika konten dimuat dengan permintaan latar belakang (ajax), dan memuat ulang halaman menggunakan JavaScript mendistorsi statistik transisi ke situs (sejak judul Referer). Dengan demikian, ada pengalihan yang mengatur cookie, yang nilainya tunduk pada logika yang tidak dapat direproduksi pada klien, dan tidak mengizinkan klien ke situs tanpa cookie ini.
Dalam pekerjaan saya, saya mengandalkan pustaka leeyiw / ngx_lua_anticc, yang saat ini tidak dikembangkan, dan saya melanjutkan peningkatan pada garpu apapacy / ngx_lua_anticc saya , karena pekerjaan pustaka asli tidak sesuai untuk semuanya.
Untuk mengoperasikan penghitung kueri di pustaka, tabel memori digunakan, yang mendukung metode incr, nyaman untuk menambah nilai penghitung, dan menyetel nilai dengan TTL. Misalnya, cuplikan kode berikut menambah jumlah permintaan dari satu alamat IP jika klien tidak memiliki cookie dengan kumpulan nama tertentu. Jika penghitung belum diinisialisasi, penghitung akan diinisialisasi ke 1 dengan TTL 60 detik. Setelah melebihi jumlah permintaan 256 (dalam 60 detik), klien tidak diperbolehkan ke situs:
local anticc = ngx.shared.nla_anticc
local remote_id = ngx.var.remote_addr
if not cookies[config.cookie_name] then
local count, err = anticc:incr(remote_id, 1)
if not count then
anticc:set(remote_id, 1, 60)
count = 1
end
if count >= 256 then
if count == 256 then
ngx.log(ngx.WARN, "client banned by remote address")
end
ngx.exit(444)
return
end
end
Tidak semua bot berbahaya. Misalnya, Anda harus melewati bot pencarian dan bot sistem pembayaran yang melaporkan perubahan status pembayaran ke situs. Ada baiknya jika Anda dapat membuat daftar semua alamat IP dari mana permintaan tersebut dapat datang. Dalam kasus ini, Anda dapat membuat daftar "putih":
local whitelist = ngx.shared.nla_whitelist
in_whitelist = whitelist:get(ngx.var.remote_addr)
if in_whitelist then
return
end
Tetapi ini tidak selalu memungkinkan. Salah satu masalahnya adalah ketidakpastian dengan alamat bot Google. Melewati semua bot yang meniru bot Google sama saja dengan menghilangkan perlindungan dari situs tersebut. Oleh karena itu, kami akan menggunakan modul resty.exec untuk menjalankan perintah host:
local exec = require 'resty.exec'
if ngx.re.find(headers["User-Agent"],config.google_bots , "ioj") then
local prog = exec.new('/tmp/exec.sock')
prog.argv = { 'host', ngx.var.remote_addr }
local res, err = prog()
if res and ngx.re.find(res.stdout, "google") then
ngx.log(ngx.WARN, "ip " .. ngx.var.remote_addr .. " from " .. res.stdout .. " added to whitelist")
whitelist:add(ngx.var.remote_addr, true)
return
end
if res then
ngx.log(ngx.WARN, "ip " .. ngx.var.remote_addr .. " from " .. res.stdout .. "not added to whitelist")
else
ngx.log(ngx.WARN, "lua-resty-exec error: " .. err)
end
end
Pengalaman menunjukkan bahwa strategi perlindungan seperti itu memungkinkan Anda melindungi situs dari kelompok serangan tertentu, yang sering digunakan untuk persaingan tidak sehat. Memahami mekanisme serangan dan metode perlindungan membantu menghemat banyak waktu pada upaya yang tidak berhasil untuk bertahan dari fail2ban, dan saat menggunakan perlindungan pihak ketiga (misalnya dari Cloudfare), pilih parameter perlindungan dengan lebih hati-hati.
apapacy@gmail.com
9 Mei 2021