一个非典型的Linux路由配置方案

标签: IP路由 ARP
3454人阅读 评论(0) 收藏 举报

上周帮人解决了一个问题,这个问题绝对是非典型性的,采用了非常规的方法。虽然最终的方案非常不符合常规非常不通用,充满了各种藏得很深的技巧或者说是trick,但是这个问题却是一个学习Linux路由的绝好机会。事后想了很久,还是决定分享出来,本文并不主张使用奇技淫巧去解决通用问题,但是本文主张遇到问题后至少要有折腾到该领域的原子级别。

  清晨马上就要天亮,听着窗外小鸟儿在歌唱,我把问题重新整理,形成一个新的问题。先看需求,以下是一个拓扑:
这里写图片描述

现在的需求是:

hostA和hostB之间双向互联互通!

这难道不是把Router做成Bridge(这是Linux的术语,正确的说法应该是switch)或者为hostA到Router之间另开辟一个IP地址段么??为什么没有这么做本文不深究也不会暴露,现在的问题是,就上面这个拓扑,怎么能通吧。

  诚然,如果你已经很熟悉Linux路由的方方面面,那么下面的内容你早就耳熟能详,但我相信大部分做不到。另外,本文将体现一种解决问题的方法和精神,即见招拆招。画出流程图或者时序图,哪里有阻碍,就清除哪里。


为了不扯过多哲学上的论述,避免进入形而上的争辩,我先把一个显然的配置配在Router上,即Router到hostA的路由:

ip route add 192.168.0.1/32 dev eth1 src 192.168.0.2

毕竟eth1连IP地址都没有,我们只能把经由它的数据包强行推给它,不然还能怎么做呢?携带src参数是因为为了让数据包到达hostA的时候,让hostA觉得这个数据包看上去是从同一网段来的,即经由了Link路由到达的本机,而不是被强行扭送到了本机。仅此,事先说明。
  然后呢?


然后我们来分两种情况看一下到达hostB的192.168.0.3的数据包如何从hostA出去。

  首先,第一种方法是一个显而易见的方法,即通过链路层发现的路由出去,但因为这个太显然了,因此我准备先介绍第二种方法,即通过默认路由让Router中转到达hostB

  为了去dig一下第二种方法,我决定对hostA进行如下配置:

ip addr add dev eth0 192.168.0.1/24
ip route add 0.0.0.0/0 via 192.168.0.2
# 删除链路层路由,避免直接ARP同网段目标IP
ip route del 192.168.0.0/24 

或者更加trick一点:

ip addr add dev eth0 192.168.0.1/30
# 占用.3广播,你要亲自试试 :-)
...

假设我采用了第一个配置,那么接下来事情就要慢慢起变化了。

  我准备采用时序图来描述这一切是为什么发生的,首先我要将hostA,hostB以及Router的各个网卡抽象成各种Object,同时Router的路由逻辑我也抽象成了一个单独的Object,这样时序图就可以更好地演绎了。另外的假设是,我假定在通信开始时,所有涉事设备的所有ARP表都是空的。下面开始演绎:

这里写图片描述

一切都非常流转,只要注意红色部分就好了,这部分是唯一被拆招的地方,其它的都是例行公事而已。然而就这个地方你要是不懂,整个链路就不会通,道理就这么简单。

  好了,接下来看看从hostB反过来ping hostA时一路上会发生什么,声明一点,我把时序图左右颠倒反过来画了,这是为了和上面的情况好做对比:

这里写图片描述

也不难,也很容易,流程清晰了就都清晰了。不是吗?

  下面该介绍第二种情况了,即hostA直接广播的情况,我们知道,这只是影响了从hostA到hostB的流程,而对反向的hostB到hostA的流程丝毫没有任何影响,因此在这种情况下,只有一幅时序图。

  先给出hostA的配置:

ip addr add dev eth0 192.168.0.1/24

仅此而已,如此一来,当在hostA上发起到达hostB的ping时,路由逻辑会首选自动生成的链路层路由,落实到链路层,即直接请求hostB的MAC,而该请求会被Router的eth1首先捕获到,它该怎么做呢?请看图:

这里写图片描述

好了,到底位置,问题全部解决。总结下来几乎什么都没说,因为这个问题确实是没有难度但很诡异,属于能让人走火入魔的那种,不管怎么说吧,本文的目标是想介绍以下的协议栈参数:

  • arp_announce
  • arp_ignore
  • proxy_arp
  • ip_forward

以及以下的命令:

  • arptables

最终总结下来就是两种方式:

方法1:使用Router默认路由中转

#### hostA
ip addr add dev eth0 192.168.0.1/24
ip route add 0.0.0.0/0 via 192.168.0.2
   # 删除链路层路由,避免直接ARP同网段目标IP
ip route del 192.168.0.0/24 

