linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查

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


client端抓包:
有发送,服务端回的都是R 重置
[root@localhost ~]# tcpdump -vv host 1.1.1.1
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:56:47.156700 IP (tos 0x10, ttl 64, id 58127, offset 0, flags [DF], proto TCP (6), length 60)
10.10.18.161.59860 > 1.1.1.1.ftp: Flags [S], cksum 0xda7b (correct), seq 2448459144, win 14600, options [mss 1460,sackOK,TS val 4000933511 ecr 0,nop,wscale 7], length 0
14:56:48.156592 IP (tos 0x10, ttl 64, id 58128, offset 0, flags [DF], proto TCP (6), length 60)
10.10.18.161.59860 > 1.1.1.1.ftp: Flags [S], cksum 0xd693 (correct), seq 2448459144, win 14600, options [mss 1460,sackOK,TS val 4000934511 ecr 0,nop,wscale 7], length 0
14:56:53.881707 IP (tos 0x0, ttl 252, id 63006, offset 0, flags [DF], proto TCP (6), length 40)
1.1.1.1.ftp > 10.10.18.161.59860: Flags [R.], cksum 0xd054 (correct), seq 0, ack 2448459145, win 0, length 0

14:58:57.481680 IP (tos 0x10, ttl 64, id 25165, offset 0, flags [DF], proto TCP (6), length 60)
10.10.18.161.56634 > 1.1.1.1.rsync: Flags [S], cksum 0x8df0 (correct), seq 1851916753, win 14600, options [mss 1460,sackOK,TS val 4001063836 ecr 0,nop,wscale 7], length 0
14:58:58.481605 IP (tos 0x10, ttl 64, id 25166, offset 0, flags [DF], proto TCP (6), length 60)
10.10.18.161.56634 > 1.1.1.1.rsync: Flags [S], cksum 0x8a08 (correct), seq 1851916753, win 14600, options [mss 1460,sackOK,TS val 4001064836 ecr 0,nop,wscale 7], length 0
14:59:08.587051 IP (tos 0x0, ttl 252, id 14708, offset 0, flags [DF], proto TCP (6), length 40)
1.1.1.1.rsync > 10.10.18.161.56634: Flags [R.], cksum 0x80e0 (correct), seq 0, ack 1851916754, win 0, length 0

server端抓包
只能收到类似下面的发过来的包,没有响应包
# tcpdump -n -vv -i eth0 tcp port 21
00:04:43.585345 IP (tos 0x14, ttl 47, id 50536, offset 0, flags [DF], proto TCP (6), length 52)
121.15.134.170.32581 > 172.18.54.135.ftp: Flags [F.], cksum 0x341d (correct), seq 1, ack 77, win 58, options [nop,nop,TS val 4071735193 ecr 877988392], length 0
00:04:43.585457 IP (tos 0x0, ttl 64, id 17336, offset 0, flags [DF], proto TCP (6), length 52)
172.18.54.135.ftp > 121.15.134.170.32581: Flags [.], cksum 0xe279 (incorrect -> 0xd9f8), seq 77, ack 2, win 57, options [nop,nop,TS val 878011469 ecr 4071735193], length 0
00:04:43.585489 IP (tos 0x0, ttl 64, id 17337, offset 0, flags [DF], proto TCP (6), length 52)
172.18.54.135.ftp > 121.15.134.170.32581: Flags [F.], cksum 0xe279 (incorrect -> 0xd9f7), seq 77, ack 2, win 57, options [nop,nop,TS val 878011469 ecr 4071735193], length 0
00:04:43.591892 IP (tos 0x14, ttl 47, id 12870, offset 0, flags [DF], proto TCP (6), length 52)
121.15.134.170.32581 > 172.18.54.135.ftp: Flags [.], cksum 0xd9f0 (correct), seq 2, ack 78, win 58, options [nop,nop,TS val 4071735199 ecr 878011469], length 0

二,排查

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

2,网卡也没有丢包

3,iptables策略也都没问题

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

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

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

7,通过netstat命令查看系统上协议统计信息,发现很多请求由于时间戳的问题被rejected

# netstat -s |grep reject
2092 passive connections rejected because of time stamp
1506 packets rejects in established connections because of timestamp

三,通过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的本质是记录数据包的发送时间。基本的步骤如下:

发送方在发送数据时,将一个timestamp(表示发送时间)放在包里面

接收方在收到数据包后,在对应的ACK包中将收到的timestamp返回给发送方(echo back)

发送发收到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/

原文地址:https://blog.51cto.com/leejia/1954628

# 配置记录
[root@sz_cc_cbs_download01:~]# cat /etc/sysctl.conf
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.

# Controls IP packet forwarding
net.ipv4.ip_forward = 0

# Controls source route verification
net.ipv4.conf.default.rp_filter = 1

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0

# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Disable netfilter on bridges.
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

# Controls the maximum size of a message, in bytes
kernel.msgmnb = 65536

# Controls the default maxmimum size of a mesage queue
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296

net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.rmem_max = 16777216
net.core.rmem_default = 8388608
net.core.wmem_max = 16777216
net.core.wmem_default = 8388608

net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 8192 436600 873200
net.ipv4.tcp_wmem = 8192 436600 873200
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
#net.ipv4.tcp_max_orphans = 32768

net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_retries2 = 5
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10

net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15

net.ipv4.ip_local_port_range = 1024 65500
net.ipv4.tcp_max_syn_backlog = 16384
#net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_max_tw_buckets = 18000

net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 3
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_abort_on_overflow = 1

net.netfilter.nf_conntrack_max = 65530
net.nf_conntrack_max = 655300
net.netfilter.nf_conntrack_tcp_timeout_established = 1200

