วันอาทิตย์ที่ 19 กรกฎาคม พ.ศ. 2558

เมื่อต้องสู้กับ สแปมเมลล์ บนซอฟต์แวร์ Zimbra Community 8.0.1.GA.5438

ยินดีต้อนรับสู่เวบบล็อกดีๆ ของคนรักโอเพ่นซอร์ส หลังจากไม่ได้อัพเดทมาหลายสัปดาห์ ผู้เขียนเองพักหลังก็ไม่ค่อยได้มีงานเกี่ยวกับด้านการดูแลระบบให้ได้แก้ไขมากนัก เพราะปัจจุบันงานที่ทำมุ่งเน้นไปยังธุรกิจ GPS TRACKER เป็นหลัก แต่อย่างไรก็แล้วแต่หากมีงานด้านการดูแลระบบเข้ามาให้แก้ไข ก็จะได้อัพเดทเรื่องราวดีๆ เหล่านี้ให้ได้ทราบกัน

เมื่อเดือนที่ผ่านมาปรากฏว่าเครื่อง Zimbra Community 8.0.1.GA.5438 ที่ผู้เขียนดูแลอยู่เป็นสแปม ไอพีติดแบล็กลิสต์ ในช่วงเวลาที่ผ่านมา 1 เดือนได้พยายามแจ้งไปยังเวบไซต์ต่างๆที่รายงานด้านสแปม จนสามารถปลดล็อกไอพีได้ แต่เซิร์ฟเวอร์เมลล์ของผู้เขียนก็ยังไม่สามารถส่งข้อความไปยังโดเมนในกลุ่มค่ายไมโครซอฟต์ได้ เช่น hotmail.com live.com และ msn.com จึงเป็นที่มา "เมื่อต้องสู้กับ สแปมเมลล์ บนซอฟต์แวร์ Zimbra Community 8.0.1.GA.5438"

ผู้เขียนมีการตั้งระบบป้องกันเบื้องต้นอยู่แล้วนั่นก็คือ fail2ban โดยใช้คอนฟิกดีฟอลต์พวก postfix และ sasl ซึ่งมันไม่ได้ผล เครื่องเมลล์เซิร์ฟเวอร์โดนโจมตีและไอพีติดแบล็คลิสต์เป็นประจำ จากการค้นคว้าไปตามเวบไซต์ต่างๆ มีการพูดถึงการป้องกันสแปมโดยใช้ fail2ban อยู่บ้างแต่เป็นแบบสั้นๆ ครั้งนี้ผู้เขียนก็ได้ยึดตามและทดลองได้ผลดี ผ่านมาสองสัปดาห์ยังไม่มีสแปมเมลล์เกิดขึ้นในระบบ ก็ลองใช้วิธีนี้ดูก่อนหากระบบเมลล์เซิร์ฟเวอร์ที่เราดูแลอยู่พบเจอปัญหาสแปมเมลล์ข้างต้น

ขั้นตอนที่ 1 โดยขั้นตอนการกำหนดค่าให้กับคอนฟิกของ fail2ban สามารถดำเนินการได้ดังนี้ ให้ทำการแก้ไขไฟล์ jail.conf


[zimbra-account]
enabled = true
filter = zimbra
action = iptables-allports[name=zimbra-account]
sendmail[name=zimbra-account, dest=admin@example.com]
logpath = /opt/zimbra/log/mailbox.log
bantime = 600
maxretry = 2

[zimbra-audit]
enabled = true
filter = zimbra
action = iptables-allports[name=zimbra-audit]
sendmail[name=Zimbra-audit, dest=admin@example.com]
logpath = /opt/zimbra/log/audit.log
bantime = 600
maxretry = 2

[zimbra-recipient]
enabled = true
filter = zimbra
action = iptables-allports[name=zimbra-recipient]
sendmail[name=Zimbra-recipient, dest=admin@example.com]
logpath = /var/log/zimbra.log
#findtime = 604800
bantime = 172800
maxretry = 2

[postfix]
enabled = true
filter = postfix
action = iptables-multiport[name=postfix, port=smtp, protocol=tcp]
sendmail-buffered[name=Postfix, dest=admin@example.com]
logpath = /var/log/zimbra.log
bantime = -1
maxretry = 5

ขั้นตอนที่ 2 จากนั้นให้ทำการสร้างไฟล์ zimbra.conf ในโฟลเดอร์ /etc/fail2ban/filter.d/
# Fail2Ban configuration file
#
# Author:
#
# $Revision: 1 $
#

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = \[ip=<HOST>;\] account - authentication failed for .* \(no such acco
unt\)$
                        \[ip=<HOST>;\] security - cmd=Auth; .* error=authenticat
