TCP/IP 协议与排查

共 17 题
📑 题目列表 17 题
#
★★★

1. PMTUD 依赖 ICMP 不可达消息,遇到 ICMP 黑洞时如何排查与规避?

路径 MTU 发现(PMTUD)依赖 ICMP 不可达消息,遇到 ICMP 黑洞时如何排查与规避?

  • PMTUD 用 IP 头 DF 标志 + ICMP "分片丢弃"消息发现路径 MTU
  • ICMP 黑洞:防火墙丢弃 ICMP 不可达导致大包静默丢失
  • 排查:tcpdump 看 ICMP、降低 MTU 测试、ping -M do 探测

PMTUD 通过发送带 DF(Don't Fragment)标志的包,若中间设备需要分片则回 ICMP "Packet Too Big",发送方据此降低 MTU。但很多防火墙/安全策略会丢弃 ICMP 不可达消息,形成 ICMP 黑洞,导致大包静默丢弃、连接超时或卡住。排查:用 tcpdump -i any icmp 抓 ICMP 不可达,用 ping -M do -s 1400 逐级探测可用 MTU,对比不同大小是否通。规避:在 Linux 上设置 ip link set mtu 1400 或全局 net.ipv4.tcp_mtu_probing=1;在代理/网关用 tcp mss 固定 MSS(如 Nginx tcp_nodelay 配合 MSS clamp),使 TCP 不依赖 PMTUD 也能工作。

ICMP 黑洞的本质是"PMTUD 依赖的 ICMP 被丢弃"。规避路径是"不依赖 ICMP"——要么固定 MSS 让 TCP 用足够小的分段,要么开启 tcp_mtu_probing 主动探测。

# 排查 ICMP 不可达
tcpdump -i eth0 icmp
# 探测路径 MTU
ping -M do -s 1472 10.0.0.1
# 规避:固定 MSS / 开启 MTU 探测
ip link set eth0 mtu 1400
sysctl net.ipv4.tcp_mtu_probing=1
#
★★★

2. TIME_WAIT 大量堆积的成因与对 listen 端口的影响

TIME_WAIT 大量堆积的成因是什么?对 listen 端口有何影响?

  • TIME_WAIT 出现在主动关闭方,2MSL 消失
  • 成因:大量短连接(频繁连接关闭)、高并发请求
  • 影响:端口可重用性、连接表占用、对新建连接的影响

TIME_WAIT 是主动关闭连接的一方在收到 FIN 后进入的状态,持续 2MSL(约 60s),用于保证后发的 ACK 不被重放在新连接上。大量堆积的成因是高频短连接——每个请求都建立并关闭 TCP 连接,尤其在高并发代理/网关场景。TIME_WAIT 本身不占用 listen 端口,但会占用本地端口(四元组),可能耗尽可用源端口导致新连接失败;同时占用连接表内存。缓解:启用连接复用(HTTP keepalive、Nginx upstream keepalive)减少关闭次数,调整 net.ipv4.tcp_fin_timeout(影响 FIN_WAIT 而非 TIME_WAIT 的 2MSL),必要时 tcp_tw_reuse(仅出站连接)或调大 net.ipv4.ip_local_port_range

TIME_WAIT 是协议正确性需要的状态,不能简单清零。影响主要是"源端口耗尽"与"资源占用",根治靠减少连接关闭(复用)而非粗暴调参。

ss -tan state time-wait | wc -l          # 统计 TIME_WAIT
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl net.ipv4.tcp_fin_timeout=15
#
★★★

3. openssl s_client 如何测试 TLS 握手并查看证书链与协议版本?

如何用 openssl s_client 测试 TLS 握手并查看证书链与协议版本?

  • openssl s_client 连接指定主机端口建立 TLS 会话
  • -showcerts 查看完整证书链,-servername 指定 SNI
  • 输出中的协议版本、密码套件、证书签名

openssl s_client -connect host:443 -servername host 建立 TLS 连接并输出握手信息。-showcerts 展示完整证书链(含中间证书),-servername 指定 SNI(多证书时必须),-brief 缩短输出,-tls1_2/-tls1_3 指定协议版本,-verify_quiet 关闭证书校验的冗长输出。输出中 "New, TLSv1.3" 表示协议版本,"Cipher is ..." 表示协商的套件,"Certificate chain" 展示证书链,可检查证书是否过期、链是否完整、SAN 是否匹配。用 -tlsextdebug 查看扩展。大量证书链问题时,可配合 openssl x509 -text 转储证书详情。

s_client 是 TLS 排障的"瑞士军刀",重点看协议版本、套件、证书链三段。SNI 与显式指定版本是排查多证书与版本不兼容的关键。

openssl s_client -connect example.com:443 -servername example.com -showcerts
openssl s_client -connect example.com:443 -tls1_3 -brief
openssl s_client -connect example.com:443 -servername example.com </dev/null \
  | openssl x509 -noout -subject -issuer -dates
#
★★

4. TCP 建连慢与握手失败的排查中 SYN 重传、窗口缩放协商与拥塞控制算法选择如何逐层定位

TCP 建连慢与握手失败如何逐层排查(SYN 重传、窗口缩放协商、拥塞控制算法)?

  • SYN 丢包/重传导致建连慢,抓包看 SYN/SYN-ACK
  • 窗口缩放(window scaling)协商影响吞吐
  • 拥塞控制算法(cubic/BBR)影响延迟与吞吐

建连慢先抓包看是否有 SYN 重传:tcpdump -i any 'tcp[tcpflags] & tcp-syn != 0',若 SYN 重传多次说明 SYN 或 SYN-ACK 被丢,涉及防火墙、半连接队列溢出或路由。窗口缩放协商失败会使窗口被限制在 64KB,严重降低吞吐,检查 tcpdump -vv 中 Window Scale 值,确认双方一致。拥塞控制算法 cubic 与 BBR 对 RTT 与吞吐影响大,高带宽高延迟链路用 BBR 更优。逐层排查顺序:先看三层连通(ping)→ 四层握手(tcpdump SYN/FIN)→ 应用层(耗时)。结合 sysctl 调整 tcp_syncookies、syn backlog 等。

建连慢要区分"包是否到达"与"协商是否异常"。SYN 重传查丢包,窗口缩放查吞吐,拥塞控制查算法选择。抓包是定位握手问题的基础。

tcpdump -i any 'tcp[tcpflags] & (tcp-syn|tcp-ack) != 0' -nn
tcpdump -i any port 443 -vv   # 看 Window Scale
sysctl net.ipv4.tcp_syncookies=1
sysctl net.ipv4.tcp_synack_retries=2
#
★★

5. TCP_DEFER_ACCEPT 如何延迟 accept 直到收到数据?

TCP_DEFER_ACCEPT 如何延迟 accept 直到收到数据?

  • TCP_DEFER_ACCEPT 让内核延迟 accept 直到收到数据
  • 减少无数据连接的资源占用,防 SYN flood 空包
  • 应用场景:HTTP 等数据驱动的协议,防空连接与 SYN flood 空包

设置 TCP_DEFER_ACCEPT 后,内核在收到数据之前不会把连接从 accept 队列交给应用,从而避免"只握手不发数据"的空连接占用资源,常用于 HTTP 等以数据为最小单位的协议。它可减少建立连接但对业务无用的连接数,并抑制部分 SYN flood 攻击(空连接)。本质是内核在 accept 前等待数据,配合 tcp_defer_accept 超时,超时未收到数据则不发 ACK 或断开。注意依赖它判断"客户端是否发数据"可能与某些协议(如服务器主动推送)不兼容。

TCP_DEFER_ACCEPT 是"延迟到有数据才 accept"的优化,权衡是减少空连接 vs 改变 accept 语义。它让"只握手不传数据"的连接无法进入应用,降低资源浪费。

# 应用层(C)设置
setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &on, sizeof(on));
# 或系统级
sysctl net.ipv4.tcp_defer_accept=1
#
★★

