惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
A
About on SuperTechFans
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
W
WeLiveSecurity
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
I
InfoQ
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
雷峰网
雷峰网
Hacker News - Newest:
Hacker News - Newest: "LLM"
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Troy Hunt's Blog
S
SegmentFault 最新的问题
Help Net Security
Help Net Security
博客园_首页
博客园 - 叶小钗
O
OpenAI News
PCI Perspectives
PCI Perspectives
月光博客
月光博客
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
GbyAI
GbyAI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Last Watchdog
The Last Watchdog
C
CXSECURITY Database RSS Feed - CXSecurity.com
有赞技术团队
有赞技术团队
D
Darknet – Hacking Tools, Hacker News & Cyber Security
腾讯CDC
Hacker News: Ask HN
Hacker News: Ask HN
I
Intezer
Y
Y Combinator Blog
阮一峰的网络日志
阮一峰的网络日志
Spread Privacy
Spread Privacy
T
Tailwind CSS Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
量子位
Cyberwarzone
Cyberwarzone
The Hacker News
The Hacker News
N
News and Events Feed by Topic
P
Proofpoint News Feed
Scott Helme
Scott Helme
D
Docker
Know Your Adversary
Know Your Adversary
Recent Commits to openclaw:main
Recent Commits to openclaw:main
TaoSecurity Blog
TaoSecurity Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tor Project blog

卡瓦邦噶!

服务器高性能网络调优 | 卡瓦邦噶! 为何写作 | 卡瓦邦噶! 读《金阁寺》 | 卡瓦邦噶! 雨季又来 | 卡瓦邦噶! MTU Probe 引起的初始延迟 | 卡瓦邦噶! 3.5 秒的固定延迟问题 | 卡瓦邦噶! 学习网络的一点经验 | 卡瓦邦噶! ARP 问题诊断 | 卡瓦邦噶! 网络断断续续…… | 卡瓦邦噶! Piccolo P2P 镜像分发 | 卡瓦邦噶! 一起看电影 | 卡瓦邦噶! 《征服C指针》 | 卡瓦邦噶! 我的姥姥 | 卡瓦邦噶! Python的哲学 Python 3.5的新特性 学校不教的计算机课 垃圾回收(GC)的三种基本方式 在编程中体验纯粹的快乐 从《美丽新世界》谈自由 在快钱实习 迷人的嗓音和迷人的故事——《Sleepyhead》 Python 的十个自然语言处理工具 记一个愚蠢的bug 一年炉石传说的游戏体验 《以撒的结合:重生》网页版图鉴 分清 C++的指针、引用和数组 笑话三则 自由比皇帝更伟大——《悲惨世界》笔记 Git 10 周年访谈:Linus 讲述背后故事 用 0x3f3f3f3f 设定最大int值的优点 Joel给计算机系学生的建议 一个词法分析器的简单实现 怎样才算健康的生活方式 MacVim 配置攻略 学习培训课程的视频效果好吗? 语言的控制 可悲的大多数 CSS样式思维导图 2014年终总结 奥巴马成为首位写程序的美国总统 青岛老城区的下水道好在哪里? 做优秀 UI 的七个建议(第二部分) 选择爱情的骑士 Git简明教程 Java集合总览 读 《1984》 java问答:终极父类(六)——等待/唤醒和接口 Java 问答:终极父类(五)——toString() Hyperlapse快速视频背后的技术细节 平庸之恶 Java程序员须知的七个日志管理工具 苏州 逛书摊随想 关于考试作弊 你的工作不仅仅是编程 推荐在线学习Java的英文资源 关注女性命运——《千禧年三部曲》 用好你的幻灯片——《演说之禅》 使用ReentrantLock和Lambda表达式让同步更纯净 新手学编程,从哪里开始? 程序员都是工程师吗? 不要学习代码,要学会思考 Java 问答:终极父类(四)——hashCode() Java 问答:终极父类(三)——finalize()和 getClass() 程序员职业之路的选择 我是一名摄影家 写给何小树的城市指南 为什么一些语言会比别的快? Java的常见误区与细节 跟朋友在一起玩游戏 死神永生——读《三体》 五种类型的程序员 创业圣经——读《黑客与画家》 纪念加西亚·马尔克斯 Junit中处理异常的另一种方式:catch-exception Java8采用Martin Fowler的方法创建内部DSL Linux HotSopt虚拟机GC线程的CPU占用率 J2EE概念介绍 如何成为一名黑客 Java 问答:终极父类(二)——equals()方法 为什么我喜欢Java Java 问答:终极父类(一)——clone()方法 七个改变世界的Java项目 java中默认类型转换的小问题 传统与创新 欢迎来到互联网 莫言和马尔克斯——读《生死疲劳》 位运算的妙用 读《人为什么活着》 写博客教会我的事情 中国特色操作系统 2013年总结 《永不妥协》影评 恨不相逢未嫁时——《廊桥遗梦》影评 如何优雅地使用PPT 给明年依然年轻的我们 天才与柱子 黑客守则和黑客精神 Looking for Freedom——《被解救的姜戈》 简洁之道
由一个子网掩码配置错误所想到的
laixintao · 2023-03-20 · via 卡瓦邦噶!