ion failed for .*, invalid password;$
                        ;oip=<HOST>;.* security - cmd=Auth; .* protocol=soap; er
ror=authentication failed for .* invalid password;$
                        \[oip=<HOST>;.* SoapEngine - handler exception: authenti
cation failed for .*, account not found$
                        WARN .*;ip=<HOST>;ua=ZimbraWebClient .* security - cmd=A
dminAuth; .* error=authentication failed for .*;$
                        NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: R
ecipient address rejected:

# .*\[ip=<HOST>;\] .* - authentication failed for .* \(invalid password\)
#
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =
root@teltonika:/etc/fail2ban/filter.d# more zimbra.conf
# Fail2Ban configuration file
#
# Author:
#
# $Revision: 1 $
#

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#
failregex = \[ip=<HOST>;\] account - authentication failed for .* \(no such account\)$
                        \[ip=<HOST>;\] security - cmd=Auth; .* error=authentication failed for .*, invalid password;$
                        ;oip=<HOST>;.* security - cmd=Auth; .* protocol=soap; error=authentication failed for .* invalid password;$
                        \[oip=<HOST>;.* SoapEngine - handler exception: authentication failed for .*, account not found$
                        WARN .*;ip=<HOST>;ua=ZimbraWebClient .* security - cmd=AdminAuth; .* error=authentication failed for .*;$
                        NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: Recipient address rejected:

# .*\[ip=<HOST>;\] .* - authentication failed for .* \(invalid password\)
#
# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =





ขั้นตอนที่ 3 ให้สั่งเริ่มต้นการทำงานเซอร์วิส fail2ban ใหม่

#/etc/init.d/fail2ban restart

ขั้นตอนที่ 4 ให้ทดสอบการตรวจสอบดูว่าเราสร้างไฟล์ข้างต้นถูกต้องสมบูรณ์หรือไม่ พร้อมกับทดสอบการป้องกันดูว่าจะได้ผลหรือไม่

# fail2ban-regex /var/log/zimbra.log /etc/fail2ban/filter.d/zimbra.conf

Running tests
=============

Use regex file : /etc/fail2ban/filter.d/zimbra.conf
Use log file   : /var/log/zimbra.log


Results
=======

Failregex
|- Regular expressions:
|  [1] \[ip=<HOST>;\] account - authentication failed for .* \(no such account\)$
|  [2] \[ip=<HOST>;\] security - cmd=Auth; .* error=authentication failed for .*, invalid password;$
|  [3] ;oip=<HOST>;.* security - cmd=Auth; .* protocol=soap; error=authentication failed for .* invalid password;$
|  [4] \[oip=<HOST>;.* SoapEngine - handler exception: authentication failed for .*, account not found$
|  [5] WARN .*;ip=<HOST>;ua=ZimbraWebClient .* security - cmd=AdminAuth; .* error=authentication failed for .*;$
|  [6] NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: Recipient address rejected:
|
`- Number of matches:
   [1] 0 match(es)
   [2] 0 match(es)
   [3] 0 match(es)
   [4] 0 match(es)
   [5] 0 match(es)
   [6] 1 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
[2]
[3]
[4]
[5]
[6]
    66.196.81.146 (Sun Jul 19 09:32:37 2015)

Date template hits:
225061 hit(s): MONTH Day Hour:Minute:Second
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second
0 hit(s): Year/Month/Day Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/MONTH/Year:Hour:Minute:Second
0 hit(s): Month/Day/Year:Hour:Minute:Second
0 hit(s): Year-Month-Day Hour:Minute:Second
0 hit(s): Year.Month.Day Hour:Minute:Second
0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond]
0 hit(s): Day-Month-Year Hour:Minute:Second
0 hit(s): TAI64N
0 hit(s): Epoch
0 hit(s): ISO 8601
0 hit(s): Hour:Minute:Second
0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 1

However, look at the above section 'Running tests' which could contain important
information.

จากตัวอย่างจะพบว่ามีการตรวจสอบพบไอพีที่ผิดกฏข้อที่ 6  "NOQUEUE: reject: RCPT from .*\[<HOST>\]: 550 5.1.1 .*: Recipient address rejected:" ซึ่งหากไอพีนี้กระทำซ้ำกันเพียง 2 ครั้งเซิร์ฟเวอร์ก็จะทำการแบบไอพีนี้ทันทีอย่างน้อย 1 ชั่วโมง