明月的服务器一直使用的是 iptables,随着近几年 IPv6 的普及,明月切身体会到还是 IPSET 最方便了,无论你是 IPv4 还是 IPv6 都可以方便的管理,无论你是加入白名单还是黑名单,都非常的简单高效!今天就参照明月自己的实操给大家分享一下。
IPSET 介绍
IPSET 是 iptables 的扩展,它允许你创建 匹配整个地址集合的规则。而不像普通的 iptables 链只能单 IP 匹配, ip 集合存储在带索引的数据结构中,这种结构即时集合比较大也可以进行高效的查找,除了一些常用的情况,比如阻止一些危险主机访问本机,从而减少系统资源占用或网络拥塞,IPSET 也具备一些新防火墙设计方法,并简化了配置。
官网:https://ipset.netfilter.org/
首先,我们可以利用 IPSET 根据不同的 CDN 服务商来创建不同的合集(set),甚至可以区别 IPv4/IPv6 来创建不同的合集分别的用在 iptables 规则里。因为明月目前使用的是 CloudFlare+奇安信网站卫士双 CDN ,所以就以此为例来创建不同的 IPSET 合集。
ipset create QNX360 hash:net #创建奇安信网站卫士节点 IPv4 合集
ipset create CloudFlare hash:net #创建 CloudFlare 节点 IPv4 合集
ipset create CloudFlare6 hash:net family inet6 #创建 CloudFlare 节点 IPv6 合集
目前奇安信网站卫士只提供 IPv4 节点 IP,所以只创建一个 IPv4 的QNX360
合集即可。而 CloudFlare 的节点包含 IPv4/IPv6,所以我们加了family inet6
参数,给 CloudFlare 的 IPv6 节点又创建一个CloudFlare6
合集,一共是三个合集。
考虑到大部分 CDN 节点 IP 数量都不少,所以明月建议大家提前将 CDN 节点 IP 单独保存到文件进行导入,可以减少出错的概率保证数据的准确性,上述三个合集需要的 CDN 节点 IP 文件内容如下:
奇安信网站卫士节点
add QNX360 183.146.28.0/24
add QNX360 123.6.81.0/24
CloudFlare 的 IPv4 节点
add CloudFlare 103.21.244.0/22
add CloudFlare 103.22.200.0/22
add CloudFlare 103.31.4.0/22
add CloudFlare 104.16.0.0/13
add CloudFlare 104.24.0.0/14
add CloudFlare 108.162.192.0/18
add CloudFlare 131.0.72.0/22
add CloudFlare 141.101.64.0/18
add CloudFlare 162.158.0.0/15
add CloudFlare 172.64.0.0/13
add CloudFlare 173.245.48.0/20
add CloudFlare 188.114.96.0/20
add CloudFlare 190.93.240.0/20
add CloudFlare 197.234.240.0/22
add CloudFlare 198.41.128.0/17
CloudFlare 的 IPv6 节点
add CloudFlare6 2400:cb00::/32
add CloudFlare6 2606:4700::/32
add CloudFlare6 2803:f800::/32
add CloudFlare6 2405:b500::/32
add CloudFlare6 2405:8100::/32
add CloudFlare6 2a06:98c0::/29
add CloudFlare6 2c0f:f248::/32
CloudFlare 节点 IP 来源:https://www.cloudflare.com/zh-cn/ips/
上述三个合集的节点 IP 可以合并保存在一个.txt 文件里,如:ip.txt(记得这里的 TXT 文件必须是纯文本编辑器以 UTF-8 编码保存哦,不要用记事本!不要用记事本!不要用记事本!重要的事儿说三遍!),因为每行都有 add 命令添加 IP 到各自的 IPSET 合集里,所以保存到一个文件里是没有问题的,我们只需要让 IPSET 导入这个 TXT 文件就可以了:
ipset restore -f ip.txt #导入 ip.txt 里的节点到对应的 IPSET 合集里
ipset list #列出当前所有合集
可以看到如下的内容:
Name: QNX360
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 592
References: 1
Number of entries: 2
Members:
183.146.28.0/24
123.6.81.0/24
Name: CloudFlare
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 1424
References: 1
Number of entries: 15
Members:
103.22.200.0/22
131.0.72.0/22
197.234.240.0/22
108.162.192.0/18
172.64.0.0/13
190.93.240.0/20
198.41.128.0/17
141.101.64.0/18
104.16.0.0/13
162.158.0.0/15
104.24.0.0/14
173.245.48.0/20
103.21.244.0/22
188.114.96.0/20
103.31.4.0/22
Name: CloudFlare6
Type: hash:net
Revision: 6
Header: family inet6 hashsize 1024 maxelem 65536
Size in memory: 2032
References: 1
Number of entries: 7
Members:
2a06:98c0::/29
2606:4700::/32
2405:8100::/32
2400:cb00::/32
2803:f800::/32
2c0f:f248::/32
2405:b500::/32
可以看到都已经导入到各个合集里了,这时候我们就可以让 iptables 决定这些合集是加入白名单规则还是黑名单规则了,具体白名单规则命令如下:
iptables -A INPUT -p tcp -m set --match-set QNX360 src -m multiport --dports 443,80 -j ACCEPT #允许奇安信网站卫士 CDN 节点访问 80、443 端口
iptables -A INPUT -p tcp -m set --match-set CloudFlare src -m multiport --dports 443,80 -j ACCEPT #允许 CloudFlare 的 IPv4 节点访问 80、443 端口
ip6tables -A INPUT -p tcp -m set --match-set CloudFlare6 src -m multiport --dports 443,80 -j ACCEPT #允许 CloudFlare 的 IPv6 节点访问 80、443 端口
反之黑名单命令如下:
iptables -A INPUT -p tcp -m set --match-set QNX360 src -m multiport --dports 443,80 -j DROP #禁止奇安信网站卫士 CDN 节点访问 80、443 端口
iptables -A INPUT -p tcp -m set --match-set CloudFlare src -m multiport --dports 443,80 -j DROP #禁止 CloudFlare 的 IPv4 节点访问 80、443 端口
ip6tables -A INPUT -p tcp -m set --match-set CloudFlare6 src -m multiport --dports 443,80 -j DROP #禁止 CloudFlare 的 IPv4 节点访问 80、443 端口
注意上述命令的差异,涉及 IPv4 的命令是 iptables,涉及 IPv6 的是 ip6tables,不要搞混了,否则是不会生效的哦!同样的重载 iptables 和保存 iptables 也是要区分 IPv4 和 IPv6 的:
systemctl reload iptables.service #重载 IPv4 规则
service iptables save #保存 IPv4 规则
systemctl reload ip6tables.service #重载 IPv6 规则
service ip6tables save #保存 IPv6 规则
好了,至此就通过 IPSET 导入了两个不同 CDN 服务商的节点 IP 了,如果后期节点 IP 有所调整,只需要在 IPSET 里清理掉对应合集重新导入新的 IP 节点即可,注意区分 IPv4/IPv6 即可。比如变更 CloudFlare 节点 IP,我们只需要清楚 CloudFlare 合集后再导入即可:
ipset flush CloudFlare
ipset flush CloudFlare6
至于导入 TXT 格式,参考上面的合集 TXT 修改即可,推荐使用 EditPlus 的搜索替换来快速的修改文本【推荐下用了十多年的老牌纯文本编辑器——EditPlus】。
如果您只用了 CloudFlare,可以直接使用下面的命令完成 iptables 节点 IP 加白:
#添加 cloudflare ips-v4 到 iptables 白名单的命令
for i in `curl https://www.cloudflare.com/ips-v4`; do iptables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
#添加 cloudflare ips-v6 iptables 白名单的命令
for i in `curl https://www.cloudflare.com/ips-v6`; do ip6tables -I INPUT -p tcp -m multiport --dports http,https -s $i -j ACCEPT; done
这个更加的简单高效,明月采用的 IPSET 主要是为了方便后期运维需要的,毕竟明月是专业干这个的嘛!