高效管理网络段和端口集合的工具之ipset

发布于:2025-09-06 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

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 加入 ipset

LOG_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.sh

LOG_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; do
    if [[ "$count" -gt "$REQ_THRESHOLD" ]]; then
        ipset add "$BAN_SET" "$ip" 2>/dev/null && echo "[$(date)] Banned IP: $ip (Requests: $count)"
    fi
done

同样地,设置 cron 任务定时执行(例如每分钟)。

案例 7:屏蔽特定国家/地区的 IP 访问

这个需求很常见,可以利用现成的国家 IP 段列表。

  1. 获取国家的 IP 段列表

    # 例如下载中国的 IP 段(假设我们要创建白名单)
    wget -O cn.zone http://www.ipdeny.com/ipblocks/data/countries/cn.zone
  2. 创建 ipset 集合并导入 IP 段

    # 创建一个 hash:net 类型的集合来存储网络段
    sudo ipset create cn-whitelist hash:net
    
    # 将下载的 IP 段添加到集合中
    for i in $(cat cn.zone); do
      sudo ipset add cn-whitelist "$i"
    done
  3. 设置 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.sh

DOMAIN_LIST="api.example.com some-cdn.com"
WHITELIST_SET="dynamic-whitelist"

# 清空集合(或者先创建一个临时集,然后交换)
sudo ipset flush "$WHITELIST_SET"

for domain in $DOMAIN_LIST; do
  # 解析域名获取 IP
  dig +short "$domain" | while read -r ip; do
    if [[ ! -z "$ip" ]]; then
      sudo ipset add "$WHITELIST_SET" "$ip"
    fi
  done
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. 注意事项

  1. 谨慎操作:错误的 iptables 或 ipset 规则可能导致你把自己锁在服务器外面。务必在本地控制台或通过一个不会受规则影响的独立连接(例如管理控制台)上进行操作

  2. 备份规则:在对规则进行重大更改之前,先备份当前的 ipset 和 iptables 规则。

  3. 性能考虑:对于非常庞大的集合(数十万条),hashsize 和 maxelem 参数的初始设置会影响性能和内存使用。根据情况调整。

  4. 组合使用:ipset 通常与 iptables 结合使用,单独使用 ipset 不会产生任何效果。

  5. 列表优化:对于大型的 IP 地址段列表,可以使用 iprange 这样的工具来合并相邻的 IP 范围,有助于减少 ipset 中的条目数量并提升性能。


网站公告

今日签到

点亮在社区的每一天
去签到