vm.swappiness= 5

#########

tcp_tw_recycle和tcp_timestamps     注意:VPC 中,这二个参数只能打开一个,即这两个参数的值一般只能tcp_timestamps  设置为1

linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查(转载)的更多相关文章

  1. Linux 系统Telnet服务

    Linux 系统Telnet服务 telnet与ssh相比,安全性能并不高,但是在ssh版本升级或者其他的情况下还是需要开启这一项服务.linux提供服务是由运行在后台的守护进程daemon来执行的, ...

  2. 大神教你如何解决Linux系统80端口被占用

    有Linux在centos下面安装webmail服务遇到80端口被占用的问题,导致无法继续安装,下面详细介绍下Linux如何查看.查找.关闭监听80端口服务以更好的的解决80端口被占用的问题. 一.查 ...

  3. 解决Linux系统80端口被占用的问题

    有Linux在centos下面安装webmail服务遇到80端口被占用的问题,导致无法继续安装,下面详细介绍下Linux如何查看.查找.关闭监听80端口服务以更好的的解决80端口被占用的问题. 一.查 ...

  4. Linux系统根据端口号来查看其进程并杀死进程

    1.首先是查看某个端口号,(以httpd服务为例) 2.查看此端口下进程以及进程号 3.我们使用awk命令过滤出第二列,即进程号 4.杀死进程 报错的这一行表示,要杀死的进程PID为3754,但是没有 ...

  5. Redis linux 外部telnet访问不通

    外部访问不通: 1.修改redis.conf中的daemonize的值设为no: 2.修改redis.conf中的bind的值127.0.0.1为linux本身的ip地址,如192.168.1.120

  6. Linux系统443端口被占用无法启动解决办法

    etstat -ano|findstr "443"         //搜索443端口占用情况,并找到进程IDTCP 0.0.0.0:443 0.0.0.0:0 LISTENING ...

  7. 类linux 系统上端口被占用

    好几次遇到这问题,明明Ctrl+C退出了node,但是下次启动的时候总是会报错: listen EADDRINUSE :::80 之类的. 这时候可能是被占用,也可能是上次进程没有真的退出. ps - ...

  8. Linux 系统开启随机端口数量 调优

    Linux系统随机端口 默认Linux系统开启的随机端口范围为 32768 ~ 65535.客户端连接服务监听端口需要使用到随机端口连接. Linux系统随机端口调优 1.添加内核配置参数:/etc/ ...

  9. Linux系统安装后IP能通端口不通的问题处理方法

    网上大部分都是针对防火墙的问题,这里首先排除防火防火墙导致端口不通的问题! 1.排除防火墙问题(防火墙的排查方式网上一搜全是,这里不再赘述) 2.查看检查端口有没有监听,发现端口未监听(比如8080端 ...

随机推荐

  1. SpringBoot -生成Entity和Dto互转的双向枚举类 -使用注解@Mapper(componentModel = "spring")

    1.导入pom文件 ,版本号自定 <!--mapStruct依赖--> <dependency> <groupId>org.mapstruct</groupI ...

  2. mysql占用内存过高调优方法

    最近测试一个站点,用mysql 5.6+mencache  内存16GB,但是进行查询的时候还是导致CPU占用过高,达到80%左右,所以想办法如何进行调优.以下几个参数进行参考选择 优化mysql数据 ...

  3. 物体检测方法(1) - YOLO 详解

    最近遇到一些卡证识别的检测问题,打算先把理论知识梳理一下,随后还会梳理一版代码注释. 以前的region+proposal来检测的框架,这一系列速度和精度不断提高,但是还是无法达到实时.存在的主要问题 ...

  4. 性能测试解读:Kyligence vs Spark SQL

    全球各种大数据技术涌现的今天,为了充分利用大量数据获得竞争优势,企业需要高性能的数据分析平台,可靠并及时地提供对海量数据的分析见解.对于数据驱动型企业,在海量数据上交互式分析的能力是非常重要的能力之一 ...

  5. 鼠标经过提高层级案例(margin,相对定位,z-index)

    <body> <ul> <li class="box1">1</li> <li class="box2"& ...

  6. Tyvj P2044 ["扫地"杯III day2]旅游景点

    二次联通门 : Tyvj P2044 ["扫地"杯III day2]旅游景点 /* Tyvj P2044 ["扫地"杯III day2]旅游景点 并查集 先把大 ...

  7. CF891C Envy(离线/在线+可撤销并查集/并查集/LCT)

    前置知识 最小生成树及证明 做法 每个不同权值没影响,仅需判断该次询问每种权值是否在"小于该权值的所有边加完"之后,可以全部加进来 离线:询问的所有边全堆到一起,按权值排序,然后同 ...

  8. 数据库blob图片文件,多图片打包下载

    数据库存储blob图片文件,前端打包下载 数据库图片文件实体类 package com.cmrh.mspserver.pos.dto; import java.io.Serializable; imp ...

  9. 三大框架 之 Hibernate查询(一对多、多对多、查询关系)

    目录 一对多 表之间关系 表之间关系建表原则 一对多关系配置 建立表 建立ORM 添加配置文件 在hibernate.cfg.xml中的标签里,添加核心配置文件 引入工具类 编写测试类 级联操作 什么 ...

  10. DELPHI LINUX中间件隆重发布

    LINUX和WINDOWS是目前最流利的两个服务器操作系统,各种云服务商也是同时提供这2种操作系统的云服务器. 即日起,在原有WINDOWS中间件的产品基础上,再隆重推出新产品:LINUX中间件.这样 ...