如何在单个表达式中写入 /16 IP 地址范围?

如何在单个表达式中写入 /16 IP 地址范围?

我想在 nginx 中禁止这个范围的中国 IP 地址:

 '223.64.0.0 - 223.117.255.255'

我知道如何禁止每个/16范围,例如:

deny 223.64.0.0/16;

但需要很多行才能包含整个223.64 - 223.117范围。是否有一种简写符号可以在一行中完成此操作?

答案1

伊普计算ipcalcDebian 上的软件包)可以帮助你解聚将一个范围分解为多个匹配项CIDRs:

$ ipcalc -r 223.64.0.0 - 223.117.255.255
deaggregate 223.64.0.0 - 223.117.255.255
223.64.0.0/11
223.96.0.0/12
223.112.0.0/14
223.116.0.0/15

与相同另一个 ipcalcipcalc-ngDebian 上的包和命令名称):

$ ipcalc-ng -d '223.64.0.0 - 223.117.255.255'
[Deaggregated networks]
Network:        223.64.0.0/11
Network:        223.96.0.0/12
Network:        223.112.0.0/14
Network:        223.116.0.0/15

该选项有更多选项来改变输出格式:

$ ipcalc-ng --no-decorate -d '223.64.0.0 - 223.117.255.255'
223.64.0.0/11
223.96.0.0/12
223.112.0.0/14
223.116.0.0/15

包括 json,如果与以下工具结合使用,它可以提供无限的重新格式化的可能性jq

$ ipcalc-ng -j -d '223.64.0.0 - 223.117.255.255' |
    jq -r '.DEAGGREGATEDNETWORK[]|"deny " + . + ";"'
deny 223.64.0.0/11;
deny 223.96.0.0/12;
deny 223.112.0.0/14;
deny 223.116.0.0/15;
$ ipcalc-ng -j -d '223.64.0.0 - 223.117.255.255' |
   jq -r '"deny " + (.DEAGGREGATEDNETWORK|join(" ")) + ";"'
deny 223.64.0.0/11 223.96.0.0/12 223.112.0.0/14 223.116.0.0/15;

答案2

@StéphaneChazelas' 答案非常好。如果OP或未来的读者可能更喜欢不是将结果汇总起来——例如,当每个 /16 被阻止时,但以一种细粒度的方式,允许将来取消阻止一个或多个单独的 /16,我经常使用 或jotseq生成必要的 IP 范围。

有时人们只知道要阻止的网络的 CIDR。假设我们想要阻止 10.24.0.0/14,但粒度为单个 /16s。

# jot -w 10.%d.0.0/16 4 24
10.24.0.0/16
10.25.0.0/16
10.26.0.0/16
10.27.0.0/16

在上面的示例中,4出现该常数是因为 /14 中有 4 个 /16,或者换句话说,2**(16-14) = 2**2 = 4。

将 10.0.64.0/19 作为一系列 /24 进行阻止:

# jot -w 10.0.%d.0/24 32 64
10.0.64.0/24
10.0.65.0/24
10.0.66.0/24
...
10.0.92.0/24
10.0.93.0/24
10.0.94.0/24
10.0.95.0/24

再次使用常数 32,因为 /19 中有 32 个 /24。或者以另一种方式计算,2**(24-19) == 2**5 == 32。

其他时候,CIDR 语法中未指定网络范围,要么是因为它不属于严格的 CIDR 边界,要么只是因为源文档的作者选择不使用 CIDR 表示法。 seq有时更容易适应这种情况。

要阻止 10.100.0.0 到 10.109.255.255:

# seq -f '10.%g.0.0/16' 100 109
10.100.0.0/16
10.101.0.0/16
10.102.0.0/16
10.103.0.0/16
10.104.0.0/16
10.105.0.0/16
10.106.0.0/16
10.107.0.0/16
10.108.0.0/16
10.109.0.0/16

显然,仅将这些 IP 范围输出到 stdout 本身不会阻止任何内容。假设用户将vi它们放入配置文件中,或者将它们通过管道传输到 shell 脚本或其他将执行必要工作的系统命令。如果所需的命令语法足够简单,seq或者jot可以直接用于生成 shell 输入:

# seq -f 'ipfw add 560 deny ip from 10.%g.0.0/16 to any' 100 109
ipfw add 560 deny ip from 10.100.0.0/16 to any
ipfw add 560 deny ip from 10.101.0.0/16 to any
ipfw add 560 deny ip from 10.102.0.0/16 to any
ipfw add 560 deny ip from 10.103.0.0/16 to any
ipfw add 560 deny ip from 10.104.0.0/16 to any
ipfw add 560 deny ip from 10.105.0.0/16 to any
ipfw add 560 deny ip from 10.106.0.0/16 to any
ipfw add 560 deny ip from 10.107.0.0/16 to any
ipfw add 560 deny ip from 10.108.0.0/16 to any
ipfw add 560 deny ip from 10.109.0.0/16 to any

seq检查这些命令的准确性后,可以通过管道传送sh并执行 的输出。

提供此解决方案只是为了表明,与许多 UNIX 任务一样,如果优先考虑(或者实际上需要)粒度而不是聚合,则有一些基本构建块可以完成此任务。

相关内容