1. Tổng quan
Trong môi trường VoIP sử dụng Asterisk, việc bị quét tài khoản SIP (REGISTER
, INVITE
) là điều rất phổ biến. Những kẻ tấn công (SIP scanner) cố gắng dò tìm username/password bằng brute-force. May mắn thay, Fail2Ban
là công cụ tuyệt vời giúp tự động chặn IP khi phát hiện các hành vi bất thường.
Tuy nhiên, log chuẩn từ Asterisk thường khó xử lý bằng regex, đặc biệt là với res_pjsip
. Vì thế, trong bài viết này, mình sẽ chia sẻ cách:
- Tùy biến log Asterisk để dễ bắt lỗi
- Dùng Fail2Ban phân tích log đó
- Tự động chặn IP độc hại
2. Sơ đồ hoạt động
┌────────────────────────┐
│ /var/log/asterisk/full │
└─────────┬──────────────┘
│ tail -F
▼
Fail2Ban phân tích
│
▼
🔒 IP bị chặn!
3. Cài đặt Fail2Ban
Sử dụng 2 command đơn giản này để cài đặt Fail2ban
apt update
apt install fail2ban -y
Sau khi cài xong, kiểm tra phiên bản:
fail2ban-client -V
Ví dụ đầu ra:
0.11.2
4. Biến log khó đọc → log dễ đọc (đây là tùy chọn, bạn có thể bỏ qua)
Vấn đề gặp phải, bạn có log gốc như sau:
[Jun 28 10:06:32] NOTICE[...] res_pjsip/pjsip_distributor.c: Request 'INVITE' ... failed for '5.196.115.163:56732' - Failed to authenticate
Cú pháp log phức tạp, regex khó khớp. Fail2Ban yêu cầu dòng log phải có định dạng rõ ràng và có IP ở đúng vị trí.
Lúc này sơ đồ sẽ đi theo luồng sau.
┌────────────────────────┐
│ /var/log/asterisk/full │
└─────────┬──────────────┘
│ tail -F
▼
┌──────────────────────────────┐
│ log_failed_ip.sh (lọc & ghi) │
└─────────┬────────────────────┘
▼
/var/log/asterisk/pjsip_auth.log
│
▼
Fail2Ban phân tích
│
▼
🔒 IP bị chặn!
Viết script lọc log Asterisk
cat > /usr/local/bin/log_failed_ip.sh <<'EOF'
#!/bin/bash
while read line; do
echo "$line" | grep -q "Failed to authenticate" || continue
ip=$(echo "$line" | grep -oP "failed for '\K[^']+")
[[ $ip ]] && echo "$(date '+%Y-%m-%d %H:%M:%S') REGISTER_FAIL ${ip%:*}" >> /var/log/asterisk/pjsip_auth.log
done
EOF
chmod +x /usr/local/bin/log_failed_ip.sh
Sau đó chạy nền bằng:
tail -F /var/log/asterisk/full | /usr/local/bin/log_failed_ip.sh &
File /var/log/asterisk/pjsip_auth.log
giờ sẽ có log dạng:
2025-06-28 10:01:16 REGISTER_FAIL 5.196.115.163
Đây là option gợi ý, mình không sử dụng nó nhé.
5. Quy trình cấu hình
Cấu hình Fail2Ban filter bằng cách tạo file /etc/fail2ban/filter.d/asterisk-pjsip.conf
.
[Definition]
failregex = failed for '<HOST>:\d+' .* - (Failed to authenticate|No matching endpoint found)
Call \(UDP:<HOST>:\d+\) to extension '.*' rejected because extension not found in context 'from-zenhub'
ignoreregex =
Bạn có thể kiểm tra regex bằng lệnh dưới và nhớ thay đường dẫn log và filter tương ứng với hệ thống của bạn.
shell> fail2ban-regex /var/log/asterisk/full /etc/fail2ban/filter.d/asterisk-pjsip.conf
Running tests
=============
Use failregex filter file : asterisk-pjsip, basedir: /etc/fail2ban
Use log file : /var/log/asterisk/full
Use encoding : UTF-8
Results
=======
Failregex: 71320 total
|- #) [# of hits] regular expression
| 1) [64735] failed for '<HOST>:\d+' .* - (Failed to authenticate|No matching endpoint found)
| 2) [6585] Call \(UDP:<HOST>:\d+\) to extension '.*' rejected because extension not found in context 'from-internal-zenhub'
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [74316] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
`-
Lines: 74316 lines, 0 ignored, 71320 matched, 2996 missed
[processed in 4.64 sec]
Missed line(s): too many to print. Use --print-all-missed to print all 2996 lines
Cấu hình Fail2Ban jail bằng cách tạo file jail riêng:
cat > /etc/fail2ban/jail.d/asterisk-pjsip.local << 'EOF'
[asterisk-pjsip]
enabled = true
port = 5060,5061
protocol = udp
filter = asterisk-pjsip
logpath = /var/log/asterisk/full
maxretry = 3
bantime = 3600
findtime = 300
EOF
Nếu cần bạn có thể tối ưu log Asterisk bằng cách kiểm tra file /etc/asterisk/logger.conf
. Dưới đây là cách tối ưu của mình.
cat > /etc/asterisk/logger.conf << 'OEF'
[general]
dateformat=%F %T
[logfiles]
console => notice,warning,error
messages.log => notice,warning,error
full => notice,warning,error,debug,verbose
OEF
Reload lại logger:
asterisk -rx "logger reload"
Khởi động lại Fail2Ban
systemctl restart fail2ban
Check status Fail2ban.
shell> systemctl status fail2ban
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled)
Active: active (running) since Sat 2025-06-28 15:37:46 UTC; 1s ago
Docs: man:fail2ban(1)
Main PID: 569147 (fail2ban-server)
Tasks: 7 (limit: 9474)
Memory: 14.1M
CPU: 1.140s
CGroup: /system.slice/fail2ban.service
└─569147 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
Jun 28 15:37:46 VPNServer1-100-151 systemd[1]: Started Fail2Ban Service.
Jun 28 15:37:47 VPNServer1-100-151 fail2ban-server[569147]: Server ready
Hãy xem kết quả log trong /var/log/asterisk/full
nhé.
shell> tail -f /var/log/asterisk/full
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 3625520650) - Failed to authenticate
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 2525337673) - No matching endpoint found
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 2525337673) - Failed to authenticate
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 1976627641) - No matching endpoint found
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 1976627641) - Failed to authenticate
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 3426223023) - No matching endpoint found
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 3426223023) - Failed to authenticate
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 91974241) - No matching endpoint found
[2025-06-28 15:37:46] NOTICE[65016] res_pjsip/pjsip_distributor.c: Request 'REGISTER' from '"866" <sip:866@113.161.201.128>' failed for '51.89.162.163:5369' (callid: 91974241) - Failed to authenticate
[2025-06-28 15:39:24] NOTICE[569508] res_pjsip/pjsip_distributor.c: Request 'INVITE' from '<sip:a'or'3=3--@92.205.110.66>' failed for '92.205.110.66:5060' (callid: 8521572-154458-1712632-182936198814@92.205.110.66) - No matching endpoint found
Khi xem trạng thái bạn thấy regex Fail2Ban sẽ khớp dòng này có IP 5.196.115.163
và đã chặn nó vì sai nhiều lần.
shell> fail2ban-client status asterisk-pjsip
Status for the jail: asterisk-pjsip
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/asterisk/full
`- Actions
|- Currently banned: 16
|- Total banned: 16
`- Banned IP list: 103.176.90.16 103.176.90.92 123.21.229.201 135.237.126.250 154.212.141.147 154.212.141.253 173.231.185.164 185.38.148.119 207.167.64.28 207.167.67.22 23.175.48.211 5.196.115.163 5.39.61.118 69.175.4.222 77.110.126.104 77.221.140.149
6. Unban một IP.
Giả sử ví dụ 123.21.229.201 là IP của mình và mình muốn gỡ chặn nó. Hiện tại IP này của mình đã bị chặn, xem kết quả của IPTables bạn cũng thấy nó đã bị chặn bởi Fail2ban.
shell> iptables -L --line-number -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 f2b-asterisk-pjsip udp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 5060,5061
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain f2b-asterisk-pjsip (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 77.221.140.149 0.0.0.0/0 reject-with icmp-port-unreachable
2 0 0 REJECT all -- * * 77.110.126.104 0.0.0.0/0 reject-with icmp-port-unreachable
3 0 0 REJECT all -- * * 69.175.4.222 0.0.0.0/0 reject-with icmp-port-unreachable
4 0 0 REJECT all -- * * 5.39.61.118 0.0.0.0/0 reject-with icmp-port-unreachable
5 0 0 REJECT all -- * * 5.196.115.163 0.0.0.0/0 reject-with icmp-port-unreachable
6 0 0 REJECT all -- * * 23.175.48.211 0.0.0.0/0 reject-with icmp-port-unreachable
7 0 0 REJECT all -- * * 207.167.67.22 0.0.0.0/0 reject-with icmp-port-unreachable
8 0 0 REJECT all -- * * 207.167.64.28 0.0.0.0/0 reject-with icmp-port-unreachable
9 0 0 REJECT all -- * * 185.38.148.119 0.0.0.0/0 reject-with icmp-port-unreachable
10 0 0 REJECT all -- * * 173.231.185.164 0.0.0.0/0 reject-with icmp-port-unreachable
11 0 0 REJECT all -- * * 154.212.141.253 0.0.0.0/0 reject-with icmp-port-unreachable
12 0 0 REJECT all -- * * 154.212.141.147 0.0.0.0/0 reject-with icmp-port-unreachable
13 0 0 REJECT all -- * * 135.237.126.250 0.0.0.0/0 reject-with icmp-port-unreachable
14 0 0 REJECT all -- * * 123.21.229.201 0.0.0.0/0 reject-with icmp-port-unreachable
15 0 0 REJECT all -- * * 103.176.90.92 0.0.0.0/0 reject-with icmp-port-unreachable
16 0 0 REJECT all -- * * 103.176.90.16 0.0.0.0/0 reject-with icmp-port-unreachable
17 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Nếu bạn gỡ iptables -D f2b-asterisk-pjsip 14
cũng không xi nhê gì vì lát cũng bị fail2ban đưa vào danh sách chặn. Cùng xem lại danh sách IP bị chặn là 16 IP.
shell> fail2ban-client status asterisk-pjsip
Status for the jail: asterisk-pjsip
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/asterisk/full
`- Actions
|- Currently banned: 16
|- Total banned: 16
`- Banned IP list: 103.176.90.16 103.176.90.92 123.21.229.201 135.237.126.250 154.212.141.147 154.212.141.253 173.231.185.164 185.38.148.119 207.167.64.28 207.167.67.22 23.175.48.211 5.196.115.163 5.39.61.118 69.175.4.222 77.110.126.104 77.221.140.149
Bạn phải chạy lệnh sau để gỡ cấm IP, ví dụ 123.21.229.201
.
shell> fail2ban-client set asterisk-pjsip unbanip 123.21.229.201
1
Bây giờ số lượng IP bị chặn chỉ còn 15 IP.
shell> fail2ban-client status asterisk-pjsip
Status for the jail: asterisk-pjsip
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/asterisk/full
`- Actions
|- Currently banned: 15
|- Total banned: 15
`- Banned IP list: 103.176.90.16 103.176.90.92 135.237.126.250 154.212.141.147 154.212.141.253 173.231.185.164 185.38.148.119 207.167.64.28 207.167.67.22 23.175.48.211 5.196.115.163 5.39.61.118 69.175.4.222 77.110.126.104 77.221.140.149
Trên IPTables cũng đã gỡ 123.21.229.201
ra khỏi danh sách chặn.
shell> iptables -L --line-number -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 1 744 f2b-asterisk-pjsip udp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 5060,5061
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain f2b-asterisk-pjsip (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 77.221.140.149 0.0.0.0/0 reject-with icmp-port-unreachable
2 0 0 REJECT all -- * * 77.110.126.104 0.0.0.0/0 reject-with icmp-port-unreachable
3 0 0 REJECT all -- * * 69.175.4.222 0.0.0.0/0 reject-with icmp-port-unreachable
4 0 0 REJECT all -- * * 5.39.61.118 0.0.0.0/0 reject-with icmp-port-unreachable
5 0 0 REJECT all -- * * 5.196.115.163 0.0.0.0/0 reject-with icmp-port-unreachable
6 0 0 REJECT all -- * * 23.175.48.211 0.0.0.0/0 reject-with icmp-port-unreachable
7 0 0 REJECT all -- * * 207.167.67.22 0.0.0.0/0 reject-with icmp-port-unreachable
8 1 744 REJECT all -- * * 207.167.64.28 0.0.0.0/0 reject-with icmp-port-unreachable
9 0 0 REJECT all -- * * 185.38.148.119 0.0.0.0/0 reject-with icmp-port-unreachable
10 0 0 REJECT all -- * * 173.231.185.164 0.0.0.0/0 reject-with icmp-port-unreachable
11 0 0 REJECT all -- * * 154.212.141.253 0.0.0.0/0 reject-with icmp-port-unreachable
12 0 0 REJECT all -- * * 154.212.141.147 0.0.0.0/0 reject-with icmp-port-unreachable
13 0 0 REJECT all -- * * 135.237.126.250 0.0.0.0/0 reject-with icmp-port-unreachable
14 0 0 REJECT all -- * * 103.176.90.92 0.0.0.0/0 reject-with icmp-port-unreachable
15 0 0 REJECT all -- * * 103.176.90.16 0.0.0.0/0 reject-with icmp-port-unreachable
16 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Bạn có thể fix cứng bằng cách thêm IP vào danh sách “ignoreip”.
Mở file cấu hình của jail asterisk-pjsip
(có thể là một trong các file sau), ví dụ trường hợp của mình /etc/fail2ban/jail.d/asterisk-pjsip.local
và thêm dòng sau.
[asterisk-pjsip]
ignoreip = 127.0.0.1/8 ::1 123.21.229.201
Khởi động lại Fail2Ban để áp dụng.
systemctl restart fail2ban
Sau đó, xác minh lại bạn sẽ không thấy IP 123.21.229.201
không còn trong danh sách bị cấm và sẽ không bị cấm lại trong tương lai.
fail2ban-client status asterisk-pjsip
6. Fail2Ban chặn IP bằng gì?
IPTables/NFTables (phổ biến nhất trên Linux)
- Đây là backend mặc định của Fail2Ban trên hầu hết hệ thống Linux (Debian, Ubuntu, CentOS).
- Nó thêm các rules tạm thời vào
iptables
hoặcnftables
để DROP hoặc REJECT các IP bị coi là tấn công.
Bạn có thể thấy các rules bằng lệnh:
iptables -L --line-number -n -v
Ví dụ ở phần demo trên, iptables đã chặn 2 IP đó là 77.110.126.104
và 51.89.162.163
.
shell> iptables -L --line-number -n -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 28 20237 f2b-asterisk-pjsip udp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 5060,5061
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain f2b-asterisk-pjsip (1 references)
num pkts bytes target prot opt in out source destination
1 20 15062 REJECT all -- * * 77.110.126.104 0.0.0.0/0 reject-with icmp-port-unreachable
2 3 1416 REJECT all -- * * 51.89.162.163 0.0.0.0/0 reject-with icmp-port-unreachable
3 5 3759 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Hoàn toàn khớp với kết quả của lệnh fail2ban-client status asterisk-pjsip
.
fail2ban-client status asterisk-pjsip
Status for the jail: asterisk-pjsip
|- Filter
| |- Currently failed: 3
| |- Total failed: 17184
| `- File list: /var/log/asterisk/full
`- Actions
|- Currently banned: 2
|- Total banned: 2
`- Banned IP list: 51.89.162.163 77.110.126.104
Hoặc nếu bạn dùng nftables:
nft list ruleset
Firewalld (CentOS/RHEL/Fedora)
Nếu hệ thống bạn dùng firewalld
, Fail2Ban có thể sử dụng backend firewalld để thêm/zones rich rules.
Các backend khác (hiếm)
Fail2Ban cũng hỗ trợ các backend khác như:
Backend | Mô tả |
---|---|
iptables | Mặc định truyền thống |
nftables | Firewall hiện đại (Debian 10+, Ubuntu 20+) |
firewalld | Cho CentOS/RHEL sử dụng firewalld |
ipset | Kết hợp với iptables để chặn theo tập hợp IP |
route | Chặn IP bằng cách thay route |
hostsdeny | Ghi vào /etc/hosts.deny (cũ) |
dummy | Không thực hiện gì (chỉ log) |
Cấu hình backend trong Fail2Ban.
Mặc định nằm ở:
/etc/fail2ban/jail.conf hoặc /etc/fail2ban/jail.local
Dòng cấu hình:
banaction = iptables-multiport
Hoặc:
banaction = nftables-multiport
✅ Kiểm tra Fail2Ban đang dùng gì:
Chạy:
fail2ban-client status
hoặc:
fail2ban-client status asterisk-pjsip
Coi mục Actions
→ sẽ hiển thị như:
Actions: iptables-multiport[...]
7. Ưu và nhược điểm của phương án này.
✅ Ưu điểm
- Regex cực kỳ đơn giản
- Hoạt động với mọi định dạng log Asterisk (miễn có
Failed to authenticate
) - Không cần sửa mã nguồn Asterisk
❌ Nhược điểm
- Tốn thêm tài nguyên do phải
tail -F
- Cần script trung gian (nhưng dễ kiểm soát)
💬 Lời khuyên
- Nên chạy
log_failed_ip.sh
bằngsystemd
hoặctmux
để không bị mất khi reboot. - Có thể mở rộng script để xử lý
No matching endpoint
hoặcWrong password
- Nếu log
full
không cóFailed to authenticate
, kiểm tra lại cấu hìnhlogger.conf
8. Kết luận
Việc bảo vệ Asterisk khỏi tấn công SIP là vô cùng quan trọng. Sử dụng Fail2Ban
kết hợp với log tùy biến là giải pháp hiệu quả, linh hoạt và cực kỳ dễ mở rộng.
Với cách tiếp cận “biến log khó thành dễ”, bạn không cần vật lộn với regex dài dòng nữa. Tập trung vào chặn IP và bảo mật hệ thống một cách nhẹ nhàng.
Hãy thử ngay hôm nay để thấy hiệu quả! 🎯
Nếu bạn thấy bài viết hữu ích, hãy chia sẻ với cộng đồng. Hoặc nếu bạn có cách tối ưu hơn, đừng ngại để lại bình luận nhé!