6. TCP_QUICKACK 如何控制立即发送 ACK?

TCP_QUICKACK 如何控制立即发送 ACK?

  • TCP_QUICKACK 让套接字立即发送 ACK 而非延迟 ACK
  • 延迟 ACK(delayed ACK)与快速 ACK 的权衡
  • 应用场景:实时交互、减少 RTT 累积

Linux 默认开启延迟 ACK(delayed ACK),等最多 40ms 或攒够数据才回 ACK,以节省带宽。TCP_QUICKACK 选项让套接字立即回 ACK,降低交互延迟,适合对延迟敏感的应用。它通常与 TCP_NODELAY(禁用 Nagle)配合,避免"Nagle 攒发送 + 延迟 ACK 攒应答"造成的 40ms 级延迟叠加。注意该选项是"一次性"的,内核可能在某次数据后恢复默认行为,需在需要时重新设置。运维上它与"小包 + 低延迟"场景相关,但也可能略增 ACK 开销。

QUICKACK 是"延迟 ACK 的开关对照组",权衡是延迟 vs 带宽。延迟 ACK 省包但增延迟,QUICKACK 反之。与 Nagle 配合是低延迟调优的常见组合。

# 应用层设置
setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &on, sizeof(on));
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
#
★★

7. ip link set mtu 如何实现 MTU 调整?

