Mengamankan Issabel dengan Fail2ban

Keperluan menginstall IP PBX dengan ip address public sepertinya memang sudah tidak bisa dihindari lagi demi mengurangi carbon footprint *halah*. Beberapa waktu yang lalu saya pernah menulis bagaimana saya mengamankan server Elastix dengan IPTABLES ketika harus dipasang dengan ip address public di sini. Cuma caranya kurang elegan karena masih mengubah port default SIP, dan firewallnya bisa dibilang statis (tidak bisa otomatis block/unblock ip address perpetrator). Padahal kalau melihat appliance yang ada di pasaran, seperti Yeastar IP PBX, Grandstream IP PBX, Sangoma IP PBX, dll (terutama yang Asterisk based), mereka sudah menerapkan Fail2ban sebagai default pengamanan dan dengan pede bisa membuka port 5060 di network public.

Fail2ban di Issabel, yang notabene sudah jalan di atas Centos 7, menggunakan tool Firewalld (bukan IPTABLES, walaupun masih disertakan juga sebagai backward compat).  Tapi saya masih kebawa ngubah port default layanan lain ke port berbeda (misal SSH jadi port 8022, http jadi port 8080, https jadi port 8443, dst), sekedar menambahkan “onion layer” ke layer pengamanan.

“Cara Kerja Fail2ban Gimana sih?”

