高效管理网络段和端口集合的工具之ipset
目录
1. 核心命令速查
2. 集合类型
3. 实战案例:使用 ipset 封禁 IP
案例 1:基础黑名单封禁(手动添加)
案例 2:自动过期和解封
案例 3:封禁 IP 和端口组合
案例 4:白名单模式
案例 5:自动化封禁(SSH 暴力破解)
案例 6:自动化封禁(Web 服务 CC 攻击)
案例 7:屏蔽特定国家/地区的 IP 访问
案例 8:动态域名白名单
4. ipset 规则持久化
方法一:使用ipset-service服务
1. 安装与配置
2. 手动保存规则
3. 自动持久化配置
方法二:systemd自定义服务
1. 保存当前规则
2. 创建服务文件
3. 启用服务
方法三:手动恢复(临时/应急)
1. 导出规则
2. 重启后恢复
保存 iptables 规则
6. 注意事项
ipset是Linux系统中一个强大的命令行工具,用于创建、维护和管理一组IP地址、端口号、MAC地址、网络接口或其他网络元素的集合(set)。它通过与防火墙系统(如iptables或nftables)集成,显著提升规则管理的效率和性能。以下是基于其核心特性、功能及实战案例的介绍:
1. 核心命令速查
先通过一个表格快速了解 ipset 的常用命令:
命令示例 | 作用说明 |
---|---|
ipset create blacklist hash:ip | 创建名为 blacklist ,类型为 hash:ip 的集合 |
ipset add blacklist 192.168.2.100 | 向 blacklist 集合添加一个 IP |
ipset add blacklist 203.204.205.0/24 | 向 blacklist 集合添加一个网段 |
ipset del blacklist 192.168.2.100 | 从 blacklist 集合删除一个 IP |
ipset list blacklist | 查看 blacklist 集合的内容 |
ipset list | 查看所有集合 |
ipset flush blacklist | 清空 blacklist 集合中的所有条目 |
ipset destroy blacklist | 彻底销毁 blacklist 集合 |
ipset save blacklist | 导出 blacklist 集合的内容 |
ipset restore -f ipset.txt | 从文件恢复集合内容 |
2. 集合类型
ipset 支持多种集合类型,以适应不同的匹配需求:
集合类型 | 存储内容 | 适用场景 |
---|---|---|
hash:ip | 单个 IP 地址 | 封禁或允许特定的主机 |
hash:net | 网络段(CIDR) | 封禁或允许整个网段 |
hash:ip,port | IP 地址和端口号(如 192.168.8.1,80 ) | 封禁或允许特定 IP 对特定端口的访问 |
hash:net,port | 网络段和端口号(如 203.8.100.0/24,443 ) | 封禁或允许特定网段对特定端口的访问 |
hash:ip,port,ip | IP、端口、IP(三层结构) | 更复杂的匹配条件 |
hash:ip,mark | IP 和数据包标记 | 与 iptables 的 MARK 动作结合使用 |
hash:mac | MAC 地址 | 基于物理地址进行过滤 |
bitmap:ip | IPv4 地址的位图,范围固定 | 适用于较小的、连续的 IP 范围 |
bitmap:port | 端口号的位图 | 适用于端口范围 |
list:set | 集合的列表 | 嵌套集合,将多个集合组合成一个更大的集合 |
3. 实战案例:使用 ipset 封禁 IP
案例 1:基础黑名单封禁(手动添加)
这是最直接的场景:手动将可疑 IP 加入黑名单并封禁。
# 1. 创建一个名为 `blacklist` 的 IP 集合,类型为 hash:ip
sudo ipset create blacklist hash:ip# 2. 添加一条 iptables 规则,拒绝所有来自 `blacklist` 集合中 IP 的输入流量
sudo iptables -I INPUT -m set --match-set blacklist src -j DROP# 3. 现在,你可以向黑名单中添加 IP 了
sudo ipset add blacklist 192.168.8.100 # 添加单个 IP
sudo ipset add blacklist 200.10.100.0/24 # 添加整个网段# 4. (可选)检查 blacklist 集合的内容
sudo ipset list blacklist
效果:所有来自 192.168.8.100
和 200.10.100.0/24
网段的流量将被服务器立即丢弃。
案例 2:自动过期和解封
对于临时封禁(例如 SSH 密码尝试失败多次),可以设置超时(timeout),让 IP 自动从黑名单中移除。
# 1. 创建名为 `ssh-ban` 的集合,并设置默认超时时间为 1 小时 (3600 秒)
sudo ipset create ssh-ban hash:ip timeout 3600# 2. 设置 iptables 规则,对 SSH (22端口) 的访问如果来自 `ssh-ban` 集合则拒绝
sudo iptables -I INPUT -p tcp --dport 22 -m set --match-set ssh-ban src -j DROP# 3. 当检测到恶意尝试时,添加 IP,并可以指定不同的超时时间
sudo ipset add ssh-ban 192.168.8.200 # 默认 1 小时后解封
sudo ipset add ssh-ban 198.168.100.55 timeout 7200 # 此 IP 2 小时 (7200秒) 后解封
注意:如果创建集合时没有指定 timeout
参数,则集合中的条目不会自动过期。
案例 3:封禁 IP 和端口组合
有时需要封禁某个 IP 对特定服务(端口)的访问,但允许访问其他服务。
# 1. 创建一个类型为 `hash:ip,port` 的集合,用于存储 IP 和端口对
sudo ipset create service-abusers hash:ip,port# 2. 设置 iptables 规则,拒绝访问 `service-abusers` 集合中定义的 IP 和端口组合
sudo iptables -I INPUT -m set --match-set service-abusers src,dst -j DROP# 3. 添加违规的 IP 和端口
sudo ipset add service-abusers 192.0.2.10,80 # 封禁该 IP 访问 80 端口
sudo ipset add service-abusers 198.51.100.20,443 # 封禁该 IP 访问 443 端口
sudo ipset add service-abusers 203.0.113.30,udp:53 # 封禁该 IP 访问 UDP 53 端口
案例 4:白名单模式
ipset 也可以用于创建白名单,只允许特定集合中的 IP 访问。
# 1. 创建一个名为 `whitelist` 的白名单集合,并添加允许的 IP
sudo ipset create whitelist hash:ip
sudo ipset add whitelist 192.0.2.1
sudo ipset add whitelist 203.0.113.5# 2. 设置 iptables 规则:**非白名单即拒绝**
# 注意这里的 `!` 表示取反
sudo iptables -I INPUT -m set ! --match-set whitelist src -j DROP
应用场景:严格限制访问源,例如数据库端口、管理后台等。
案例 5:自动化封禁(SSH 暴力破解)
结合日志分析和 cron 定时任务,实现自动封禁 SSH 暴力破解的 IP。
#!/bin/bash
# 文件名: /root/ban_ssh_abuse.sh
# 监控 /var/log/secure(CentOS/RHEL)或 /var/log/auth.log(Debian/Ubuntu),将多次尝试失败的 IP 加入 ipsetLOG_FILE="/var/log/secure"
FAILED_THRESHOLD=5 # 失败次数阈值
BAN_SET="ssh-ban" # ipset 集合名,需要预先创建好(带 timeout)# 分析过去一小时的日志,找出失败次数超过阈值的 IP
grep "Failed password" "$LOG_FILE" | awk -v threshold="$FAILED_THRESHOLD" '
{# 提取 IP 地址(根据你的日志格式调整 awk 字段)if (match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {ip = substr($0, RSTART, RLENGTH)count[ip]++}
}
END {for (ip in count) {if (count[ip] > threshold) {print ip}}
}' | while read -r malicious_ip; do# 将恶意 IP 添加到 ipset 集合中ipset add "$BAN_SET" "$malicious_ip" 2>/dev/null && echo "[$(date)] Banned IP: $malicious_ip"
done
然后,使用 crontab -e
添加定时任务,每 5 分钟运行一次此脚本:
*/5 * * * * /root/ban_ssh_abuse.sh
案例 6:自动化封禁(Web 服务 CC 攻击)
类似地,可以监控 Nginx 或 Apache 日志,封禁请求频率过高的 IP。
#!/bin/bash
# 文件名: /root/ban_http_abuse.shLOG_FILE="/var/log/nginx/access.log"
REQ_THRESHOLD=1000 # 一分钟内请求数阈值
BAN_SET="http-ban" # ipset 集合名# 分析上一分钟的日志,统计每个 IP 的请求数
DATE=$(date -d '1 minute ago' +%d/%b/%Y:%H:%M)
grep "$DATE" "$LOG_FILE" | awk '{print $1}' | sort | uniq -c | sort -nr | \
while read -r count ip; doif [[ "$count" -gt "$REQ_THRESHOLD" ]]; thenipset add "$BAN_SET" "$ip" 2>/dev/null && echo "[$(date)] Banned IP: $ip (Requests: $count)"fi
done
同样地,设置 cron 任务定时执行(例如每分钟)。
案例 7:屏蔽特定国家/地区的 IP 访问
这个需求很常见,可以利用现成的国家 IP 段列表。
-
获取国家的 IP 段列表:
# 例如下载中国的 IP 段(假设我们要创建白名单) wget -O cn.zone http://www.ipdeny.com/ipblocks/data/countries/cn.zone
-
创建 ipset 集合并导入 IP 段:
# 创建一个 hash:net 类型的集合来存储网络段 sudo ipset create cn-whitelist hash:net# 将下载的 IP 段添加到集合中 for i in $(cat cn.zone); dosudo ipset add cn-whitelist "$i" done
-
设置 iptables 规则:
# 示例:只允许来自中国 IP 段的流量访问 80 和 443 端口 sudo iptables -A INPUT -p tcp --dport 80 -m set --match-set cn-whitelist src -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -m set --match-set cn-whitelist src -j ACCEPT # 然后设置相应的 DROP 规则(务必谨慎,以免锁自己于服务器之外)
案例 8:动态域名白名单
如果你的服务器需要允许访问一些域名,但这些域名的 IP 可能会变,可以用脚本定期解析并更新 ipset。
#!/bin/bash
# 文件名: /root/update_dynamic_whitelist.shDOMAIN_LIST="api.example.com some-cdn.com"
WHITELIST_SET="dynamic-whitelist"# 清空集合(或者先创建一个临时集,然后交换)
sudo ipset flush "$WHITELIST_SET"for domain in $DOMAIN_LIST; do# 解析域名获取 IPdig +short "$domain" | while read -r ip; doif [[ ! -z "$ip" ]]; thensudo ipset add "$WHITELIST_SET" "$ip"fidone
done
设置 cron 任务定期运行(例如每小时),确保 IP 地址是最新的。
4. ipset 规则持久化
重要提示:默认情况下,ipset 规则和 iptables 规则一样,重启后会丢失。必须手动保存和恢复。
方法一:使用ipset-service服务
1. 安装与配置
# CentOS为例
yum install -y ipset-service
systemctl enable ipset --now
2. 手动保存规则
ipset save > /etc/ipset.conf # 导出规则至配置文件
3. 自动持久化配置
编辑/etc/sysconfig/ipset-config
,确保以下参数启用
IPSET_SAVE_ON_STOP="yes" # 停止服务时自动保存
IPSET_SAVE_FILE="/etc/ipset.conf" # 配置文件路径
方法二:systemd自定义服务
1. 保存当前规则
ipset save > /etc/ipset.conf
2. 创建服务文件
vim /etc/systemd/system/ipset-persistent.service
内容如下:
[Unit]
Description=ipset persistent configuration
Before=network.target [Service]
Type=oneshot
ExecStart=/usr/sbin/ipset restore -f /etc/ipset.conf
ExecStop=/usr/sbin/ipset save -f /etc/ipset.conf
RemainAfterExit=yes [Install]
WantedBy=multi-user.target
3. 启用服务
systemctl daemon-reload
systemctl enable ipset-persistent --now
方法三:手动恢复(临时/应急)
1. 导出规则
ipset save > /etc/ipset.conf
2. 重启后恢复
ipset restore < /etc/ipset.conf
- 自动加载:可将命令加入
/etc/rc.local
(确保文件有执行权限)。
保存 iptables 规则
同样,别忘了保存和持久化 iptables 规则。
sudo iptables-save > /etc/iptables/rules.v4 # 对于 IPv4
sudo ip6tables-save > /etc/iptables/rules.v6 # 对于 IPv6
# 然后启用 iptables-persistent 服务,或配置相应机制。
6. 注意事项
-
谨慎操作:错误的 iptables 或 ipset 规则可能导致你把自己锁在服务器外面。务必在本地控制台或通过一个不会受规则影响的独立连接(例如管理控制台)上进行操作。
-
备份规则:在对规则进行重大更改之前,先备份当前的 ipset 和 iptables 规则。
-
性能考虑:对于非常庞大的集合(数十万条),
hashsize
和maxelem
参数的初始设置会影响性能和内存使用。根据情况调整。 -
组合使用:ipset 通常与 iptables 结合使用,单独使用 ipset 不会产生任何效果。
-
列表优化:对于大型的 IP 地址段列表,可以使用
iprange
这样的工具来合并相邻的 IP 范围,有助于减少 ipset 中的条目数量并提升性能。