ip link set mtu 如何实现 MTU 调整?

  • ip link set 修改接口的 MTU 值
  • 语法与作用范围(单接口、持久化)
  • 调整后对分片/PMTUD/GRE 隧道的影响

ip link set dev eth0 mtu 1400 修改接口的最大传输单元,属于运行时变更,重启后失效。调整接口 MTU 后,该接口发送的 IP 包超过该值时会被分片(或触发 PMTUD),影响吞吐与兼容性。常见于 DHCP 网关 MTU 异常、隧道/PPPoE 场景(需减 8 字节开销)或需要规避 ICMP 黑洞时。持久化需写入网络配置:netplan 的 mtu: 1400、systemd-networkd 的 MTU=1400、ifcfg 的 MTU=1400。调整后可用 ip link show 验证,用 ping -M do 确认路径 MTU。

MTU 调整是"接口级"变更,影响的是该接口处理 IP 包的分片与 PMTUD 行为。运行时与持久化两种方式要区分,隧道场景需为封装开销预留空间。

ip link set dev eth0 mtu 1400
ip link show eth0
# netplan 持久化
# network:
#   ethernets:
#     eth0:
#       mtu: 1400
#
★★

8. tracepath 如何实现 MTU 路径发现?

tracepath 如何实现 MTU 路径发现?

  • tracepath 用 UDP 探测 + TTL 递增发现路径 MTU
  • 利用 PMTUD(ICMP fragmentation needed)逐段测 MTU
  • 与 traceroute 的差异(同时测 MTU)

tracepath 类似 traceroute,通过 TTL 递增的 UDP 包逐跳探测,但它同时利用 PMTUD 消息发现每跳的 MTU。它发送带 DF 标志的探测包,当中间设备因包过大回 ICMP "fragmentation needed" 时,tracepath 逐步降低探测包大小,从而确定每跳可用的路径 MTU。输出中每行显示 IP、RTT 与可达的 MTU。相比 traceroute 只测路径与延迟,tracepath 额外给出路径 MTU 信息,适合定位 MTU 黑洞与分片问题。它不需要 root 权限即可运行。

tracepath 的价值是"路径 + MTU 一站式探测"。它依赖 ICMP 不可达消息,若中间网络丢弃 ICMP(ICMP 黑洞)则无法正确测 MTU,需配合 ping -M do 验证。

tracepath 10.0.0.1
# 输出每跳 IP、RTT 与可用的路径 MTU
#

9. TCP 重传的抓包分析中 tcpdump 里重传、快速重传与乱序包如何识别以及丢包方向如何判定

如何在 tcpdump 中识别 TCP 重传、快速重传与乱序包,并判定丢包方向?

  • tcpdump -S 显示绝对序号,重传 = 相同序号重复出现
  • 快速重传:收到 3 个重复 ACK 后重传
  • 乱序包:接收序号小于期望序号

