Nginx 设置频率限制
超过限制 Fail2ban 把 IP 加入 Cloudflare IP list
对于 List 中的 IP ,Cloudflare 设定 Managed Challenge
过了半年多,我已经完全想不起来这套的缺陷在哪儿了,好像是不能动态加载白名单,有但是在一个小项目上工作良好我就没管了。
```
# 1.1.1.1 测试版
#!/bin/bash
IP=$1
TIME=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$IP" = "1.1.1.1" ]; then
# 测试用数据
INFO='{
"ip": "1.1.1.1",
"country_name": "Test Country",
"asn": "AS13335",
"org": "Test Organization"
}'
else
INFO=$(curl -s "
https://ipapi.co/$IP/json/")
fi
COUNTRY=$(echo $INFO | jq -r '.country_name')
ORG=$(echo $INFO | jq -r '.org')
ASN=$(echo $INFO | jq -r '.asn')
# Log and mail separately
{
echo "$TIME | IP: $IP | Country: $COUNTRY | ASN: $ASN | Org: $ORG" >> /var/log/fail2ban-ip.log
echo "IP: $IP has been banned at $TIME
Country: $COUNTRY
ASN: $ASN
Organization: $ORG" | mail -s "IP Banned Alert"
[email protected]} &> /dev/null
# Output clean JSON for jq processing
echo "{\"ip\":\"$IP\",\"time\":\"$TIME\",\"country\":\"$COUNTRY\",\"asn\":\"$ASN\",\"org\":\"$ORG\"}"
# 创建 Fail2ban 动作配置文件 /etc/fail2ban/action.d/cloudflare-ip-list.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = IP="<ip>"; \
INFO=$(/usr/local/bin/
ip-info.sh <ip>); \
TIME=$(echo $INFO | jq -r '.time'); \
COUNTRY=$(echo $INFO | jq -r '.country'); \
ASN=$(echo $INFO | jq -r '.asn'); \
ORG=$(echo $INFO | jq -r '.org'); \
curl -X POST "
https://api.cloudflare.com/client/v4/accounts/<your_account_id>/rules/lists/<your_list_id>/items" \
-H "Authorization: Bearer <your_api_token>" \
-H "Content-Type: application/json" \
--data "[{\"ip\": \"$IP\", \"comment\": \"Banned at $TIME | Country: $COUNTRY | ASN: $ASN | Org: $ORG\"}]"
# 移除 actionunban ,这样 IP 就不会被自动解封
actionunban = IP="<ip>"; \
ITEM_ID=$(curl -s -X GET "
https://api.cloudflare.com/client/v4/accounts/<your_account_id>/rules/lists/<your_list_id>/items" \
-H "Authorization: Bearer <your_api_token>" \
-H "Content-Type: application/json" | jq -r --arg IP "$IP" '.result[] | select(.ip == $IP) | .id'); \
if [ ! -z "$ITEM_ID" ]; then \
curl -X DELETE "
https://api.cloudflare.com/client/v4/accounts/<your_account_id>/rules/lists/<your_list_id>/items" \
-H "Authorization: Bearer <your_api_token>" \
-H "Content-Type: application/json" \
--data "{\"items\":[{\"id\":\"$ITEM_ID\"}]}"; \
fi
[Init]
```