หากเซิร์ฟเวอร์ของคุณตั้งอยู่บนอินเตอร์เน็ต เพื่อให้บริการเว็บไซต์หรืออื่นๆ และคุณจำเป็นต้องเปิด SSH เพื่อสามารถ login เข้าไปตรวจสอบสถานะของเครื่องได้
คุณต้องเคยเจอปัญหานี้แน่นอน คือมีการพยายามเจาะระบบด้วยการ ssh เข้ามา ด้วย user, password ต่างๆ ที่คาดว่าจะมีในเครื่อง
ตัวอย่างไฟล์ /var/log/secure แสดงถึงการพยายาม ssh แต่ไม่สำเร็จ
May 2 16:39:27 server sshd[8309]: Invalid user john from x.x.x.x May 2 16:39:27 server sshd[8310]: input_userauth_request: invalid user john May 2 16:39:27 server sshd[8309]: pam_unix(sshd:auth): check pass; user unknown May 2 16:39:27 server sshd[8309]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=x.x.x.x May 2 16:39:27 server sshd[8309]: pam_succeed_if(sshd:auth): error retrieving information about user john May 2 16:39:29 server sshd[8309]: Failed password for invalid user john from x.x.x.x port 3291 ssh2 May 2 16:39:29 server sshd[8310]: Received disconnect from x.x.x.x: 11: Bye Bye
การป้องกัน หรือคำแนะนำอย่างแรก ที่พึงกระทำคือ ตั้ง user, password ให้ยากต่อการคาดเดา แต่เท่านั้นอาจไม่เพียงพอ
บทความนี้ขอเสนอวิธีการป้องกันด้วย fail2ban ซึ่งจะช่วยแบน ip ที่พยายาม login แต่ไม่สำเร็จได้
หลักการทำงานคร่าวๆ คือ โปรแกรม fail2ban จะคอยตรวจสอบไฟล์ที่ตั้งไว้ โดยค้นหาคำหรือประโยคที่เกิดขึ้นในไฟล์ เมื่อมีการ failed attempts เกิดขึ้นถึงจำนวนครั้งที่กำหนด fail2ban จะทำการบางอย่างที่ตั้งไว้ เช่น รันคำสั่ง iptables เพื่อ DROP packets ได้
ติดตั้งไฟล์ rpm
ในที่นี้ทดสอบบน Fedora 14 ต้องติดตั้งไฟล์ rpm เพิ่มเติมดังนี้
[root@fc14-x64 ~]# rpm -ivh gamin-python-0.1.10-8.fc14.x86_64.rpm [root@fc14-x64 ~]# rpm -ivh shorewall-4.4.11.1-1.fc14.noarch.rpm [root@fc14-x64 ~]# rpm -ivh fail2ban-0.8.4-25.fc14.noarch.rpm
เพื่อความชัดเจนในการทดสอบ จะรันคำสั่ง service iptables stop เพื่อเคลียร์ rule ของ iptables ทั้งหมดออกก่อน
[root@fc14-x64 ~]# service iptables stop iptables: Flushing firewall rules: [ OK ] iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Unloading modules: [ OK ]
ใช้คำสั่ง iptables เพื่อแสดง rule ที่ใช้งานอยู่
[root@fc14-x64 ~]# iptables -L -v -n Chain INPUT (policy ACCEPT 46 packets, 3176 bytes) pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 40 packets, 5272 bytes) pkts bytes target prot opt in out source destination
ใช้คำสั่ง service เพื่อสตาร์ต fail2ban
[root@fc14-x64 ~]# service fail2ban start Starting fail2ban: [ OK ]
ใช้คำสั่ง ps เพื่อดูโปรเซสของ fail2ban
[root@fc14-x64 ~]# ps -ef | grep fail2ban root 1151 1 0 23:32 ? 00:00:00 /usr/bin/python /usr/bin/fail2ban-server -b -s /var/run/fail2ban/fail2ban.sock -x
ดูในไฟล์ /var/log/messages แสดงการเริ่มต้นทำงานของ fail2ban
[root@fc14-x64 ~]# tail /var/log/messages
May 6 23:35:32 fc14-x64 fail2ban.server : INFO Changed logging target to SYSLOG for Fail2ban v0.8.4 May 6 23:35:32 fc14-x64 fail2ban.jail : INFO Creating new jail 'ssh-iptables' May 6 23:35:32 fc14-x64 fail2ban.jail : INFO Jail 'ssh-iptables' uses Gamin May 6 23:35:32 fc14-x64 fail2ban.filter : INFO Added logfile = /var/log/secure May 6 23:35:32 fc14-x64 fail2ban.filter : INFO Set maxRetry = 5 May 6 23:35:32 fc14-x64 fail2ban.filter : INFO Set findtime = 600 May 6 23:35:32 fc14-x64 fail2ban.actions: INFO Set banTime = 600 May 6 23:35:32 fc14-x64 fail2ban.jail : INFO Jail 'ssh-iptables' started
ดีฟอลต์คอนฟิกไฟล์ rpm ที่ได้มาจาก Fedora 14 จะตรวจสอบเฉพาะการพยายาม SSH โดยดูในไฟล์ /var/log/secure
fail2ban จะสร้าง rule และ chain ใหม่ขึ้นมา ใน iptables
[root@fc14-x64 ~]# iptables -L -v -n
Chain INPUT (policy ACCEPT 92 packets, 7885 bytes)
pkts bytes target prot opt in out source destination
53 4052 fail2ban-SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 84 packets, 8087 bytes) pkts bytes target prot opt in out source destination
Chain fail2ban-SSH (1 references) pkts bytes target prot opt in out source destination 53 4052 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
ไฟล์คอนฟิกของ fail2ban
ไฟล์คอนฟิกของ fail2ban อยู่ใน /etc/fail2ban/
ไฟล์ /etc/fail2ban/jail.conf จะเป็นการกำหนดการทำงานของ fail2ban
คอนฟิกบางส่วนจากไฟล์ jail.conf
[root@fc14-x64 ~]# cat /etc/fail2ban/jail.conf
...
[DEFAULT]
...
# "bantime" is the number of seconds that a host is banned.
bantime = 600
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 600
...
[ssh-iptables]
enabled = true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] sendmail-whois[name=SSH, dest=root, sender=fail2ban@mail.com] logpath = /var/log/secure maxretry = 5
คำอธิบายคร่าวๆ จากไฟล์ jail.conf คือ ให้ตรวจสอบ (filter) การ ssh โดยดูในไฟล์ (logpath) /var/log/secure ว่า ถ้ามีการ failed login เกิน (maxretry) ครั้ง ภายในเวลา (findtime) 600 วินาที ให้ทำการ (action) รัน iptables ด้วยออปชั่นในวงเล็บ
สามารถดูรายละเอียด filter ในไฟล์ /etc/fail2ban/filter.d/sshd.conf
[root@fc14-x64 ~]# cat /etc/fail2ban/filter.d/sshd.conf ... [Definition]
_daemon = sshd ... failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$ ^%(__prefix_line)sFailed (?:password|publickey) for .* from <HOST>(?: port \d*)?(?: ssh\d*)?$ ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$ ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$ ^%(__prefix_line)sUser \S+ from <HOST> not allowed because not listed in AllowUsers$ ^%(__prefix_line)sauthentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$ ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$ ^%(__prefix_line)sAddress <HOST> .* POSSIBLE BREAK-IN ATTEMPT!*\s*$ ^%(__prefix_line)sUser \S+ from <HOST> not allowed because none of user's groups are listed in AllowGroups$
คำอธิบายจากไฟล์คอนฟิก filter คือ ให้ตรวจสอบหาคำหรือประโยคที่ระบุไว้ใน failregex (regular expression)
ส่วน action ที่ทำ หลังจาก maxretry ดูได้ในไฟล์ /etc/fail2ban/action.d/iptables.conf
[root@fc14-x64 ~]# cat /etc/fail2ban/action.d/iptables.conf ... actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP ... actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
คำอธิบาย คือการรันคำสั่ง iptables เพื่อสร้าง rule เพื่อจะ ban <ip> ที่พยายามเข้ามา
และเมื่อเกินเวลา (bantime) 600 วินาที แล้ว ก็รันคำสั่ง iptables เพื่อลบ rule ที่สร้างขึ้น อนุญาตให้ <ip> สามารถเข้ามาได้อีกครั้ง
ทดสอบการ login fail
คำเตือน การทดลองใช้ fail2ban ให้ลองบนเครื่องที่สามารถ console ได้ เพราะการคอนฟิกหรือลอง login fail จะทำให้คุณไม่สามารถ ssh เข้าเครื่องนั้นได้ ช่วงเวลาหนึ่ง
สมมุติให้ลอง ssh login fail ด้วย root จาก 192.168.1.12
ดูไฟล์ /var/log/secure ที่เกิดขึ้นบน server
[root@fc14-x64 ~]# tail -f /var/log/secure May 6 23:43:47 fc14-x64 unix_chkpwd[1340]: password check failed for user (root) May 6 23:43:47 fc14-x64 sshd[1338]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.12 user=root May 6 23:43:49 fc14-x64 sshd[1338]: Failed password for root from 192.168.1.12 port 34811 ssh2
May 6 23:43:56 fc14-x64 unix_chkpwd[1342]: password check failed for user (root) May 6 23:43:58 fc14-x64 sshd[1338]: Failed password for root from 192.168.1.12 port 34811 ssh2
May 6 23:44:00 fc14-x64 unix_chkpwd[1343]: password check failed for user (root) May 6 23:44:01 fc14-x64 sshd[1338]: Failed password for root from 192.168.1.12 port 34811 ssh2 May 6 23:44:01 fc14-x64 sshd[1339]: Connection closed by 192.168.1.12 May 6 23:44:01 fc14-x64 sshd[1338]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.12 user=root
May 6 23:44:16 fc14-x64 unix_chkpwd[1348]: password check failed for user (root) May 6 23:44:16 fc14-x64 sshd[1346]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.12 user=root May 6 23:44:19 fc14-x64 sshd[1346]: Failed password for root from 192.168.1.12 port 34812 ssh2
May 6 23:44:22 fc14-x64 unix_chkpwd[1349]: password check failed for user (root) May 6 23:44:25 fc14-x64 sshd[1346]: Failed password for root from 192.168.1.12 port 34812 ssh2 May 6 23:44:25 fc14-x64 sshd[1347]: Connection closed by 192.168.1.12 May 6 23:44:25 fc14-x64 sshd[1346]: PAM 1 more authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.12 user=root
เมื่อ login fail เกินค่า maxretry ที่ตั้งไว้ ในที่นี้คือ 5 ครั้ง สังเกตในไฟล์ /var/log/messages โปรแกรม fail2ban จะทำการ action ขึ้นมา เพื่อ ban 192.168.1.12
[root@fc14-x64 ~]# tail /var/log/messages
May 6 23:44:27 fc14-x64 <28>fail2ban.actions: WARNING [ssh-iptables] Ban 192.168.1.12
ใช้คำสั่ง iptables เพื่อตรวจสอบ rule ที่เพิ่มขึ้น
[root@fc14-x64 ~]# iptables -L -v -n
Chain INPUT (policy ACCEPT 61 packets, 10699 bytes)
pkts bytes target prot opt in out source destination
453 37587 fail2ban-SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 60 packets, 7044 bytes) pkts bytes target prot opt in out source destination
Chain fail2ban-SSH (1 references)
pkts bytes target prot opt in out source destination
2 120 DROP all -- * * 192.168.1.12 0.0.0.0/0
451 37467 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
สังเกตว่า rule ที่สร้างขึ้น จะ DROP เฉพาะการ ssh (tcp 22) เท่านั้น แปลว่า ip ที่ถูก ban ไป จะไม่สามารถ ssh เข้าเครื่อง server ได้อีก แต่ยังสามารถเปิด web (tcp 80) หรืออื่นๆ ได้ตามปกติ
คอนฟิกในไฟล์ jail.conf เมื่อมีการ ban เกิดขึ้น จะมีการส่ง mail หา root ด้วย
ตัวอย่าง mail ที่ส่งให้ root
From fail2ban@mail.com Fri May 6 23:44:28 2011 Return-Path: <fail2ban@mail.com> Date: Fri, 6 May 2011 23:44:27 +0700 Subject: [Fail2Ban] SSH: banned 192.168.1.12 From: Fail2Ban <fail2ban@mail.com> To: root@fc14-x64.example.com Status: R
Hi,
The IP 192.168.1.12 has just been banned by Fail2Ban after 5 attempts against SSH. ...
เมื่อเวลาผ่านไป เกินเวลา bantime ในที่นี้ 600 วินาที โปรแกรม fail2ban ก็จะปลดการ ban ออก ดูได้จากไฟล์ /var/log/messsages
[root@fc14-x64 ~]# tail /var/log/messages
May 6 23:44:27 fc14-x64 <28>fail2ban.actions: WARNING [ssh-iptables] Ban 192.168.1.12
May 6 23:54:28 fc14-x64 <28>fail2ban.actions: WARNING [ssh-iptables] Unban 192.168.1.12
ใช้คำสั่ง iptables เพื่อตรวจสอบ rule ที่ใช้งานอยู่ หลังจาก unban
[root@fc14-x64 log]# iptables -L -v -n Chain INPUT (policy ACCEPT 561 packets, 50572 bytes) pkts bytes target prot opt in out source destination 1753 141K fail2ban-SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 501 packets, 50410 bytes) pkts bytes target prot opt in out source destination
Chain fail2ban-SSH (1 references) pkts bytes target prot opt in out source destination 1751 141K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
ลองนำไปใช้ดูครับ เพิ่มความปลอดภัยให้เครื่องได้อีกระดับ