tcpdump -i any -nn -S(-S 显示绝对序号)抓包,重传表现为"同一序列号的数据段在一段时间内再次出现",且重传包往往带 RTO 时间间隔。快速重传表现为收到 3 个重复 ACK(同一 ACK 号重复 3 次)后立即重传,时间短于 RTO。乱序包表现为接收方收到的序号小于其期望的下一序号(即收到了比当前窗口更新的包)。丢包方向判定:若发送方频繁重传数据段,说明"数据→接收方"方向丢包;若接收方多次重传 ACK/FIN,则"ACK→发送方"方向丢包。结合 -ttt 看包间时间差能判断重传 RTO。

抓包分析的要点是"用序号对齐 + 用时间戳区分超时/快速重传"。重传看同一序号重复,快速重传看重复 ACK 数,乱序看序号跳变,丢包方向看谁在重传。

tcpdump -i any -nn -S 'tcp port 443' -ttt
# 观察相同 seq 重复出现(重传)、重复 ACK(快速重传)
#

10. net.ipv4.tcp_congestion_control 如何选择 TCP 拥塞控制算法?

net.ipv4.tcp_congestion_control 如何选择 TCP 拥塞控制算法?

  • 内核支持的拥塞控制算法列表与默认值
  • cubic 默认、bbr 高带宽长距离、reno 传统
  • 运行时修改与持久化

sysctl net.ipv4.tcp_congestion_control 查看/设置默认拥塞控制算法,sysctl net.ipv4.tcp_allowed_congestion_control 查看允许的算法。cubic 是 Linux 默认,适合普遍网络;bbr 基于瓶颈带宽与 RTT 探测,在高带宽高延迟或丢包场景吞吐更高、延迟更低;reno 是经典算法。修改用 sysctl net.ipv4.tcp_congestion_control=bbr,持久化写入 /etc/sysctl.conf。选择考量:cubic 兼容性好、bbr 在带宽大/丢包链路更优但可能对公平性有影响,需结合线路条件与实验验证。

拥塞控制算法决定"如何感知并响应网络拥塞"。cubic 看丢包,bbr 看带宽与 RTT,在丢包不敏感场景 bbr 更抗丢包。选择要根据链路特性并做 AB 对比。

sysctl net.ipv4.tcp_congestion_control
sysctl net.ipv4.tcp_congestion_control=bbr
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
#

11. traceroute 的工作原理(TTL 递增+ICMP/UDP 探测)与在路由环路、不对称路径排查中的应用

traceroute 的工作原理是什么?在路由环路与不对称路径排查中使用?

  • TTL 递增逐跳触发 ICMP Time Exceeded
  • 默认 UDP 探测,-I 用 ICMP,-T 用 TCP
  • 路由环路:TTL 耗尽前跳数剧增/超时

traceroute 通过递增 TTL 发送探测包,每经过一跳 TTL 减 1,TTL 归零时该路由器返回 ICMP "Time Exceeded",从而逐跳探测出到目标的路径。默认用 UDP 探测(高端口),-I 用 ICMP echo,-T 用 TCP SYN。路由环路表现为:跳数异常多、同一跳重复出现或 TTL 一直递增到超时仍不到目标。不对称路径表现为:去程与回程经过的跳不同(可用 traceroute 与反向 traceroute 对比,或 traceroute -I-T 对比),常用于排查黑洞、丢包方向与路由策略问题。

traceroute 的核心是"TTL 递减 + ICMP Time Exceeded"。环路看跳数异常,不对称看往返路径差异。注意它依赖 ICMP,被丢弃时输出 *

traceroute -n 10.0.0.1
traceroute -I -n 10.0.0.1
traceroute -T -n -p 443 example.com
#

12. 带宽与延迟测量工具中 iperf3 的 TCP/UDP 双向测试与 ping 的 RTT/丢包率如何组合评估链路质量

如何用 iperf3 与 ping 组合评估链路质量(带宽与延迟)?

  • iperf3 服务器/客户端模式测 TCP 与 UDP 吞吐
  • 双向测试 -R、多流 -P、UDP 的 -b 与丢包/jitter
  • ping 测 RTT 与丢包率