今天线上发现了一个机器的子网掩码配置错了,其实问题比较简单,一开始没有想到会是这个问题,想了好久才想到这里。

我觉得网络有意思的地方就是在于这些网络协议要考虑的不仅仅是正常的情况,处理正常的情况很简单,而主要的设计其实都是针对不正常的情况如何处理的,比如处理网络中的错误、环路,错误的路由等等。但现实就是,各种各样奇怪的事情会发生,协议必须能处理好各种异常。

不妨拿这个问题来复习一下网络协议:如果子网掩码配置错了,那么两台机器能 ping 通吗?

这个问题看似比较简单,但是答案并不是一个简单的“是”或者“不是”,因为这分成好几种情况。

首先,我们明确这个子网掩码的作用,简单来说,就是判断目标地址和自己是否在同一个网络内

  • 如果是,就直接走二层网络便可达;
  • 如果不是,那么就应该将数据发给网关,让路由器去路由到目的地址,需要三层网络。

即,这个判断是发生在本地的,是一台机器判断应该将数据包的目标地址设置成网关的 MAC(不在同一个子网),还是目的 IP 的 MAC(在同一个子网下)。

对于其他的计算机来说,他们不知道你设置的子网是什么,对于他们发送给你的数据包来说,无论你的子网设置成什么,只要 IP 设置对了,都可以收到。子网的设置只对 egress 流量有影响,对 ingress 流量没有影响(不考虑 ingress 依赖 ARP 这些的话)。下文中会用 “我” 来表示本地的机器。

子网配置的比较大的情况

首先看子网配置的范围比正确范围大的情况,比如我的 IP 本来应该是 1.1.3.2/24, 但是错误的配置成了 1.1.3.2/16.

可以从不同的目标地址来分析影响:

  • 1.1.3.0/24 本来,这个范围和我是在同一个地址下面,现在由于我的子网配置的过大,那么现在,这个段还是跟我在同一个子网下面,所以我和它们之间的通讯丝毫不会收到影响;
  • 1.1.0.0/16 下面,不包含 1.1.3.0/24 的部分:本来,这部分不是跟我在同一个子网下面,现在由于我的子网配置过大,导致我认为它们跟我在一个子网下。那么,本来数据应该发往 router,现在由于我错误地认为这些目标和我在同一个子网,所以我现在会直接查询 ARP 表,通过 ARP 查到目的地址然后发出去。这显然是查询不到的,发出去的 ARP 也不会有响应的,故,这些 IP 是一定不可达

子网配置较小的情况

比如我的 IP 本来应该是 1.1.3.2/16, 但是错误的配置成了 1.1.3.2/24

如上,首先,1.1.3.0/24 这个网段,在错误之前和之后都是和我在同一个网段,所以不会收到影响,能够正确路由。

