第28章 原始IP

所属:TCP/IP详解 卷2:实现 来源:TCP/IP详解 卷2:实现

本章描述原始IP(Raw IP)套接字的实现,包括原始IP的输出、输入、用途和安全考虑。


28.1 引言

什么是原始IP

原始IP(Raw IP):

  • SOCK_RAW类型的套接字
  • 直接读写IP数据报
  • 不经过TCP/UDP处理
  • 需要特殊权限(通常是root)

原始套接字给用户态直接访问IP层的能力。


原始IP的用途

主要用途:

  1. 诊断工具

    • ping:发送ICMP回显请求
    • traceroute:探测路径
    • 各种网络诊断工具
  2. 实现新协议

    • 在用户态实现新的传输层协议
    • 不需要修改内核
    • 快速原型开发
  3. 安全工具

    • 端口扫描
    • 漏洞扫描
    • 安全测试
  4. 研究和实验

    • 网络协议研究
    • 性能测试
    • 实验新特性

原始套接字是网络研究和诊断的重要工具。


28.2 原始IP的输出

输出过程

原始IP的输出过程:

应用程序
   |
   v
构造数据(或IP首部+数据)
   |
   v
sendto / sendmsg
   |
   v
内核处理
   |
   +---> IP_HDRINCL设置?
   |        |
   |        +---> 是 → 用户提供完整IP首部
   |        |
   |        +---> 否 → 内核构造IP首部
   |
   v
IP层发送
   |
   v
接口输出

IP_HDRINCL选项

IP_HDRINCL套接字选项:

值说明
0(默认)内核构造IP首部,用户只提供数据
1用户提供完整IP首部,内核不构造

默认情况(IP_HDRINCL=0):

  • 用户只提供数据部分
  • 内核构造IP首部
  • 内核填充:版本、首部长度、TOS、总长度、标识、标志、偏移、TTL、协议、校验和、源地址、目的地址
  • 源地址可以用IP_OPTIONS等选项控制

设置IP_HDRINCL=1:

  • 用户提供完整的IP首部
  • 内核基本不修改
  • 用户可以控制所有字段
  • 校验和可能还是内核计算

IP_HDRINCL让用户可以完全控制IP首部。


输出的细节

源地址选择:

  • 默认用输出接口的地址
  • 可以用IP_SRCADDR选项指定
  • IP_HDRINCL时用户自己填

目的地址:

  • 由sendto的参数指定
  • IP_HDRINCL时从首部取

协议号:

  • socket的protocol参数
  • IP_HDRINCL时用户自己填

校验和:

  • 内核计算IP首部校验和
  • 不管IP_HDRINCL是否设置

内核还是会做一些基本处理。


28.3 原始IP的输入

输入过程

原始IP的输入过程:

网卡接收
   |
   v
IP层处理
   |
   v
检查协议号
   |
   +---> 匹配TCP? → 交给TCP
   |
   +---> 匹配UDP? → 交给UDP
   |
   +---> 匹配ICMP? → 交给ICMP
   |
   +---> 都不匹配? → 检查原始套接字
            |
            v
        遍历原始套接字
            |
            +---> 协议号匹配?
            |        |
            |        +---> 是 → 复制一份给它
            |
            v
        都不匹配?
            |
            +---> 是 → 丢弃,发ICMP协议不可达

匹配规则

原始套接字的匹配规则:

  1. 协议号匹配

    • socket的protocol参数
    • 和IP首部的协议字段比较
    • 必须匹配
  2. 本地地址匹配(可选)

    • 如果套接字bind了本地地址
    • 目的地址要匹配
  3. 外部地址匹配(可选)

    • 如果套接字connect了对端地址
    • 源地址要匹配

协议号必须匹配,地址可选匹配。


多个原始套接字

多个原始套接字的情况:

  • 一个数据报可能匹配多个原始套接字
  • 每个匹配的套接字都收到一份拷贝
  • 数据报被复制多份
  • 每个套接字独立处理

多个原始套接字可以同时收到同一个数据报。


不匹配的情况

没有匹配的原始套接字:

  • 内核丢弃数据报
  • 发送ICMP协议不可达
  • 告诉发送方协议不支持

未知协议会返回ICMP错误。


28.4 原始套接字的用途

ping

