文章目录
前言
昨天萌新学习了net.ipv4.ip_local_port_range参数的作用,今天再来学习一下net.ipv4.tcp_tw_reuse
这个参数。
下面是萌新测试环境的系统和内核版本
# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
# uname -a
Linux sd02 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
准备工作
由于这次需要修改服务器端的配置,所以不能白嫖了,萌新准备了2台测试机器
- 服务器: sd01
- 客户端: sd02
将客户端(sd02) net.ipv4.ip_local_port_range
这个参数按照昨天的文章修改为60001 60002。
sd01的配置
sd02的配置
开始测试
关闭net.ipv4.tcp_tw_reuse
先在sd02使用nc
命令创建两个连接
使用ss
命令查看,发现这两个连接目前处于ESTAB状态
刚刚使用nc
命令创建的两个连接目前都在后台,使用fg
命令将一个调到前台,并用ctrl + c
终止
然后我们再用ss
命令观察一下,发现这目前这两个连接已经有一个处于TIME-WAIT状态了
再使用nc
命令创建一个连接,发现创建失败,提示Cannot assign requested address.
可以看到在关闭net.ipv4.tcp_tw_reuse
的情况下,是不能重复利用TIME_WAIT的,需要等待TIME_WAIT自己关闭,并且TIME_WAIT的时间不能通过参数进行配置,如果修改的话,需要自己编译内核。
萌新通过测试,发现客户端关闭TCP连接后,需要在TIME_WAIT阶段大概54-55秒。
打开net.ipv4.tcp_tw_reuse
下面我们将客户端(sd02)的net.ipv4.tcp_tw_reuse
打开
vim /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
使其立即生效
sysctl -p
验证一下,发现确实已经打开了
下面我们使用nc
命令创建两个连接
使用fg
命令将一个连接调到前台,然后关闭,再使用nc
创建一个连接,发现创建成功了
使用ss
命令看一下,果然刚刚关闭的那个连接没有TIME_WAIT了,现在的两个连接都处于ESTAB状态
关闭客户端的net.ipv4.tcp_timestamps
在客户端(sd02)上关闭net.ipv4.tcp_timestamps
vi /etc/sysctl.conf
net.ipv4.tcp_timestamps = 0
sysctl -p
使用nc
命令创建两个连接
然后结束一个连接
看到现在有两个连接一个处于ESTAB状态,另一个处于TIME-WAIT状态
使用nc
命令创建一个连接
发现果然不行,提示Cannot assign requested address.
关闭服务器端的net.ipv4.tcp_timestamps
先将客户端(sd02)的net.ipv4.tcp_timestamps
打开
vi /etc/sysctl.conf
net.ipv4.tcp_timestamps = 1
sysctl -p
然后将服务器(sd01)的net.ipv4.tcp_timestamps
关闭
vi /etc/sysctl.conf
net.ipv4.tcp_timestamps = 0
sysctl -p
使用nc
命令创建两个连接
使用ss
命令观察,看到有两个处于ESTAB
状态的连接
关闭一个连接
看到有一个连接已经处于TIME-WAIT
状态了
再用nc
命令创建一个连接,发现提示Cannot assign requested address.
reuse的握手过程和正常握手是一样的吗?
先在sd02上使用tcpdump抓一下包
在sd02上使用ping
命令ping一下服务器(sd01),使用-s 1
指定一下包的大小为1,这样可以一会区分抓的包,然后使用nc
命令创建两个连接
看到目前两个连接都处于ESTAB状态
结束一个连接
然后在用ping
命令ping一下sd01,这次使用-s 2
指定包大小为2字节,然后再用nc
创建一个连接
好了,接下来我们用wireshark看一下抓到的包
30607、30608、30609这三个包为第三个TCP连接的三次握手过程,wireshark还非常智能的帮我们标注了一下正在重新使用TCP端口(TCP Port numbers reused)。
可以看到除此之外reuse和正常的TCP连接没什么区别,即使是reuse也要经历正常的三次握手。
总结
开启net.ipv4.tcp_tw_reuse
可以复用TIME_WAIT的连接,但是要求服务器与客户端都必须开启net.ipv4.tcp_timestamps
。
这也是为了保证安全性,假如说没有net.ipv4.tcp_timestamps
,当连接被复用后,如果这时候有延迟或者重发的数据包到达,新的连接就无法判断数据包属于复用前的连接还是复用后的连接了。
所以需要客户端与服务器双方都开启net.ipv4.tcp_timestamps
。