ModSecurity: Instalasi
Cara Set Up mod_security dengan Apache di Debian / Ubuntu
Mod security adalah Web Application Firewall (WAF) gratis yang bekerja dengan Apache, Nginx dan IIS. Mendukung aturan yang fleksibel untuk melakukan operasi sederhana dan kompleks dan dilengkapi dengan Core Rule Set (CRS) yang memiliki aturan untuk injeksi SQL, cross site scripting scripting, Trojans, user agen yang jahat, session hijacking dan banyak eksploit lainnya. Untuk Apache, ini adalah modul tambahan yang membuatnya mudah untuk menginstal dan mengkonfigurasi.
Dalam rangka untuk menyelesaikan tutorial ini, Anda akan perlu LAMP diinstal pada server anda.
Kebutuhan
- Instalasi Ubuntu LTS server, or yang terbaru di mesin anda.
- Instalasi Apache2 webserver, di setup dan di konfigurasi:
sudo add-apt-repository ppa:ondrej/php sudo apt-get update
apt-get install apache2 php7.0 php7.0-xmlrpc php7.0-mysql php7.0-gd php7.0-cli \ php7.0-curl mysql-client mysql-server dovecot-common dovecot-imapd \ dovecot-pop3d postfix php7.0 php5.6 \ php5.6-mysql php5.6-mbstring php-mbstring php7.0-mbstring \ php-xdebug libapache2-mod-php5.6 libapache2-mod-php7.0
- Instalasi dependensi yang dibutuhkan untuk modsecurity
sudo apt-get install libxml2 libxml2-dev libxml2-utils \ libaprutil1 libaprutil1-dev
- Untuk mengguna 64bit, perlu menambahkan link berikut
ln -s /usr/lib/x86_64-linux-gnu/libxml2.so /usr/lib/libxml2.so ln -s /usr/lib/x86_64-linux-gnu/libxml2.so.2 /usr/lib/libxml2.so.2 ln -s /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1 /usr/lib/libxml2.so.2.9.1
Instalasi mod_security
Instalasi ModSecurity
sudo su apt-get install libapache2-modsecurity modsecurity-crs
Untuk ubuntu 22.04
sudo su apt-get install libapache2-mod-security2 modsecurity-crs
Periksa apakah modul mod_security dimuat.
apachectl -M | grep --color security
Akan keluar
security2_module (shared)
Anda akan melihat modul bernama security2_module (shared) yang menunjukkan bahwa modul dimuat.
Instalasi ModSecurity meliputi file konfigurasi yang disarankan yang harus diganti:
mv /etc/modsecurity/modsecurity.conf{-recommended,}
Reload Apache
service apache2 reload
Cek directory log Apache, akan ada file
ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Mar 30 14:07 /var/log/apache2/modsec_audit.log
Konfigurasi mod_security
Apa adanya, ModSecurity tidak melakukan apa-apa karena kebutuhan aturan untuk bekerja. File konfigurasi default diset ke DetectionOnly yang mencatat permintaan sesuai dengan aturan yang cocok dan tidak memblokir apa-apa. Hal ini dapat diubah dengan mengedit file modsecurity.conf:
nano /etc/modsecurity/modsecurity.conf
Temukan kalimat ini
SecRuleEngine DetectionOnly
Ubah menjadi
SecRuleEngine On
Jika Anda mencoba ini pada server produksi, ubah direktif ini hanya setelah menguji semua aturan Anda.
Direktif lain yang perlu dimodifikasi adalah SecResponseBodyAccess. Ini mengkonfigurasi apakah tubuh respon dibuffered (yaitu dibaca oleh ModSecurity). Ini hanya diperlukan jika deteksi kebocoran data dan perlindungan diperlukan. Oleh karena itu, membiarkannya On akan menggunakan sumber daya droplet dan juga meningkatkan ukuran logfile.
Temukan
SecResponseBodyAccess On
Ubah menjadi
SecResponseBodyAccess Off
Sekarang kita akan membatasi data maksimum yang dapat diposting ke aplikasi web Anda. Dua parameter yang mengkonfigurasi ini:
SecRequestBodyLimit SecRequestBodyNoFilesLimit
Parameter SecRequestBodyLimit menentukan ukuran data POST maksimal. Jika ada yang lebih besar dikirim oleh client maka server akan merespon dengan error 413 Request Entity Too Large. Jika aplikasi web Anda tidak memiliki file upload nilai ini dapat sangat dikurangi.
Nilai yang disebutkan dalam file konfigurasi
SecRequestBodyLimit 13107200
yaitu 12.5MB.
Sama dengan cara di atas adalah parameter SecRequestBodyNoFilesLimit . Perbedaan terutama pada besarnya data yang di POST dikurangi file uploads -- nilai ini sebaiknya "sekecil-kecilnya yang memungkinkan".
Nilai yang disebutkan dalam file konfigurasi
SecRequestBodyNoFilesLimit 131072
yaitu 128KB.
Diantara parameter-parameter diatas, parameter yang mungkin akan sangat mempengaruhi performance adalah SecRequestBodyInMemoryLimit. Parameter ini menentukan berapa banyak "request body" data (POST data) yang akan di simpan di RAM, selebihnya akan di simpan di harddisk (seperti swap). Jika kita menggunakan SSD, maka hal ini bukan sebuah masalah besar. Kita dapat menset lebih besar jika kita mempunyai RAM lebih,
SecRequestBodyInMemoryLimit 131072
Nilai ini 128KB seperti yang di set di file konfigurasi.
Testing SQL Injection
Sebelum melanjutkan dengan konfigurasi aturan, kita akan membuat script PHP yang rentan terhadap injeksi SQL dan mencobanya. Harap dicatat bahwa ini hanyalah sebuah script PHP untuk login tanpa penanganan sesi. Pastikan untuk mengganti password MySQL di script di bawah ini sehingga akan terhubung ke database:
/var/www/html/login.php
Jika password root MySQL adalah 123456, maka isinya
<html> <body> <?php if(isset($_POST['login'])) { $username = $_POST['username']; $password = $_POST['password']; $con = mysqli_connect('localhost','root','123456','sample'); $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'"); if(mysqli_num_rows($result) == 0) echo 'Invalid username or password'; else echo 'Logged in - A Secret for you....'; } else { ?> <form action="" method="post"> Username: <input type="text" name="username"/>
Password: <input type="password" name="password"/>
<input type="submit" name="login" value="Login"/> </form> <?php } ?> </body> </html>
Script ini akan menampilkan form login. Dengan memasukan password yang tepat akan menampilkan pesan "A Secret for you."
Kita perlu password dalam database. Buat database MySQL dan table, kemudian masukkan username dan password.
mysql -u root -p123456
create database sample; connect sample; create table users(username VARCHAR(100),password VARCHAR(100)); insert into users values('jesin','pwd'); insert into users values('alice','secret'); quit;
Buka browser, masuk ke
http://ip-address-web-anda/login.php
misalnya
http://192.168.0.100/login.php
dan masukan pasangan kredensial
Username: jesin Password: pwd
Kita akan melihat message yang mengindikasikan login sukses. Coba lagi, tapi masukan pasangan kredential yang salah -- kita akan melihat message
Invalid username or password
Langkah selanjutnya, kita dapat mencoba SQL injection untuk mem-bypass login page. Masukan perintah berikut di username:
' or true --
Perhatikan ada "spasi" sesudah -- , jika "spasi" tidak di tambahkan sesudah -- maka SQL injection ini tidak akan jalan. Biarkan password kosong. Tekan tombol login.
Simsalabim! script akan memperlihatkan semua message yang harusnya untuk user yang terauthentikasi!
Set Up Rules / Aturan
Untuk membuat hidup kita lebih mudah, akan banyak aturan yang di install bersama dengan mod_security. Hal ini di sebut CRS (Core Rule Set) dan lokasinya di
ls -l /usr/share/modsecurity-crs/
total 44 drwxr-xr-x 2 root root 4096 Mar 31 06:15 activated_rules drwxr-xr-x 2 root root 4096 Mar 31 06:15 base_rules drwxr-xr-x 2 root root 4096 Mar 31 06:15 experimental_rules drwxr-xr-x 2 root root 4096 Mar 31 06:15 lua -rw-r--r-- 1 root root 13774 Jul 13 2013 modsecurity_crs_10_setup.conf drwxr-xr-x 2 root root 4096 Mar 31 06:15 optional_rules drwxr-xr-x 2 root root 4096 Mar 31 06:15 slr_rules drwxr-xr-x 8 root root 4096 Mar 31 06:15 util
Dokumen tersedia di
ls -l /usr/share/doc/modsecurity-crs/
total 16 -rw-r--r-- 1 root root 623 Jul 12 2013 changelog.Debian.gz -rw-r--r-- 1 root root 1297 Jul 2 2012 copyright -rw-r--r-- 1 root root 1138 Mar 16 2012 README.Debian -rw-r--r-- 1 root root 1485 Jul 2 2013 README.md
Untuk me-load aturan / rules ini, kita perlu memberitahukan Apache untuk melihat directory tersebut. Edit file mod-security.conf
vi /etc/apache2/mods-enabled/security2.conf
Tambahkan aturan berikut di dalam <IfModule security2_module> </IfModule>:
Include "/usr/share/modsecurity-crs/*.conf" Include "/usr/share/modsecurity-crs/activated_rules/*.conf"
Directory activated_rules sama dengan directory mods-enabled pada Apache. Rules / Aturan yang ada tersedia di directory:
/usr/share/modsecurity-crs/base_rules /usr/share/modsecurity-crs/optional_rules /usr/share/modsecurity-crs/experimental_rules
Kita perlu membuat symlinks di dalam directory activated_rules untuk mengaktifkan aturan tersebut.
Contoh, untuk mengaktifkan rules / aturan SQL injection.
cd /usr/share/modsecurity-crs/activated_rules/ ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .
Apache harus di reload agar rules beroperasi / berefek.
service apache2 reload
Sekarang buka halaman login yang kita buat sebelumnya dan coba menggunakan SQL injection query pada kolom username. Jika kita sudah mengubah SecRuleEngine menjadi On, kita akan melihat 403 Forbidden error.
Jadi semua tergantung pada opsi DetectionOnly, injection akan berhasil tapi akan tercatat pada file modsec_audit.log .
Menulis Rules mod_security sendiri
Pada bagian ini, kita akan mencoba membuat aturan yang akan memblok request juga ada kata-kata "yang tidak di inginkan" di masukan ke dalam form HTML.
Pertama-tama, kita akan membuat script PHP yang akan mengambil input dari textbox dan akan menampilkannya kembali ke user.
/var/www/html/form.php
isinya
<html> <body> <?php if(isset($_POST['data'])) echo $_POST['data']; else { ?> <form method="post" action=""> Enter something here:<textarea name="data"></textarea> <input type="submit"/> </form> <?php } ?> </body> </html>
Custom rules dapat di tambahkan ke semua file konfigurasi atau di letakan di directory modsecurity. Kita akan mencoba untuk menempatkan aturan / rules kita di sebuah file baru:
vi /etc/modsecurity/modsecurity_custom_rules.conf
Tambahkan perintah kalimat berikut:
SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'" SecRule REQUEST_METHOD "POST" chain SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"
Save file kemudian reload Apache. Buka lagi
http://websiteanda.com/form.php
atau (contoh)
http://192.168.0.100/form.php
Masuk ke browser dan masukan text yang ada kata-kata: pills, insurance, rolex.
Anda akan akan melihat halman 403 dan catatan di log, atau hanya catatan di log berdasarkan konfigurasi SecRuleEngine. Sintaks untuk SecRule adalah
SecRule VARIABLES OPERATOR [ACTIONS]
Disini kita menggunakan chain action untuk mencocokan variable REQUEST_FILENAME dengan form.php, REQUEST_METHOD dengan POST dan REQUEST_BODY dengan regular expression (@rx) string (pills|insurance|rolex). Variable ?i: melakukan pencocokan yang tidak case sensitive. Jika ke tiga aturan tersebut berhasil cocok dengan baik, ACTION yang dilakukan adalah menolak dan mencatat di log dengan message "Spam detected." Chain action mensimulasi operasi logical AND untuk mencocokan ke tiga rules / aturan.
Excluding Host dan Directory
Kadang kala ada baiknya kita meng-exclude directory tertentu atau domain name jika dia menjalankan aplikasi seperti phpMyAdmin karena modsecurity akan memblok SQL queries. Juga sebaiknya meng-exclude admin backend dari aplikasi CMS seperti WordPress.
Untuk men-disable modsecurity untuk sebuah VirtualHost lakukan / tambahkan sebagai berikut
<IfModule security2_module> SecRuleEngine Off </IfModule>
dalam bagian <VirtualHost>
Untuk directory tertentu:
<Directory "/var/www/wp-admin"> <IfModule security2_module> SecRuleEngine Off </IfModule> </Directory>
Jika kita tidak ingin mem-disable secara penuh modsecurity, gunakan SecRuleRemoveById untuk membuang aturan / rule / rule chain tertentu dengan menentukan ID-nya sebagai berikut
<LocationMatch "/wp-admin/update.php"> <IfModule security2_module> SecRuleRemoveById 981173 </IfModule> </LocationMatch>