排障:Linux不转发流量

Background

实验环境打算用trex打流,然后用下面环境测试cable,但物理server配置好路由后,发现只能收路由,不转发流量,我们确认已经开启了ipv4转发的指令,路由也是正常的,但就是不work,所以我在EVE NG的环境上搭了一个类似的环境,确认下是否是trex本身的问题;

# sysctl -a |grep net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 1

对于trex内容,请看我之前的相关文章:http://www.zhaocs.info/tag/trex

Topology

故障及排查过程

在EVE NG环境上,我竟然遇到了同样的问题,流量进来后不进行转发。。。难道真的跟trex相关,不应该呀,之前在做灰度测试使用时确实没任何问题,因此根据KT经验,排除了下面信息:

  • 确认Server的ipv4转发已经打开(net.ipv4.conf.all.forwarding = 1);
  • 通过在Server上用tcpdump抓包,确认IP,Mac均正常,ARP也正常;
  • 特意在Server上确认了路由的写法,指明下一跳,这样可以直接找下一跳的arp对应的mac即可,但仍然不转发流量;
  • 在Server上使用“iptables -F”删掉所有规则,仍然一样的现象;
  • 关闭switch20的gi1/1和gi1/2,在交换机上的gi0/1和gi0/2配置跟Server e1和e2相同的IP,然后指静态路由,发现是正常的!这说明问题还是在Server本身;
  • 由于这台Server我之前用于测试BIRD,因此开过VRF,为了避免这种问题,我在写静态路由时分别加了local,0,以及default,(例如:“ip route add 192.0.0.0/24 table local via 40.1.1.1 dev eth2”)但仍然有同样的问题;
  • 通过相应的命令查看,但看不到任何drop:“ethtool -S eth0”,“netstat -s -u”;
  • 为了刨除路由问题,我在trex上构建流量时直接写的是trex e2的地址,这样流量到了Server后,就会发现目的地址跟Server的e2在同一个网段,因此直接转发,但测试后发现一样的问题!!
  • 为了排查Server本身问题,我新建了一个kvm Linux23,这台使用了不同内核,不同版本的Centos,配置上同样的IP后,并指向路由,发现是可以work的!!这说明还是原来那个Server的问题,但那个Server到底发生了什么?为什么不转发流量;

深入研究

经过各种Google,发现了一个比较好用的排障命令,如“ip route get x.x.x.x from y.y.y.y iif ethx”,意思就是模拟从端口ethx进来的报文,原地址是y.y.y.y,目的是x.x.x.x,是否能找到路由;

下面是正常的Linux23的输出:

[root@linux23] ~$ ip route get 40.1.1.1 from 16.0.0.0 iif eth1
40.1.1.1 from 16.0.0.0 dev eth2 
    cache iif eth1

然后就发现了很神奇的现象,下面是问题Server的输出:

[root@server ~]# ip route get 40.1.1.1 from 16.0.0.0 iif eth1
RTNETLINK answers: Invalid cross-device link

那么上面的告警到底代表了什么,经过查找,找到了一个比较类似的故障:Centos 8多网卡时非主网卡路由不通的reverse path filtering(rp_filter)问题 ;根据这里的介绍,特定版本的OS会默认启动rp_filter,什么是rp_filter?其实在网络里我们一定不会陌生,就是URPF,该特性会去确认源地址是否有回城路由,如果没有并且不是从该端口回去的,那么就会丢弃,常用于网络安全特性,在linxu上我是第一次看到。。。可以通过下面查看:

[root@server ~]# cat /proc/sys/net/ipv4/conf/eth1/rp_filter
1
[root@server ~]# cat /proc/sys/net/ipv4/conf/eth2/rp_filter
1

在我的测试中,我没有特意指定原地址,所以正中rp_filter下怀。。。通过下面配置关闭这个特性,再次确认Server,发现问题解决了!真是不容易呀!

[root@server ~]# echo 0 > /proc/sys/net/ipv4/conf/eth1/rp_filter
[root@server ~]# echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter

不过对比了下两台Server,都是Centos7.x,所以不能简单的界定,Centos8默认开启,所以有类似的问题,建议先确认下这个比较好:

[root@server ~]# cat /etc/*-release
CentOS Linux release 7.9.2009 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.9.2009 (Core)
CentOS Linux release 7.9.2009 (Core)
[root@linux23] ~$ cat /etc/*-release
CentOS Linux release 7.5.1804 (Core) 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.5.1804 (Core) 
CentOS Linux release 7.5.1804 (Core) 

nstat

根据rp_filter查找了下,可以通过下面命令查看这些drop信息。其中这些counter代表了什么,可以直接从kernel文档查看:https://www.kernel.org/doc/html/latest/networking/snmp_counter.html

[root@server ~]# nstat -z | grep IPReversePathFilter
TcpExtIPReversePathFilter       1608008            0.0

nstat常用命令和解释

nstat的输出有三列,分别为:

  • Column 1:kernel SNMP mib 的 identifier;
  • Column 2:自上次测量以来的增量值,根据不同的option,显示的也不一样,比如某个counter已经不再增加了,那么默认的输出就不会显示这个mib的信息;
  • Column 3:计数器每秒的平均增长率;

默认nstat的输出是显示跟上次输出对比的增量:

[root@server ~]# nstat 
#kernel
IpInReceives                    7                  0.0
IpInDelivers                    7                  0.0
IpOutRequests                   9                  0.0
TcpInSegs                       7                  0.0
TcpOutSegs                      10                 0.0
TcpExtTCPPureAcks               5                  0.0
TcpExtTCPHPAcks                 1                  0.0
TcpExtTCPOrigDataSent           11                 0.0
TcpExtTCPDelivered              11                 0.0
IpExtInOctets                   548                0.0
IpExtOutOctets                  5440               0.0
IpExtInNoECTPkts                8                  0.0

想查看mib的绝对counter,可以带上“-a”:

[root@server ~]# nstat -a
#kernel
IpInReceives                    3344812            0.0
IpInAddrErrors                  323                0.0
IpForwDatagrams                 1718209            0.0
IpInDelivers                    7985               0.0
IpOutRequests                   1724945            0.0
......

计数不增加的mib默认是不会显示的,必须带上-z才可以:

[root@server ~]# nstat -z
#kernel
IpInAddrErrors                  323                0.0
IpInUnknownProtos               0                  0.0
......

nstat对比netstat

对于nstat和netstat的对比,可以看这个文章:https://loicpefferkorn.net/2016/03/linux-network-metrics-why-you-should-use-nstat-instead-of-netstat/ ;如果查看不了,可以看我保存的pdf:

下面是上面文章总结的结论:

  • nstat offers all the linux network metrics provided by the kernel, but without any knowledge of the aforementioned RFCs their names might look more or less cryptic.
  • netstat is obsolete and does not provide all the available metrics, but many are described with plain English, which is easier to understand when looking for simple metrics.
  • If you want to extract every possible information on your established connections, ss is what you are looking for.
本文出自 Frank's Blog

版权声明:


本文链接:排障:Linux不转发流量
版权声明:本文为原创文章,仅代表个人观点,版权归 Frank Zhao 所有,转载时请注明本文出处及文章链接
你可以留言,或者trackback 从你的网站

留言哦

blonde teen swallows load.xxx videos