Fail2ban membaca file log layanan (ssh, http, https, Asterisk, FreeSWITCH, dst) untuk dibandingkan dengan regex yang ada di direktori ~fail2ban/filter.d/*.conf. Misal di Issabel ini, saya sudah menginstruksikan Fail2ban membaca file /var/log/asterisk/full (file log utama Asterisk) di ~fail2ban/jail.conf seperti di bawah ini:

...
[asterisk]

port = 5060,5061
action = %(banaction)s[name=%(__name__)s-tcp, port="%(port)s", protocol="tcp", chain="%(chain)s", actname=%(banaction)s-tcp]
%(banaction)s[name=%(__name__)s-udp, port="%(port)s", protocol="udp", chain="%(chain)s", actname=%(banaction)s-udp]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s"]
logpath = /var/log/asterisk/full
maxretry = 3
...

Nilai default maxretry di setting ini 10. Sengaja saya turunkan menjadi 3.

Fail2ban akan membaca file /var/log/asterisk/full (defaultnya /var/log/asterisk/messages) untuk dicocokkan dengan regex yang ada di dalam file ~fail2ban/filter.d/asterisk.conf . Silahkan check sendiri, isinya agak panjang jadi ndak saya paste di sini. Yang perlu diperhatikan adalah keyword  . Regex akan mengeluarkan variable yang disimpan di  untuk kemudian dijadikan parameter blocking di Firewalld, lalu meyimpan record tersebut di database SQLite. Kalau mau tau di mana lokasi databasenya jalankan saja perintah:

[root@issabel ~]# fail2ban-client get dbfile
Current database file is:
`- /var/lib/fail2ban/fail2ban.sqlite3

Kalo ngerti SQLite, silahkan dilihat2 isi dari database tersebut, sementara ndak saya bahas di sini cara ngeliatnya pake SQLite.

“Kenapa catatan ip address yang diblokir harus disimpan? “

Kadang-kadang kan memang kejadiannya ndak sengaja. Misal ada user yang pada saat setting endpoint salah dalam mengisikan password. Jadi ada baiknya diberikan kesempatan. Untuk jumlah berapa kali boleh diberikan kesempatan tergantung Sysadminnya segalak apa. Jadi Fail2ban secara default akan memberikan kesempatan 5x autentikasi, lalu diblokir selama 3 menit, kemudian dibuka blokirnya. Jika terjadi lagi salah autentikasi 5x, akan dilakukan blokir selama 3 menit lagi. Block/unblock ini akan dihitung oleh Fail2ban. Jika sudah sampai 10x, maka ip address client akan diblokir permanen. Ini sebabnya dibutuhkan database untuk mencatat.

Untuk server dengan ip address public, biasanya saya menurunkan jumlah toleransi dari 5x percobaan autentikasi yang diperbolehkan menjadi 3x saja. Lalu blocking/unblocking yang defaultnya dari 10 menjadi 3. Lumayan saving resource karena saat server hadap ke jaringan public, jumlah percobaan akan berlipat puluhan kali, bahkan sampai ribuan kali lebih banyak jika dibandingkan dengan jaringan internal kantor, misalnya.

Walhasil baru sebentar sudah panen hama:

[root@issabel fail2ban]# fail2ban-client status asterisk
Status for the jail: asterisk
|- Filter
| |- Currently failed: 2
| |- Total failed: 227890
| `- File list: /var/log/asterisk/full
`- Actions
|- Currently banned: 5
|- Total banned: 31
`- Banned IP list: 46.29.162.24 185.22.152.78 46.29.162.11 185.22.152.88 62.210.143.116

Untuk menjalankan Fail2ban default install, yang perlu diubah hanya lokasi file log di Asterisk seperti yang sudah saya cantumkan di atas. Selain itu matikan layanan IPTABLES, dan aktifkan Firewalld.

[root@issabel ~]# systemctl stop iptables
[root@issabel ~]# systemctl disable iptables
[root@issabel ~]# systemctl enable firewalld
[root@issabel ~]# systemctl start firewalld

Lalu tambahkan layanan Issabel/Asterisk untuk SIP di Firewalld:

[root@issabel ~]# firewall-cmd --permanent --zone=public --add-port={5060,5061}/tcp
[root@issabel ~]# firewall-cmd --permanent --zone=public --add-port={5060,5061}/udp
[root@issabel ~]# firewall-cmd --permanent --zone=public --add-port=10000-20000/udp
[root@issabel ~]# firewall-cmd --reload

Dan pastikan level logging di Asterisk di dalam file logger_logfiles_additional.conf ada baris:

full => debug,error,notice,verbose(3),warning

Jika ingin mengubah verbosity, maka perlu dipikirkan juga perubahan regex yang mungkin terjadi di dalam file ~fail2ban/filter.d/asterisk.conf.

Dan terakhir aktifkan Fail2ban:

[root@issabel ~]# systemctl enable fail2ban
[root@issabel ~]# systemctl start fail2ban

Selamat mencoba dan selamat menyambut tahun baru 2018!

Links

Update

Di setup Issabel belakangan, untuk menjalankan fail2ban, saya harus menyalin file jail.conf ke jail.local:

cp -pf /etc/fail2ban/jail.conf  /etc/fail2ban/jail.local

[Tips] Kazoo Media Server – Tidak Bisa Memainkan Voice Recording

Jika kita memiliki platform Kazoo dengan media server terpisah, ada kemungkinan tidak bisa mendengarkan voice recording, misal, jika kita salah mendial nomer seharusnya mendapatkan pesan suara:

“The call can not be completed as dialed. Please check your number and dial again.”

alih-alih akan mendapatkan error message di console FreeSWITCH seperti berikut:

[ERR] mod_http_cache.c:1170 Received HTTP error 0 trying to fetch http://127.0.0.1:15984/system_media/en-us%2Ffault-can_not_be_completed_as_dialed/fault-can_not_be_completed_as_dialed.wav?rev=6-585c8f2e3b6b3f4063efb1c18cce5309

Sebelum melanjutkan ke setting HAPROXY, pastikan semua rekaman suara sudah berada di dalam direktori /opt/kazoo/sounds (dalam contoh ini, karena menggunakan bahasa inggris, lokasi direktori lengkapnya /opt/kazoo/sounds/en/us). Jika belum ada, copy manual langsung dari server ecallmgr yang sudah berjalan.

Selanjutnya, ubah config HAPROXY yang mengarah ke server database CouchDB (biasanya karena server terpisah dengan media server) dengan bind server ke 0.0.0.0 misal :

....
listen bigcouch-data
bind 0.0.0.0:15984
balance roundrobin
server db_1.couch.db 127.0.0.1:5984 check
server db_2.couch.db 127.0.0.1:5984 check
server db_3.couch.db 127.0.0.1:5984 check backup
server db_4.couch.db 127.0.0.1:5984 check backup

listen bigcouch-mgr
bind 0.0.0.0:15986
balance roundrobin
server db_1.couch.db 127.0.0.1:5986 check
server db_2.couch.db 127.0.0.1:5986 check
server db_3.couch.db 127.0.0.1:5986 check backup
server db_4.couch.db 127.0.0.1:5986 check backup
...

Pastikan juga firewall hanya menerima koneksi ke service-service tersebut dari ip address cluster kita sendiri untuk keamanan.

Lalu di server FreeSWITCH juga diinstall HAPROXY dengan config sebagai berikut (misal HAPROXY database terpasang di ip address 1.2.3.4 dengan port 15984 dan 15986):

....
listen bigcouch-data
bind 127.0.0.1:15984
balance roundrobin
server db_1.couch.db 1.2.3.4:15984 check
server db_2.couch.db 1.2.3.4:15984 check
server db_3.couch.db 1.2.3.4:15984 check backup
server db_4.couch.db 1.2.3.4:15984 check backup

listen bigcouch-mgr
bind 0.0.0.0:15986
balance roundrobin
server db_1.couch.db 1.2.3.4:15986 check
server db_2.couch.db 1.2.3.4:15986 check
server db_3.couch.db 1.2.3.4:15986 check backup
server db_4.couch.db 1.2.3.4:15986 check backup
...

Reload semua HAPROXY di ke-2 server/cluster tersebut, lalu test kembali.

 

[TIPS] Error Create Database OpenSIPS Dengan “opensipsdbctl create”

Baru iseng-iseng nguprek OpenSIPS, pada saat create database dengan tool opensipsdbctl create, saya mendapatkan error berikut:

error:
RROR 1101 (42000) at line 2: BLOB, TEXT, GEOMETRY or JSON column 'extra_hdrs' can't have a default value
ERROR: Failed to create presence tables!

Setelah baca sana sini, ada petunjuk bahwa sql-mode di server memiliki setting STRICT_TRANS_TABLE (ndak tau juga ini apa, mau browse kok malah nanti repotnya jadi distraksi ke mana mana). Yang kemudian saya lakukan adalah masuk ke console mysql dan menjalankan perintah berikut:

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SET @@GLOBAL.sql_mode ='';
Query OK, 0 rows affected, 1 warning (0.00 sec)

Sebagai catatan saja, sebelum saya kosongkan isi dari GLOBAL.sql_mode adalah:

mysql> SELECT @@GLOBAL.sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@GLOBAL.sql_mode                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Dan setelah dikosongkan:

+-------------------+
| @@GLOBAL.sql_mode |
+-------------------+
|                   |
+-------------------+
1 row in set (0.00 sec)

Berikutnya dicoba lagi menjalakan perintah opensipsdbctl create :

root# opensipsdbctl create
MySQL password for root:
INFO: test server charset
INFO: creating database opensips ...
INFO: Using table engine InnoDB.
INFO: Core OpenSIPS tables successfully created.
Install presence related tables? (y/n): y
INFO: creating presence tables into opensips ...
INFO: Presence tables successfully created.
Install tables for imc cpl siptrace domainpolicy carrierroute userblacklist b2b cachedb_sql registrant call_center fraud_detection emergency? (y/n): y
INFO: creating extra tables into opensips ...
INFO: Extra tables successfully created.

Done.

Link: