云计算百科
云计算领域专业知识百科平台

网络协议安全笔记(上):链路层到传输层

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}

网络协议安全笔记(上):链路层 → 传输层

一句话总纲:这套协议设计之初只追求「能通」,认证、完整性、机密性几乎没写进去。所以协议安全的本质就是对着每个协议问三句话:它凭什么相信对方?它拿什么证明数据没被改?它在链路上是明文还是密文?

本文按 链路层 → 网络层 → 传输层 → 应用层 逐层往下走,每个协议固定用同一个模板拆,最后统一收口到「攻击面总表 + 明文可见性 + 简答模板」。

⚠️ 本文只讨论协议原理与原生设计缺陷,用于学习、排障和防御,不包含可直接运行的攻击代码。

本篇范围:0 阅读约定、一 总览、二 链路层、三 网络层、四 传输层(TCP / UDP)。应用层协议与安全总结放在下篇。

0 阅读约定

0.1 每个协议统一按这个模板写

模板项要回答的问题
名称 / 层级 全称、缩写、属于哪一层、上层协议号是多少
核心作用 一句话说清它解决了什么问题(以及不解决什么)
报文结构 首部字段、长度、关键字段的坑
缺陷 协议原生设计就缺的东西(不是实现 bug)
利用 这些缺陷被组合成了哪些攻击
防御 在哪一层能补上

0.2 抓包环境与记号

  • 工具:Wireshark,开启 相对序号(Relative sequence number),Seq 从 0 开始显示,不是真实原始序列号。
  • Len=0 表示 TCP 载荷为 0,是纯控制报文;Win 是接收窗口;[PSH, ACK] 这类方括号是 Wireshark 的推断标记。
  • 「一个以太网帧 = 一个二层包」,绝大多数 DNS 查询/响应单独占一个帧。

一、总览

1.1 TCP/IP 四层 ↔ OSI 七层

TCP/IP 四层对应 OSI 七层包含协议(加粗 = 本文重点拆解)
应用层 应用层 + 表示层 + 会话层 HTTP、HTTPS、DNS、TLS、DHCP、SSH、FTP
传输层 传输层 TCP、UDP
网络层(互联网层) 网络层 IPv4、ICMP、IGMP、ARP(跨二三层)
网络接口层(链路层) 数据链路层 + 物理层 以太网、NDP、WiFi、PPP、VLAN

分层的一句话记忆:

  • 链路层解决「同一个广播域里,这一帧交给哪块网卡」→ MAC 地址
  • 网络层解决「跨网段,这个包怎么一跳跳送到」→ IP 地址 + 路由
  • 传输层解决「到了这台主机,交给哪个进程」→ 端口号
  • 应用层解决「这个进程要干什么」→ 业务语义

1.2 封装与解封装

image-20261104103129670

