版本比较
标识
- 该行被添加。
- 该行被删除。
- 格式已经改变。
简介
fail2ban简单来说就是通过不断读取设定的日志文件,并通过正则校验每条日志是否符合规则。一旦符合,则提取日志中的IP地址与时间戳,然后写入到fail2ban的数据库中。写库的同时进行计数,如果该IP在设定的时间间隔内被匹配的次数超过阈值,则调用iptables,将其的请求reject。
前期的准备操作请参考0007-CentOS7/8 系统安装标准。Fail2ban 结构如下:
/etc/fail2ban ## fail2ban 服务配置目录
/etc/fail2ban/action.d ## iptables 、mail 等动作文件目录
/etc/fail2ban/filter.d ## 条件匹配文件目录,过滤日志关键内容
/etc/fail2ban/jail.conf ## fail2ban 防护配置文件
/etc/fail2ban/fail2ban.conf ## fail2ban 配置文件,定义日志级别、日志、sock 文件位置等
检查防火墙
代码块 | ||||
---|---|---|---|---|
| ||||
#如果您已经安装iptables建议先关闭 service iptables stop #查看Firewalld状态 firewall-cmd --state #启动firewalld systemctl start firewalld #设置开机启动 systemctl enable firewalld.service #放行22端口 firewall-cmd --zone=public --add-port=80/tcp --permanent #重载配置 firewall-cmd --reload #查看已放行端口 firewall-cmd --zone=public --list-ports |
安装配置
安装
安装成功后fail2ban配置文件位于/etc/fail2ban,其中jail.conf为主配置文件,相关的匹配规则位于filter.d目录,其它目录/文件一般很少用到,如果需要详细了解可自行搜索。
配置jail
代码块 | ||||
---|---|---|---|---|
| ||||
cp jail.conf jail.local vim jail.local |
代码块 | ||||
---|---|---|---|---|
| ||||
banaction = firewallcmd-ipset action = %(action_mwl)s #将默认的执行动作由iptables改为firewallcmd-ipset [waf-blockip] enabled = true filter = waf-blockip port = http,https logpath = /tmp/2019*_waf.log blocktype = DROP action = %(action_mwl)s datapattern = %Y-%m-%d %H:%M:%S bantime = 120 maxretry = 1 findtime = 1 [nginx-cc] enabled = true filter = nginx-cc port = http,https logpath = /tmp/cc.log blocktype = DROP action = %(action_mwl)s bantime = 120 maxretry = 1 findtime = 1 |
以上每行内容的大致意义如下:
[nginxx-cc]:定义jail名称
- enabled:是否启用该jail,默认的所有规则都没有该项,需要手动添加
- port:指定封禁的端口,默认为0:65535,也就是所有端口,但可以在jail中设定
- filter:指定过滤器名称
- logpath:日志路径
- action:达到阈值后的动作
- maxretry:阈值
- findtime:时间间隔
- bantime:封禁时长
- ignoreip:忽略的IP
提示 | ||
---|---|---|
| ||
logpath与action可以有多行,如action中的设定:调用iptables-multiport封禁目标IP访问的多个端口,调用sendmail发送告警邮件 findtime不是检查日志的时间间隔,日志的检查是实时的。因为fail2ban自带数据库,所以可以在设定的时间内统计匹配次数 ignoreip添加后端服务器的IP或CDN的IP |
配置filter
代码块 | ||||
---|---|---|---|---|
| ||||
vim waf-blockip.conf [Definition] failregex = \"<HOST>\",\"rule_tag\" ignoreregex = |
日志内容如下所示:
代码块 | ||||
---|---|---|---|---|
| ||||
{"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 11:59:45","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"ApacheBench\/2.3"} {"local_time":"2019-06-18 12:00:13","client_ip":"192.168.13.215","rule_tag":"-","attack_method":"CC_Attack","server_name":"status.myj.com.cn","req_url":"\/","req_data":"-","user_agent":"curl\/7.29.0"} |
代码块 | ||||
---|---|---|---|---|
| ||||
vim nginx-cc.conf [Definition] failregex = <HOST> - - \[.*\] .*GET \/\?=* #failregex = <HOST> - - \[.*\] \".*(403|400).*\" #匹配403或404的错误 ignoreregex = |
代码块 | ||||
---|---|---|---|---|
| ||||
47.52.195.189 - - [13/Jun/2019:18:18:47 +0800] "GET /?=18566 HTTP/1.1" 403 552 "https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24" 47.52.195.189 - - [13/Jun/2019:18:18:47 +0800] "GET /?=18566 HTTP/1.1" 403 552 "https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24" 47.52.195.189 - - [13/Jun/2019:18:18:47 +0800] "GET /?=18566 HTTP/1.1" 403 552 "https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24" 47.52.195.189 - - [13/Jun/2019:18:18:47 +0800] "GET /?=18566 HTTP/1.1" 403 552 "https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24" 50.195.104.171 - - [13/Jun/2019:18:18:47 +0800] "GET /?=13253 HTTP/1.1" 504 905"https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; U; NetBSD amd64; en-US; rv:1.9.2.15) Gecko/20110308 Namoroka/3.6.15" 47.52.195.189 - - [13/Jun/2019:18:18:47 +0800] "GET /?=18566 HTTP/1.1" 403 552 "https://www.google.com/search?q=120.79.35.33/" "Mozilla/5.0 (X11; Linux x86_64)AppleWebKit/534.24 (KHTML, like Gecko) Ubuntu/10.10 Chromium/12.0.703.0 Chrome/12.0.703.0 Safari/534.24" 192.168.13.43 - - [06/Jun/2019:18:25:58 +0800] "GET /ngx_status HTTP/1.1" 301 16"-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" |
常用配置
代码块 | ||||
---|---|---|---|---|
| ||||
#查看被ban IP,其中ssh-iptables为名称,比如上面的[ssh-iptables]和[nginx-dir-scan] fail2ban-client status ssh-iptables #添加白名单 fail2ban-client set ssh-iptables addignoreip IP地址 #删除白名单 fail2ban-client set ssh-iptables delignoreip IP地址 #查看状态 fail2ban-client status #查看日志 tail /var/log/fail2ban.log #查看规则 firewall-cmd --direct --get-all-rules ipset list |
定时清理日志
代码块 | ||||
---|---|---|---|---|
| ||||
vi /root/del_waf_log.sh #! /bin/bash cat /dev/null > /tmp/`date +"%Y-%m-%d"`-waf.log chmod +x /root/del_waf_log.sh crontab -e 30 3 * * 0 sh /root/del_waf_log.sh |
1002-Linux常用指令中有介绍crontab的用法。
内核优化
针对TIME_WAIT的问题,可以通过调整内核的方式进行优化。
代码块 | ||||
---|---|---|---|---|
| ||||
#修改超时时间为30秒,某些情况可以进一步降低该值 net.ipv4.tcp_fin_timeout = 30 #将keepalive的发送频率降低为20分钟一次 net.ipv4.tcp_keepalive_time = 1200 #开启SYN Cookies,当SYN队列溢出时启用Cookies net.ipv4.tcp_syncookies = 1 #开启TIME-WAIT sockets重用功能 net.ipv4.tcp_tw_reuse = 1 #开启TIME-WAIT sockets快速回收功能 net.ipv4.tcp_tw_recycle = 1 #加大SYN队列 net.ipv4.tcp_max_syn_backlog = 8192 #最大TIME_WAIT保持数,超过将全部清除 net.ipv4.tcp_max_tw_buckets = 5000 |
过滤规则
nginx的验证
代码块 | ||
---|---|---|
| ||
fail2ban-regex /tmp/2019-07-10_waf.log /etc/fail2ban/filter.d/waf-blockip.conf failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$ ^ \[error\] \d+#\d+: \*\d+ no user/password was provided for basic authentication, client: <HOST>, server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$ |
检查fail2ban启动问题
代码块 | ||
---|---|---|
| ||
fail2ban-client -x start |
modsecurity 日志过滤
利用 modsecurity 结合 nginx 并整合到 微服务网关实现 web 安全防护。1212-kong 增加 WAF 功能
kong 网关结合 modsecurity 输出的日志格式如下
代码块 | ||
---|---|---|
| ||
112.119.33.91 - - [18/Dec/2020:09:21:58 +0800] "GET /socket.io/?__sails_io_sdk_version=0.13.8&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=polling&t=NPpS75x&sid=o6ZI8VoIHqBUgvFMAACb HTTP/2.0" 200 4 "https://dashboard.waringid.me/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" 2020/12/18 09:23:10 [error] 25142#0: *659 [client 113.78.65.148] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "79"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "172.19.0.5"] [uri "/.env"] [unique_id "1608254590"] [ref ""], client: 113.78.65.148, server: kong, request: "GET /.env HTTP/1.1", host: "dashboard.waringid.me" 113.78.65.148 - - [18/Dec/2020:09:23:10 +0800] "GET /.env HTTP/1.1" 403 150 "-" "curl/7.29.0" 51.159.23.43 - - [18/Dec/2020:09:28:46 +0800] "GET / HTTP/1.1" 404 48 "-" "-" 89.97.157.10 - - [18/Dec/2020:09:43:52 +0800] "GET / HTTP/1.1" 404 48 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" |
注意2种不同的日志格式类型,2中不同日志类型匹配不同的正则式。
同时注意不同日志时间格式也不一样。
frp 的 RDP 规则
内容 | 描述 |
---|---|
操作系统 | ubuntu 22 |
frp | 0.60 |
frps.toml
代码块 | ||
---|---|---|
| ||
bindPort = 8003 kcpBindPort = 8003 webServer.addr = "127.0.0.1" webServer.port = 8002 webServer.user = "admin" webServer.password = "admin" log.to = "/tmp/frps.log" log.level = "info" log.maxDays = 30 log.disablePrintColor = false detailedErrorsToClient = true auth.method = "token" auth.token = "token" vhostHTTPPort = 8004 subdomainHost = "XXX.com" allowPorts = [{ start = 20000, end = 20010 }, { single = 3001 },{ single = 3003 },{ start = 4000, end = 50000 }] maxPortsPerClient = 5 udpPacketSize = 1500 natholeAnalysisDataReserveHours = 168 |
frps.toml
代码块 | ||
---|---|---|
| ||
[common] server_addr = frps.XXXX.com server_port = 8003 protocol = kcp tls_enable = true authenticate_heartbeats = true authenticate_new_work_conns = true authentication_method = token token = 52gqTvPh1gPM log_file = ./frpc.log [RDP-20001] type = tcp local_ip = 127.0.0.1 local_port = 3389 remote_port = 20001 |
/etc/fail2ban/filter.d/frps-rdp-ban.conf
代码块 |
---|
[Definition] failregex = ^.*\[.*rdp.*\] get a user connection \[<HOST>:[0-9]*\] ignoreregex = |
这个用来匹配 frps 的日志文件,其日志文件的输出内容如下所示:
代码块 | ||
---|---|---|
| ||
2024-09-23 08:14:41.412 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:63981] 2024-09-23 08:14:44.308 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [211.21.123.115:63136] 2024-09-23 08:14:44.588 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:53202] 2024-09-23 08:14:47.247 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:57434] 2024-09-23 08:14:47.849 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [79.124.56.98:55196] 2024-09-23 08:14:47.966 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [82.156.52.66:60816] 2024-09-23 08:14:49.950 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:61851] 2024-09-23 08:14:51.278 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [79.124.56.98:57478] 2024-09-23 08:14:52.579 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:49965] 2024-09-23 08:14:55.397 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:54936] 2024-09-23 08:14:58.689 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:60820] 2024-09-23 08:15:01.047 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [60.22.145.91:58053] 2024-09-23 08:15:01.392 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:65291] 2024-09-23 08:15:03.807 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [103.246.244.75:52594] 2024-09-23 08:15:04.531 [I] [proxy/proxy.go:204] [21534afeadc68513] [rdp] get a user connection [116.148.225.90:64580] |
/etc/fail2ban/jail.conf
代码块 | ||
---|---|---|
| ||
[frps-rdp-ban] enabled = true findtime = 10m maxretry = 3 bantime = 8h filter = frps-rdp-ban logpath = /tmp/frps.log protocol = all port = all chain = all action = iptables-allports[name=frps,protocol=tcp] |
代码块 | ||
---|---|---|
| ||
systemctl restart fail2ban fail2ban-client status frps-rdp-ban |
目录 | ||
---|---|---|
|