在使用 iptables 管理 IP 进出规则时,碰到数量大的场景就非常头痛了。一是维护规则麻烦,二是数量上来后,iptables 的执行效率也会下降。使用 ipset 命令正好可以解决这种问题。
ipset 是 iptables 的扩展,它把 iptables 要匹配的数据源抽象出来,作为一个单独的存储对象。从而实现了在 iptables 规则不变的情况下,单独管理 IP 地址数据的功能。以黑名单的场景来举例,在 iptables 命令中只要指定禁止访问规则和 ipset 的集合名称,然后就只要通过 ipset 命令来增减 IP 即可。而且使用 ipset 提供的集合数据结构,再多的数量也不会影响到 iptables 的处理性能,一举解决了单独使用 iptables 时的两个痛点。
ipset 命令格式
ipset [选项...] 子命令 [子命令选项...]
ipset 命令示例
创建一个以 mylist 命名的 IP 集合,使用散列类型保存 IP 地址:
ipset create mylist hash:ip hashsize 3
查看创建的 IP 集合:
ipset list
往刚创建的 IP 集合中添加 IP 地址:
ipset add mylist 127.0.0.1
使用 IP 段的方式添加:
ipset add mylist 192.168.0.0/32
删除添加的 IP:
ipset del mylist 127.0.0.1
或是直接清空:
ipset flush mylist
IP 集合可以保存为文件:
ipset save mylist -f mylist.txt
同样也可以从文件中还原:
ipset -exist restore -f mylist.txt
定义好的 IP 集合可以在 iptables 中直接使用。使用 iptables 命令的 -m set 加 --match-set 选项指定集合名称即可。比如要禁止 mylist 集合中的 IP 访问:
iptables -I INPUT -m set --match-set mylist src -j DROP
或是只允许 mylist 集合中的 IP 访问:
iptables -I INPUT -m set --match-set mylist src -j ACCEPT
ipset 命令选项
Ipset 的命令选项类型比较复杂,下面通过类型来罗列这些选项和参数。
子命令
名称
说明
n, create SETNAME TYPENAME [ CREATE-OPTIONS ]
创建一个以指定名称(SETNAME)和指定类型(TYPENAME)为标识的集合。
add SETNAME ADD-ENTRY [ ADD-OPTIONS ]
向指定集合中添加条目。
del SETNAME DEL-ENTRY [ DEL-OPTIONS ]
从集合中删除一个条目。
test SETNAME TEST-ENTRY [ TEST-OPTIONS ]
测试集合中是否存在指定条目。
x, destroy [ SETNAME ]
删除指定集合。
list [ SETNAME ] [ OPTIONS ]
列出指定集合的头数据和条目。
save [ SETNAME ]
保存指定的集合。
restore
从保存的集合会话中恢复集合。
flush [ SETNAME ]
清空集合中的所有条目。
e, rename SETNAME-FROM SETNAME-TO
重命名指定集合。
w, swap SETNAME-FROM SETNAME-TO
交换两个集合的内容。
help [ TYPENAME ]
显示帮助信息。
version
显示命令版本。
-
使用交互模式,并从标准输入读取命令。使用 quit 伪命令退出。
常用选项
缩写
完整名称
说明
-!
-exist
在创建,编辑,或是删除集合条目时,忽略与条目是否存在相关的错误。
-o
-output { plain | save | xml }
指定 list 子命令的数据输出格式。
-q
-quiet
静默执行命令,不输出任何信息。
-r
-resolve
显示集合列表时,强制解析主机名称。
-s
-sorted
在显示或保存集合时进行排序处理。
-n
-name
查看集合列表时只显示名称。
-t
-terse
显示集合名称和表头。
-f
-file filename
使用指定的文件名替换命令的标准输入和输出。
create 和 add 子命令选项
名称
说明
timeout
指定条目的超时时间,单位为秒,可使用的最大值为 2147483。
counters, packets, bytes
设置集合计数器。
comment
设置集合注释。
skbinfo, skbmark, skbprio, skbqueue
设置集合可存储元数据。
hashsize
设置哈希集合大小,默认为 1024。
maxelem
设置哈希集合下能存储的元素数量,默认为 65536。
bucketsize
设置哈希桶(hash bucket)的大小。
family { inet | inet6 }
设置集合的 IP 协议族。
nomatch
标记不匹配的集合条目。当匹配集合中的元素时,标记为 nomatch 的条目会被跳过。
forceadd
强制添加集合条目。
wildcard
此选项只对 hash:net 和 iface 类型的集合有效。在对集合元素进行匹配时,将使用前缀匹配模式。
集合类型
名称
说明
示例
bitmap:ip
使用内存范围存储 IPv4 格式的主机或网络地址。可存储 65536 个条目。
ipset create foo bitmap:ip range 192.168.0.0/16
bitmap:ip,mac
使用内存范围存储 IPv4 + MAC 地址。可存储 65536 个条目。
ipset create foo bitmap:ip,mac range 192.168.0.0/16
bitmap:port
使用内存范围存储端口号。可存储 65536 个端口条目。
ipset create foo bitmap:port range 0-1024
hash:ip
使用散列存储 IP 或网络地址。
ipset create foo hash:ip netmask 30
hash:mac
使用散列存储 MAC 地址。
ipset create foo hash:mac
hash:ip,mac
使用散列存储 IP + MAC 地址。
ipset create foo hash:ip,mac
hash:net
使用散列存储网络地址。
ipset create foo hash:net
hash:net,net
使用散列存储网络地址 + 网络地址。
ipset create foo hash:net,net
hash:ip,port
使用散列存储 IP + 端口。
ipset create foo hash:ip,port
hash:net,port
使用散列存储网络地址 + 端口。
ipset create foo hash:net,port
hash:ip,port,ip
使用散列存储 IP + 端口 + IP。
ipset create foo hash:ip,port,ip
hash:ip,port,net
使用散列存储 IP + 端口 + 网络地址。
ipset create foo hash:ip,port,net
hash:ip,mark
使用散列存储 IP + 包标记。
ipset create foo hash:ip,mark
hash:net,port,net
使用哈希存储网络地址 + 端口 + 网络地址。
ipset create foo hash:net,port,net
hash:net,iface
使用散列存储网络地址 + 网卡名称。
ipset create foo hash:net,iface
list:set
使用列表存储集合名称。