iproute2 策略路由与流量控制笔记


原文链接: iproute2 策略路由与流量控制笔记

清理dns缓存

sudo ip link set dev enp4s0 down && sudo ip link set dev enp4s0 up

iproute2 策略路由与流量控制笔记

-- 前提知识: --
如果需要使用策略路由需确认编译内核时配置中带有IP:advanced route和IP:policy routing

iproute匹配条件:from源地址,to目的地址,Tos域,Dev物理接口,Fwmark防火墙标记 这些做为匹配条件

iproute动作:可以以table指明所用的表,nat网络地址转换,prohibit丢弃并发送icmp信息,reject单纯丢弃,unreachable丢弃并发送icmp信息.

ip rule首先程序从优先级高到低扫描所有的规则,如果规则匹配,处理该规则的动作。如果是普通的路由寻址或者是nat地址转换的换,首先从规则得到路由表,然后对该路由表进行操作。这样RPDB(routing policy database)终于清晰的显现出来了。

iproute相关的内核编译选项:CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_FWMARK=y

/etc/iproute2/rt_tables 保存规则的名字与数字的关联

iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 允许调整tcp syn包里的MSS域,用于控制连接包的最大长度。一些防火墙或主机会很不适当的过滤掉type 3、code 4(需要分片)的icmp包。目前发行的linux的内核从2.4.7开始已经包含了这个补丁。

IMQ 中介队列设备
被打了特定标记的数据包在netfilter的NF_IP_PRE_ROUTING和NF_IP_POST_ROUTING两个钩子函数处被拦截,并被送到一个队列规定中,该队列规定附加到一个IMQ设备上。可以实现对入口流量整形,而且可以把网卡当成一个个的类来看待而进行全局整形设置。

--应用案例1 --

通过iptables与iproute2协同实现根据 应用 的策略路由
实现要点: iptables根据端口将服务类的数据包打上标示,iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 100 (用这些标记我们可以做带宽限制和基于请求的分类)
根据情况做nat iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
然后设置路由策略ip rule add fwmark 100 table 100

-- 应用案例2 --

普通双ISP的设置 外网接口$IF1 IF1接口地址$IP1 ISP1网关地址$P1 ISP1的网络地址P1_NET
#分别指定两条默认网关负责单独的上行流
ip route add $P1_NET dev $IF1 src $IP1 table T1 源地址为IP1且目的为ISP1网段从IF1接口发出(必需的,它能够让我们找到该子网内的主机及本网关) 将这条路由加入表T1
ip route add default via $P1 table T1
ip route add $P2_NET dev $IF2 src $IP2 table T2 源地址为IP2且目的为ISP2网段从IF2接口发出((必需的,它能够让我们找到该子网内的主机及本网关) 将这条路由加入表T2
ip route add default via $P2 table T2

#也加入到main路由表
ip route add $P1_NET dev $IF1 src $IP1
ip route add $P2_NET dev $IF2 src $IP2
main缺省走ISP1
ip route add default via $P1

#设置路由规则
ip rule add from $IP1 table T1
ip rule add from $IP2 table T2
#设置负载均衡
ip route add default scope global nexthop via $P1 dev $IF1 weight 1
nexthop via $P2 dev $IF2 weight 1

均衡是基于路由进行的,而路由是经过缓冲的,所以这样的均衡并不是100%精确.

-- 应用案例3 --
TC带宽管理的主要实现步骤 主要是在输出端口处建立一个队列进行流量控制,控制的方式是基于路由,亦即基于目的IP地址或目的子网的网络号的流量控制。
1 编译内核时注意事项
以下实例:发往A主机8M带宽 发往B主机1M带宽 发往C主机1M带宽
2  1) 针对网络物理设备(如以太网卡eth0)绑定一个CBQ队列;
tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit avpkt 1000 cell 8 mpu 64
  2) 在该队列上建立分类;
tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit maxburst 20 allot \ 1514 prio 8 avpkt 1000 cell 8 weight 1Mbit
tc class add dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 8Mbit maxburst 20 allot \ 1514 prio 2 avpkt 1000 cell 8 weight 800Kbit split 1:0 bounded
tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot \ 1514 prio 1 avpkt 1000 cell 8 weight 100Kbit split 1:0
tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot \ 1514 prio 6 avpkt 1000 cell 8 weight 100Kbit split 1:0
  3) 为每一分类建立一个基于路由的过滤器;
tc filter add dev eth0 parent 1:0 protocol ip prio 100 route
tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 2 flowid 1:2
tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 3 flowid 1:3
tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 4 flowid 1:4
  4) 最后与过滤器相配合,建立特定的路由表。
ip route add 192.168.1.24 dev eth0 via 192.168.1.66 realm 2
ip route add 192.168.1.30 dev eth0 via 192.168.1.66 realm 3
ip route add 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4
3 应用,监控

--关于负载平衡--
关于负载平衡 CONFIG_IP_ROUTE_MULTIPATH内核选项将把所有这些路径(缺省路由)等同看待,然后再根据/usr/src/linux /Documentation/Configure.help来选择其特定的方式。Ip route命令的equalize选项,会让Linux内核基于IP地址平衡外部连接。对于一个特定的IP地址,内核会选择一个接口用于传输流出的数据包,然后内核会为该IP地址在路由缓冲中建一个记录。这样,其它到达的有相同IP地址的数据包就会使用同一个接口,直到该记录从路由缓冲中删除。我们可以使用ip route list cache命令来查看路由缓冲。

通过DNS循环来实现的服务的负载平衡
各种不同的服务(DNS、SMTP、HTTP、LDAP、SSH等) 可以通过DNS循环来实现。
循环复用DNS还有太多的限制(DNS缓存,忽略TTL值,修改后的刷新时间,不能意识到服务器的可用性),只能算是一种勉强可接受的负载平衡方案

--相关命令 --
ip link list 显示链路
ip address show 显示IP地址 对于PPP0接口还会告诉我们链路另一端的地址
ip route show 输出结果之一default via x.x.x.x dev x

ip neigh show 查看缓存的ARP表
ip neigh delete x.x.x.x dev x

--TC流量控制:--
我们只能对发送数据进行整形
默认整形方式是Pfifo_fast队列规定。特点为先进先出。只看数据包的TOS字节节来判断应该放到哪个频道(优先).一般的应用程序会如何设置他们的TOS值。
HTB分层的令牌桶
HTB 可以保障提供给每个类带宽的数量是它所需求的最小需求或者等于分配给它的数量.当一个类需要的带宽少于分配的带宽时,剩余的带宽被分配给其他需要服务的类.

SFQ随机公平队列
简单轮转。使用一个散列算法,把所有的会话映射到有限的几个队列中去。(只有当你的出口网卡确实已经挤满了的时候,SFQ才会起作用)

(如果你并不希望进行流量整形,只是想看看你的网卡是否有比较高的负载而需要使用队列,可使用pfifo队列。它缺乏内部频道但是可以统计backlog)

--HTB应用案例4--
1)
tc qdisc add dev eth0 root handle 1: htb default 12
2)
tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps
3)为队列规定分配子类, 如果没有指定缺省是pfifo
tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: sfq perturb 10
1:12队列的类不定义时,即所有不匹配其它类规则的数据包。

--流量分析与故障诊断--
tc -s -d qdisc show dev eth0 队列状态
tc -s class show dev eth0 类状态
tc filter show dev eth0 过滤器状态

`