ping程序:

  • 用原始套接字发送ICMP回显请求
  • 接收ICMP回显应答
  • 测量往返时间
  • 测试连通性

为什么用原始套接字:

  • ICMP是网络层协议
  • 没有对应的传输层
  • 需要直接访问IP层

ping是最经典的原始套接字应用。


traceroute

traceroute程序:

  • 用原始套接字发送UDP或ICMP
  • 逐渐增加TTL
  • 接收ICMP超时消息
  • 追踪路径上的路由器

为什么用原始套接字:

  • 需要接收ICMP错误消息
  • 需要控制TTL
  • 普通套接字做不到

traceroute也是原始套接字的经典应用。


其他用途

自定义协议:

  • 在用户态实现新协议
  • 不需要修改内核
  • 快速开发和测试

网络扫描:

  • 端口扫描
  • 主机发现
  • 安全审计

协议研究:

  • 研究协议行为
  • 测试各种场景
  • 性能分析

原始套接字的用途非常广泛。


28.5 安全考虑

原始套接字的安全风险

安全风险:

  1. 伪造IP首部

    • 可以伪造源地址
    • 可以伪造各种字段
    • 可能用于攻击
  2. 发送任意协议

    • 可以发送任何协议的报文
    • 可以构造各种攻击报文
    • 可能被滥用
  3. 接收敏感数据

    • 可以收到所有不匹配的IP数据报
    • 可能窃听
    • 安全隐患
  4. 拒绝服务

    • 发送大量伪造报文
    • 消耗目标资源
    • DoS/DDoS攻击

原始套接字功能强大,也有安全风险。


安全措施

常见的安全措施:

  1. 权限限制

    • 需要root权限
    • 普通用户不能创建
    • 最基本的保护
  2. 特权分离

    • 只给需要的程序权限
    • 最小权限原则
    • 降低风险
  3. 网络过滤

    • 防火墙过滤
    • 限制出站报文
    • 防止伪造
  4. 监控和审计

    • 监控原始套接字的使用
    • 记录可疑行为
    • 及时发现攻击

权限限制是最基本的安全措施。


不同系统的差异

不同系统的实现差异:

系统权限要求说明
BSDroot需要超级用户
Linuxroot需要超级用户,也可以用能力
WindowsAdministrator需要管理员权限

基本都需要特殊权限。


28.6 小结

原始IP概述

  1. 什么是原始IP

    • SOCK_RAW类型
    • 直接读写IP数据报
    • 不经过TCP/UDP
  2. 用途

    • 诊断工具(ping、traceroute)
    • 实现新协议
    • 安全工具
    • 研究实验

原始IP的输出

  1. 输出过程

    • 应用构造数据
    • 内核处理
    • IP层发送
  2. IP_HDRINCL选项

    • 0:内核构造首部
    • 1:用户提供首部
    • 控制粒度不同
  3. 输出细节

    • 源地址选择
    • 目的地址
    • 协议号
    • 校验和

原始IP的输入

  1. 输入过程

    • IP层分用
    • 不匹配已知协议的交给原始套接字
    • 遍历匹配
  2. 匹配规则

    • 协议号必须匹配
    • 本地地址可选匹配
    • 外部地址可选匹配
  3. 多个套接字

    • 每个匹配的都收到一份
    • 复制多份
  4. 不匹配

    • 丢弃
    • 发ICMP协议不可达

原始套接字的用途

  1. ping

    • ICMP回显
    • 测试连通性
  2. traceroute

    • 追踪路径
    • 接收ICMP超时
  3. 其他

    • 自定义协议
    • 网络扫描
    • 协议研究

安全考虑

  1. 安全风险

    • 伪造IP首部
    • 发送任意协议
    • 接收敏感数据
    • 拒绝服务
  2. 安全措施

    • 权限限制
    • 特权分离
    • 网络过滤
    • 监控审计
  3. 系统差异

    • 都需要特殊权限
    • 实现略有不同

关键概念

  1. 原始IP套接字

    • SOCK_RAW
    • 直接访问IP层
    • 功能强大
  2. IP_HDRINCL

    • 控制谁构造IP首部
    • 用户可以完全控制
  3. 输入匹配

    • 协议号匹配
    • 多个套接字可以同时收到
    • 不匹配返回ICMP错误
  4. 安全

    • 需要特殊权限
    • 有安全风险
    • 合理使用

原始IP