iperf3 以 -s 起服务端、-c 起客户端,测 TCP 吞吐;-R 反向测试、-P 多流并发、-u 测 UDP(-b 指定带宽,可测丢包与 jitter)。ping 测 RTT、抖动与丢包率,ping -f 可测丢包。组合评估:带宽能力用 iperf3 的 TCP 吞吐(多流逼近真实上限),延迟与稳定性用 ping 的 RTT 均值/抖动/丢包率,UDP 测试再验证丢包与延迟抖动。若带宽高但 RTT 抖动大,说明排队/拥塞;若带宽低且丢包高,说明链路或配置问题。

两者互补:iperf3 是"加压测容量",ping 是"轻量测延迟"。组合能区分"容量不足"与"延迟/抖动异常",是链路质量评估的标准组合。

# 服务端
iperf3 -s
# 客户端
iperf3 -c 10.0.0.1 -R -P 4 -t 30       # 反向多流 TCP
iperf3 -c 10.0.0.1 -u -b 100M -t 30    # UDP 测丢包/抖动
ping -c 100 -f 10.0.0.1                 # 测 RTT 与丢包率
#

13. 应用层延迟与网络层指标的关联分析中如何结合 curl 耗时分解、TCP 重传与抓包判断慢在应用还是网络

如何结合 curl 耗时分解、TCP 重传与抓包判断慢在应用还是网络?

  • curl -w 输出各阶段耗时(DNS/TCP/TLS/首字节/总耗时)
  • TCP 重传与 RTT 反映网络层问题
  • 抓包看握手与数据段时序

curl -w 的输出分解 DNS、TCP 连接、TLS 握手、首字节(TTFB)与总耗时。若 TCP 连接耗时高且伴随重传,说明网络层问题;若 TCP 握手正常但 TTFB 高,说明服务端处理慢(应用问题)。结合 tcpdump 抓包看握手是否正常、数据段发送间隔是否均匀、是否有重传。判断方法:网络慢 → 握手/重传异常、RTT 高;应用慢 → 握手正常但首字节迟迟不来。进一步用 ss -i 看当前 RTT 与重传并发,用 iperf3 排除带宽瓶颈。

关键是把"耗时发生在哪一段"定位出来。curl 各阶段耗时 + 抓包时序 + 重传/RTT 指标,能区分网络层与应用层瓶颈。

curl -o /dev/null -s -w "dns:%{time_namelookup} tcp:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com
tcpdump -i any port 443 -nn -ttt
#

14. 用 ss 分析 TCP 连接状态分布时 SYN-SENT/ESTABLISHED/TIME_WAIT 异常分别对应哪些故障场景

如何用 ss 分析 TCP 连接状态分布,识别各状态异常对应的故障场景?

  • ss -tan 列连接,按状态统计
  • SYN-SENT 多:连接建立失败/对端不可达/半连接队列满
  • TIME_WAIT 多:短连接频繁

ss -tan 列出所有 TCP 连接,可用于统计各状态数量。SYN-SENT 大量堆积说明发出的 SYN 无响应,常见于对端不可达、防火墙丢弃、半连接队列满或 SYN flood。ESTABLISHED 数量异常增长说明并发连接建立过多或连接泄漏。TIME_WAIT 大量堆积说明短连接频繁(主动关闭方),可能耗尽源端口。CLOSE_WAIT 大量堆积说明服务端收到对端 FIN 但应用未调用 close,是应用层连接泄漏的典型。结合 ss -ltn 看监听端口、ss -i 看 RTT 与重传,可进一步定位。

ss 是"连接状态快照",各状态对应不同故障语义。SYN-SENT 是建连失败,TIME_WAIT 是短连接,CLOSE_WAIT 是应用未关闭,ESTABLISHED 是并发/泄漏。

ss -tan | awk '{print $1}' | sort | uniq -c
ss -tan state established | wc -l
ss -tan state time-wait | wc -l
ss -tan state close-wait | wc -l
#

15. 网络不通的快速二分法中按二层/三层/四层逐层验证以及 MTU 分片、DNS 解析与防火墙策略如何排查

网络不通时如何按二层/三层/四层逐层二分排查,并结合 MTU、DNS、防火墙?

  • 逐层验证:连通性(二层)、路由(三层)、端口(四层)
  • 二层:arping/同网段 ping;三层:ping/路由;四层:telnet/nc/ss
  • MTU 分片、DNS 解析、防火墙策略的排查

