首先说明下面三个和keepalive相关的内核参数以及默认的值
# sysctl -a | grep keepalive
# 在会后一次发送数据包后多久向对方发起探测
net.ipv4.tcp_keepalive_time = 7200
# 在没有收到对方确认时,会按照这个时间间隔再次探测
net.ipv4.tcp_keepalive_intvl = 75
# 在没有收到对方确认时,进行探测的次数
net.ipv4.tcp_keepalive_probes = 9
下面通过在本地环境上测试这些参数,首先将本地的默认keepalive参数进行修改
# sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 20
下载并编译带keepalive功能支持的netcat命令行工具
git clone https://github.com/cyberelf/netcat-keepalive.git
cd netcat-keepalive/
make linux
运行tcpdump进行抓包
tcpdump -iany port 18888
启动服务端监听
./nckl-linux -v4K -l 18888
使用nc去连接
nc -v -p55666 localhost 18888
可以看到抓包内容如下
root@debian:/home/blue# tcpdump -iany port 18888
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
15:42:49.840078 IP localhost.55666 > localhost.18888: Flags [S], seq 4147250120, win 65495, options [mss 65495,sackOK,TS val 3777822786 ecr 0,nop,wscale 7], length 0
15:42:49.840104 IP localhost.18888 > localhost.55666: Flags [S.], seq 2015925109, ack 4147250121, win 65483, options [mss 65495,sackOK,TS val 3777822786 ecr 3777822786,nop,wscale 7], length 0
15:42:49.840124 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777822786 ecr 3777822786], length 0
# 这里三次握手结束并且在客户端发送了一个字符
15:42:50.991399 IP localhost.55666 > localhost.18888: Flags [P.], seq 1:4, ack 1, win 512, options [nop,nop,TS val 3777823937 ecr 3777822786], length 3
15:42:50.991421 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777823937 ecr 3777823937], length 0
# 从这里开始下面是每隔20秒钟进行一次探测
15:43:11.005311 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777843951 ecr 3777823937], length 0
15:43:11.005343 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777843951 ecr 3777823937], length 0
15:43:31.101311 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777864047 ecr 3777843951], length 0
15:43:31.101346 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777864047 ecr 3777823937], length 0
15:43:51.325306 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777884271 ecr 3777864047], length 0
15:43:51.325328 IP localhost.55666 > localhost.18888: Flags [.], ack 1, win 512, options [nop,nop,TS val 3777884271 ecr 3777823937], length 0
# 在这里执行了一个iptables -A INPUT -p tcp --dport 55666 -j DROP命令,可以看到在没有收到对方应答的情况下会每隔5秒进行一次探测,连续9次没有收到应答,操作系统重置了这个连接
15:44:11.549314 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777904495 ecr 3777884271], length 0
15:44:16.669304 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777909615 ecr 3777884271], length 0
15:44:21.789312 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777914735 ecr 3777884271], length 0
15:44:26.909310 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777919855 ecr 3777884271], length 0
15:44:32.029305 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777924975 ecr 3777884271], length 0
15:44:37.149314 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777930095 ecr 3777884271], length 0
15:44:42.269309 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777935215 ecr 3777884271], length 0
15:44:47.389304 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777940335 ecr 3777884271], length 0
15:44:52.509319 IP localhost.18888 > localhost.55666: Flags [.], ack 4, win 512, options [nop,nop,TS val 3777945455 ecr 3777884271], length 0
15:44:57.629320 IP localhost.18888 > localhost.55666: Flags [R.], seq 1, ack 4, win 512, options [nop,nop,TS val 3777950575 ecr 3777884271], length 0