最後更新: 2019-12-03
介紹
TIME_WAIT 的用圖
- ensure the remote end has closed the connection
- "TIME_WAIT" purpose is to make sure any lost packets that arrive after a connection is closed do not confuse the TCP subsystem
- prevent delayed segments
Linux will reuse an existing connection in the TIME-WAIT state for a new outgoing connection
if the new timestamp is strictly bigger than the most recent timestamp recorded for the previous connection:
an outgoing connection in the TIME-WAIT state can be reused after just one second.
過程
主動關閉連接的一方
ESTABLISHED fin --> ack <-- FIN_WAIT_2 fin <-- ack --> TIME_WAIT
* 主動一方最終會進入 "TIME_WAIT" 狀態 (2 MSL 後 -> CLOSED 狀態)
被動關閉連接的一方
ESTABLISHED fin <-- CLOSE_WAIT ack --> App 處理 close() fin --> LAST_ACK ack <-- CLOSED
* 被動一方會有一段時間在 "CLOSE_WAIT"
Checking
netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
1 CLOSING 1 established) 1 Foreign 2 SYN_RECV 4 FIN_WAIT1 11 LISTEN 17 ESTABLISHED 1232 TIME_WAIT
被攻擊時引起的問題:
* the slot taken in the connection table preventing new connections of the same kind,
* the memory occupied by the socket structure in the kernel
Linux Setting
tcp_fin_timeout
# Default: 60
net.ipv4.tcp_fin_timeout=30
check
cat /proc/sys/net/ipv4/tcp_fin_timeout
This basically means your system cannot guarantee more than ((61000 - 32768) / 60 = 470) ports at any given time.
ipv4.tcp_tw_reuse (client side)
# Allow to reuse TIME-WAIT sockets for new connections when it is safe from protocol viewpoint.
# not recommended since this causes problems when working with NAT
net.ipv4.tcp_tw_reuse = 0
The first purpose of the TIME-WAIT state was to avoid duplicate segments to be accepted in an unrelated connection.
(duplicate segments will come with an outdated timestamp and therefore be discarded)
The second purpose was to ensure the remote end is not in the LAST-ACK state
The remote end will retransmit the FIN segment until:
it gives up (and tear down the connection), or
it receives the ACK it is waiting (and tear down the connection), or
it receives a RST (and tear down the connection)
i.e.
cat /proc/sys/net/ipv4/tcp_tw_reuse
setting:
sysctl -w net.ipv4.tcp_tw_reuse="1"
ipv4.tcp_tw_recycle
# This enables fast recycling of TIME_WAIT sockets.
# I wouldn't recommend using net.ipv4.tcp_tw_recycle as it causes problems with NAT clients
# affects both incoming and outgoing connections (reuse a socket if the timestamp has correctly increased)
# reducing the expiration timer (re-use the socket after retransmission timeout (RTO) interval)
net.ipv4.tcp_tw_recycle = 1
Find rto
ss --info sport = :2112 dport = :4057
i.e.
cat /proc/sys/net/ipv4/tcp_tw_recycle
ip_local_port_range
# 用於向外連接的端口範圍; Default: 32768 61000
# Checking
sysctl -n net.ipv4.ip_local_port_range
tcp_max_tw_buckets
# "TIME_WAIT" 的最大數量; Default: 4096
# Checking
sysctl -n net.ipv4.tcp_max_tw_buckets
Remark
RFC 1323 - it defines a new TCP option carrying two four-byte timestamp fields.