#### Router
ip route add 192.168.0.1/32 dev eth1 src 192.168.0.2
sysctl -w net.ipv4.conf.eth0.proxy_arp=1
sysctl -w net.ipv4.conf.eth1.proxy_arp=1
sysctl -w net.ipv4.ip_forward=1
arptables -A OUTPUT -o eth1 -j mangle --mangle-ip-s 192.168.0.2

方法2:默认路由

#### hostA
ip addr add dev eth0 192.168.0.1/24
ip route add 0.0.0.0/0 via 192.168.0.2
ip route del 192.168.0.0/24 

#### Router:
ip route add 192.168.0.1/32 dev eth1 src 192.168.0.2
sysctl -w net.ipv4.conf.eth0.proxy_arp=1
sysctl -w net.ipv4.conf.eth1.arp_ignore=3
sysctl -w net.ipv4.ip_forward=1
arptables -A OUTPUT -o eth1 -j mangle --mangle-ip-s 192.168.0.2

arp_ignore和proxy_arp有什么区别?

  • arp_ignore:IP地址在本机,但是不在本网卡上,是否回复自己的MAC;
  • proxy_arp:IP地址不在本机,但路由可达,是否回复自己的MAC

最后宣传下iproute2,劝你放弃iputils…这是潮流。iptoute2指的是统一由ip命令分发子命令的操作,很多的主流网络操作平台都是这种方式,比如Cisco,华为VRP,甚至微软的netsh等都是这样的风格,而iputils则是之前独立的命令行方式,比如ifconfig,arp,route这些都是独立的命令,这种目前是不提倡的,这是古老的风格…

查看评论

linux 路由

 目录 第1章 贡献 1 第2章 简介 2 2.1. 除外责任与许可 2 2.2. 预备知识 2 2.3. LINUX能为你做什么 3 2.4. 内务声明 3 2.5. 访问,CVS和提交更新 4 2...
  • HoO_flying
  • HoO_flying
  • 2007-04-16 13:44:00
  • 3669

linux route命令添加永久路由

双网卡的linux系统中,同时使用2个网关时,需要加一条静态路由。一,使用 route 命令添加路由信息 注意,使用route 命令添加的路由,机器重启或网卡重启后路由会失效。 //添加到主机的路...
  • shirayukixue
  • shirayukixue
  • 2016-08-10 11:06:07
  • 15309

<em>linux</em>做<em>路由</em>全过程(教你如何使用<em>linux</em>系统配置<em>路由器</em>)

如果有淘汰的电脑,您可以安装一个<em>linux</em>,配置成<em>路由器</em>,用来共享上网是很爽的。本文就是教你如何配置基于<em>linux</em>的<em>路由器</em> 综合评分:3(26位用户评分) 收藏评论(11)...
  • 2018年03月23日 00:00

Linux下的路由表详解

linux 路由表 的一些相关资料 =============================================================================...
  • H002399
  • H002399
  • 2015-04-08 14:52:29
  • 6967

linux route路由

网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连就好像一个房间可以有多扇门一样,一台主机可以有多个网关。默认网关的意思是一台主机如果找不到可用的网关,就把数据包发给默认指...
  • zhangxuechao_
  • zhangxuechao_
  • 2016-02-03 23:29:47
  • 215

Linux 路由学习笔记之路由缓存与路由

一、二者对比 1、Linux 系统中可能创建多张路由表来支持策略路由,因此路由表有多个,但是路由缓存只有一个。 2、二者对象粒度也不同 路由表:使用连续地址的集合即子网 缓存:与单个IP地址相关联 二...
  • huyoufu200920201078
  • huyoufu200920201078
  • 2015-01-02 17:20:58
  • 1283

Linux路由器开发详解

宽带上网已经不是什么新鲜事情,人们对相关的网络器件已经不再陌生,比如说常见的路由器。对于一般的网络用户,他们能知道怎样使用路由器来上网、玩游戏等就已经感到很满足了, 通常情况下对路由器的深层技术很少去...
  • qq_21792169
  • qq_21792169
  • 2016-11-12 22:41:15
  • 3561

linux的路由实现

这段时间一直在看《深入理解linux网络内幕》,看完了路由系统的前几章,包括30,31和32章,在此做个小结。(感觉外国...
  • zhangx105_3
  • zhangx105_3
  • 2013-01-06 19:34:06
  • 616

linux下添加永久路由

在linux下永久保存路由表的写法 一、SuSe Linux 在/etc/sysconfig/network/routes里添加。 /etc/sysconfig/network/...
  • chenfei_5201213
  • chenfei_5201213
  • 2012-08-14 13:00:39
  • 15894
    个人资料
    持之以恒
    等级:
    访问量: 726万+
    积分: 8万+
    排名: 17
    文章存档
    最新评论