ถ้า Asterisk ที่เราใช้งานอยู่ต่อกับ Internet โดยตรง ลองเข้าไปดู Log ไฟล์ /var/log/asterisk/messages หรือ /var/log/asterisk/full ดูครับ อาจจะเจอข้อความลักษณะนี้ก็ได้
[Mar 22 10:03:03] NOTICE[8818] chan_sip.c: Registration from '1900<sip:1900@58.59.60.61>' failed for '58.8.95.7' - No matching peer found
[Mar 22 10:03:03] NOTICE[8818] chan_sip.c: Registration from '1901<sip:1901@58.59.60.61>' failed for '58.8.95.7' - No matching peer found
[Mar 22 10:03:03] NOTICE[8818] chan_sip.c: Registration from '1902<sip:1902@58.59.60.61>' failed for '58.8.95.7' - No matching peer found
[Mar 22 10:03:03] NOTICE[8818] chan_sip.c: Registration from '1903<sip:1903@58.59.60.61>' failed for '58.8.95.7' - No matching peer found
ข้อความลักษณะนี้เกิดจากมีผู้พยายามเดา Username ใน Asterisk ครับ โดยส่งมาจากโฮสต์ 58.8.95.7 สงสัยใช้โปรแกรมหรือ Script ส่งมา ซึ่งผมได้เขียนบทความเกี่ยวกับ How to Secure Asterisk มาบทความหนึ่งแล้ว แต่ก็ป้องกันไม่ได้ 100% เพราะว่า IP นี้ก็ยังส่ง Message มาเดา Username/Password ได้อีก ถ้า Asterisk เจอแบบนี้ถี่ๆเข้า แบบวินาทีนึงเจอเป็นหลายสิบหรือหลายร้อยครั้ง ก็มีโอกาสน๊อกได้นะครับ การโจมตีแบบนี้เราเรียกว่า SIP Brute Force Attacks ครับ บางทีผู้ไม่หวังดีไม่ได้ต้องการจะรู้ Username/Password หรอกครับ เขาตั้งใจจะโจมตี SIP Server มากกว่า
บทความนี้ผมจะบล๊อก IP ไว้เลยถ้ามีความพยายามจะเดา Username/Password หรือส่งแพ็กเก็ตมาโจมตีอีก
ผมจะใช้โปรแกรม Fail2Ban จัดการบล๊อก IP Address ที่พยายามจะส่ง Brute Force Attacks มาที่ Asterisk Server โดยโปรแกรมมันจะเช็คไฟล์ล๊อกของ Asterisk ถ้าเจอข้อความที่เรากำหนดไว้มันก็จะจัดการเพิ่ม rule แบบไดนามิคเข้าไปใน iptables เพื่อบล๊อก IP Address นั้น
1. ติดตั้ง Python และ iptables (ถ้ายังไม่ได้ติดตั้ง)
โปรแกรม Fail2Ban เขียนด้วย Python (ควรใช้เวอร์ชั่น 2.4 ขึ้นไป) และจะบล๊อก IP โดยใช้โปรแกรม iptables
- โค้ด: เลือกทั้งหมด
yum -y install python iptables
2. ดาวน์โหลดโปรแกรม Fail2Ban
เช็คเวอร์ชั่น http://sourceforge.net/projects/fail2ban/files/
- โค้ด: เลือกทั้งหมด
wget http://downloads.sourceforge.net/project/fail2ban/fail2ban-stable/fail2ban-0.8.4/fail2ban-0.8.4.tar.bz2?use_mirror=nchc
tar xvf fail2ban-0.8.4.tar.bz2 -C /usr/src
3. ติดตั้งโปรแกรม Fail2Ban
- โค้ด: เลือกทั้งหมด
cd /usr/src/fail2ban-0.8.4
python setup.py install
ข้อความขณะติดตั้งเป็นแบบนี้ครับ
running install
running build
running build_py
running build_scripts
running install_lib
running install_scripts
changing mode of /usr/bin/fail2ban-regex to 755
changing mode of /usr/bin/fail2ban-server to 755
changing mode of /usr/bin/fail2ban-client to 755
running install_data
Please do not forget to update your configuration files.
They are in /etc/fail2ban/.
โปรแกรม Fail2Ban อยู่ที่ไดเร็คตอรี่ /usr/share/fail2ban และมี 3 ไฟล์ในไดเร็คตอรี่ /usr/bin/ คือ fail2ban-client, fail2ban-regex และ fail2ban-server ไฟล์คอนฟิกจะอยู่ที่ไดเร็คตอรี่ /etc/fail2ban และไฟล์ Log คือ /var/log/fail2ban.log
4. ติดตั้ง Init Script และทำให้รันทุกครั้งที่เปิดเครื่อง
- โค้ด: เลือกทั้งหมด
cp /usr/src/fail2ban-0.8.4/files/redhat-initd /etc/init.d/fail2ban
chmod 755 /etc/init.d/fail2ban
chkconfig --level 35 fail2ban on
5. เซ็ตคอนฟิกของ Fail2Ban
เราต้องบอก Fail2Ban ด้วยนะครับว่า ข้อความแบบไหนบ้างใน Log File ที่แสดงว่ากำลังมีคนพยายาม Hack
- โค้ด: เลือกทั้งหมด
cd /etc/fail2ban/filter.d
vi asterisk.conf
แล้วใส่บรรทัดต่อไปนี้เข้าไป
- โค้ด: เลือกทั้งหมด
[Definition]
#_daemon = asterisk
failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Wrong password
NOTICE.* .*: Registration from '.*' failed for '<HOST>' - No matching peer found
NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Username/auth name mismatch
NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Device does not match ACL
NOTICE.* <HOST> failed to authenticate as '.*'$
NOTICE.* .*: No registration for peer '.*' \(from <HOST>\)
NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
NOTICE.* .*: Failed to authenticate user .*@<HOST>.*
NOTICE.*: Registration from '*.*' failed for '<HOST>:*.*' - Wrong password
NOTICE.*: Registration from '*.*' failed for '<HOST>' - Peer is not supposed to register
ignoreregex =
6. แก้ไขไฟล์ /etc/fail2ban/jail.conf
ไฟล์นี้จะบอก Fail2Ban ว่าให้เช็คที่ไฟล์ไหน (logpath) ให้ Try ได้กี่ครั้ง (maxretry) บล๊อกเป็นเวลากี่วินาที (bantime) ถ้าพบว่ามี Try มากกว่า maxretry ภายในระยะเวลา findtime ก็จะบล๊อกเลย
เพิ่มบรรทัดต่อไปนี้เข้าไป เอาไว้ท้ายสุดของไฟล์เลยก็ได้ครับ
- โค้ด: เลือกทั้งหมด
[asterisk-iptables]
enabled = true
filter = asterisk
action = iptables-allports[name=ASTERISK, protocol=all]
sendmail-whois[name=ASTERISK, dest=your_email_here, sender=fail2ban-192.168.1.1@myemail.com]
logpath = /var/log/asterisk/full
maxretry = 5
findtime = 60
bantime = 259200
แก้ไขคำว่า your_email_here ให้เป็นอีเมล์แอดเดรสของท่านด้วยนะครับ ท่านจะได้รับอีเมล์เมื่อมีการบล๊อก IP
สำหรับ Asterisk 1.8 ให้แก้บรรทัด logpath จาก /var/log/asterisk/full เป็น /var/log/asterisk/message
ซึ่ง bantime คือระยะเวลาเป็นวินาที ที่โฮสต์จะถูกแบน ตัวอย่าง 259200 วินาที คือ 72 ชั่วโมงหรือ 3 วันครับนับจากวินาทีที่ถูกแบน, findtime คือช่วงระยะเวลาที่จะเช็คค่า maxretry จากโฮสต์หนึ่งๆ, maxretry คือจำนวนครั้งสูงสุดที่จะ fail ได้ภายในช่วงระยะเวลา findtime
ยกตัวอย่างเช่น maxretry=5, findtime=60, bantime=259200 ก็หมายความว่า fail2ban มันจะเช็คไฟล์ /var/log/asterisk/full ทุกๆ 60 วินาที ถ้าพบว่าโฮสต์หนึ่ง fail 5 ครั้งขึ้นไป มันก็จะบล๊อกไอพีของโฮสต์
7. ป้องกันตัวเองไม่ให้ถูกบล๊อก
เราสามารถบอก Fail2Ban ไม่ให้บล๊อก IP ได้ด้วยนะครับ โดยใส่บรรทัด ignoreip เข้าไปในไฟล์ jail.conf ภายใต้ [DEFAULT] แบบนี้ครับ
- โค้ด: เลือกทั้งหมด
[DEFAULT]
ignoreip=192.168.1.1
ถ้ามีหลายไอพีก็ใส่แบบนี้ (เว้นว่างระหว่างแต่ละไอพี)
- โค้ด: เลือกทั้งหมด
[DEFAULT]
ignoreip = 127.0.0.1 192.168.1.10 203.147.8.9
ถ้ามีหลายไอพีแบบ Subnet เลยก็ใส่แบบนี้
- โค้ด: เลือกทั้งหมด
[DEFAULT]
ignoreip = 127.0.0.1 192.168.1.10 192.168.5.0/24 203.147.96.32/27
อย่าลืมทำนะครับ เพราะถ้า Fail2Ban มันบล๊อกมันจะไปเขียน Rules ไว้ใน iptables ประมาณว่าบล๊อกทุกอย่างที่มาจากไอพีนั้น และใส่บรรทัด ignoreip ได้บรรทัดเดียวนะครับ มีหลายไอพีก็ใส่ต่อๆกันไป
8. เปลี่ยน Time Stamp ใน Log ของ Asterisk
ดีฟอลท์ Asterisk จะเซ็ต Time Stamp ใน Log แบบนี้ครับ Mar 22 10:03:03 ซึ่งไม่เวอร์คกับ Fail2Ban เราต้องเปลี่ยน
- โค้ด: เลือกทั้งหมด
vi /etc/asterisk/logger.conf
เพิ่มบรรทัดนี้ไว้ภายใต้ [general]
dateformat = %F %T
ถ้าไม่เห็น {general] ก็ไม่ต้องตกใจครับ ให้สร้างขึ้นมาเอง สร้างไว้ก่อน [logfiles] นะครับ
ถ้ามีบรรทัด dateformat อยู่แล้วแต่มี ; หน้าบรรทัด ก็ให้หรือเอาเครื่องหมาย ; หน้าบรรทัดออก
- โค้ด: เลือกทั้งหมด
[general]
dateformat = %F %T
[logfiles]
full => notice,warning,error,debug,verbose
รีโหลดโมดูล Logger ของ Asterisk (ตัวอย่างนี้ผมรันจากพร้อมท์ของ Linux)
- โค้ด: เลือกทั้งหมด
# asterisk -rx "logger reload"
แล้ว Asterisk ก็จะเปลี่ยน Time Stamp เป็นแบบนี้ 2010-03-22 15:20:39
9. สตาร์ท iptables ถ้ายังไม่ได้สตาร์ท
- โค้ด: เลือกทั้งหมด
service iptables start
10. สตาร์ท Fail2Ban
- โค้ด: เลือกทั้งหมด
service fail2ban start
ข้อความขณะ Start Fail2Ban
Starting fail2ban: [ OK ]
11. ตรวจสอบ iptables
- โค้ด: เลือกทั้งหมด
iptables -L -v
Chain fail2ban-ASTERISK (1 references)
pkts bytes target prot opt in out source destination
111 10025 RETURN all -- any any anywhere anywhere
12. ตรวจสอบการทำงานของ Fail2Ban
ขณะที่ Fail2Ban มันจะเก็บ Log ไว้ที่ไฟล์ /var/log/fail2ban.log
ลองมอนิเตอร์ไฟล์นี้ดูครับ ถ้ามันบล๊อกไอพีไหนก็แสดงว่าไอพีนั้นกำลังคิดเล่นไม่ซื่อกับ Asterisk น้อยๆของเราอยู่
- โค้ด: เลือกทั้งหมด
#tail -f /var/log/fail2ban.log
fail2ban.actions: WARNING [asterisk-iptables] Ban 58.8.114.211
13. เช็คผลการทำงานของโปรแกรม Fail2Ban
- โค้ด: เลือกทั้งหมด
iptables -L -v
แจ่มครับ มีบล๊อก IP ppp-58-8-95-7.revip2.asianet.co.th ไว้ (ไอพีผมเองครับ ผมเทสส่ง Username ผิดๆไปรีจิสเตอร์กับ Asterisk ผลก็คือถูก iptables บล๊อกไว้ โดนบล๊อกทุก Server เลยทั้ง Web, SSH, FTP ) โดย Fail2Ban จะเพิ่ม rule เข้าไปใน iptables แบบไดนามิก
Chain fail2ban-ASTERISK (1 references)
pkts bytes target prot opt in out source destination
60 18750 DROP all -- any any ppp-58-8-95-7.revip2.asianet.co.th anywhere
1908 199K RETURN all -- any any anywhere anywhere
14. วิธีการปลดล๊อก IP ที่ถูกบล๊อก
สมมติว่า IP ที่ถูกบล๊อกเป็น IP ของลูกค้าหรือ IP ของเราเอง วิธีการปลดล๊อกทำได้ 2 วิธีคือ
14.1 รีสตาร์ท iptables หรือ
14.2 เพิ่มบรรทัด ignoreip= ไว้ในไฟล์ jail.conf เอาไว้ภายใต้ [DEFAULT] แล้วรีสตาร์ท Fail2Ban
15. ทำ Log Rotate ไฟล์ Log
- โค้ด: เลือกทั้งหมด
vi /etc/logrotate.d/fail2ban
- โค้ด: เลือกทั้งหมด
/var/log/fail2ban.log {
weekly
rotate 7
missingok
compress
postrotate
/usr/bin/fail2ban-client reload 1>/dev/null || true
endscript
}
บทความที่เกี่ยวข้อง
iptables firewall
Asterisk Security