Linux routes路由问题定位及解决

作者:简简单单 2016-07-28

linux的静态路由特是是在双网卡的时候非常重要,有时候你会发现你设置完成之后网直接不通了,或者没有按照计划来走数据包,所有路由部分还是需要好好搞搞的

Adding static routes in Linux can be troublesome, but also absolutely necessary depending on your network configuration. I call static routes troublesome because they can often be the cause of long troubleshooting sessions wondering why one server can’t connect to another.

添加静态路由可能会引起一些麻烦,但是,有时候根据你的网络情况来说,这又是必须的,我说静态路由麻烦的原因是静态路由会导致一些服务器之间相互不通的情况

This is especially true when dealing with teams that may not fully understand or know the remote servers IP configuration.

特别是我们没有完全弄清楚远程服务器的ip配置

The Default Route

默认路由

Linux, like any other OS has a routing table that determines what is the next hop for every packet.

Linux,和其它所有操作系统一样,有一个路由表来决定每个数据包下一跳该跳到哪里

Print the routing table contents

打印路由表内容

There are numerous commands that show the routing table but today we will use the ip command as this command will be replacing the route command in future releases.

有很多个命令可以展示路由表的内容,但是今天我们要使用ip 这个命令,因为将来它会提换route命令


# ip route show
 10.1.6.0/26 dev eth0 proto kernel scope link src 10.1.6.21
 10.1.7.0/24 dev eth1 proto kernel scope link src 10.1.7.41
 default via 10.1.6.1 dev eth0
 
As you can see in the example routing table there are numerous routes however 1 route shows as the default route. This routing table tells the system that if the IP that is being communicated to does not fall into any of the other routes than send the packets to the default route defined as 10.1.6.1. The default route basically acts as a catchall for any packet that isn’t being told what to do in the above routes.

正如你能从例子中看到的,有很多结果,但是,第一条路由就是默认路由,路由表告诉系统如果有的包没有符合的路由记录,那么就会发送到默认路由10.1.6.1。默认路由就是那些没有指明的包的去处

Our Example System

我们的测试环境

In today’s article I will be referencing an example network configuration in order to show how static routes are added, why to add them and some basic troubleshooting.

今天的文章我们将会参考我们的测试环境的网络配置来说明如何添加静态路由,为什么需要添加,和一些基本的问题处理

Example Interface Configuration

网卡配置

eth0:


# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=10.1.6.21
NETMASK=255.255.255.192
ONBOOT=yes
 
eth1:

# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
IPADDR=10.1.7.41
NETMASK=255.255.255.0
ONBOOT=yes
 
Example Default Route Configuration

默认路由设置:


# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=testing.example.com
GATEWAY=10.1.6.1
 
The GATEWAY configuration in /etc/sysconfig/network tells the system that10.1.6.1 is the default route. This configuration could also be added to/etc/sysconfig/network-scripts/ifcfg-eth0 file; However if multipleifcfg- files have a GATEWAY this may provide unexpected results as there can only be one default route.

在/etc/sysconfig/network中的GATEWAY配置告诉系统10.1.6.1 是默认路由,这个配置也可以在在/etc/sysconfig/network-scripts/ifcfg-eth0中添加,但是,如果多个网卡ifcfg-都设置了GATEWAY,这可能会引发预料不到的结果,因为默认路由只有一条

Example Why we need a static route

为什么我们需要静态路由

For our example network configuration we have two interfaces; eth0 (10.1.6.21)for the internet, and eth1 (10.1.7.41) for the internal network. If we were to hook up to a backup server such as 10.1.5.202 we would want the connectivity to go through eth1 the internal network, rather than eth0 which is the internet network.

在我们的测试环境中,我们有两个网卡eth0(10.1.6.21)用来链接外网,eth1(10.1.7.41)用来链接内王,如果我们想链接一个备份服务器,比如10.1.5.202,我们当然希望它能通过eth1也就是内网来沟通,而不是通过外网的网络eth0

Since 10.1.5.202 is not in the same subnet at eth1 (10.1.7.0/24) the routing table does not automatically route the packet through eth1 and would then hit the “catchall” default route out eth0. To force all of our packets destined for10.1.5.202 out eth1 we will need to set up a static route.

因为10.1.5.202和eth1(10.1.7.0/24)不是同一个子网,所以路由表不会默认把请求通过eth1发送,并且会通过默认的eth0来发送(因为没有相应的路由表),为了强制所有的10.1.5.202的数据包通过eth1,我们需要设置一个静态路由

Adding a Static Route

添加一个静态路由

Adding the route to the current routing table

添加路由到路由表

Adding the static route is a fairly simple task however before we start we must first know the gateway for the internal network; for our example the gateway is10.1.7.1.

添加静态路由非常简单,但是在操作之前我们必须知道内网的gateway,例子中是10.1.17.1

Adding a single IP

增加一个单独的IP


# ip route add 10.1.5.202/32 via 10.1.7.1 dev eth1
 
The above command adds a route that tells the system to send all packets for10.1.5.202 and only that IP to 10.1.7.1 from device eth1.

上面的命令添加了一个路由告诉系统说:所有10.1.5.202的数据包 发送到10.1.7.1 通过eth1

Adding a subnet of IP’s

增加一个子网段:

In order to add a whole subnet than you will need to change the CIDR on the end of the IP. In this case I want to add anything in the 10.1.5.0 – 10.1.5.255 IP range. To do that I can specify the netmask of 255.255.255.0 in CIDR format(/24) at the end of the IP itself.

为了添加整个子网,我们需要修改CIDR,在这个例子中,我们希望所有的10.1.5.0-10.1.5.255这个段,为了设置这个,我们可以使用子网掩码(255.255.255.0)也就是/24,

If a CIDR (or netmask) is not specified the route will default to a /32 (single ip) route.

如果没有特殊的设置 ,默认的子网为/32


# ip route add 10.1.5.0/24 via 10.1.7.1 dev eth1
 
The difference between these two routes is that the second will route anything between 10.1.5.0 and 10.1.5.255 out eth1 with 1 route command. This is useful if you need to communicate with multiple servers in a network and don’t want to manage lengthy routing tables.

两条路由的不同是所有第二条路由添加了整个段10.1.5.0-10.1.5.255,这个在我们要一次设置多个主机的时候非常有用,一条命令节省了路由表空间

Adding the route even after a network restart

添加一个路由即使网络重启

While the commands above added the static route they are only in the routing table until either the server or network service is restarted. In order to add the route permanently, the route can be added to the route- file.

上面的命令添加的路由记录只能坚持到网络重启,为了永久的添加路由的,我们可以将路由信息添加到route-列表中


# vi /etc/sysconfig/network-scripts/route-eth1
 
Append:


10.1.5.0/24 via 10.1.7.1 dev eth1
 
If the above configuration file does not already exist than simply create it and put only the route itself in the file (# comments are ok). When the interface is restarted next the system will add any valid route in the route-eth1 file to the routing table.

如果文件不存在,我们直接创建并将信息添加进去就好了,当网卡重启的时候,系统会自动的添加route-eth1中的内容添加到路由表中

I highly suggest that when possible anytime you add a route to the route- files that the interface itself is restarted to validate whether the route is actually in place correctly or not. I have been on many late night calls where a static route was not added correctly to the configuration files and was removed on the next reboot, which is also long after everyone has forgotten that a static route was required.

我强烈建议所有的时候我们都通过修改routte-文件的方式来添加路由,因为重启之后会自动验证路由表中是否已经存在,我曾经多次大半夜被电话吵醒就是应为没有添加到配置文件中,系统重启后路由就消失了,因为时间太久了,大家都忘记了静态路由的需要。

Troubleshooting a Static Route

静态路由的问题定位及解决

Check if the route is in the routing table

检查路由是否在路由表中

Before performing any deep down troubleshooting steps the easiest and first step should be to check if the routing table actually has the route you expect it to have.

在我们执行任何操作之前,我们应该第一步先检查路由表中是否有相应的路由

 

# ip route show
 10.1.5.0/24 via 10.1.7.1 dev eth1
 10.1.6.0/26 dev eth0 proto kernel scope link src 10.1.6.21
 10.1.7.0/24 dev eth1 proto kernel scope link src 10.1.7.41
 default via 10.1.6.1 dev eth0
 
Use tcpdump to see tcp/ip communication

通过tcpdump来查看tcp/ip的通信

The easiest way that I have found to find out whether a static route is working correctly or not is to use tcpdump to look at the network communication. In our example above we were attempting to communicate to 10.1.5.202 through device eth1.

最简单的方式来检查路由是否正常工作就是使用tcpdupm来查看网络之间的通信,例如,我们想让10.1.5.202通过eth1来通信


# tcpdump -qnnvvv -i eth1 host 10.1.5.202
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
16:50:35.880941 IP (tos 0x10, ttl 64, id 59563, offset 0, flags [DF], proto: TCP (6), length: 60) 10.1.7.41.41403 > 10.1.5.202.22: tcp 0
16:50:35.881266 IP (tos 0x0, ttl 59, id 0, offset 0, flags [DF], proto: TCP (6), length: 60) 10.1.5.202.22 > 10.1.7.41.41403: tcp 0
 
The above tcpdump command will only listen on eth1 and output only results that to or from 10.1.5.202.

上面的tcpdump命令会仅仅监听eth1的输出,并且只检测10.1.15.202来或者出的包

TCP connections require communication from both the source and the destination, to validate a static route you can simply initiate a tcp connection (telnet to port 22 in this case) from the server with the static route to the destination server. In the output above you can see communication from10.1.7.41 to 10.1.5.202 from the eth1 interface, this line alone shows that the static route is working correctly.

TCP链接需要目标和源的沟通,验证静态路由,我们可以简单的创建一个tcp链接(telnet 22端口),从这台有静态路由的机器到目标主机,从输出中我们哪呢个看到从10.1.7.41到10.1.5.202通过eth1接口,这就说明静态路由是正常工作的

If the static route was incorrect or missing the tcpdump output would look similar to the following.

如果静态路由是没有办法正常工作的,那么输出结果就如下边的结果:


# tcpdump -qnnvvv -i eth1 host 10.1.5.202
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
16:50:35.881266 IP (tos 0x0, ttl 59, id 0, offset 0, flags [DF], proto: TCP (6), length: 60) 10.1.5.202.22500 > 10.1.7.41.22: tcp 0
 
In the above, only the target server is communicating over eth1.

上边的输出中,只有目标主机通过eth1交流

相关文章

精彩推荐