然后下面就是有意思的部分了。

假设现在要发送到的一个目的地址是 1.1.4.3, 正确的话,这应该是和我在同一个子网,但是现在我的子网变小了,我会认为它不和我在同一个网络内,需要经过路由器转发,所以我会将要发给 1.1.4.3 的数据包的目标 MAC 地址设置成路由器,并且发给路由器。

现在又出现了两种情况,第一种比较简单,是路由器的 IP 地址和我也因为错误变成了不同的网段,比如 1.1.2.1, 那么我会直接认为是 Unreachable,ping 失败。

第二种情况比较有意思:如果我因为阴差阳错,即使子网掩码配置小了,但是依然幸运地和路由器处在同一个网络内呢?

上面已经分析过,这个时候我是可以 ping 通路由器的:

那么我能 ping 通 1.1.4.3 这个地址吗?

让我们一步一步分析一下。

按照上面的逻辑,我会把去往 1.1.4.3 的包丢给路由器,对于路由器来说,它遇到了一个奇怪的事情:这个家伙来自 1.1.3.2/16(路由器视角,路由器的子网配置是正确的),然后要把这个包发送给 1.1.4.3/16, 这不是都在同一个网络 1.1.0.0/16 内吗?发给我干嘛,直接发给它呀!

这时候路由器会怎么做呢?

对于 ICMP 包来说,路由器还是会帮我把这个包转发到目的地址,即路由器通过这个 interface 收到我的包,一看,发现是目的同一个 network,它再从同一个 interface 发出去。

RFC 792 (Internet Protocol)

The gateway sends a redirect message to a host in the following situation.
A gateway, G1, receives an internet datagram from a host on a network
to which the gateway is attached. The gateway, G1, checks its routing
table and obtains the address of the next gateway, G2, on the route to
the datagram’s internet destination network, X. If G2 and the host
identified by the internet source address of the datagram are on the same
network, a redirect message is sent to the host. The redirect message
advises the host to send its traffic for network X directly to gateway
G2 as this is a shorter path to the destination. The gateway forwards
the original datagram’s data to its internet destination.

在路由器上抓包,也可以看到它产生的 Redirect message,里面有说,你应该直接去找 1.1.4.3 , 不要再来找我啦!

所以说,ping request 的包是可以发给目的地址的,只不过会多回复给发送这一个错误消息而已。

现在请求到了 ping reply 这边,reply 能成功发回去吗?

按理说前面提到过,对于其他人来说,正常发给我消息是没有问题的。但是这个回复有一个依赖,就是它要知道我的 MAC 地址,要知道我的 MAC 地址,就需要我来告诉它。

那么第二个有意思的问题就来了:如果我收到了一个 ARP 请求,和我不在同一个网段,但是询问的确实是我的 MAC 地址,我会回复吗?

这个是 Linux 配置参数,位置在 /proc/sys/net/ipv4/conf/eth0/arp_ignore 含义如下:

arp_ignore – INTEGER
Define different modes for sending replies in response to
received ARP requests that resolve local target IP addresses:
0 – (default): reply for any local target IP address, configured
on any interface
1 – reply only if the target IP address is local address
configured on the incoming interface
2 – reply only if the target IP address is local address
configured on the incoming interface and both with the
sender’s IP address are part from same subnet on this interface
3 – do not reply for local addresses configured with scope host,
only resolutions for global and link addresses are replied
4-7 – reserved
8 – do not reply for all local addresses

The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}

因为默认值是 0, 所以是会回复的。通过 tcpdump 在 linux1 上抓包可以确认:

这时候 1.1.4.3 拿到了我的 MAC,就直接在二层把 ping 的 reply 发给我了。

如果在 Linux2 这台机器上,即 1.1.4.3 上,抓包,会发现一个有意思的现象:它从路由器 MAC 收到的 ping 包,回复给了另一个 MAC 地址。

这个奇怪的 ping 链路整体的数据流向如下:

所以说,这种情况下是可以 ping 通的。