作者: 耳朵里有风
本篇主要学习了Linux路由的基本概念和一些简单操作,在下一篇中会结合Linux虚拟网络、iptables和本篇的路由来实现在namespace中如何访问局域网和互联网。
路由概念
作为一个软件行业半路出家的人,有一次去客户现场办公,带的笔记本电脑上不了网,客户就帮忙配置了ip和网关。从下图可以看到要上网得配置四个东西,ip/子网掩码、默认网关、DNS服务器;其中ip/子网掩码是告诉网络我计算机当前位置的,DNS服务器是告诉网络要访问的域名真实的ip地址的。网络要找到某一台服务器设备是根据IP来定位的,比如当在浏览器输入域名 “www.baidu.com” 时,首先要询问DNS服务器 “www.baidu.com”这个域名对应的ip地址是多少,然后再根据ip找到提供百度搜索的服务器设备。
那么这里配置的网关又是什么作用呢?我们知道互联网两台机器直接通信是需要经过多个站点的,比如访问百度时,首先将请求发给第一个站点,也就是配置的网关,网关在接收到请求后,再把请求转给下一个网关,一直到请求达到目标机器结束。
网关并不是具体的某个设备,它是指用来连接不同的网关设备的一个网络层概念, 比如可以由路由器来实现网关的功能,也可以是三层交换机,甚至也可以直接使用Linux服务器实现。
上面这些都在讲网关,理解网关之后,再来看什么是路由,还是看图2,一个请求从PC到最终的服务器需要经过层层网关,那请求走的 “网关1-网关2-服务器” 还是“网关1-网关3-服务器”的呢?是了,决定一个请求所走的路线就是我理解的路由。常用到的路由器设备就是用来判断把网关1的请求是转给网关2还是网关3。从整个网络来看路由决定着请求的走向,下面具体来看一看Linux的路由功能。
Linux的路由功能
当提到路由决定请求走向,如果你看过 Docker网络学习第二篇-认识iptables就会知道iptables 里nat表和FORWARD链其实也是决定请求走向的,除了iptables之外,Linux系统在IP层维护了路由表来实现路由功能。可以使用ip route命令来操作路由(也可以使用net-tools的route命令)。
[root@2030-edu-01-no ~]# ip route show
default via 172.31.131.1 dev eth0
10.1.1.0/24 dev bridge0 scope link
169.254.0.0/16 dev eth0 scope link metric 1002
172.17.0.0/16 dev docker0 scope link
172.18.0.0/16 dev br-40a246442710 scope link
172.31.131.0/24 dev eth0 proto kernel scope link src 172.31.131.49
[root@2030-edu-01-no ~]#
路由表
从Linux-2.2开始,内核把路由归纳到许多路由表中,这些表都进行了编号,编号数字的范围是1到255。另外,为了方便,还可以在/etc/iproute2/rt_tables中为路由表命名。默认情况下,路由使用的是MAIN表(编号254)中, 主要用于各类网络ip地址的转发。除了MAIN表外,常用表还有用于本地网络接口之间的数据转发(配置设备是会自动创建)的LOCAL表(编号255)。上面一段代码是用ip route show
命令查看main表的所有条目(等效于ip route show table main
或ip route show table 254
)。如果要查看所有表条目,就可以使用 ip route show table all
命令。
路由条目
每个条目有着不同的要素,包括:
-
目的地址(Destination):就是请求要到达的地址,比如请求10.1.1.2这台服务,就会走
10.1.1.0/24 dev bridge0 scope link
这条路由,因为10.1.1.2 是在10.1.1.0/24这个网段中的。 - dev: 网络设备,比如请求10.1.1.2这台服务,就会经过bridge0 这台设备。
- scope: 常用包括三种
host, 表示该地址只用于主机的内部通信。例如:127.0.0.1
link, 表示地址只在局域网内部有意义(链路层互联),如子网广播地址
global,表示地址可以在任何地方使用,也是默认的scope - src:源地址,通常进程请求时会绑定源地址,如果没有绑定的话就是使用路由中src指定的地址
- proto: kernel, boot,static,NUMBER, 信息项,表示谁创建的,如
proto boot
表示该条目是启动过程安装的路由 - metric: 为路由指定所需跃点数的整数值, 当有两个及以上的路由都匹配上请求,选择metric相对较小的走。
- type: 路由类型,unicast ,local, broadcast ,multicast , throw,unreachable ,prohibit , blackhole, nat
类型 | 说明 |
---|---|
unicast | 该类型路由描述到目的地址的真实路径 |
local | 目的地址被分配给本机,数据包通过回环被投递到本地 |
broadcast | 目的地址是广播地址,数据包作为链路广播发送。 |
multicast | 使用多播路由。在普通的路由表中,这种路由并不存在。 |
throw | 如果选择了这种路由,就会认为没有发现路由,在这个表中的查询就会被终止,并产生ICMP信息net unreachable。本地发送者会返回ENETUNREACH错误。 |
unreachable | 目的地址是不可达的。如果发过去的数据包都被丢弃并且收到ICMP信息host unreachable,目的地址就会被标记为不可达。在这种情况下,本地发送者将返回EHOSTUNREACH错误。 |
prohibit | 路由是不可达的。发过去的数据包都被丢弃,而且产生ICMP信息communication administratively prohibited 。本地发送者会返回EACCESS错误。 |
blackhole | 目的地址不可达,而且发过去的数据包都被丢弃。在这种情况下,本地发送者将返回EINVAL错误。 |
nat | 特定的NAT路由。目标地址属于哑地址(或者称为外部地址),在转发前需要进行地址转换。 |
-
下一个路由:就是请求经过这条路由之后,接下来往哪去, 可以是下一个网关,也可能是具体的某个设备接口。比如
default via 172.31.131.1 dev eth0
via指定的地址172.31.131.1
(下一个网关)。 如果你用 'route -n' (需要安装net-tools) 查看,就是Gateway字段值。
[root@2030-edu-01-no ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.31.131.1 0.0.0.0 UG 0 0 0 eth0
- 标志(Flags):标记目标地址类型,下一个路由类型等。
U (route is up):该路由是启动的;
H (target is a host):目标是一部主机 (IP) 而非网段;
G (use gateway):需要透过外部的主机 (gateway) 来转递封包(该行有gw);
R (reinstate route for dynamic routing):使用动态路由时,恢复路由资讯的旗标;
D (dynamically installed by daemon or redirect):已经由服务或转 port 功能设定为动态路由
M (modified from routing daemon or redirect):路由已经被修改;
! (reject route):这个路由将不会被接受(用来抵挡不安全的网域!)
A (installed by addrconf)
C (cache entry)
路由条目还是比较复杂的,以上只列出了部分属性,如果再后续文章具体涉及,再另行解释。使用ip -d route show
(-d detail) 查看第一条结果是 unicast default via 172.31.131.1 dev eth0 proto boot scope global
default 表示默认路由,意思是当没有找到合适的路由时, 就使用该条。比如在访问百度时,由于没有合适的路由,就会走第一条,将请求发送给 172.31.131.1
这个网关。
参考资料
1、https://zhuanlan.zhihu.com/p/43279912
2、https://blog.csdn.net/liuqun69/article/details/88888612