你平时查 IP 地址的时候,肯定见过192.168.1.100/24这种写法。/24是什么?为什么要这么写?它跟传统的子网掩码255.255.255.0是什么关系?如果你刚开始学网络协议,很容易被这一串数字绕晕。这篇学习笔记是我重新梳理CIDR(无类别域间路由)时整理的,不讲废话,直接从“为什么需要它”讲到“怎么算、怎么配、怎么排错”。无论你是准备考证、做运维,还是纯粹想搞懂网络底层逻辑,这篇文章都值得你花十分钟慢慢看。
1. 从“分类编址”到 CIDR:一次地址空间的绝地求生
1.1 当年 A/B/C 类地址是怎么设计的
在了解 CIDR 之前,得先回到互联网早期的“分类编址”(Classful Addressing)时代。那时候 IP 地址被强行分成 A、B、C、D、E 五类,判断标准很简单——看第一个八位组的二进制高位:
- A 类地址第一位是 0,范围
1.0.0.0 ~ 126.255.255.255,默认掩码是255.0.0.0,也就是/8。 - B 类地址前两位是 10,范围
128.0.0.0 ~ 191.255.255.255,默认掩码255.255.0.0,也就是/16。 - C 类地址前三位是 110,范围
192.0.0.0 ~ 223.255.255.255,默认掩码255.255.255.0,也就是/24。
这样设计的初衷是“看 IP 就知道它在哪个网络”,简单粗暴。比如拿到172.16.0.0,开头是 172,属于 B 类,自动认为网络位是 16 位,主机位 16 位,整个网络能容纳约 6.5 万台主机。拿到192.168.1.0,属于 C 类,自动认为网络位是 24 位,主机位 8 位,最多 254 台设备。
这种设计在 ARPANET 时代没什么问题,因为网络少、设备少。但到了 90 年代,互联网开始商业化,问题立刻暴露出来。
1.2 分类编址的三个致命问题
第一个问题是地址浪费严重。一个公司如果只需要 300 个 IP,B 类地址有 65534 个可用地址,太大了;C 类地址只有 254 个,又不够用。于是只能给它分一个 B 类,剩下的六万多个地址就白白空着。这在当时被称为“地址饥饿”的一大根源。
第二个问题是路由表爆炸。因为每个 A 类、B 类网络都要在骨干路由器上占一条路由条目,而分类编址又没法把多个小网络聚合成一个大网络。到 1994 年前后,核心路由器的路由表已经膨胀到难以维护的程度,硬件跟不上了。
第三个问题是缺乏灵活性。分类编址把网络边界固定死了,要么 8 位、16 位、24 位,不支持中间的任意位数。你不能把一个 C 类地址块切出两个 126 台主机的子网,也不能把 8 个 C 类地址合并成一个路由条目。网络设计只能将就。
我最早学到这里时,最大的感受是:这就像一家餐厅只有固定三种规格的盘子——小盘只能装 254 粒米,中盘能装 6 万粒,大盘能装 1600 万粒。来了一个 300 粒米的客人,只能给他端中盘,剩下大半盘全部倒掉。这种浪费放到今天看,简直不可想象。
1.3 CIDR 出现的标志:RFC 1518 / RFC 1519
为了解决路由爆炸和地址浪费,IETF 在 1993 年发布了 RFC 1518 和 RFC 1519,正式提出无类别域间路由(Classless Inter-Domain Routing)。它的核心思想只有一个:彻底抛弃 A/B/C 类的固定边界,由网络管理员自己用“前缀长度”来指定网络位和主机位的分界线。
前缀长度写成/n,n 表示 IP 地址前 n 位是网络位。比如10.0.0.0/8表示前 8 位是网络位,10.1.0.0/16表示前 16 位是网络位。10.0.0.0/8和10.1.0.0/16可以同时存在,因为后者更具体,这就是无类别的意思——不再因为 10 开头就强制是 A 类,你可以自己定义边界。
从这一刻起,划分子网不再受 8/16/24 的限制,路由聚合也有了可能。CIDR 的本质,是把“IP 地址 + 掩码”作为一个整体来看待,而不是把 IP 和掩码割裂开。后面所有的高级网络技术,比如 VLSM(可变长子网掩码)、路由汇总,全都建立在这个基础上。
2. CIDR 的核心语法:斜杠后面那个数字到底在表达什么
2.1 网络前缀与主机位的关系
/n这个数字看起来简单,但新手最容易忽略它背后的二进制含义。IP 地址是 32 位二进制数,CIDR 用n指定前 n 位是网络位,剩下的32 - n位是主机位。比如:
192.168.1.0/24:前 24 位固定,后 8 位可变。192.168.1.0/25:前 25 位固定,后 7 位可变,更“小”的子网。192.168.1.0/23:前 23 位固定,后 9 位可变,更“大”的子网。
这里的关键思维是:判断一个地址属于哪个网络,不是看它是不是 192 开头,而是看它和前缀长度一起算出来的网络地址是否匹配。地址192.168.1.130/25就不能跟192.168.1.0/25直接互通吗?不一定。/25的块大小是 128,192.168.1.128/25才是它的网络地址。所以一定要把“IP + 前缀”当成一个整体来做与运算。
2.2 从点分十进制到二进制切片
手算 CIDR 的时候,最可靠的方法是把四段十进制地址转成二进制,然后进行“切片”。我习惯把 32 位地址想成一根长度固定的绳子:
- 前
n位是网络部分,不能变。 - 后
32-n位是主机部分,可以自由分配。
比如172.16.10.0/20,把它转成二进制:
172.16.10.0 = 10101100.00010000.00001010.00000000 /20 表示前20位是网络位: 10101100.00010000.0000 | 1010.00000000网络位是10101100.00010000.0000,后面剩下的 12 位是主机位。为了得到网络地址,需要把主机位全部置 0,于是172.16.10.0/20的网络地址就是10101100.00010000.00000000.00000000,也就是172.16.0.0/20。注意,前缀是 20,所以网络地址不一定和“IP 本身”看起来一致——172.16.10.0/20的网络地址是172.16.0.0。这个点我当年总搞混,老觉得 10.0 应该属于一个独立子网,其实在/20下,它只是172.16.0.0这个大块的一部分。
2.3 /8、/16、/24 常见前缀规模对照
把常见前缀和可用地址数放在一起,方便查:
| 前缀长度 | 等价子网掩码 | 块大小(地址总数) | 可用主机数(减网络和广播) |
|---|---|---|---|
| /8 | 255.0.0.0 | 16,777,216 | 16,777,214 |
| /16 | 255.255.0.0 | 65,536 | 65,534 |
| /20 | 255.255.240.0 | 4,096 | 4,094 |
| /24 | 255.255.255.0 | 256 | 254 |
| /25 | 255.255.255.128 | 128 | 126 |
| /26 | 255.255.255.192 | 64 | 62 |
| /30 | 255.255.255.252 | 4 | 2 |
| /32 | 255.255.255.255 | 1 | 1(单主机) |
这里要说一个重要细节:/31在点对点链路中通常可以分配 2 个地址且不用保留网络和广播地址,但这是 RFC 3021 的特殊情况。日常做子网时,/30才是最常用的点对点网段——两个可用地址,正好给链路两端设备用。
3. 子网划分与路由聚合:CIDR 的一体两面
3.1 用 CIDR 做子网划分:不求整字节对齐
CIDR 最直接的应用是子网划分。以前按分类编址,划分一个 C 类只能切成两个、四个、八个……一切必须以 2 的幂次为单位。现在有了 CIDR,你甚至可以把一个/24切成一个/26和一个/26再加两个/25的混合体?严格来说,子网划分要求同一层级内的子网块大小可以不同(VLSM),但为了路由汇聚方便,通常还是按 2 的幂次切。
举个例子,一家公司拿到了192.168.1.0/24,需要给四个部门分配网段,每个部门不超过 50 台设备。用老思路只能切四个/26,每个部门 62 个可用地址。但实际部门 A 只要 10 台,部门 B 要 40 台,部门 C 要 30 台,部门 D 要 20 台。用 CIDR 可以这样分配:
- 部门 B:
192.168.1.0/26,可用地址 1.1 ~ 1.62 - 部门 C:
192.168.1.64/26,可用地址 1.65 ~ 1.126 - 部门 D:
192.168.1.128/27,可用地址 1.129 ~ 1.158 - 部门 A:
192.168.1.160/28,可用地址 1.161 ~ 1.174
但这种划分方式会留下192.168.1.176/28到192.168.1.255的空闲块,不太利于后续路由聚合。所以实际工作中,要么统一切一样大的子网,要么按 VLSM 仔细设计,保证剩余空间连续。CIDR 给了你自由,但也考验你的规划能力。
3.2 超网聚合如何让路由表瘦身
路由聚合是 CIDR 的另一个大杀器。传统的分类编址下,如果你的公司有 8 个连续的 C 类网段:192.168.8.0/24到192.168.15.0/24,公司出口路由器需要向上游宣告 8 条路由。但用 CIDR 可以把它们聚合成一条:
192.168.8.0/21为什么是/21?因为从192.168.8.0到192.168.15.0,第三段的高 5 位(8~15)是固定的,对应二进制:
8 = 00001000 9 = 00001001 10 = 00001010 11 = 00001011 12 = 00001100 13 = 00001101 14 = 00001110 15 = 00001111前三位从 000 到 111 全一样(高 5 位中的前 3 位固定?实际上 8~15 的二进制高 5 位前 3 位为 000,后 2 位变化,第四段的 8 位全变化。加起来就是第三段的高 3 位 + 整个第四段 = 11 位主机位,32-11=21),所以前缀长度是 21。路由表立刻从 8 条变成 1 条,这就是“超网”的意义。
聚合不是随便聚的,要求这些网段在地址空间上连续且数量是 2 的幂。如果公司拿的是192.168.9.0/24和192.168.10.0/24,那没法聚合成一个/23,因为它们跨越了 8/9 的边界。这也是为什么申请 IP 地址段时,尽量申请连续地址的原因。
3.3 最长前缀匹配:为什么路由表不怕地址重叠
有了聚合路由后,路由表里会出现地址范围重叠的情况。比如上游有两条路由:
192.168.8.0/21 192.168.10.0/24一条聚合路由覆盖了192.168.8.0 ~ 192.168.15.255,另一条更具体的路由只覆盖192.168.10.0 ~ 192.168.10.255。当路由器要转发到192.168.10.5时,它会选择哪一条?
答案是:最长前缀匹配。路由器会挑选前缀长度最长的那条路由,也就是更具体的那条。因为/24比/21长,所以数据包会走192.168.10.0/24这条链路。这个机制保证了聚合路由不会吞掉更精细的路由,也是 CIDR 能安全工作的核心。
我第一次理解到这一层时,觉得网络设计者真的很聪明。聚合是“宏观上合并”,最长前缀匹配是“微观上精细优先”,两者配合,既减小了路由表,又不丢失任何可达性。
4. 手算 CIDR:不用计算器也能快速得出网络地址和可用主机数
4.1 快速判断网络位的“256 减法”
实际工作中,你经常需要快速判断一个 CIDR 的“块大小”,也就是这个网络包含多少个 IP 地址。有个很简单的方法:
块大小 = 256 - 对应字节的掩码值。
举例:/26的掩码是255.255.255.192,第四个字节掩码 192,那么块大小就是 256 - 192 = 64。这个 64 的含义是:每一个子网的第四字节从 0、64、128、192 开始,每次加 64。/23的掩码是255.255.254.0,第三字节掩码 254,块大小是 256 - 254 = 2,所以它横跨第三字节的 2 个数字,比如192.168.10.0/23覆盖192.168.10.0 ~ 192.168.11.255。
这个方法比每次都转二进制快得多。但要注意,块大小只在掩码最后一段是“整段”时成立,比如/20的掩码是255.255.240.0,块大小不是用最后一段 0 去减,得看 240 在哪一段。/20的第三字节掩码是 240,块大小是 256 - 240 = 16,所以它的地址范围从x.x.0.0到x.x.15.255,每 16 个第三字节一个段。
4.2 实例拆解:从一个 /23 里切出不同大小的子网
纸上谈兵没用,我们直接算一个更复杂的案例。假设你拿到192.168.10.0/23,总地址数 512,可用主机数 510。现在需要切成两个/24和四个/26,怎么切?要保证地址不重叠、不浪费。
先看整体:
192.168.10.0/23 → 192.168.10.0 ~ 192.168.11.255切成两个/24,很好办:
- 子网 A:
192.168.10.0/24,范围 10.0 ~ 10.255 - 子网 B:
192.168.11.0/24,范围 11.0 ~ 11.255
但如果我想把192.168.10.0/24再切成四个/26,每个块大小 64:
192.168.10.0/26:可用 10.1 ~ 10.62192.168.10.64/26:可用 10.65 ~ 10.126192.168.10.128/26:可用 10.129 ~ 10.190192.168.10.192/26:可用 10.193 ~ 10.254
然后剩下192.168.11.0/24可以继续分配给另一个局域网。这样设计既满足了不同部门的规模需求,又保留了路由连续性——对外仍然可以宣告一条192.168.10.0/23。
实际操作时我习惯写一个表,把每个子网的“网络地址、起始可用 IP、结束可用 IP、广播地址”都列出来,因为很容易算着算着就忘记广播地址。每个子网的网络地址是主机位全 0,广播地址是主机位全 1,这两个地址不能分配给主机。
4.3 检查清单:算完怎么验证
手算完,我建议你按下面这套清单自查一遍:
- 网络地址是否满足“前缀位不变,主机位全 0”?
- 广播地址是否满足“前缀位不变,主机位全 1”?
- 起始可用 IP 是网络地址 + 1?
- 结束可用 IP 是广播地址 - 1?
- 可用主机数是否等于
2^(32-前缀长度) - 2? - 切分的多个子网范围是否连续、无重叠?
如果以上任意一项不满足,就说明计算有误。我在学习时经常卡在网络地址不是“看起来整段”的情况,比如172.16.10.0/20的网络地址其实变成了172.16.0.0,必须靠“主机位全 0”来验证。
5. 真实环境里配置 CIDR:Linux、路由器与云平台
5.1 Linux 下用 ip 命令配置 CIDR 地址
Linux 里配置 IP 地址,推荐用ip命令而不是老掉牙的ifconfig。给接口添加一个带 CIDR 的地址:
sudo ip addr add 192.168.10.5/24 dev eth0这条命令的效果等价于设置 IP 为192.168.10.5,掩码为255.255.255.0。但注意,ip命令里只有前缀长度,没有单独掩码参数,写惯了 Cisco 的人要特别小心。查看接口状态:
ip addr show eth0输出里会明确标注inet 192.168.10.5/24 brd 192.168.10.255 scope global eth0。这里的brd是广播地址,系统会根据前缀长度自动计算。
如果你要添加多个地址(比如一个网卡绑定多个 CIDR 网段),直接重复执行ip addr add即可。这在测试环境里非常有用,可以模拟多个网段的路由行为:
sudo ip addr add 10.10.0.1/16 dev eth0 sudo ip addr add 172.16.5.1/24 dev eth0需要注意的是,在网卡上配置了非对端预期的 CIDR 时,通信会失败。比如你给 eth0 配了/24,但对端网关在/25的另一个子网里,两边不在同一个广播域,二层能通但三层路由可能走得不对。排查思路我放在最后一节。
5.2 路由器上配置聚合路由
企业路由器上配置 CIDR 聚合路由,不同厂商语法略有差异,但思路一样。以常见厂商为例,宣告一个聚合网段到路由协议里:
ip route 192.168.8.0 255.255.248.0 10.0.0.1这里的255.255.248.0就是/21的点分十进制写法。很多路由器命令不接受/21这种简写,必须翻译成子网掩码。这种跨写法的转换是新手最容易栽跟头的地方,我后面会讲怎么快速转换。
静态路由搞聚合是“手工汇总”,OSPF、BGP 里也有自动汇总或手动汇总功能。比如 BGP 宣告通告时,你希望对外只通告聚合路由,可以用network 192.168.8.0 mask 255.255.248.0。这样上游路由器看到的就是一条大路由,而不是几条明细路由。
5.3 云平台安全组与 CIDR 白名单
现在的云服务器安全组规则几乎都用 CIDR 来限定来源 IP。比如 AWS 安全组入站规则:
类型: SSH (22) 来源: 203.0.113.0/24意思是只允许203.0.113.1 ~ 203.0.113.254这个网段连接 SSH。很多人配置时图省事,直接写0.0.0.0/0,表示放通所有来源。这在测试环境没问题,生产环境就是安全隐患。
我在云上踩过一个坑:打算只允许公司出口 IP 访问管理端口,结果出口 IP 是一个 NAT 后的动态地址,落在203.0.113.0/24到203.0.114.0/24两个段上。我只写了前面一个/24,结果时不时连不上。后来干脆申请固定 IP,然后把两个连续网段聚合成/23,一条规则搞定。所以理解 CIDR 的聚合,不仅在路由器上有用,在云安全策略里也是刚需。
数据库白名单、Redis 白名单、对象存储桶策略,底层都是 CIDR 匹配逻辑。遇到“为什么这个 IP 能访问、那个 IP 不能访问”的问题,先检查规则里的前缀是否覆盖了目标地址,再检查是否有更具体的拒绝规则。
6. 学习 CIDR 时最容易踩的坑与我的排查经验
6.1 把 /24 和 255.255.255.0 混用导致理解混乱
/24和255.255.255.0是完全等价的,但在不同场景下,混着写会让人非常难受。有一次我在一个配置脚本里看到192.168.1.1/255.255.255.0,这种写法其实来自某些老的网络设备或软件,它不是标准的 CIDR 记法,但不少人会写。看到这种写法,最好立刻翻译成标准的 CIDR 前缀,避免后续计算时产生歧义。
反过来,有些工具只接受子网掩码,不接受/xx。比如某些防火墙的 CLI 老版本,要求写mask 255.255.255.128。这时候如果直接把/25填进去,命令直接报错。我的习惯是:第一步先确认当前环境接受哪种写法,第二步做一次显式转换,不要依赖工具帮你自动转。
6.2 子网掩码不连续?CIDR 的前缀必须是连续的 1
CIDR 的前缀长度隐含了一个前提:网络位必须是地址中连续的“1”。也就是说,子网掩码从二进制角度看,永远是左边一串 1,右边一串 0。比如/22是11111111.11111111.11111100.00000000,不会有中间断层。
但有时候你会看到一些特殊配置,比如255.255.255.192没问题,而255.255.0.255这种“不连续掩码”在某些老设备上是可以配的,但它不是 CIDR,也不满足无类别域间路由的规范**。如果你在学习时遇到这种掩码,不要试图用 CIDR 概念去理解它,那属于极特殊的访问列表掩码(wildcard mask)范畴,跟 CIDR 完全是两回事。
有一次我看一道题:10.10.10.10/255.255.255.128的网络地址是多少?答案是10.10.10.0,因为10.10.10.10的最后一个字节二进制00001010,跟11111110? 不对,255.255.255.128是/25,最后一位是 0,网络地址第四字节是 0。如果写成通配符0.0.0.127,那是 ACL 用的,不要搞混。
6.3 连通性故障排查中如何验证 CIDR 是否配置正确
实际排障时,CIDR 配错会导致“IP 能 ping 通网关,但跨网段不通”这种诡异现象。我一般按以下步骤排查:
- 用
ip addr show检查本机地址和前缀长度。 - 用
ip route show查看路由表,确认网关和网段匹配。 - 用
ping -c 3 网关地址测试二层连通信。 - 如果网关通但外网不通,重点检查路由表里是否有指向错误前缀的默认路由。
- 用
ip neigh查看 ARP 表,确认网关 MAC 是否学到。
最常见的问题是把地址配成了192.168.1.10/23,本机认为自己在192.168.0.0/23这个网段,而网关配置的是192.168.1.1/24,两边对“广播域”的理解不同,ARP 可能时通时不通。解决办法是统一两端的 CIDR 前缀,让它们在同一个子网内。如果你不确定,可以用一个小工具ipcalc快速计算:
ipcalc 192.168.1.10/23输出里会显示:
Address: 192.168.1.10 Netmask: 255.255.254.0 = 23 Network: 192.168.0.0 Broadcast: 192.168.1.255一眼就能看到网络地址是192.168.0.0而不是你以为的192.168.1.0。很多“诡异”的网络问题,根子都在这里。
6.4 用 CIDR 计算器学习 vs 手算:哪个更可靠
最后聊一个学习层面的建议。现在网上有很多 CIDR 计算器,输入 IP 和前缀,网络地址、可用主机范围全出来了。我用过不少,包括命令行的sipcalc、网页版的在线工具。它们的准确率没得说,省时省力。
但我强烈建议你前期先手算至少 20 道题。原因很简单:计算器是黑盒,它只能告诉你答案,不能帮你建立“地址空间拓扑感”。手算几次之后,你会慢慢形成一种直觉——看到/23就知道它跨两个 C 段,看到/20就知道它跨 16 个 C 段,看到一个 IP 就能大致判断它在哪个段里。这种直觉对排查网络问题、规划地址段太重要了。
等你熟了,再用计算器做验证,效率会高很多。我个人习惯是:手算定方案,计算器防呆。两边结果一致,才敢落到配置里。
CIDR 不是什么高深莫测的东西,它就是把“网络位有多长”这件事从固定分类里解放出来,让地址分配和路由设计都有了弹性。这篇笔记里我尽量把“为什么有 CIDR”“斜杠怎么写”“子网怎么切”“路由怎么聚”“排障怎么看”串成了一条线。如果你能把192.168.10.0/23这类地址随手拆成子网、算清可用范围,再遇到网络问题,心里会踏实很多。