linux系统收到SYN但不回SYN+ACK问题排查

一,背景:

今天下午发现线上的一台机器从办公网登录不上且所有tcp端口都telnet不通,但是通过同机房的其它机器却可以正常访问到出问题的机器。于是就立即在这台出问题的server端抓包分析,发现问题如下:
server端收到了本地pc发的SYN包,但是没有回syn+ack包,所以确认是server端系统问题。tcpdump抓包如下:

二,排查

1,发现系统没有任何负载

2,网卡也没有丢包

3,iptables策略也都没问题

4,系统的SYN_RECV连接很少,也没超限

5,系统的文件描述符等资源也都没问题

6,messages和dmesg中没有任何提示或者错误信息

三,通过google来协助

发现有同样的人遇见这个问题:

是通过调整sysctl -w net.ipv4.tcp_timestamps=0或者sysctl -w net.ipv4.tcp_tw_recycle=0来解决这个问题,于是我就顺藤摸瓜继续查。

而在查询这两个参数的过程中,发现问题原因如下:

发现是 Linux tcp_tw_recycle/tcp_timestamps设置导致的问题。 因为在linux kernel源码中发现tcp_tw_recycle/tcp_timestamps都开启的条件下,60s内同一源ip主机的socket connect请求中的timestamp必须是递增的。经过测试,我这边centos6系统(kernel 2.6.32)和centos7系统(kernel 3.10.0)都有这问题。

    源码函数:kernel 2.6.32 tcp_v4_conn_request(),该函数是tcp层三次握手syn包的处理函数(服务端);
    源码片段:
       if (tmp_opt.saw_tstamp &&
            tcp_death_row.sysctl_tw_recycle &&
            (dst = inet_csk_route_req(sk, req)) != NULL &&
            (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
            peer->v4daddr == saddr) {
            if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
                (s32)(peer->tcp_ts - req->ts_recent) >
                            TCP_PAWS_WINDOW) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
                goto drop_and_release;
            }
        }
        
        tmp_opt.saw_tstamp:该socket支持tcp_timestamp
        sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项
        TCP_PAWS_MSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内
        TCP_PAWS_WINDOW:1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于 本次tcp

总结:

我这边和其它同事通过公司出口(NAT网关只有1个ip地址)访问问题server,由于timestamp时间为系统启动到当前的时间,故我和其它同事的timestamp肯定不相同;根据上述SYN包处理源码,在tcp_tw_recycle和tcp_timestamps同时开启的条件下,timestamp大的主机访问serverN成功,而timestmap小的主机访问失败。并且,我在办公网找了两台机器可100%重现这个问题。

解决:

# echo "0" > /proc/sys/net/ipv4/tcp_tw_recycle

四,扩展

1,net.ipv4.tcp_timestamps

tcp_timestamps的本质是记录数据包的发送时间。基本的步骤如下:

  1. 发送方在发送数据时,将一个timestamp(表示发送时间)放在包里面
  2. 接收方在收到数据包后,在对应的ACK包中将收到的timestamp返回给发送方(echo back)
  3. 发送发收到ACK包后,用当前时刻now - ACK包中的timestamp就能得到准确的RTT

当然实际运用中要考虑到RTT的波动,因此有了后续的(Round-Trip Time Measurement)RTTM机制。

TCP Timestamps Option (TSopt)具体设计如下

Kind: 8             // 标记唯一的选项类型,比如window scale是3
Length: 10 bytes    // 标记Timestamps选项的字节数
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
| Kind=8 | Length=10 | TS Value (TSval) | TS ECho Reply (TSecr) |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
   1          1             4                       4

timestamps一个双向的选项,当一方不开启时,两方都将停用timestamps。比如client端发送的SYN包中带有timestamp选项,但server端并没有开启该选项。则回复的SYN-ACK将不带timestamp选项,同时client后续回复的ACK也不会带有timestamp选项。当然,如果client发送的SYN包中就不带timestamp,双向都将停用timestamp。

tcp数据包中timestamps的value是系统开机时间到现在时间的(毫秒级)时间戳。

参数:

0:停用

1:启用

2,net.ipv4.tcp_tw_recycle

TCP规范中规定的处于TIME_WAIT的TCP连接必须等待2MSL时间。但在linux中,如果开启了tcp_tw_recycle,TIME_WAIT的TCP连接就不会等待2MSL时间(而是rto或者60s),从而达到快速重用(回收)处于TIME_WAIT状态的tcp连接的目的。这就可能导致连接收到之前连接的数据。为此,linux在打开tcp_tw_recycle的情况下,会记录下TIME_WAIT连接的对端(peer)信息,包括IP地址、时间戳等。这样,当内核收到同一个IP的SYN包时,就会去比较时间戳,检查SYN包的时间戳是否滞后,如果滞后,就将其丢掉(认为是旧连接的数据)。这在绝大部分情况下是没有问题的,但是对于我们实际的client-server的服务,访问我们服务的用户一般都位于NAT之后,如果NAT之后有多个用户访问同一个服务,就有可能因为时间戳滞后的连接被丢掉。

参数:

0:停用

1:启用

参考:

https://serverfault.com/questions/235965/why-would-a-server-not-send-a-syn-ack-packet-in-response-to-a-syn-packet

http://hustcat.github.io/tcp_tw_recycle-and-tcp_timestamp/

时间: 2024-10-29 10:46:12

linux系统收到SYN但不回SYN+ACK问题排查的相关文章

Linux系统-抵御SYN洪水攻击

本文源链接地址:https:www.93bok.com 说明: 本文中所提到的这些内核配置参数应该在每台服务器上线之前配置好的,防止意外. SYN攻击: SYN攻击是利用TCP/IP协议3次握手的原理,发送大量的建立连接的网络SYN包,但不实际建立连接,最终导致被攻击服务器的网络队列被占满,无法被正常用户访问. 原理图: 正常情况下TCP三次握手: SYN攻击情况: SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送

桌面Linux系统的先驱者慕尼黑现在正在考虑切换回Windows

From: http://arstechnica.com/business/2014/08/linux-on-the-desktop-pioneer-munich-now-considering-a-switch-back-to-windows/ 市政府称,用户不满意Linux的成本高于预期. 世界仍然在等待的Linux桌面这一年的到来,但在2003年看起来好像是可以实现的这个目标. 当时,慕尼黑市宣布计划将属于市政府的14000台PC从微软的技术切换到Linux. 虽然该计划遭到推迟 ,它于2

Linux系统如何装回Windows系统

直接插上制作的WindowsU盘启动,到选择安装到哪个磁盘时,Windows无法识别Linux的磁盘格式ext4. 解决办法是: 选中驱动器,点击下面的删除按钮,重新分区即可,最多好像只能分4个区. 装好系统后,除系统盘之外的盘需要重新格式化. Linux系统如何装回Windows系统,布布扣,bubuko.com

确认Linux系统是否收到和响应ping包

简单说就是发现某系统无法被ping通,需要确认是服务器收到了ping包没有响应,还是它压根没有收到ping包 在Linux系统上执行以下命令 tcpdump -i eth0 icmp -i:指定检测哪个网口,不指定此参数将捕获所有接口数据,包括lo: #-v:显示详细信息,可选,对于上述问题来讲,不加-v也能完成,且输出格式更整齐: icmp:ping包走icmp协议,这个不用解释了吧 执行命令后,查看是否有request和reply.如下: [[email protected] ~]# tcp

linux系统下解决getch()输入数值不回显示

在linux系统下开发C 程序却会遇到系统不支持conio.h头文件,无法使用getch()不回显函数.下面就演示如何构建函数实现数值输入不回显. 1 #include <stdio.h> 2 3 #include <termios.h> 4 5 #include <unistd.h> 6 7 #include <errno.h> 8 9 #define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL) 10 11 //函数

高并发情况下Linux系统及kernel参数优化

众所周知在默认参数情况下Linux对高并发支持并不好,主要受限于单进程最大打开文件数限制.内核TCP参数方面和IO事件分配机制等.下面就从几方面来调整使Linux系统能够支持高并发环境. Iptables相关 如非必须,关掉或卸载iptables防火墙,并阻止kernel加载iptables模块.这些模块会影响并发性能. 单进程最大打开文件数限制 一般的发行版,限制单进程最大可以打开1024个文件,这是远远不能满足高并发需求的,调整过程如下: 在#号提示符下敲入: # ulimit–n 6553

Linux系统运维常见面试题汇总

一.填空题 1.?在Linux?系统 中,以文件方式访问设备 . 2. Linux?内核引导时,从文件/etc/fstab中读取要加载的文件系统 . 3. Linux?文件系统中每个文件用indoe节点来标识. 4.?全部磁盘块由四个部分组成,分别为引导块?.专用块?.?i?节点表块?和?数据存储块?. 5.?链接分为:硬链接?和?符号链接?. 6.?超级块包含了i?节点表?和?空闲块表?等重要的文件系统信息. 7.?某文件的权限为:d-rw-_r--_r--,用数值形式表示该权限,则该八进制数

Linux系统安全及应用

实验案例 某公司新增了一台企业级服务器,已安装运行RHEL6操作系统,由系统运维部.软件开发部.技术服务部共同使用.由于用户数量众多,且使用时间不固定,要求针对账号和登录过程采取基本的安全措施. 需求描述 1.允许用户radmin使用su命令进行切换,其他用户一律禁止切换身份. 2.授权用户zhangsan管理所有员工的账号,但禁止其修改root用户的信息. 3.授权用户lisi能够执行/sbin./usr/sbin目录下的所有特权命令,不需要密码验证. 4.所有的su.sudo操作,必须在系统

linux系统瓶颈分析(精)

linux系统瓶颈分析(精) (2013-09-17 14:22:00)   分类: linux服务器瓶颈分析 1.0 性能监控介绍 性能优化就是找到系统处理中的瓶颈以及去除这些的过程,多数管理员相信看一些相关的"cook book"就 可以实现性能优化,通常通过对内核的一些配置是可以简单的解决问题,但并不适合每个环境,性能优化其实 是对OS 各子系统达到一种平衡的定义,这些子系统包括了: CPU Memory IO Network 这些子系统之间关系是相互彼此依赖的,任何一个高负载都