对于 Linux 网络,好奇心强的同学一定思考过两个问题:
今天,我们就来分析这两个问题的核心所在:路由。
我们学习计算机网络的时候,一般都会了解到基于目的地址(cidr)的路由(ip route),但是在 Linux 2.0 之后,RPDB (Routing Policy DataBase)诞生了,引入了更丰富的路由策略(ip rule)。除此以外,我们还可以通过 iptables 来操纵数据包,作为路由策略实施的依据,间接地影响路由过程。
至此,我们就认识了 Linux 路由的三大件。那么,三大件分别是什么原理,又是是如何交互的呢?且看下文分析。
注:虽然 Linux 提出了 nftables 来替换 iptables,但 iptables 仍然是事实上的标准
首先我们来看看 RPDB,RPDB 由两部分组成,一个是 rule 列表,一个是 routing table 列表。
ip rule
命令可以展示所有的 rule,每个 rule 由 selector(依据什么特征选择包) 和对应 action(对包做什么) 组成。
selector 主要有几种类型:
action 主要由几种类型:
routing table 最开始只有一个,RPDB 后引入了多个(可以通过 cat /etc/iproute2/rt_tables
查看),默认有三个:
ip route
命令默认展示的是 main table,ip route show table local
形式可以展示其它 table。
routing table 里面每个 route 代表了 dst 为某个/些/类地址 的数据包应该 通过哪个渠道 转发。route 由几部分组成:
cat /etc/iproute2/rt_scopes
,默认有三个
/etc/iproute2/rt_protos
,默认有三个
参考 fib_lookup 函数:如果你没有动过 RPDB,那么直接用 mian table 进行路由查找(fib_table_lookup)了;如果动过,则通过 __fib_lookup/fib_rules_lookup 进行 rule 匹配,匹配逻辑为:
路由查找逻辑为:
iptables 主要用于包过滤、修改和 NAT。再次拿出下面这张神图,来阐释它五大表和五大链,及其生效顺序和范围:
资料直通车:Linux内核源码技术学习路线+视频教程内核源码
学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈
了解了各自原理之后,我们当然想知道它们是怎么交互的。上面那张图实际上已经阐释了他们之间的交互,不过下面这张图能看得更清晰:
原图:http://www.adminsehow.com/2011/09/iptables-packet-traverse-map/
这是一个完全没动过的环境:
我们现在来设计一个需求:源端口为 30300 的包,默默丢弃;源端口为 30301 的包,丢弃并报错;源端口为 30302 的包,用新的 route table 转发。
先看看实施前的结果,用 http://taobao.com 来测试
nc -zv taobao.com 443 -p 30300
Connection to taobao.com (59.82.122.115) 443 port [tcp/https] succeeded!
nc -zv taobao.com 443 -p 30301
Connection to taobao.com (106.11.226.158) 443 port [tcp/https] succeeded!
nc -zv taobao.com 443 -p 30302
Connection to taobao.com (106.11.226.158) 443 port [tcp/https] succeeded!
虽然实现这个需求有很多方式,但是我这里为了演示三大件的交互而选择了下面的这种方式:
首先需要标记这三种类型的包,由于是本地发包,我们采用 mangle output
iptables -A OUTPUT -t mangle -o enp0s1 -p tcp --sport 30300 -j MARK --set-mark 1
iptables -A OUTPUT -t mangle -o enp0s1 -p tcp --sport 30301 -j MARK --set-mark 2
iptables -A OUTPUT -t mangle -o enp0s1 -p tcp --sport 30302 -j MARK --set-mark 3
iptables -t mangle -L
展示,iptables -t mangle -F
清理。
然后增加相应的 route table
echo 2 custom >> /etc/iproute2/rt_tables
ip route add default via 192.168.64.1 dev enp0s1 src 192.168.64.4 table custom
以及 rule
ip rule add from all fwmark 1 blackhole
ip rule add from all fwmark 2 prohibited
ip rule add from all fwmark 3 table custom
结果发现 30302 依然能通,但是 30300 和 30301 都超时了,没看出来返回的错误。
采用 traceroute 的 tcp 模式作为测试工具则能够看出一些差别。
ip rule add from all fwmark 2 unreachable
对应结果也确实符合期望
traceroute -T --sport=30301 --port=443 tabao.com
traceroute to tabao.com (128.14.151.194), 30 hops max, 60 byte packets
send: Network is unreachable
原文作者:九零后程序员