发送方自上而下加头(封装),接收方自下而上剥头(解封装)。三个容易记错的点:

  • 以太网头 14B(目的 MAC 6 + 源 MAC 6 + 类型 2),尾部还有 4B FCS,但 FCS 一般不被 Wireshark 计入长度。
  • MTU = 1500B 指的是「以太网头之后的部分」最多 1500 字节,也就是 IP 包最大 1500;超过就要分片。
  • ping 不经过传输层:ICMP 直接装在 IP 里,所以没有端口,这也是「ICMP 没有端口」的准确原因。
  • 1.3 一次「打开网页」到底用了多少协议

    顺序动作用到的协议关键点
    1 拿到本机 IP DHCP(UDP 67/68)或静态配置 DHCP 无认证 → 可被伪造服务器劫持
    2 域名换 IP DNS(UDP 53,必要时 TCP 53) 无认证 → 缓存投毒、放大攻击
    3 查网关 MAC ARP(以太网 0x0806) 无认证 → ARP 欺骗、中间人
    4 与服务器建连 TCP 三次握手 半连接队列有限 → SYN Flood
    5 协商加密 TLS 握手(证书 + 密钥交换) 证书信任链是唯一身份依据
    6 发请求 HTTP over TLS 明文 HTTP → 中间人直接读
    7 传输中途 IP 路由、TTL 递减、可能分片 源 IP 可伪造、分片可攻击

    1.4 全文地图

    章层协议一句话缺陷
    二 链路层 以太网 MAC 可伪造,交换机只认地址不认人
    二 链路层 ARP 收到应答就采信,无认证
    三 网络层 IPv4 源 IP 可随便填,只校验首部
    三 网络层 ICMP 谁都能发,早期网络还都放行
    四 传输层 TCP 握手耗资源,老系统序号可预测
    四 传输层 UDP 无连接无状态 → 源 IP 伪造零成本,天然适合反射放大
    五 应用层 HTTP 全明文,不防篡改
    五 应用层 DNS 原始版本无认证、明文、UDP
    五 应用层 TLS/HTTPS 旧版本漏洞、证书信任体系、SNI 明文

    二、链路层

    这一层的一句话:局域网里没有「身份」,只有「地址」。谁报出自己的 MAC,交换机就照着转发 —— 这就是后面所有二层欺骗的根。

    2.1 以太网(Ethernet)

    核心作用:在同一个广播域内,用 MAC 地址把数据帧从一块网卡送到另一块网卡。它只管「这一跳」,不管跨网段。

    EtherType 字段(以太网头最后 2 字节,用来告诉上层「我装的是什么」):

    EtherType含义
    0x0800 IPv4(最常用,ping、TCP、UDP 都装在这个里面)
    0x0806 ARP
    0x8035 RARP(反向 ARP,现在几乎淘汰)
    0x8100 802.1Q VLAN 标签帧(带 VLAN)
    0x86DD IPv6
    0x8863 PPPoE Discovery(拨号发现)
    0x8864 PPPoE Session(拨号数据)
    0x8809 LACP 链路聚合协议

    两种帧格式:

    现代 Ethernet II(DIX):
    目的MAC(6B) | 源MAC(6B) | EtherType(2B) | 载荷(46~1500B) | FCS校验(4B)

    老式 IEEE 802.3:
    目的MAC(6B) | 源MAC(6B) | 长度(2B) | LLC头 | 载荷 | FCS(4B)

    区分方法:第 13、14 字节 ≥ 0x0600 → 是 EtherType(Ethernet II);
    ≤ 0x05DC(1500)→ 是长度字段(802.3)
    载荷最小 46B:不够要填充(padding),否则连 64B 最小帧都凑不齐

    缺陷

  • 无身份认证:源 MAC 完全由发送方自己填,网卡「混杂模式」下还能收到不是发给自己的帧。
  • 交换机只学地址、不验证:源 MAC 出现在哪个口,就把该 MAC 记到哪个口。
  • 广播域是共享的:同一个 VLAN 内所有主机都能收到广播帧(ARP、DHCP 都靠广播)。
  • VLAN 只是逻辑隔离,配置错误或 VLAN 跳跃(双重标签)就能跨域。
  • 利用

  • MAC 泛洪(MAC Flooding):灌满交换机 CAM 表,交换机退化成集线器,开始泛洪所有帧 → 攻击者可旁听。
  • MAC 欺骗:把源 MAC 改成网关的 MAC,抢流量。
  • VLAN 跳跃(VLAN Hopping):双重 802.1Q 标签 / 交换机间 trunk 协商欺骗,跨 VLAN 访问。
  • 交换机 STP 攻击:伪造 BPDU 抢根桥,把流量引到自己身上。
  • 防御:端口安全(限制每口 MAC 数量)、DAI(动态 ARP 检测)、DHCP Snooping、禁用未使用端口、显式配置 trunk、BPDU Guard。

    2.2 ARP(Address Resolution Protocol,地址解析协议)

    层级:介于网络层与链路层之间,封装在以太网帧里,EtherType = 0x0806。

    适用范围:只在同一个广播域(同一个子网)生效。IPv4 局域网专用;IPv6 抛弃了 ARP,改用 NDP(邻居发现协议)。

    核心作用:已知目标 IP,查询对应的 MAC 地址。反过来(已知 MAC 查 IP)叫 RARP,已淘汰。

    报文结构(28 字节,固定):

    字段长度典型值说明
    硬件类型 2B 1 以太网
    协议类型 2B 0x0800 上层是 IPv4
    硬件地址长度 1B 6 MAC 6 字节
    协议地址长度 1B 4 IPv4 4 字节
    操作码 2B 1 = 请求 / 2 = 应答
    发送方 MAC 6B
    发送方 IP 4B
    目标 MAC 6B 请求时全 0
    目标 IP 4B

    工作过程:

  • 主机要发给 192.168.1.1,先查本机 ARP 缓存(arp -a);
  • 没有 → 发 ARP 请求(广播,目的 MAC 全 F),内容:「谁是 192.168.1.1?请告诉 192.168.1.59」;
  • 目标主机回 ARP 应答(单播):「我是,我的 MAC 是 XX」;
  • 双方都写入缓存,缓存有老化时间(Windows 约几十秒到几分钟)。
  • 补充:免费 ARP(Gratuitous ARP) —— 主机主动广播「我的 IP 对应我的 MAC」,用于 IP 冲突检测和「我换了网卡,大家更新一下」。这一机制本身也常被攻击者用来主动刷新别人的缓存。

    实拍:一次 ARP 请求 + 应答(ping 10.41.231.140 触发,过滤器 arp)

    image-20261104112411313

    • 第 1 条 Who has 10.41.231.140? Tell 10.41.231.117:目的 MAC 是 ff:ff:ff:ff:ff:ff(广播),Target MAC 全 0(还不知道);
    • 第 2 条 10.41.231.140 is at 82:48:ed:2e:cd:4a:单播回到我的 MAC,Opcode = reply (2);
    • 下方面板里 Sender IP 10.41.231.117 / Target IP 10.41.231.140 就是这次「IP 换 MAC」的全部内容 —— 没有签名,没有校验,也没有「我没问过你别答」。这就是 ARP 欺骗的入口。

    缺陷

    ARP 协议无身份认证、无校验,主机收到 ARP 应答就直接更新本机 ARP 缓存,不验证这个应答是不是真的目标主机发的,也不要求「我没问过你就别答」。

    利用:ARP 欺骗(ARP 中毒)

    攻击者发送伪造 ARP 应答:告诉受害者「网关 IP 的 MAC 是我」,同时告诉网关「受害者 IP 的 MAC 是我」。两个方向的流量都经过攻击者主机,实现中间人:抓 HTTP 明文、篡改网页、直接断网。

    image-20261104103151952

    配套的两个变种:

    • ARP 扫描:遍历网段发 ARP 请求,快速发现存活主机(比 IP 扫描更可靠,因为 ARP 不过路由器)。
    • ARP 表溢出:灌满主机/交换机 ARP 表,让正常映射被挤掉,被迫重新广播 → 配合伪造应答抢占。

    防御:静态 ARP 绑定(arp -s)、ARP 防火墙、DAI(动态 ARP 检测,交换机层面)、划分 VLAN 缩小广播域、重要服务器用静态映射。

    DAI 的前提是 DHCP Snooping:交换机要先知道「这个口合法的 IP-MAC 是谁」,才能判断 ARP 应答真假 —— 这是配置题里常考的依赖关系。

    2.3 补充:IPv6 的 NDP(一句话)

    IPv6 用 NDP(Neighbor Discovery Protocol) 取代 ARP,靠 ICMPv6 的 NS/NA(邻居请求/通告,Type 133/135/136) 实现地址解析,另外还有 RS/RA(路由器请求/通告,Type 133/134)做 SLAAC 自动配置。

    安全性同样的坑:NDP 也没有认证 → NS/NA 欺骗(NDP 欺骗)= IPv6 版 ARP 欺骗,防御是 RA Guard / ND Guard。

    2.4 补充:VLAN(一句话)

    VLAN 在以太网帧里插 4 字节 802.1Q 标签(EtherType 0x8100,里面 12 位 VID 表示 1~4094),把一台交换机的端口逻辑切成多个广播域。

    安全含义:VLAN 不是安全边界(很多人误以为是)。跨 VLAN 必须过三层设备,这时候防火墙/ACL 才真正起作用。


    三、网络层

    这一层的一句话:IP 只负责「尽最大努力把包送到」,所以它不保证送到、不保证顺序、不保证不重复、不保证完整。这些坑全部留给上层去补。

    3.1 IP(Internet Protocol,网际协议)

    核心作用:寻址 + 路由,完成「主机到主机」的任务。

    首部结构(固定 20 字节 + 可变选项):

    image-20261104103205042

    实际抓包对照(ping 223.5.5.5):

    ping 的 IPv4 首部实拍

    必须记牢的字段:

    字段长度为什么重要
    版本 + 首部长度 4 + 4 位 IHL 以 4 字节为单位,5 → 20 字节
    总长度 16 位 首部 + 数据,最大 65535;抓包里的 Total Length
    标识 / 标志 / 片偏移 16 / 3 / 13 位 分片三件套:同一 ID 属于同一个原始包,MF 表示「后面还有」,片偏移 ×8 表示位置
    TTL 8 位 每过一个路由器减 1,减到 0 就丢弃并回 ICMP 超时 → 这就是 traceroute 的原理
    协议号 8 位 告诉 IP「里面装的是谁」,见下表
    首部校验和 16 位 只校验首部,不校验数据
    源/目的 IP 各 32 位 源 IP 由发送方自己填 → 可伪造

    常见协议号:

    协议号协议协议号协议
    1 ICMP 47 GRE(隧道)
    2 IGMP 50 ESP(IPSec 加密载荷)
    6 TCP 51 AH(IPSec 认证头)
    17 UDP 89 OSPF
    41 IPv6(6in4 隧道) 132 SCTP

    分片与 MTU:

    • 以太网 MTU = 1500,IP 包超过就要分片;分片可以发生在源主机,也可以发生在中途路由器。
    • 接收方靠「标识 + 片偏移 + MF」重组,任一分片丢失 → 整个原始包丢弃。
    • DF=1(禁止分片) 时,如果路上 MTU 太小,路由器回 ICMP Type 3 Code 4(需要分片),源主机据此调小 —— 这就是 PMTUD(路径 MTU 发现)。
    • 现实中的坑:ICMP 被防火墙全禁 → PMTUD 失效 → 大包发不出去、小包正常,表现为「网页能开但图片加载卡死」。这是运维高频故障,也是考试爱问的点。

    实拍:ping -l 3000 被拆成 3 个分片(过滤器 ip.flags.mf == 1 or ip.frag_offset > 0)

    image-20261104112358749

    三条记录的 Identification 全是 0x9592(表示「我们属于同一个原始包」),Fragment Offset 依次是 0 / 1480 / 2960 字节,前两条 More fragments = 1、最后一条为 0;第 1、2 条被标成 [Reassembled in #3],说明重组是在接收端完成的,中间路由器只负责转发碎片。

    缺陷

  • 无身份认证:源 IP 可以随便填(IP 地址伪造)。
  • 无完整性校验:只校验首部,不校验数据载荷,数据可篡改。
  • 分片机制存在风险:分片重叠、超小分片、分片数量爆炸。
  • 不加密,裸传:链路上任何人可读。
  • 利用

    • IP 源地址伪造:用于 DDoS 反射攻击、扫描时隐藏自身。注意:伪造源 IP 只能「发出去」,收不到回包,所以只适合单向攻击(SYN Flood、反射放大),不能用作正常通信。
    • IP 分片攻击:
      • Teardrop / 重叠分片:构造片偏移重叠的分片,老系统重组时崩溃;
      • 分片绕过 IDS:把攻击载荷切碎,让特征串跨分片,简单 IDS 逐包匹配就失效;
      • 微小分片(tiny fragment):第一片只装 8 字节 TCP 头的一部分,逼防火墙无法判断端口。
    • TTL 欺骗:伪造较小 TTL 让包提前丢弃,隐藏扫描源(配合 traceroute 探测拓扑)。

    防御:入方向 uRPF 反向路由校验(源 IP 是否真的从这条路来)、防火墙过滤、IPsec 加密、分片重组策略(丢弃异常分片)、IDS 做流重组而不是逐包匹配。

    IPv6 改善了部分,但基础依然无认证。

    补充:IPv6 干了什么(对比表)

    维度IPv4IPv6
    地址长度 32 位 128 位
    首部 20B + 可变选项 固定 40B,选项放扩展头
    首部校验和 有 取消(交给上下层)
    分片 路由器可分段 只有源主机能分片,用 Fragment 扩展头
    地址解析 ARP(广播) NDP(ICMPv6 组播)
    自动配置 DHCP SLAAC(也可 DHCPv6)
    广播 有 取消广播,改用组播
    NAT 普遍使用 设计上不需要(但要隐私仍有 NAT66)

    安全影响:IPv6 没有 NAT 的「伪隔离」,主机直接暴露 → 防火墙必须显式配置;NDP 欺骗、RA 欺骗是 ARP 欺骗的等价物;IPv6 首部无校验和 意味着载荷完整性完全依赖上层。

    3.2 ICMP(Internet Control Message Protocol,互联网控制报文协议)

    介绍:属于 网络层(IP 层)协议,依附于 IP 协议(协议号 1),封装在 IP 报文中,没有独立的传输端口。

    核心作用:传递网络控制信息、差错报告、探测网络状态,不是用来传输业务数据的。

    一句话概括:IP 负责送包,ICMP 负责告诉对方:包有没有送到、为什么送不到、网络是否通畅。

    一个标准的 ping,链路是【以太网 → IPv4 → ICMP】,不经过传输层。

    ping 的 ICMP 实拍

    ICMP 报文结构:Type(1B) + Code(1B) + 校验和(2B) + 4B 头部(随类型变化)+ 数据。

    必记的类型/代码:

    Type名称常见 Code用途 / 安全含义
    0 / 8 Echo Reply / Echo Request 0 ping 的往返;扫描第一步
    3 Destination Unreachable 0 网络 / 1 主机 / 3 端口 / 4 需分片但 DF=1 / 13 管理禁止 UDP 扫描靠 Code 3(端口不可达)判断端口关闭;Code 4 是 PMTUD
    5 Redirect 0 网络 / 1 主机 让主机改走别的网关 → 伪造可劫持路由
    11 Time Exceeded 0 TTL 耗尽 / 1 分片重组超时 traceroute 的原理
    12 Parameter Problem 0 首部字段出错
    13 / 14 Timestamp Request / Reply 0 可探测对端时间
    4 Source Quench — 已废弃(早期拥塞控制)

    ICMPv6 是另一套类型号:1 目的不可达、2 包过大、3 超时、4 参数问题、128/129 Echo、133~137 NDP 五件套。

    缺陷

  • 无认证,任何人都可以发 ICMP 报文,也可以伪造源 IP。
  • 很多网络早期宽松放行 ICMP(为了「能 ping 通好排障」)。
  • ICMP 载荷没有语义限制 → 可以被拿来当传输通道。
  • 利用

  • Ping 洪水(ICMP Flood)DDoS:大量 Echo Request 打向目标,耗尽带宽和处理资源。
  • Smurf 攻击:伪造源 IP = 受害者,把 Echo Request 发到广播地址,整个子网的主机都回 Echo Reply 给受害者 → 1 个包放大成几百个(现代设备默认不响应广播 ping,已基本失效,但概念常考)。
  • ICMP 重定向欺骗:伪造 Type 5 重定向报文,诱导受害者修改路由,流量走攻击者。
  • ICMP 隧道:把其他数据封装在 ICMP 载荷里,绕过防火墙外传数据(数据渗出)。工具如 ptunnel、icmpsh。
  • 扫描:ping 扫描探测主机是否存活;ICMP Timestamp 探测时区/时间。
  • 防御:防火墙限制 ICMP 速率、禁止 ICMP 重定向(Redirect 全丢)、阻断 ICMP 隧道(限制载荷大小和频率)、但不要一刀切全禁 —— 会打断 PMTUD。

    3.3 补充:IGMP(一句话)

    IGMP(Internet Group Management Protocol,协议号 2)用来管理组播组成员:主机告诉本地路由器「我要加入/退出某个组播组」,路由器据此决定往这个网段转发哪些组播流。IPTV、视频会议用它。安全上关注 IGMP 报文伪造导致组播流量泛洪。


    四、传输层

    这一层的一句话:网络层只管把包送到主机,传输层靠端口把数据交给进程;同时只有这一层开始,才出现「可靠性」这个话题。

    4.0 端口(一句话带过)

    端口 0~65535,用来在同一台主机内区分不同进程;TCP 端口和 UDP 端口是两个独立的编号空间(53/UDP 和 53/TCP 是两个不同的东西,DNS 同时用)。五元组 源IP, 源端口, 目的IP, 目的端口, 协议 唯一标识一条连接。

    详细内容(知名端口划分、Socket、C/S 模型)见同目录《Web安全基础.md》的「前置知识」一节,这里不重复。

    4.1 TCP(Transmission Control Protocol,传输控制协议)

    核心作用:在不可靠的 IP 之上,提供面向连接、可靠、有序、有流量控制和拥塞控制的字节流服务。

    首部结构(固定 20 字节 + 最多 40 字节选项):

    image-20261104103257002

    关键字段:

    字段作用坑
    序号 Seq 本报文数据第一个字节的编号 32 位回绕;SYN/FIN 各占 1 个序号
    确认号 Ack 期望收到的下一个字节 = 对方 Seq + 对方数据长度 只对 ACK=1 的报文有效
    数据偏移 首部长度,单位 4 字节 有选项时 > 5
    标志位 URG ACK PSH RST SYN FIN + CWR ECE PSH = 尽快交给应用层;RST = 直接断连
    窗口 Win 接收方还能收多少字节 16 位不够用 → 靠 WS 选项左移放大
    校验和 伪首部 + 首部 + 数据 与 IP 首部校验和分工不同

    三次握手 / 四次挥手(实拍抓包)

    TCP 三次握手与四次挥手实拍

    编号标志含义
    10350 [SYN] 客户端发起连接(握手第 1 步)
    10351 [SYN, ACK] 服务端应答(握手第 2 步)
    10352 [ACK] 客户端确认,连接建立(握手第 3 步)
    10353 HTTP GET 发送 HTTP GET 请求
    10367 [PSH, ACK] 推送数据
    10369 HTTP/1.1 200 OK 服务器返回 JSON 响应
    10372 [FIN, ACK] 客户端主动关闭连接
    10379 [FIN, ACK] 服务端关闭
    10385 [ACK] 最后确认,连接断开
    TCP 抓包分析(HTTP GET 示例)

    环境:Wireshark,开启相对序号,Seq 从 0 开始显示,不是真实原始序列号

    • 客户端:192.168.1.59:1896(本机,随机端口)
    • 服务端:44.206.195.5:80(httpbin,HTTP 80 端口)
    • 浏览器访问 http://httpbin.org/get 的包

    核心规则:

    Ack 号 = 对方上一个 Seq + 对方报文携带的数据长度
    ✅ SYN / FIN 标志本身占用 1 个序号,即使载荷 Len=0

    一、TCP 三次握手(建立连接)

    报文方向标志说明
    1896 → 80 [SYN] Seq=0 Win=65535 Len=0 客户端发起连接请求,初始序号 0,无应用数据
    80 → 1896 [SYN,ACK] Seq=0 Ack=1 Win=26883 Len=0 服务端确认收到 SYN(Ack=0+1=1),同时发起自己的连接请求
    1896 → 80 [ACK] Seq=1 Ack=1 Win=65280 Len=0 客户端确认收到服务端 SYN(Ack=0+1=1)

    ✅ 三次握手完成,TCP 通道就绪,可以传输上层 HTTP 数据。

    二、HTTP 业务数据传输

    报文方向标志说明
    1896 → 80 GET /get HTTP/1.1 客户端发送 GET 请求,TCP 载荷 79 字节,带 PSH,ACK;PSH:通知内核尽快把数据交给应用层,不要缓存
    80 → 1896 [ACK] Seq=1 Ack=80 Win=27136 Len=0 服务端确认:已收到 1+79=80 字节
    80 → 1896 [PSH,ACK] Seq=1 Ack=80 Len=230 服务端推送 HTTP 200 OK + JSON 响应,载荷 230 字节
    1896 → 80 [ACK] Seq=80 Ack=487 Win=65024 Len=0 客户端确认收到服务端响应数据

    ✅ HTTP 一问一答交互完成。

    三、TCP 挥手断开连接(客户端主动关闭)

    教材标准是四次挥手;真实网络中,服务端的 ACK 和 FIN 经常合并成一个报文,抓包只看到 3 个包属于正常优化,考试答题仍写四次挥手。

    报文方向标志说明
    1896 → 80 [FIN,ACK] Seq=80 Ack=487 Win=65024 Len=0 客户端告知:我方无数据发送,请求关闭【客户端→服务端】方向
    80 → 1896 [FIN,ACK] Seq=487 Ack=81 Win=27136 Len=0 服务端:确认客户端 FIN(Ack=80+1=81);同时我方也无数据,关闭【服务端→客户端】方向
    1896 → 80 [ACK] Seq=81 Ack=488 Win=65024 Len=0 客户端确认收到服务端 FIN(Ack=487+1=488)

    ✅ 双向连接全部释放。

    四、字段释义

    字段含义
    Win 滑动窗口大小,流量控制,告诉对方当前本机最多可接收字节数
    MSS=1460 最大分段大小;TCP 单段最大载荷,MTU(1500) – IP头(20) – TCP头(20)
    WS=256 Window Scale 窗口缩放因子,用于高速网络放大窗口
    SACK_PERM 允许选择性确认,丢包时只重传丢失分片,不用重传全部
    Len TCP 载荷长度(不含 TCP 头部);Len=0 代表纯 TCP 控制报文,无应用层数据

    五、序号校验示例

  • 客户端 SYN Seq=0 → 服务端 Ack = 0 + 1 = 1 ✔
  • 服务端 SYN Seq=0 → 客户端 Ack = 0 + 1 = 1 ✔
  • 客户端 HTTP 载荷 79 字节,Seq=1 → 服务端 Ack = 1 + 79 = 80 ✔
  • TCP 状态机

    状态谁在什么条件下进入说明
    LISTEN 服务端 listen() 之后 等待 SYN
    SYN_SENT 客户端发 SYN 之后 等待 SYN+ACK
    SYN_RCVD 服务端收到 SYN、回了 SYN+ACK 半连接队列在这里堆积 → SYN Flood 打的就是它
    ESTABLISHED 双方都收到 ACK 数据可传
    FIN_WAIT_1/2 主动关闭方发 FIN 之后
    CLOSE_WAIT 被动关闭方收到 FIN 大量 CLOSE_WAIT = 应用没调 close(),代码问题
    TIME_WAIT 主动关闭方最后 等 2MSL,保证最后一个 ACK 能重传、老报文自然消亡
    LAST_ACK 被动关闭方发完 FIN

    排障口诀:TIME_WAIT 多 = 连接被主动关闭得太多,端口可能不够用;CLOSE_WAIT 多 = 应用没关连接,是 bug;SYN_RCVD 多 = 有人在打 SYN Flood。

    流量控制 vs 拥塞控制(一句话区分)

    流量控制拥塞控制
    解决谁的问题 接收方来不及处理 网络承受不住
    手段 滑动窗口(Win) 慢启动、拥塞避免、快重传、快恢复(CUBIC / BBR)
    信号 接收方通告窗口 丢包 / 时延

    缺陷

  • 三次握手机制:SYN 队列资源有限,半连接状态要占内存。
  • 序号可预测(老旧系统):初始序号若用简单递增,可被猜中。
  • 连接无强身份绑定:TCP 连接只靠四元组标识,谁能构造出合法四元组+序号,谁就是「这条连接」。
  • 队头阻塞:一个包丢了,后面所有数据都要等它重传(HTTP/2 多路复用也只解决了应用层队头阻塞,TCP 层的还在 → HTTP/3 改用 QUIC/UDP)。
  • TIME_WAIT 占用端口:高并发短连接场景下端口耗尽。
  • 利用

  • SYN 洪水攻击(SYN Flood):大量伪造源 IP 的 SYN 包,服务器回 SYN+ACK 后等待 ACK,占满半连接队列,拒绝服务(经典 DDoS)。因为源 IP 是伪造的,服务器的 SYN+ACK 全打到别人身上,同时自己队列爆掉。
  • TCP 会话劫持:老系统序号可预测,猜序号插入伪造报文,劫持已建立的 TCP 连接(本质是「TCP 没有密码」)。
  • RST 包攻击:伪造 RST 报文,直接踢断一条正常 TCP 连接(中间人只需知道四元组 + 在窗口内的序号)。
  • TCP 反射/放大:某些服务在握手阶段就回大量数据(如 chargen),可被用于放大。
  • 连接耗尽:慢速攻击(Slowloris)用大量「握手完成但慢慢发头」的连接占满服务端并发数。
  • 防御:SYN Cookie、SYN 队列调大 + 首包丢弃、防火墙/清洗设备、随机强初始序列号(现代 OS 用加密随机 ISN)、连接跟踪、限制单 IP 并发。

    4.2 UDP(User Datagram Protocol,用户数据报协议)

    这一节是原笔记缺失的部分,也是「为什么 DDoS 反射放大几乎都走 UDP」的答案所在。

    4.2.1 是什么

    项内容
    名称 UDP,User Datagram Protocol,用户数据报协议
    层级 传输层;IP 协议号 17
    核心作用 提供最小的传输服务:端口复用/分用 + 一个可选的校验和。不做连接、不做可靠、不做流控、不做拥塞控制
    数据单位 数据报(datagram),一次发送一条,保留报文边界
    一句话 TCP 保证「字节流完整送到」;UDP 只保证「把这个数据报贴好端口号扔出去」,剩下的全交给应用层

    它的设计哲学:把 IP 的能力几乎原样交给应用,只补两件事 —— 端口(进程寻址)和校验和(最基本的差错检测)。所以 UDP 的所有「缺点」,本质都是「故意不做」。

    4.2.2 报文结构

    image-20261104103354949

    首部只有 8 字节,4 个字段:

    字段长度含义要点
    源端口 2B 发送方端口 不需要回包时可以填 0
    目的端口 2B 接收方端口 交付给哪个进程
    长度 2B 首部 + 数据的总长 最小 8;16 位 → 单个数据报最大 65535 − 8 = 65527B
    校验和 2B 覆盖伪首部 + 首部 + 数据 IPv4 下可填 0 表示「不校验」;IPv6 下强制

    对比一下就知道差距:

    TCP 首部UDP 首部
    长度 20~60B 固定 8B
    字段数 10+ 4
    有没有序号/确认号/窗口 有 一个都没有

    4.2.3 校验和与伪首部

    UDP 校验和的计算范围是:

    伪首部(12B) + UDP 首部(8B) + UDP 数据
    伪首部 = 源 IP(4B) + 目的 IP(4B) + 全 0(1B) + 协议号 17(1B) + UDP 长度(2B)

    伪首部不真的发到线路上,只在计算校验和时临时拼出来。为什么要这么麻烦?因为要把 IP 层的源/目的地址也拉进校验 —— 否则一个包被错误投递(NAT 改写地址后没重算校验和)也检测不出来。

    三个必须知道的点:

  • IPv4 里校验和填 0 是合法的,意思是「发送方没算校验和」。这让中间设备可以完全跳过校验 —— 安全上意味着「载荷完整性完全依赖上层协议」。
  • IPv6 里不允许填 0,必须算。
  • NAT 的经典坑:NAT 改写了源/目的 IP,就必须重算 UDP/TCP 校验和;有的实现偷懒不重算,导致某些严格校验的主机丢包。
  • 4.2.4 「8 字节首部」意味着什么

    特性后果(好处)后果(代价 / 攻击面)
    首部只有 8B 小包开销极低(DNS 40B 的包里首部只占 20%) 没有序号/确认号,做不到可靠传输
    保留报文边界 一次 sendto 对应一次 recvfrom,接收方拿到完整一条 TCP 的「粘包」问题在 UDP 里不存在(这题常考)
    无连接 无握手,省 1 个 RTT;服务端无状态,DNS 单机可扛极高 QPS 源 IP 伪造零成本 → 反射放大的首选载体
    无序、无重传、无流控 协议栈实现简单,时延低(语音/游戏) 丢包、乱序、重复全上抛给应用层自己处理
    无拥塞控制 应用可以按自己节奏发 UDP Flood 只需无脑发包,不用管网络是否拥塞
    超过 MTU 由 IP 分片 单条数据报可以很大 丢一个分片,整条数据报全废,且应用层不会自动重传

    image-20261104112319470

    第 1 片 off=0 带 More fragments,第 2 片 off=185(185×8 = 1480 字节偏移)收尾;点开第 2 片看 UDP 长度字段写的是 Length: 2008,可这一帧只有 562 字节 —— 差的那 1480 字节在第 1 片里。中间丢任何一片,接收端都拼不出这条数据报,而 UDP 自己不会重传,只能靠应用层超时重发。

    4.2.5 UDP 抓包:一次 DNS 查询

    想看 UDP,最方便的例子就是 DNS。一条命令就够:

    nslookup example.com # 触发一次 UDP 53 查询

    Wireshark 过滤器:

    udp.port == 53

    抓到的应该是这样两个包(一往一返,没有任何握手和确认):

    #方向协议关键字段说明
    1 客户端:随机高位端口 → DNS:53 DNS Transaction ID = 0x8f3a,Queries = 1,A? example.com 只有 8B UDP 头 + 一个 DNS 查询
    2 DNS:53 → 客户端:随机高位端口 DNS 同 Transaction ID,Answers = 1,A 93.184.216.34 端口对调,ID 必须一致才算「这是对刚才那个查询的回答」

    image-20261104103406922

    上图左半是 4.1 节那条 HTTP 连接的完整过程(握手 3 包 + 数据 2 包 + 挥手 3 包),右半是这条 DNS 查询 —— 总共就 2 个包,问和答,完了。这就是「无连接」最直观的样子。

    再补一张真正抓下来的(本机 10.41.231.117,校园网 DNS 10.41.231.140:53,nslookup www.hust.edu.cn):

    image-20261104112303223

    第 3 条是查询、第 4 条是响应,时间差只有 0.7 ms;下方面板把 UDP 首部 4 个字段和 DNS 头都展开了,和 4.2.2 的结构图一一对应:

    位置抓包里看到对应哪个字段
    UDP Src Port: 55884 / Dst Port: 53 源端口(客户端随机高位端口)、目的端口(DNS 服务)
    UDP Length: 41 首部 8B + 载荷 33B = 41
    UDP Checksum: 0x9820 [unverified] 校验和;unverified 是网卡「校验和卸载」导致,不是抓包出错
    DNS Transaction ID: 0x0002 请求与响应靠它配对
    DNS Flags: 0x0100 Standard query QR=0 查询,RD=1 希望递归
    DNS Questions: 1 / Answer RRs: 0 查询报文没有回答段
    DNS www.hust.edu.cn: type A, class IN 问的是 A 记录
    DNS [Response In: 4] Wireshark 自动关联到第 4 条:A 202.114.0.245,91 字节

    三个值得注意的点:① 整条交互只有 2 个包,没有建立/确认/释放;② 响应比请求大(91B vs 75B),这个比例到了反射放大里会被放大到成千上万倍;③ 列表里第 1~24 条都是同一时段的其它 DNS 查询,只有第 3、4 条是这次 nslookup。

    4.2.6 跑在 UDP 上的常见协议

    端口协议为什么用 UDP
    53 DNS(主)/ mDNS 5353 一问一答、报文小、要求快;超 512B 或区域传送才走 TCP
    67 / 68 DHCP(服务端 / 客户端) 客户端此时还没有 IP,只能广播,无法建 TCP 连接
    69 TFTP 极简实现(交换机刷固件)
    123 NTP 时间同步要求低时延,一次往返就够
    161 / 162 SNMP / SNMP Trap 轮询式管理,简单
    500 / 4500 IKE / IPsec NAT-T 隧道协商
    3478 / 5349 STUN / TURN NAT 穿透,打洞必须 UDP
    1900 / 5353 SSDP / mDNS 局域网服务发现,靠组播
    5060 SIP 语音信令,重传自己实现
    443 QUIC(HTTP/3) 在用户态自己实现可靠传输,绕开 TCP 队头阻塞
    11211 memcached 缓存查询;公网暴露就是灾难级放大器

    4.2.7 缺陷

  • 无连接、无状态 → 服务端没有任何手段验证源 IP 是真的(TCP 至少要用 SYN Cookie 做一次往返)。这是 UDP 一切放大攻击的根因。
  • 无认证、无加密 → 载荷明文可读可改(DNS 投毒、DHCP 伪造、TFTP 任意读文件)。
  • 无速率控制、无拥塞控制 → 发送方想发多快就多快,直接打满带宽和网卡中断(pps 打满比带宽打满更致命)。
  • 校验和可关(IPv4) → 载荷完整性没有下限保证。
  • 无分片感知 → 大 UDP 包被 IP 分片后,攻击者可以用畸形分片绕过检测或打崩重组逻辑。
  • 4.2.8 利用

    ① UDP Flood(直接洪泛)

    伪造源 IP 向目标的大量端口发送 UDP 包 → 目标主机要么处理,要么回 ICMP 端口不可达(这又消耗一份资源)→ 带宽和 pps 被打满。

    变种 Fraggle:把 UDP 包发到广播地址的 echo(7) / chargen(19) 端口,整个子网的主机都回包 → 1 个包变 N 个(和 ICMP 的 Smurf 是同一个思路)。

    ② 反射放大(Reflection & Amplification)—— UDP 最危险的用法

    三步链条:

    ① 攻击者伪造源 IP = 受害者地址
    ② 向大量「开放服务」发送小请求(这些服务的响应很大)
    ③ 所有响应都打到受害者身上 → 放大倍数 = 响应大小 / 请求大小

    反射源端口放大倍数(公开测量中的常见量级)备注
    memcached 11211 数千到数万倍 最猛,2018 年 GitHub 1.35 Tbps 攻击就是它
    NTP(monlist) 123 数百倍 老版本 NTP 的 monlist 会返回最近 600 个客户端
    CLDAP 389 数十倍 LDAP 的 UDP 版
    DNS 53 数十倍 需要开放递归解析器;ANY 查询、DNSSEC 响应更大
    SSDP 1900 数十倍 UPnP 设备发现
    SNMP 161 数倍~数十倍 默认口令 public 就能查大量信息
    Chargen 19 数百倍 每包回随机字符流

    ⚠️ 上表的倍数随配置、响应内容、请求构造变化很大,写论文/答题时应表述为「量级」而非精确值。

    为什么必须是 UDP? 因为 TCP 要三次握手 —— 伪造源 IP 就收不到 SYN+ACK,连接根本建不起来,无法形成放大。UDP 无连接,一个包就能触发一个大响应。 这一句是这类题的标准答案。

    ③ UDP 分片攻击

    • 构造总长 > 65535 或分片偏移重叠的 UDP 包,打老系统重组逻辑(Teardrop 的 UDP 版本);
    • 把攻击载荷拆到多个分片,让只做逐包匹配的 IDS 漏检。

    ④ UDP 隧道 / 数据渗出

    把其他协议封装进 UDP 载荷(DNS over UDP 53、NTP、甚至 53 端口跑自定义协议),穿出防火墙。因为「53 端口必须放行」是很多内网的做法。

    ⑤ UDP 扫描

    UDP 没有握手,扫描器发一个空包,等 ICMP 端口不可达(Type 3 Code 3):收到 → 端口关闭;没收到 → 端口可能开着(也可能被防火墙静默丢弃,所以 UDP 扫描又慢又不准,nmap -sU 需要重试)。

    ⑥ QUIC 带来的新问题

    HTTP/3 跑在 UDP 443 上,载荷全程 TLS 1.3 加密,中间设备看不到 SNI 之外的任何东西,传统基于 TCP 明文特征的 IDS 直接失效 → 只能靠流量行为特征(包长分布、时序)识别。这和你做流量分类是直接相关的点。

    4.2.9 防御

    层面手段
    根治 入口过滤(BCP 38 / uRPF):运营商侧丢弃源 IP 不属于本网段的包 → 从源头消灭伪造源 IP
    服务侧 关闭公网暴露的开放递归 DNS、NTP monlist、memcached、SNMP 默认口令
    网络侧 每源 IP 的 pps/带宽限速、ANY 查询限流、分片策略(丢弃异常/微小分片)
    应用侧 DNSSEC(防投毒)、DoH/DoT(加密)、QUIC 自带 TLS 1.3
    监测 入向大包突增、单一目的端口 pps 突增、响应包 >> 请求包的流量模式

    一句话:UDP 的防御重点不在「协议内部」(它什么都没有),而在边界过滤 + 服务配置 + 速率限制。

    4.2.10 TCP 与 UDP 逐项对比

    维度TCPUDP
    连接 三次握手 / 四次挥手 无连接
    可靠性 确认 + 超时重传 无
    顺序 有序,乱序重排 无
    数据边界 字节流(有粘包问题) 保留报文边界
    首部开销 20~60B 8B
    流量控制 滑动窗口 无
    拥塞控制 慢启动 / CUBIC / BBR 无(QUIC 在用户态自己实现)
    传输方式 点对点(不支持广播/组播) 支持广播、组播
    建连开销 1 个 RTT 0
    典型应用 HTTP/1.1、SSH、SMTP、FTP DNS、DHCP、NTP、语音、游戏、QUIC
    主要攻击 SYN Flood、会话劫持、RST 注入 UDP Flood、反射放大、分片攻击
    一句话比喻 打电话:先接通,确认对方在听 寄明信片:写好就投,丢不丢不管

    4.2.11 为什么 DNS 用 UDP、HTTP 用 TCP

    判断依据DNSHTTP
    单次数据量 小(通常 < 512B) 大(页面、图片、JSON)
    交互模式 一问一答就结束 长连接、连续多轮
    能否容忍丢包 能(超时重发一次即可) 不能(内容必须完整)
    延迟敏感度 极高(每次上网第一步,多 1 RTT 就很明显) 相对低
    结论 UDP 为主,必要时降级到 TCP TCP 为主

    DNS 的「必要时走 TCP」有三个触发条件,考试常考:

  • 响应超过 512 字节(未启用 EDNS0)→ 服务器把响应截断,置 TC=1 标志 → 客户端改用 TCP 重查;
  • 区域传送(AXFR / IXFR,主从同步)→ 必须 TCP;
  • 启用了 EDNS0(可到 4096B)仍超长时,同样回落到 TCP。


  • 下一篇:应用层与安全视角

    《网络协议安全笔记(下):应用层与安全视角》接着讲:

    • HTTP / DNS / TLS / HTTPS / DHCP / SSH 的报文结构与原生缺陷(TLS 的 SNI 为什么是明文、DNS 投毒怎么发生、伪造 DHCP 服务器为什么能一次劫持整个网段)
    • 一张「攻击面总表」,把 10 个协议的缺陷、典型攻击、防御对上号
    • 「明文与密文边界」:普通链路 / HTTPS / IPSec 隧道 / GRE 隧道 四种情况,链路上到底谁看得见什么
    • 「抓包排错清单」:看到 Retransmission、Port unreachable、Fragmented IP protocol 分别说明什么问题,以及每张图的复现命令
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 网络协议安全笔记(上):链路层到传输层
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!