网络不通的排查用二分法逐层收敛。先确认"是网络问题还是应用问题":ping 测三层连通、telnet/nc 测四层端口、curl 测应用。二层看同网段 ARP(arpingip neigh),三层看路由(ip routetraceroute)、MTU(ping -M do),四层看监听状态(ss -ltn)与防火墙(iptables -L)。若 ping 通但 telnet 不通,问题在四层或防火墙;若 ping 不通但同网段通,问题在路由或防火墙。MTU 分片导致大包不通,DNS 解析失败导致主机名不通(dig 验证),防火墙策略逐条核对放行。逐层二分可快速定位到具体层。

二分法核心是"每层验证一个假设,逐层收敛"。二层/三层/四层逐层验证 + MTU/DNS/防火墙专项,能系统化定位网络故障。

ping -c 3 10.0.0.1                     # 三层
telnet 10.0.0.1 443                     # 四层
nc -vz 10.0.0.1 443                     # 四层
ip route show                          # 路由
iptables -L -n -v                       # 防火墙
dig example.com A                       # DNS
#

16. 网络延迟的构成分解中传输延迟、排队延迟与处理延迟如何通过 ping -D、ss 与抓包定位

网络延迟如何分解为传输、排队与处理延迟,并用 ping -D、ss、抓包定位?

  • 延迟构成:传播/传输/排队/处理延迟
  • ping -D 显示时间戳,分析 RTT 抖动
  • ss -i 看 RTT 与 cwnd

网络延迟分解为传播延迟(物理距离)、传输延迟(带宽决定)、排队延迟(队列拥塞)与处理延迟(设备转发)。ping -D 显示时间戳,可通过 RTT 的分布与抖动判断是否存在排队延迟(突发拥塞导致 RTT 波动)。ss -i 显示当前 RTT 与拥塞窗口,可观察 RTT 变化。抓包用 tcpdump -ttt 看 ACK 间隔,若 ACK 间隔大且波动剧烈,多为排队延迟;若延迟稳定但整体高,多为传播/处理延迟。结合 tc -s qdisc 看队列深度可进一步定位排队延迟。

延迟分解的关键是"用抖动区分排队延迟"。传播/传输延迟稳定,排队延迟随拥塞波动。ping -D 看时间戳、ss -i 看 RTT、抓包看 ACK 间隔,三者结合定位。

ping -D -c 100 10.0.0.1        # 时间戳
ss -i dst 10.0.0.1             # RTT/cwnd
tcpdump -i any host 10.0.0.1 -ttt
tc -s qdisc show dev eth0
#

17. 跨设备链路排障中交换机端口错误计数、防火墙会话表与丢包计数器如何交叉验证定位瓶颈

跨设备链路排障时如何用交换机端口错误计数、防火墙会话表与丢包计数器交叉验证定位瓶颈?

  • 交换机端口错误计数(CRC、碰撞、错包)反映物理层
  • 防火墙会话表看丢弃与该连接状态
  • 各设备丢包计数器对比,定位丢包点

跨设备排障要采集并交叉验证各层数据。交换机端口错误计数(show interface 的 CRC、runts、collisions、errors)反映物理层问题,如线缆、光模块、双工不匹配。防火墙会话表(show sessionshow conn)看该连接是否建立、是否有会话超时/拒绝,配合会话表利用率看是否溢出。丢包计数器(show counters)把各设备/接口的丢包数对齐时间轴,定位丢包发生在哪一跳。交叉验证:若交换机端口有 CRC 错误且应用丢包,说明物理层;若交换机无错但防火墙丢包,说明安全策略或会话表;若各层都无丢包但延迟高,说明排队或应用。把 snmp 采集的计数器、抓包、会话表对齐是定位瓶颈的关键。

排障的核心是"多源数据对齐"。物理层看交换机错误计数,安全层看防火墙会话表,转发层看丢包计数器,最后横向交叉验证定位真正瓶颈。

# 交换机
show interface Gi0/1
show interfaces counters errors
# 防火墙
show session filter protocol tcp
show firewall session
# 主机丢包
netstat -s | grep -i retrans | grep drop