修订:
关于rp_filter的作用,本文的内容会有些容易引起误解的地方,如果你亲自试过配置,就会发现即便不配置rp_filter,也不妨碍两者互通,所以我加了一个配置说明来消除这个误解,请留意。
本文描述的是一道抬杠题,但我希望不屑于配路由的程序员看了题目后先不要抬杠,先看看自己是不是能用不到5分钟的时间解答这个问题,期间不许查阅资源。
问题我就不详述了,请参见《两台不同网段的PC直连是否可以ping通》,但是为了防止这篇文章的链接失效,我还是简单表述:
主机一配置:
eth0:1.1.1.1/32
主机二配置:
eth0:2.2.2.2/32
主机一和主机二的eth0用一根网线直连,不必在意是交叉线还是直连线,它们是自协商的,这不是较真儿点。
问题是:在两台主机都不添加任何新的IP地址的前提下,主机一和主机二可以相互ping通吗?
-------------------
常规的答案肯定是,不能ping通,理由无非就是“两个地址不在同一个网段”之类云云。但我的答案却是,完全可以ping通,只要有路由即可!
-------------------
我以Linux为例来使其相互ping通,配置如下:
主机2.2.2.2上的配置:
ip route add 1.1.1.1/32 via 1.1.1.1 dev eth0 onlink
net.ipv4.conf.eth0.rp_filter设置为0:sysctl -w net.ipv4.conf.eth0.rp_filter=0
主机1.1.1.1的配置:
ip route add 2.2.2.2/32 via 2.2.2.2 dev eth0 onlink
net.ipv4.conf.eth0.rp_filter设置为0:sysctl -w net.ipv4.conf.eth0.rp_filter=0
至于Windows怎么配置,王姐姐告诉我不需要任何配置,直接配了路由就可以通,我没有亲自试,所以不深入讨论,以下的讨论全部针对Linux。
配置说明:
其实net.ipv4.conf.eth0.rp_filter是不需要配置的,仅仅配置路由即可,我之所以列举出net.ipv4.conf.eth0.rp_filter配置为1,是因为本文的问题其实包含两个方面,首先是要想启动传输,必须要有路由,且仅仅有路由即可,其次,要想完成传输,必须要进行下一跳解析,逐级向下解析下层的地址,本例中就是arp解析MAC地址,这两个方面从下往上看是递归进行的,缺一不可,然而从下往上看,只要配置了路由,arp也会自然而然完成,然而问题就出在这里,很多人都觉得这是自然而然完成的一个过程,但其实如何分开讲的话,你会学到更多的东西。以从1.1.1.1来ping 2.2.2.2为例,如果2.2.2.2上没有配置到1.1.1.1的onlink路由,显然是不通的,但是这并不意味着arp无法完成,事实上,arp是可以完成的,即便没有路由也是可以完成的。详见下面rp_filter的作用解析。
-------------------
这就是答案,即便直连的两台机器配置的IP地址不属于同一网段,也可以相互ping通,关键是要有路由!TCP/IP协议族虽然不像OSI/RM那么和谐融洽,至少也是一套分层体系架构模型,层与层之间要做到尽可能互不牵涉,本题中可见一斑,三层互通,关直不直连鸟事啊?!直连不直连,那是链路的事情,与IP层无关。
-------------------
要成功秒解这个问题,需要的知识点并不多,但是却很深入,包括:
1.onlink路由是干什么的?
onlink路由是可以直接arp目标地址的,而不是arp下一跳地址。意思就是说,目标地址是属于跟本地直连的二层链路上,不跨三层。既然是不跨三层的链路,arp就可以畅行无阻,而标准中又没有规定arp协议包的请求源和请求目标必须是同一个网段的地址(甚至都没有掩码约束),所以说,一个以下的arp请求是有效的:
源地址1.1.1.1请问,地址为2.2.2.2的网卡的MAC地址是多少?
好了,arp已经可以发出了,问题是当2.2.2.2网卡收到arp之后,该如何反应呢?
2.rp_filter如何起作用?
为了解释rp_filter的作用,我先假设删除主机2.2.2.2上到达1.1.1.1的路由,此时虽然2.2.2.2的eth0能收到来自1.1.1.1的arp请求,问题是它会回应吗?
地址为2.2.2.2的网卡收到arp请求之后,会执行arp处理。由于arp是广播发送,因此只要不跨三层的链路上所有的主机都能收到这个arp请求,所以每一个主机首先它会检查这个arp是不是发给自己的,检查的办法很简单,就是执行一次路由查找!注意,就是路由查找而已。
路由查找的目标IP就是arp的目标IP,如果路由查找结果的路由项属性是本地地址,那么就说明请求的目标IP就是本机,这个arp请求就是发给自己的。到此为止,好像问题没有了,收到的arp请求的是本机IP地址,照理说本机理应回应一个arp repy了。是这样吗?
如果使用的是Linux,在默认情况下,这次路由查找将失败!But why?
因为默认Linux针对每个网卡启用了rp_filter选项,这个选项是使能的是反向路由查找,即针对收到数据包的源地址做路由查找,如果查找结果的出口网卡不是收到数据包的网卡的话,查找将失败。在本例中,主机2.2.2.2在eth0收到了来自1.1.1.1的arp请求,那么针对1.1.1.1做路由查找,非常抱歉,没有找到路由,所以rp_filter验证将失败!因此arp reply将不会被发出。
在本例中,由于主机2.2.2.2已经配置了到达1.1.1.1的onlink路由,所以说查找是成功的,问题是你要知道这是如何成功的。
要想arp reply被发出,禁用掉rp_filter,让路由查找通过,随后arp reply就发出了。arp既然已打通,onlink路由也配置了,那么自然路就通了。尽情ping吧!
3.arp_ignore/arp_filter又如何?
稍微知道点Linux网络疑难杂症的可能会往arp_ignore,arp_filter的路子上走,其实这个思路是对的,只是本例没有把事情搞的这么复杂。我来换个实例。主机一配备两块网卡,分别为eth0和eth1,分别插有网线。主机一的eth1配置IP为1.1.1.1/32,而不再是eth0配置该地址,然而依然是eth0与主机二的eth0直连,主机二的eth0依然配置地址2.2.2.2/32。事情会怎样?这个时候你就不得不考虑arp_ignore,arp_filter了...详情如何,我想温州老板可以搞定。
-------------------
温州皮鞋厂老板看了这个问题,以为这种问题毫无意义,然而如果我要来面试的话,我绝对会问这种问题,当然,我会给出个5分钟时间让面试者思考,理清知识点,但也仅仅有5分钟时间,且期间不许查阅资料。
能把这个问题回答正确的人,肯定是对Linux协议栈的实现理解非常透彻的人,这个问题的完美回答(如果不是提前准备的话)并不仅仅意味着答题者是一个好的运维,好的技术支持,而是可以表明答题者可以秒杀80%以上的研发人员。很多人会把这种配路由的操作看作是十分低等的外围操作,认为没法跟那些精读TCP协议实现的人比,其实真实情况恰恰反过来,声称自己精通Linux内核TCP实现的人并不一定真的懂网络,他可能只是能看懂代码而已,有很多写过书的那些人,其实基本原理都不懂,恰恰那些配路由的人,常常被认为是运维,配网络,搬机器上架,扭螺丝的人懂得可能反而更多。
---------------------
版权声明:本文为CSDN博主「dog250」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dog250/article/details/68951615
本文链接:https://www.kinber.cn/post/898.html 转载需授权!
推荐本站淘宝优惠价购买喜欢的宝贝: