📑 ???
?????????????????
?????????????????????????????????????????????????????hydra??code>medusa??code>nmap smtp-brute ????????????????????????????????????????????/p>
| ??? | ??? | ??? | ?????? | ?????????? |
|---|---|---|---|---|
| SMTP ?????ubmission??/td> | 587 | STARTTLS | SASL PLAIN/LOGIN | ??/td> |
| SMTPS | 465 | Implicit TLS | SASL PLAIN/LOGIN | ??/td> |
| IMAPS | 993 | Implicit TLS | Dovecot ?????? | ??/td> |
| POP3S | 995 | Implicit TLS | Dovecot ?????? | ??/td> |
| Webmail ??? | 443 | HTTPS | ?????? | ??????????????/td> |
?????????????????efense in Depth????????????????????/p>
- ?????/strong>??ptables/nftables ?????? + fail2ban + knockd
- ?????/strong>??mtpd_delay_reject + smtpd_client_restrictions + Dovecot auth_failure_delay
- ?????/strong>????????+ ????????+ Honeypot ???
- ???????uditd + pam_unix ??? + ??????
????ovecot ??????????????fail2ban ???
2.1 Dovecot ?????????
Dovecot ??2.2 ????????auth_failure_delay??? 2.3 ???????????????????/p>
# /etc/dovecot/conf.d/10-auth.conf
# ????????????????? 2 ???????????????????auth_failure_delay = 2 secs
# Dovecot 2.3+ ??auth_penalty ???
# ??? IP ??????????????????????????# delay = auth_failure_delay ? min(log2(failure_count), max_multiplier)
# max_multiplier ??? 16??????????32 ???
# ??? SQL ??????????????auth_verbose = yes
auth_verbose_passwords = no # ???????????auth_debug_passwords = no # ???????????????
# ????????????????????# /etc/dovecot/conf.d/auth-sql.conf.ext
# password_query ??? active ???????password_query = SELECT username AS user, password AS password, \
'maildir:/var/mail/%d/%n' AS userdb_mail \
FROM mailbox \
WHERE username = '%u' AND active = '1' AND locked_until IS NULL
# ??locked_until > NOW() ????????????????????/code>
2.2 Dovecot + fail2ban ???
fail2ban ?????? Dovecot ???????????????????? iptables/nftables ??? IP??strong>??????????????????????/strong>??/p>
# /etc/fail2ban/filter.d/dovecot-auth.conf
# ??? Dovecot ????????????
[Definition]
failregex = ^%(__prefix_line)s(?:pop3|imap)-login: (?:Info|Debug): \
(?:Aborted login|Authentication failed) \
.*rip=(?P\S+).*$
# ?????? Dovecot ??????
^%(__prefix_line)s(?:pop3|imap)-login: \
(?:Info )?(?:Disconnected):.*rip=(?P\S+),.*failed$
ignoreregex =
# /etc/fail2ban/jail.d/dovecot.conf
[dovecot]
enabled = true
port = imap,imaps,pop3,pop3s
filter = dovecot-auth
logpath = /var/log/dovecot.log
/var/log/mail.log
maxretry = 5
findtime = 600 # 10 ?????bantime = 86400 # 1 ??banaction = nftables-multiport # ??iptables-multiport
# ?????????????????
action_ = %(action_)s
action_dovecot_block = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="tcp"]
action_mw = %(action_mw)s[dovecot_alert]
[mail action=%(action_)s[name=%(__name__)s, dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]]
# ?????????
fail2ban-regex /var/log/dovecot.log /etc/fail2ban/filter.d/dovecot-auth.conf \
--print-all-matched
2.3 Dovecot 2.3+ ??? auth_penalty ???
Dovecot 2.3 ????????? auth_penalty??????????????? fail2ban ??????????????
# /etc/dovecot/conf.d/10-auth.conf
# ??? auth policy ?????????????????auth_policy_server_url = http://localhost:8080/policy
auth_policy_server_api_header = X-Api-Key: your-api-key
auth_policy_hash_nonce = some-random-string
auth_policy_hash_user = %u
auth_policy_hash_domain = %d
auth_policy_hash_remote = %r
# ?????auth_penalty ???
# ??10-master.conf ?????auth-penalty ???
service auth-penalty {
unix_listener auth-penalty {
mode = 0600
user = $default_internal_user
}
# ???????????????
# penalty ?????????????? # ?????? in-memory + SQLite ?????}
????ostfix SMTP AUTH ?????????
3.1 Postfix ????????????
Postfix ??? Dovecot SASL ??? SMTP AUTH ???????????????????????????
# Postfix + Dovecot SASL ???????????Jul 20 14:23:45 mx postfix/smtpd[12345]: warning: unknown[203.0.113.5]: \
SASL LOGIN authentication failed: authentication failure
Jul 20 14:23:46 mx postfix/smtpd[12345]: warning: unknown[203.0.113.5]: \
SASL PLAIN authentication failed: generic failure
# ??? Dovecot SASL ???Dovecot ???????????Jul 20 14:23:45 mx dovecot: auth-worker(12346): \
pam(user@example.com,203.0.113.5): \
unknown user
Jul 20 14:23:46 mx dovecot: auth-worker(12346): \
pam(sales@example.com,203.0.113.5): \
password mismatch
3.2 ?????fail2ban ???
# /etc/fail2ban/filter.d/postfix-auth.conf
[Definition]
failregex = ^%(__prefix_line)swarning: .*\[\]: SASL (?:LOGIN|PLAIN) \
authentication failed(?:, .*)?$
ignoreregex =
# ?????? Postfix ??????
^%(__prefix_line)swarning: .*\[\]: SASL (?:LOGIN|PLAIN) \
authentication failed: authentication failure$
^%(__prefix_line)swarning: .*\[\]: SASL (?:LOGIN|PLAIN) \
authentication failed: generic failure$
^%(__prefix_line)swarning: .*\[\]: SASL (?:LOGIN|PLAIN) \
authentication failed: no mechanism available$
# ??????????????????????? ^%(__prefix_line)swarning: .*\[\]: SASL LOGIN authentication failed: \
server didn't send SASL mechanisms$
# /etc/fail2ban/jail.d/postfix-auth.conf
[postfix-auth]
enabled = true
port = smtp,submission,submissions,smtps
filter = postfix-auth
logpath = /var/log/mail.log
maxretry = 5
findtime = 600
bantime = 86400
# ???????????? Dovecot ??? IP ????????action_ = %(action_)s
dovecot-block-ip.sh[name=%(__name__)s, ip=""]
3.3 Dovecot IP ???????????/h3>
# ??fail2ban ??? SMTP AUTH IP ???????????? Dovecot ?????????
cat > /usr/local/bin/dovecot-block-ip.sh << 'SH'
#!/bin/bash
# ???: dovecot-block-ip.sh
# ??fail2ban action_ ???
IP="$2"
ACTION="$3" # ban / unban
BLOCKLIST="/etc/dovecot/blocked-ips.conf"
case "$ACTION" in
ban)
echo "$IP" >> "$BLOCKLIST"
# ????????????????Dovecot
# ??Dovecot ??auth policy ?????????
sort -u -o "$BLOCKLIST" "$BLOCKLIST"
logger -t dovecot-block "IP blocked: $IP"
;;
unban)
sed -i "/^${IP}$/d" "$BLOCKLIST"
logger -t dovecot-block "IP unblocked: $IP"
;;
esac
SH
chmod 755 /usr/local/bin/dovecot-block-ip.sh
# Dovecot ???????????# ??? auth policy ????????# auth_policy_server_url = http://127.0.0.1:8080/policy
# ?????passdb checkpassword ??????
????mtpd_delay_reject ??smtpd_client_restrictions ???
4.1 smtpd_delay_reject ???
# ??fail2ban ??? SMTP AUTH IP ???????????? Dovecot ?????????
cat > /usr/local/bin/dovecot-block-ip.sh << 'SH'
#!/bin/bash
# ???: dovecot-block-ip.sh
# ??fail2ban action_ ???
IP="$2"
ACTION="$3" # ban / unban
BLOCKLIST="/etc/dovecot/blocked-ips.conf"
case "$ACTION" in
ban)
echo "$IP" >> "$BLOCKLIST"
# ????????????????Dovecot
# ??Dovecot ??auth policy ?????????
sort -u -o "$BLOCKLIST" "$BLOCKLIST"
logger -t dovecot-block "IP blocked: $IP"
;;
unban)
sed -i "/^${IP}$/d" "$BLOCKLIST"
logger -t dovecot-block "IP unblocked: $IP"
;;
esac
SH
chmod 755 /usr/local/bin/dovecot-block-ip.sh
# Dovecot ???????????# ??? auth policy ????????# auth_policy_server_url = http://127.0.0.1:8080/policy
# ?????passdb checkpassword ?????? Postfix ??smtpd_delay_reject?????yes?????Postfix ??????????????????????? RCPT TO ????????553 ??554?????????????????strong>?????/strong>??/p>
| ??? | ??? | ????????? |
|---|---|---|
yes?????? | HELO/EHLO ???????????reject_unknown_client_hostname????????????????????RCPT TO ????????? | ????????? RCPT TO?????????????????????????????????????????????????????? |
no | ?????????????????HELO ??? reject_unknown_client_hostname ?????? 504??/td> | ?????????????????????????????? fail2ban ??????????? |
# ???????????delay_reject=yes ????????????????????# /etc/postfix/main.cf
# ???????????????
smtpd_delay_reject = yes
# smtpd_client_restrictions ??EHLO/HELO ???????????# ?????delay_reject ?????smtpd_client_restrictions =
# ????????? fail2ban ?????????????? # ??? postscreen ?????????
check_client_access cidr:/etc/postfix/client_access.cidr,
permit_mynetworks,
reject_unknown_client_hostname,
# ????DNSBL????????? ????EHLO ?????? DNSBL
# reject_rbl_client zen.spamhaus.org,
permit
# smtpd_recipient_restrictions ??RCPT TO ??????????????smtpd_recipient_restrictions =
permit_mynetworks,
reject_unauth_destination,
# ????????? SASL ??????? permit_sasl_authenticated,
reject_unauth_destination,
reject
# smtpd_relay_restrictions ??????????ostfix 2.10+??# ??????????????????
smtpd_relay_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
# ?????????????delay_reject ??????
# 1. smtpd_client_restrictions (EHLO) ?????????????????????????# 2. smtpd_helo_restrictions (HELO) ?????
# 3. smtpd_sender_restrictions (MAIL FROM)
# 4. smtpd_recipient_restrictions (RCPT TO) ??????????
4.2 smtpd_delay_reject = no ????????/h3>
??smtpd_delay_reject ??? no ????????????????????/p>
??????????????????
- ?????? SMTP ????????HLO ?????????????????/li>
- ?????
reject_unknown_client??????????????????????? - ???????????????????????????????????????/li>
- ??????
reject_rbl_client???????????????????????IP ???
???????????/strong>?????????
- ????????????????????ail.log ???????????HELO ???????????ail2ban ????????? EHLO ????????/li>
- ?????? RCPT TO ????????????
- Postfix ????????????????????EHLO ???????????/li>
# ????????submission/smtps ??????????????delay_reject=no
# /etc/postfix/master.cf
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_delay_reject=no # ????????????
-o smtpd_client_restrictions=\
permit_sasl_authenticated,\
reject
smtps inet n - n - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_delay_reject=no
-o smtpd_tls_wrappermode=yes
-o smtpd_client_restrictions=\
permit_sasl_authenticated,\
reject
# ??? 25 ?????TA-MTA????????delay_reject=yes
# ?????????????????? RCPT TO ????????????
????ostfix ???????????????????/h2>
5.1 ??????????/h3>
?????Postfix ??????SASL ??????????????/var/log/mail.log ???????????????????????
- ?????? SASL ????????????????????????
- ?????
smtpd_sasl_authenticated_header = yes??????????????? - ???
smtpd_pw_server_security = none??????????????/li> - ??????????????? Postfix ????????? syslog
??fail2ban ?????Postfix ??????????????????????????????????/p>
5.2 ??? A?????pam_unix ???
??? Dovecot SASL ??? PAM ?????code>pam_unix ?????? /var/log/auth.log ???????????????????????????????????Postfix ????????????
# pam_unix ???????????# auth.log:
# Jul 20 14:23:45 mx postfix/smtpd: pam_unix(smtp:auth): \
# authentication failure; logname= uid=0 euid=0 tty= \
# ruser= rhost=203.0.113.5 user=user@example.com
# fail2ban ??? pam_unix ???
cat > /etc/fail2ban/filter.d/pam-generic.conf << 'CONF'
[Definition]
failregex = ^%(__prefix_line)%(__pam_auth)s[^:]*authentication failure;.*rhost=\s
ignoreregex =
CONF
# ??? PAM ???
cat > /etc/fail2ban/jail.d/pam-auth.conf << 'CONF'
[pam-auth]
enabled = true
filter = pam-generic
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 86400
port = smtp,submission,submissions,smtps,imap,imaps,pop3,pop3s
CONF
# ??? Postfix SMTP AUTH ??? PAM
# /etc/dovecot/conf.d/auth-system.conf.ext
passdb {
driver = pam
args = session=yes dovecot
}
# ????????Postfix ??? saslauthd ??PAM
# /etc/default/saslauthd
START=yes
MECHANISMS="pam"
5.3 ??? B??uditd ??????????????/h3>
auditd ??Linux ????????????????????? pam_unix ??pam_sm_authenticate ???????????????????????????Postfix ?????????pam_unix ?????????????????udit ??????????????/p>
# ??? auditd
apt install auditd audispd-plugins
# ??? audit ??? ?????????pam ??????
cat >> /etc/audit/rules.d/50-mail-auth.rules << 'RULES'
# ??? pam_unix.so ??pam_sm_authenticate ???
-w /lib/x86_64-linux-gnu/security/pam_unix.so -p x -k mail-auth
# ???????postfix/smtpd ??pam ?????-w /usr/sbin/smtpd -p x -k smtpd-exec
RULES
# ??????
auditctl -R /etc/audit/rules.d/50-mail-auth.rules
# ??????????????????
ausearch -k mail-auth -ts today -i | grep -E "success=no|failed"
# fail2ban ??? auditd ???
cat > /etc/fail2ban/filter.d/audit-mail-auth.conf << 'CONF'
[Definition]
failregex = ^type=USER_AUTH.*msg=audit\(.*\):.*\sres=failed\b.*\bacct="[^"]+"\s.*\shostname=\S+\saddr=\s.*exe="/usr/sbin/smtpd"
ignoreregex =
CONF
# ??? auditd fail2ban
cat > /etc/fail2ban/jail.d/audit-mail-auth.conf << 'CONF'
[audit-mail-auth]
enabled = true
filter = audit-mail-auth
logpath = /var/log/audit/audit.log
maxretry = 5
findtime = 600
bantime = 86400
port = smtp,submission,submissions,smtps
CONF
5.4 ??? C?????Dovecot ?????????
????????????????Dovecot ???????SASL ???????????? Postfix ?????????
# /etc/dovecot/conf.d/10-master.conf
# ??? Dovecot ?????????????????service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
# ?????????
verbose = yes
}
# /etc/dovecot/conf.d/10-logging.conf
# ?????????
auth_verbose = yes
auth_verbose_passwords = no # ???????????auth_debug = no # ????????????????????????
# ???????????????????mail_log_prefix = "%s(%u): "
plugin {
mail_log_events = delete undelete expunge copy mailbox_create mailbox_delete
mail_log_fields = uid box msgid size
}
# ??? Dovecot ????????fail2ban ????????# ??? fail2ban ?????? dovecot.log ??? mail.log
# /etc/fail2ban/jail.d/postfix-auth.conf
# logpath = /var/log/dovecot.log
# ??? dovecot.log ?????? smtp ??imap ????????/code>
????mtpd_client_restrictions ???????????????/h2>
6.1 ????????IP ????????
Postfix ??smtpd_client_restrictions ??????????????????????IP ??10 ????????5 ??????"???????????????????????????????????????????????????
# ??? 1???????????IDR ?????# /etc/postfix/client_access.cidr
# ????????IP ??203.0.113.0/24 REJECT Known attack source
198.51.100.0/24 REJECT Known attack source
# fail2ban ????????IP
# ??fail2ban ?????IP ????? action ????????# ????????iptables/nftables ???????????
# ??? 2?????postscreen ??Postfix ?????SMTP ?????????
# /etc/postfix/main.cf
# ??? postscreen
postscreen_access_list = permit_mynetworks,
cidr:/etc/postfix/postscreen_access.cidr
postscreen_blacklist_action = drop
# postscreen ????????ostfix 2.11+??postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites =
zen.spamhaus.org=127.0.0.[2..11]*3
b.barracudacentral.org=127.0.0.2*2
postscreen_greet_action = enforce
# postscreen ?????SMTP ???????????? 25 ???
# ??? SMTP ????????postscreen ??????????????2525??/code>
6.2 Postfix ?????? postscreen ???
# /etc/postfix/main.cf ??postscreen ??????
# ?????ort 25 ??postscreen ??port 2525 ??postfix smtpd
# ??? postscreen ???????SMTP ?????mtpd ??????"????????"?????
# postscreen ???
postscreen_access_list =
permit_mynetworks,
cidr:/etc/postfix/postscreen_access.cidr
postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
postscreen_cache_map = btree:$data_directory/postscreen_cache
postscreen_dnsbl_action = enforce
# postscreen ??????????????# ??? cache_map ?????? IP ????????postscreen_reject_frequency = 3 # ??60 ?????3 ?????????
postscreen_reject_limit = 5 # ??60 ?????5 ?????????
# ??SMTP ?????2525 ??????
# 25 ?????postscreen ???
2525 inet n - n - - smtpd
-o smtpd_tls_security_level=may
-o smtpd_sasl_auth_enable=yes
# postscreen + fail2ban ??????
# postscreen ??????????????ail2ban ?????????
6.3 ???????????????????/h3>
# ????????????
cat > /usr/local/bin/adaptive-rate-limit.sh << 'SH'
#!/bin/bash
# ????????????????? fail2ban ?????# ??15 ??????????
DATA_FILE="/var/lib/rate-limit/stats.json"
mkdir -p "$(dirname "$DATA_FILE")"
# ?????? 15 ???????????IP
cd /tmp
TMP=$(mktemp)
grep "$(date -d '15 minutes ago' '+%Y-%m-%d %H')" /var/log/mail.log | \
grep "authentication failed" | \
sed 's/.*\[\([0-9.]*\)\].*/\1/' | sort | uniq -c | sort -rn > "$TMP"
# ??????
while read count ip; do
if [ "$count" -gt 50 ]; then
# ?????? ????? iptables ??? 7 ?? iptables -A INPUT -s "$ip" -p tcp --dport 25,587,465,993,995 -j DROP
logger -t rate-limit "HIGH: $ip blocked for 7 days ($count attempts)"
elif [ "$count" -gt 20 ]; then
# ??? ????? postscreen ????????????
echo "$ip REJECT Excessive authentication failures" >> \
/etc/postfix/postscreen_access.cidr
logger -t rate-limit "MEDIUM: $ip added to postscreen blocklist ($count attempts)"
elif [ "$count" -gt 5 ]; then
# ??? ??????????fail2ban ???????? logger -t rate-limit "LOW: $ip noted for repeated failures ($count)"
fi
done < "$TMP"
# ??? 7 ?????iptables ???
# ????????????????????? ipset + timeout ????????SH
chmod 755 /usr/local/bin/adaptive-rate-limit.sh
????oneypot ??????
# ????????????
cat > /usr/local/bin/adaptive-rate-limit.sh << 'SH'
#!/bin/bash
# ????????????????? fail2ban ?????# ??15 ??????????
DATA_FILE="/var/lib/rate-limit/stats.json"
mkdir -p "$(dirname "$DATA_FILE")"
# ?????? 15 ???????????IP
cd /tmp
TMP=$(mktemp)
grep "$(date -d '15 minutes ago' '+%Y-%m-%d %H')" /var/log/mail.log | \
grep "authentication failed" | \
sed 's/.*\[\([0-9.]*\)\].*/\1/' | sort | uniq -c | sort -rn > "$TMP"
# ??????
while read count ip; do
if [ "$count" -gt 50 ]; then
# ?????? ????? iptables ??? 7 ?? iptables -A INPUT -s "$ip" -p tcp --dport 25,587,465,993,995 -j DROP
logger -t rate-limit "HIGH: $ip blocked for 7 days ($count attempts)"
elif [ "$count" -gt 20 ]; then
# ??? ????? postscreen ????????????
echo "$ip REJECT Excessive authentication failures" >> \
/etc/postfix/postscreen_access.cidr
logger -t rate-limit "MEDIUM: $ip added to postscreen blocklist ($count attempts)"
elif [ "$count" -gt 5 ]; then
# ??? ??????????fail2ban ???????? logger -t rate-limit "LOW: $ip noted for repeated failures ($count)"
fi
done < "$TMP"
# ??? 7 ?????iptables ???
# ????????????????????? ipset + timeout ????????SH
chmod 755 /usr/local/bin/adaptive-rate-limit.shHoneypot??????????????????????????????????????????????????????????????????????IP ?????????????/p>
7.1 Honeypot ??????
# ??????????????????????????????????????????
useradd -m -s /sbin/nologin honeypot@example.com
passwd honeypot@example.com <<< "$(openssl rand -base64 48)"
# ??var/mail/example.com/honeypot ???????????????
# ??? Dovecot ????????? IMAP/POP3 ?????????????????????
# ??/etc/dovecot/users ???????????? passwd-file??echo "honeypot@example.com:{SHA512-CRYPT}\$6\$$(openssl rand -base64 16):" >> /etc/dovecot/users
# ????????fail2ban ????cat > /etc/fail2ban/filter.d/dovecot-honeypot.conf << 'CONF'
[Definition]
failregex = ^%(__prefix_line)s(?:imap|pop3)-login: (?:Info )?Disconnected: \
.*user=.*rip=.*$
ignoreregex =
CONF
# ?????????????maxretry=1 ?????????????????????????????cat > /etc/fail2ban/jail.d/dovecot-honeypot.conf << 'CONF'
[dovecot-honeypot]
enabled = true
filter = dovecot-honeypot
logpath = /var/log/dovecot.log
maxretry = 1
findtime = 31536000 # 1 ????????????????????
bantime = 864000 # 10 ??port = imap,imaps,pop3,pop3s
action = %(action_)s
CONF
# ????????????????????????????????????# ??????????????????????????
# ?????dmin, postmaster, info, support, test, backup, root
for user in admin info support test root; do
if ! id "${user}@example.com" &>/dev/null; then
# ???????????????????? echo "?????????: ${user}@example.com"
fi
done
7.2 Honeypot ??????????????????
cat > /usr/local/bin/honeypot-alert.sh << 'SH'
#!/bin/bash
# ???????????????
IP="$1"
USER="$2"
# 1. ??????????echo "Honeypot triggered by IP: $IP, attempted user: $USER at $(date)" | \
mail -s "[ALERT] Honeypot ??? - $IP" security@example.com
# 2. ??? IP ??????????????for port in 25 587 465 993 995; do
iptables -A INPUT -s "$IP" -p tcp --dport $port -j DROP
done
# 3. ????????????
echo "$IP REJECT Honeypot trigger" >> /etc/postfix/client_access.cidr
postfix reload
# 4. ?????SIEM
logger -t honeypot -p local0.alert "HONEYPOT_TRIGGER: $IP attempted $USER"
SH
chmod 755 /usr/local/bin/honeypot-alert.sh
??????????????????????/h2>
8.1 ?????????
| ??? | ??? | ??? | ?????? |
|---|---|---|---|
| 0 ???????? | iptables/nftables + ipset | ?????? IP ?????? | ??? |
| 1 ???????? | postscreen | ???????????NSBL????????/td> | ??? |
| 2 ???????1 | smtpd_client_restrictions | CIDR ????????????????/td> | ?????? |
| 3 ???????2 | smtpd_delay_reject=no (??????) | ???????????? | EHLO ??? |
| 4 ???????? | Dovecot auth_failure_delay | ????????? | ?????? |
| 5 ???????? | fail2ban??ostfix + Dovecot + auditd??/td> | ????????? | ?????? |
| 6 ?????????/td> | Honeypot ??? | ???????????/td> | ?????? |
| 7 ??????????/td> | ?????? + ????????/td> | ????????? | ?????? |
8.2 ??????????/h3>
echo "=== ???????????????????==="
echo "1. ????? iptables/nftables ??????"
nft list ruleset 2>/dev/null | grep -q "thash" && echo " ??nftables hashlimit ????? || echo " ??nftables ???????????
echo ""
echo "2. postscreen ????
postconf -n 2>/dev/null | grep -q "^postscreen" && echo " ??postscreen ????? || echo " ??postscreen ?????
echo ""
echo "3. fail2ban ???????
for jail in postfix-auth dovecot dovecot-honeypot; do
systemctl is-active fail2ban &>/dev/null
if [ $? -eq 0 ]; then
STATUS=$(fail2ban-client status "$jail" 2>/dev/null | grep -E "Status|Total banned")
if [ -n "$STATUS" ]; then
echo " ??$jail: $STATUS"
else
echo " ? $jail: jail ????????????"
fi
else
echo " ??fail2ban ?????
break
fi
done
echo ""
echo "4. Dovecot auth_failure_delay"
doveconf -n 2>/dev/null | grep -q "auth_failure_delay" && echo " ??auth_failure_delay ????? || echo " ???????
echo ""
echo "5. SMTP ??? delay_reject ???"
postconf -M submission 2>/dev/null | grep -q "smtpd_delay_reject=no" && echo " ??submission ??? delay_reject=no" || echo " ??submission ?????? delay_reject=no"
echo ""
echo "6. ??????"
id honeypot@example.com &>/dev/null && echo " ??honeypot ???????? || echo " ?????????????
echo ""
echo "7. auditd ???"
auditctl -l 2>/dev/null | grep -q "mail-auth" && echo " ??auditd ?????????????? || echo " ???????auditd ??????"
echo ""
echo "8. ??????"
# ???????SCORE=0
[ "$(systemctl is-active fail2ban)" = "active" ] && ((SCORE++))
postconf -n 2>/dev/null | grep -q "^postscreen" && ((SCORE++))
doveconf -n 2>/dev/null | grep -q "auth_failure_delay" && ((SCORE++))
[ -f /etc/postfix/client_access.cidr ] && ((SCORE++))
auditctl -l 2>/dev/null | grep -q "mail-auth" && ((SCORE++))
echo ""
echo "??????: $SCORE/5"
echo "???: $([ "$SCORE" -ge 4 ] && echo '???' || echo '???????)"
8.3 ???????????/h3>
# ???????????????
cat > /usr/local/bin/brute-force-daily-report.sh << 'SH'
#!/bin/bash
# ????????fail2ban ?????IP ????????
REPORT="/var/reports/brute-force-$(date +%Y%m%d).txt"
mkdir -p /var/reports
echo "=== ????????????: $(date +%Y-%m-%d) ===" > "$REPORT"
echo "" >> "$REPORT"
# ??jail ??????
for jail in postfix-auth dovecot dovecot-honeypot pam-auth audit-mail-auth; do
banned=$(fail2ban-client status "$jail" 2>/dev/null | \
grep "Total banned" | awk '{print $4}')
[ -n "$banned" ] && echo "$jail: $banned ??IP ????? >> "$REPORT"
done
echo "" >> "$REPORT"
echo "--- ????????? ---" >> "$REPORT"
for jail in postfix-auth dovecot dovecot-honeypot; do
fail2ban-client status "$jail" 2>/dev/null | \
grep "Currently banned" >> "$REPORT"
done
echo "" >> "$REPORT"
echo "--- iptables ????????---" >> "$REPORT"
iptables -L INPUT -n 2>/dev/null | grep "DROP" | wc -l >> "$REPORT"
echo "" >> "$REPORT"
echo "--- Top 5 ?????????/ASN ---" >> "$REPORT"
cat /var/log/mail.log | grep "authentication failed" | \
sed 's/.*\[\([0-9.]*\)\].*/\1/' | sort | uniq -c | sort -rn | \
head -5 | while read count ip; do
echo "$count ? $ip" >> "$REPORT"
done
mail -s "[SECURITY] ???????????? $(date +%Y%m%d)" \
security@example.com < "$REPORT"
SH
chmod 755 /usr/local/bin/brute-force-daily-report.sh
# crontab ?????? 9 ??echo "0 9 * * * /usr/local/bin/brute-force-daily-report.sh" > /etc/cron.d/brute-force-report
8.4 ????????SIEM ???
echo "=== ???????????????????==="
echo "1. ????? iptables/nftables ??????"
nft list ruleset 2>/dev/null | grep -q "thash" && echo " ??nftables hashlimit ????? || echo " ??nftables ???????????
echo ""
echo "2. postscreen ????
postconf -n 2>/dev/null | grep -q "^postscreen" && echo " ??postscreen ????? || echo " ??postscreen ?????
echo ""
echo "3. fail2ban ???????
for jail in postfix-auth dovecot dovecot-honeypot; do
systemctl is-active fail2ban &>/dev/null
if [ $? -eq 0 ]; then
STATUS=$(fail2ban-client status "$jail" 2>/dev/null | grep -E "Status|Total banned")
if [ -n "$STATUS" ]; then
echo " ??$jail: $STATUS"
else
echo " ? $jail: jail ????????????"
fi
else
echo " ??fail2ban ?????
break
fi
done
echo ""
echo "4. Dovecot auth_failure_delay"
doveconf -n 2>/dev/null | grep -q "auth_failure_delay" && echo " ??auth_failure_delay ????? || echo " ???????
echo ""
echo "5. SMTP ??? delay_reject ???"
postconf -M submission 2>/dev/null | grep -q "smtpd_delay_reject=no" && echo " ??submission ??? delay_reject=no" || echo " ??submission ?????? delay_reject=no"
echo ""
echo "6. ??????"
id honeypot@example.com &>/dev/null && echo " ??honeypot ???????? || echo " ?????????????
echo ""
echo "7. auditd ???"
auditctl -l 2>/dev/null | grep -q "mail-auth" && echo " ??auditd ?????????????? || echo " ???????auditd ??????"
echo ""
echo "8. ??????"
# ???????SCORE=0
[ "$(systemctl is-active fail2ban)" = "active" ] && ((SCORE++))
postconf -n 2>/dev/null | grep -q "^postscreen" && ((SCORE++))
doveconf -n 2>/dev/null | grep -q "auth_failure_delay" && ((SCORE++))
[ -f /etc/postfix/client_access.cidr ] && ((SCORE++))
auditctl -l 2>/dev/null | grep -q "mail-auth" && ((SCORE++))
echo ""
echo "??????: $SCORE/5"
echo "???: $([ "$SCORE" -ge 4 ] && echo '???' || echo '???????)"# ???????????????
cat > /usr/local/bin/brute-force-daily-report.sh << 'SH'
#!/bin/bash
# ????????fail2ban ?????IP ????????
REPORT="/var/reports/brute-force-$(date +%Y%m%d).txt"
mkdir -p /var/reports
echo "=== ????????????: $(date +%Y-%m-%d) ===" > "$REPORT"
echo "" >> "$REPORT"
# ??jail ??????
for jail in postfix-auth dovecot dovecot-honeypot pam-auth audit-mail-auth; do
banned=$(fail2ban-client status "$jail" 2>/dev/null | \
grep "Total banned" | awk '{print $4}')
[ -n "$banned" ] && echo "$jail: $banned ??IP ????? >> "$REPORT"
done
echo "" >> "$REPORT"
echo "--- ????????? ---" >> "$REPORT"
for jail in postfix-auth dovecot dovecot-honeypot; do
fail2ban-client status "$jail" 2>/dev/null | \
grep "Currently banned" >> "$REPORT"
done
echo "" >> "$REPORT"
echo "--- iptables ????????---" >> "$REPORT"
iptables -L INPUT -n 2>/dev/null | grep "DROP" | wc -l >> "$REPORT"
echo "" >> "$REPORT"
echo "--- Top 5 ?????????/ASN ---" >> "$REPORT"
cat /var/log/mail.log | grep "authentication failed" | \
sed 's/.*\[\([0-9.]*\)\].*/\1/' | sort | uniq -c | sort -rn | \
head -5 | while read count ip; do
echo "$count ? $ip" >> "$REPORT"
done
mail -s "[SECURITY] ???????????? $(date +%Y%m%d)" \
security@example.com < "$REPORT"
SH
chmod 755 /usr/local/bin/brute-force-daily-report.sh
# crontab ?????? 9 ??echo "0 9 * * * /usr/local/bin/brute-force-daily-report.sh" > /etc/cron.d/brute-force-report
8.4 ????????SIEM ???
???????????SIEM??? Elasticsearch + Kibana???
# ??? Filebeat ?????????????# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/mail.log
- /var/log/dovecot.log
- /var/log/auth.log
fields:
service: mail-security
fields_under_root: true
# ??Elasticsearch ?????????????????# Example ES query for brute force detection:
# POST /_watcher/watch/mail_brute_force
# {
# "trigger": { "schedule": { "interval": "5m" } },
# "input": {
# "search": {
# "request": {
# "indices": ["filebeat-*"],
# "body": {
# "query": {
# "bool": {
# "filter": [
# { "range": { "@timestamp": { "gte": "now-5m" } } },
# { "terms": { "event.type": ["authentication_failure"] } }
# ]
# }
# },
# "aggs": {
# "attacker_ips": {
# "terms": { "field": "source.ip", "min_doc_count": 5 }
# }
# }
# }
# }
# }
# },
# "actions": {
# "webhook": {
# "webhook": {
# "host": "alertmanager.example.com",
# "port": 9093,
# "path": "/api/v2/alerts",
# "method": "POST"
# }
# }
# }
# }
???????/h3>
- Postfix Documentation ??SMTPD ACCESS POLICIES. https://www.postfix.org/SMTPD_ACCESS_README.html
- Postfix Documentation ??POSTSCREEN(8). https://www.postfix.org/postscreen.8.html
- Dovecot Documentation ??Authentication Configuration. https://doc.dovecot.org/configuration_manual/authentication/
- Dovecot Documentation ??Auth Policy Server. https://doc.dovecot.org/configuration_manual/auth_policy/
- fail2ban ??Official Documentation. https://fail2ban.readthedocs.io/
- Red Hat Enterprise Linux 9 ??Security Hardening Guide, Chapter 10: Auditing the System. https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/
- NIST SP 800-177 Rev. 1 ??Trustworthy Email, Section 6.2: Authentication Security.
- NIST SP 800-53 Rev. 5 ??AC-7: Unsuccessful Logon Attempts; IA-2: Identification and Authentication.
- RFC 4954 ??SMTP Service Extension for Authentication. IETF, July 2007.
- OWASP ??Email Security Cheat Sheet: Brute Force Prevention. https://cheatsheetseries.owasp.org
引用本文
ztpop.net 知识库编辑. "IMAP ??????????????? fail2ban ???????????????" ztpop.net 知识库.
本站技术文章采用 CC-BY 4.0 许可,可自由引用,仅需标注来源 ztpop.net。
