Linux中的路由

cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
IPADDR=172.16.108.128
NETMASK=255.255.255.0
GATEWAY=172.16.108.129


route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.108.0	0.0.0.0		255.255.255.0	U     0      0        0 eth0
169.254.0.0	0.0.0.0		255.255.0.0	U     1002   0        0 eth0
0.0.0.0         172.16.108.129  0.0.0.0         UG    0      0        0 eth0

这里的最后一条就是默认路由,表示到达任意网络(目标0.0.0.0表示任意,掩码0.0.0.0表示0位掩码,相当0.0.0.0/0),Flags后面带有G的表示是网关,Gateway地址必须是本机可达的地址。

但是第一和第二条路由就有点看不明白,尤其第二条。

注意到如果有多网卡,169.254.0.0这个路由会出现多次。实际上,Gateway是0.0.0.0(或“*”)是本地直通路由,直接对应接口,不需要网关(所以是0.0.0.0)。准确来说,这里是指定了172.16.108.128这个IP地址,于是产生了172.16.108.0这条直通路由(直接到达eth0接口)。而指定的网关未172.16.108.129则自动产生了默认路由。

169.254.0.0这个直通路由时在使用DHCP分配IP时,在分配失败时,主机会自动分配一个169.254.0.0网段的和其它主机不重复的IP地址,所以就产生了这个路由。
如果不希望出现这个路由,只需要保证不分配这种IP即可:

vi /etc/sysconfig/network-scripts/ifcfg-eth0

NOZEROCONF=yes

这样就不会分配这种地址,自然也不会产生这种默认路由了。

Route命令的输出项说明

输出项
Destination	目标网段或者主机
Gateway		网关地址,”0.0.0.0”或“*”,表示目标是本主机所属的网络,不需要路由(通常意味着本机直通路由)
Genmask		网络掩码
Flags		标记
		U 路由是活动的
		H 目录是一个主机
		G 路由指向网关
		R 
		D
		M
		! 拒绝路由
Metric		路由距离
Ref		路由项引用次数
Use 		此路由项被路由软件查找的次数
Iface		该路由表项对应的输出接口

路由类型
1 主机路由
目标是一个IP地址,Flags有H标记。
2 网络路由
目标是一个网络,经过网关,Flags有G标记。直通路由也是网络路由,网关是0.0.0.0,Flags没有G,可以认为就是专门为网卡IP而设置的路由。
3 默认路由
目标是0.0.0.0,经过网关,Flags有G标记

注:路由匹配有顺序,最匹配的优先,所以目标是0.0.0.0的路由放最后。


配置静态路由

# route  [add|del] [-net|-host] target [netmask Nm] [gw Gw] [[dev] If]
    add : 添加一条路由规则
    del : 删除一条路由规则
    -net : 目的地址是一个网络
    -host : 目的地址是一个主机
    target : 目的网络或主机
    netmask : 目的地址的网络掩码
    gw : 路由数据包通过的网关
    dev : 为路由指定的网络接口

# 添加主机路由

# 添加网络路由
route add -net 10.10.10.0 netmask 255.255.255.0 eth0
route add -net 10.10.10.0 netmask 255.255.255.0 gw 10.10.10.254
route add -net 10.10.10.0/24 eth1

# 添加默认路由
route add default gw 10.10.10.254

# 删除路由
route del default gw 192.168.1.1

场景一:单个路由器,一个外网一个内网
外网:172.16.108.0/24
内网:172.16.195.0/24

关注设备:Host1 Router1 Host2
Host1网关设置为172.16.108.129, Host2网关设置为172.16.195.131。Router1只配置IP地址,不设置网关。

Router1上开启IP转发就可以实现两个网段互通:

#
vi /etc/sysctrl.conf
net.ipv4.ip_forward = 1

#修改生效
sysctl -p

每个接口配置IP时都分配了接口路由(直通路由,理解为接口所在的网络,直接从接口出去),这种和网关路由有本质不一样,接口路由是本机接口之间的包转发,而网关路由是把数据吧发送到网关。

当172.16.195.130向172.16.108.128发送数据时,数据首先发送到172.16.195.131这个网关,网关接收到数据后发现不是本机地址,直接转发,然后选择路由,得到172.16.108.129所在的接口,然后把数据发送出去(这里类似中介,什么不做,仅仅过手了一道而已)。 注:这里的接口路由就发挥了作用。

当172.16.195.130向172.16.108.129发送数据时,情况有点不同,数据首先发送到172.16.195.131这个网关,网关接收到数据后发现是本机地址(不转发),进行路由选择,匹配到172.16.108.129的接口路由,数据从接口路由的接口输出给用户空间,用户空间响应数据,选择172.16.195.131这个接口路由把数据送回去。

所以,路由链接的两个网络,是互通的。这个模型的应用主要是NAT方案,假设172.16.195.0是内网,172.16.109.0是外网,路由器上的eth1接口的IP地址必须是公网IP,所以路由器需要以某种方式从运营商那边取到这个公网IP(拨号或者静态分配,静态分配跟这里的模型一样。拨号的结果是给接口分配IP,由于信号要进行远程传输,所以还需要一个转换设备),所有从内网过来的数据,需要把来源地址更换为这个公网IP,因为内网的数据包来源不是公网IP,无法在公网路由中传递。这里描述的就是SNAT,另一让人困惑的地方是:这种方式出去的数据包,响应时如何进入内网,实际上SNAT会把数据包的目标地址自动修改为数据包到达时未修改前的来源地址,接下来是就是路由器的路由选择问题。

如果路由器有多个外网口(多wan,或虚拟多个wan),然后在多个wan口上取到公网IP后,数据从内网到达路由器时,会选择路由,这时可能产生随机匹配,那么上行将产生叠加,具体说就是一个文件分成了10个包,有10个wan口,那么这10个包同时从10个口出去,原来是一个个传,这里是批量传。 所以这里涉及到负载均衡的问题,比如某个或某些内网从某个wan口出去,另一些从另一个口出去。多wan口,路由器性能就有一些要求。

主要注意的是:如果内网就是公网IP,不需要SNAT,但是还是涉及负载均衡的问题,负载均衡的问题实际是一个路由选择问题。

另外,如果需要把内网的服务器对外开放时,需要在路由器上做DNAT,就是外部访问路由器时,路由器把IP修改为内网服务器IP地址,内网服务响应数据到路由器时,路由自动把数据包的源地址修改回来。

可见,SNAT后的响应数据会自动进行DNAT,而DNAT出去的数据会自动进行SNAT。

场景二:内网中接一个路由器,实现网络隔离,构建专用网络。
在Host3配置IP为172.16.109.128,网关配置为172.16.109.129。Router2中配置一条目录默认路由,网关指定为Router1的172.16.195.131。

这样172.16.109.0网络的数据就可以正常送到Router1,Router1再把数据送出去,响应数据到达Router1后,需要路由到Router2,所以需要在Router1中把建一条默认路由,把数据路由到Router2的172.16.195.132。

由于现在的智能路由器基本都是NAT路由器,所以内网接入路由,就跟正确配置一台机器的IP一样(正确设置网关,上层路由器的内网IP)。而上层路由器也不需要设置默认路由,因为NAT会修改目标地址。进入到子路由器时,子路由器NAT继续修改目标地址。