# IP

:因特网协议(Internet Protocol)

  • 属于网络层协议。
  • IP 协议主要有 IPv4、IPv6 两个版本,后者尚未普及。
  • 两个主机,可以通过 IP 协议相互通信,但需要注意:
    • 各个主机,必须使用不同的 IP 地址,表示自己的身份。相当于一个身份 ID 。因此:
      • 一个主机加入一个网络时,必须绑定一个该网络的 IP 地址,才能通过 IP 协议与该网络的其它主机相互通信。
      • 一个主机可以拥有同一个网络的多个 IP 地址。也可以同时加入多个网络,拥有不同网络的多个 IP 地址。
    • 两个主机之间通过 IP 协议通信时,不会建立连接。IP 协议只提供尽力而为的数据传输服务,只管把数据发送出去,不进行差错控制。因此是不可靠的通信协议。

# 寻址

  • IP 数据包中会记录源 IP 地址、目标 IP 地址。封装成以太网帧之后,记录的就是源 Mac 地址、目标 Mac 地址。

    • 在数据链路层,通常采用以太网协议进行网络通信,根据 Mac 地址来寻址。
      • 每个主机收到一个以太网帧时,会检查其目标 Mac 地址。如果是本机地址,则接收该帧,否则转发或丢弃该帧。
    • 在网络层,通常采用 IP 协议进行网络通信,根据 IP 地址来寻址。
      • 每个主机收到一个 IP 数据包时,会检查其目标 IP 地址。如果是本机地址,则接收该包,否则转发该包。
  • 假设主机 A 的 IP 为 10.0.0.1/24 ,想发送一个 IP 协议的数据包给主机 B 。

    • 如果已知主机 B 的 IP 为 10.0.1.2/24 ,位于另一个子网。则主机 A 会将 IP 包发送给网关,进行路由转发。
      • 在网络层,该 IP 包的目标地址填的是 10.2.0.2 。
      • 在数据链路层,该 IP 包封装在以太网帧里,帧头的目标地址填的是网关的 Mac 地址。
    • 如果已知主机 B 的 IP 为 10.0.0.2/24 ,位于同一个子网,则可以在物理层直接通信:将 IP 包封装在以太网帧里,帧头的目标地址填的是主机 B 的 Mac 地址。
    • 如果已知主机 B 的 IP 为 10.0.0.2/24 ,但不知道主机 B 的 Mac 地址,则不能在物理层寻址,比如 ping 不通。需要使用 ARP 协议,查询主机 B 的 Mac 地址。
  • 根据接收者数量的不同,可将目标 IP 地址分为几类:

    • 单播地址(unicast):发往单个 IP 地址。
    • 多播地址(multicast):发往一组 IP 地址。
    • 广播地址(broadcast):地址全为 1 ,可以被所有 IP 的主机接收。
  • 根据网络用途的不同,可将 IP 地址分为两类:

    • 私有 IP 地址
      • :接入私有网络(比如一个局域网)的每台主机,需要绑定一个私有 IP 地址,在该网络中唯一。
    • 公有 IP 地址
      • 接入因特网的每台主机,需要绑定一个公有 IP 地址,在全球因特网中唯一。

# IPv4

  • IP 协议主要有 IPv4、IPv6 两个版本,后者尚未普及。
  • IPv4 地址的长度为 32 位,分为 4 个字段。
    • 每个字段有 8 位,用点分十进制表示就是每个字段为一个 0~255 的十进制数。
    • 采用 "网络号+主机号" 的结构,每个网络号表示一个逻辑网络。

# 分类

根据开头几位的不同,可将 IPv4 地址分为 5 类:

  • A 类地址
    • 以一个 0 开头,网络号占 8 位,主机号占 24 位,取值范围为 0.0.0.0~127.255.255.255
    • 第一个字段有 2^7=128 个可能值,取值范围为 0~127 。
    • 排除网络号全为 0 的 IP 地址、私有地址 10.*.*.*、环回地址 127.*.*.* 之后,可分配的网络号有 125 个。
      • 每个网络排除全为 0、全为 1 的主机号之后,可分配的主机号有 224-2 个。
      • 因此,可分配的 A 类地址总共有 231 个左右,占全部 IP 地址的一半。
    • A 类的私有地址:10.*.*.*
  • B 类地址
    • 以 10 开头,网络号占 16 位,主机号占 16 位,取值范围为 128.0.0.0~191.255.255.255
    • 第一个字段有 2^6=64 个可能值,取值范围为 128~191 。
    • 可分配的网络号有 214 个,每个网络可分配的主机号有 216-2 个。
    • B 类的私有地址:172.16.*.*~172.31.*.* ,共 16 个网络号。
  • C 类地址
    • 以 110 开头,网络号占 24 位,主机号占 8 位,取值范围为 192.0.0.0~223.255.255.255
    • 第一个字段有 2^5=32 个可能值,取值范围为 192~223 。
    • 可分配的网络号有 221 个,每个网络可分配的主机号只有 28-2=254 个。
    • C 类的私有地址:192.168.*.* ,共 256 个网络号。
  • D 类地址
    • 以 1110 开头,用于多播地址,取值范围为 224.0.0.0~239.255.255.255
  • E 类地址
    • 以 11110 ,保留给实验或未来使用,取值范围为 240.0.0.0~247.255.255.255

# 特殊地址

以下 IPv4 地址不能用于因特网:

  • 私有 IP 地址 :保留给私有网络使用。这样当主机接入因特网时,路由器能识别出该 IP 是私有 IP 从而忽视它。
  • 127.*.*.* :环回地址(lookback、localhost)。
    • 发向该 IP 地址的数据包会直接回送到本机,不会被网卡发出去。即只在物理层传输,不会到数据链路层。
    • 127.0.0.0 是网络号,一般使用 127.0.0.1 。
    • 环回地址对应的子网掩码为 255.255.255.255 。
  • 0.0.0.0 :在路由表中用作默认网关,没有找到路由的数据包都会转发给默认网关。
    • 如果服务器监听 0.0.0.0 ,则会接受来自任何 IP 地址的访问。

每个网络的以下 IPv4 地址有特殊用途:

  • 主机号全为 0 :表示该网络本身的网络号。
  • 网络号全为 0 :表示只发送给该网络的主机。
    • 数据包会被路由器限制在该网络内,发送给主机号对应的主机。
  • 主机号全为 1 :直接广播地址,数据包会被广播给目标网络内的所有主机。
  • IP 地址全为 1 :受限广播地址,数据包会广播给当前网络内的所有主机。
    • 对应的 MAC 地址为 ffff.ffff.ffff 。
  • 一般将每个网络的第一个主机号留给网关使用,比如 10.0.0.1 。

# 短缺问题

随着因特网的发展,用户越来越多,IPv4 越来越短缺。主要原因:

  • B 类地址的一个网络中可分配的主机号太多,实际接入的主机少,即使接入了这么多主机也会因为路由表太大增加路由器的负担,导致网络服务质量下降。
  • C 类地址可分配的网络号很多,但每个网络中可分配的主机号较少,只适用于小型局域网。

为了解决 IPv4 地址短缺的问题,人们研发了多种对策:

  • 划分子网(subnet)
    • :将一个容量大的网络分成几个子网络,将 IP 地址改成 网络号+子网号+主机号 的三级结构(只适用于 A、B、C 类地址),然后用 ip 子网掩码ip/子网掩码长度 的形式表示该子网。
      • 网络号和子网号对应位的子网掩码(subnet mask)全为 1 ,主机号对应位的子网掩码全为 0 。
      • 一个子网 IP 地址与其子网掩码按位与的结果,就是其子网号。
    • 例如:对于 192.168.0.0 ,该网络可容纳 2^8-2 个主机,
      • 从 8 位主机号中取出前一位,便可划分 192.168.0.0/25 和 192.168.0.128/25 两个子网,每个子网可容纳 2^7-2 个主机。
      • 再将 192.168.0.128/25 的子网掩码延长一位,又可划分两个子网,每个子网可容纳 2^6-2 个主机。
      • 每个网络中全为 0 和全为 1 的主机号不可用,因此在 192.168.0.128/25 这个子网中,第一个可用的 IP 地址是 192.168.0.129/25 ,最后一个可用的 IP 地址是 192.168.0.254/25 。
    • 不划分子网时,A 类地址的默认子网掩码是 255.0.0.0 ,B 类地址的默认子网掩码是 255.255.0.0 ,C 类地址的默认子网掩码是 255.255.255.0 。
    • 子网掩码为 255.255.255.255 表示该子网只有一个主机,通常用于环回网口。
  • 构成超网(supernet)的无类别域间路由(CIDR)技术
    • :将网络号前 n 位相同的网络看作同类并合并为一个网络,又称为地址聚合、路由聚合。
    • 例如:192.168.0.129 与 192.168.0.130 的前 30 位相同,聚合后的网络为 192.168.0.128/30 。
    • 例如:汇聚 .01010000 与 .01010001 、 .01010010 时,三个 IP 地址的前 30 位相同,但是只有两位主机号,去掉全为 0 和全为 1 的主机号后只能分配两个主机号,所以聚合后的网络应该为 .01010000/29 。又因为 .01010000 这个地址已经被占用,为了避免发生冲突,要一直退位,所以聚合结果为 .01000000/27 。
  • 网络地址转换(Network Address Translation ,NAT)
    • :在一个私有网络中,每个主机访问内网的某个主机时,源地址、目标地址都使用私有 IP 地址。访问公网的某个主机时,源地址、目标地址才使用公有 IP 地址。
  • 使用 IPv6 地址
    • 这能从根本上解决 IPv4 地址短缺的问题。
    • 不过目前 IPv6 协议尚未在全球普及,不够通用。

# IPv6

  • IPv6 地址的长度为 128 位,分为 8 个字段,每个字段有 16 位,用冒号十六进制表示就是每个字段有 4 个 0~F 的十六进制数。
  • 每个字段前面的 0 可以省略,不过每个位段至少要有一个数字,或者连续几个位段全为 0 时可以省略它们而用双冒号表示。
    • 双冒号不可以出现两次,否则无法判断省略的位数。
    • 例如:0000:210A:0000:0000:02AA:000F:0000:0000 可简写成 0:210A:0:0:2AA:F:0:0 ,再进一步可简写成 0:210A::2AA:F:0:00:210A:0:0:2AA:F::
  • IPv6 协议具有巨大的地址空间、新的协议格式、有效的分级结构等优点。

# 相关概念

# MTU

  • MTU(Maximum Transmission Unit,最大传输单元)是指允许传输的数据包的最大体积,单位为 bytes 。
    • IP 包需要封装成以太网帧之后才能传输。而封装时,需要添加几十字节的以太网协议的 metadata ,增加了网络流量。
      • IEEE 802.3 定义了一个以太网帧的体积最小为 64 bytes ,最大为 1518 bytes 。
      • 为了节约网络流量,应该让每个 IP 包只封装成一个以太网帧(而不是多个),因此通常限制每个 IP 包的最大体积 MTU 为 1500 bytes 。
      • 如果一个 IP 包超过 MTU ,在 IPv4 的情况下会被拆分成多个 IP 包再传输,在 IPv6 的情况下会被丢弃。
    • 网卡通常提供了 MTU 配置参数,允许用户调整。
      • 例如某台主机的 MTU 比路由器的 MTU 大,则可能发送体积过大的 IPv4 包,被路由器拆分传输,导致以太网帧数量变多,增加了网络流量。

# IPsec

  • IPsec 是加密版本的 IP 协议。
  • IP 协议的数据包中,payload 是明文传输,可能被第三方窃听、篡改。
  • IPsec 协议将 IP 数据包的 payload 加密之后再传输,从而提高通信安全性。而数据包的头部(比如 src_ip、dst_ip)依然公开,从而能被路由转发。

# NAT

  • NAT(Network Address Translation,网络地址转换)不是一种网络协议,而是对 IP 协议包的一种操作,修改其中的源 IP 地址或目标 IP 地址。

  • 例如:

    • 用户可以在某台 Linux 主机上,用 iptables 命令添加 NAT 规则,处理该主机收发的 IP 包。
    • 用户可以在局域网的路由器软件中,配置 NAT 规则,处理该局域网收发的所有 IP 包。此时,该路由器称为 NAT 网关。
  • NAT 操作分为两类:

    • DNAT(Destination NAT):修改目标 IP 地址。
    • SNAT(Source NAT):修改源 IP 地址。
  • NAT 网关的常见用途是,让一个私有网络接入公网。

    • 原理:
      • 一个私有网络中,可能所有主机都没有公网 IP 地址,因此不能访问公网。
      • 可以给私有网络部署一台 NAT 网关,绑定一个公网 IP 地址。此时,该 NAT 网关同时接入了私有网络、公网,能将内网主机的 IP 包转发到公网,或者将公网的 IP 包转发到内网。
      • NAT 网关转发 IP 包时,必须修改其中源 IP 地址或目标 IP 地址,才能让 IP 包被送到正确的目标主机。
      • NAT 网关会维护一张 NAT 表,记录每个私网 IP 与公网 IP 的转换关系。
  • NAT 表的分类:

    • 静态 NAT(Static NAT)
      • :给每个内网 IP 映射一个独享的公网 IP 。因此配置 NAT 表之后,映射关系不会变化。
      • 缺点:
        • 如果有 n 个内网 IP ,就需要购买 n 个公网 IP ,成本高。
    • 动态 NAT(Pooled NAT)
      • :让一个公网 IP 被多个内网 IP 共享,但同时只能被一个内网 IP 映射。每次修改映射关系,就需要更新 NAT 表。
      • 缺点:
        • 同时只有一个内网 IP 能访问公网。
    • 端口多路复用(Port Address Translation ,PAT)
      • :让一个公网 IP 被多个内网 IP 共享,但使用不同的 TCP 端口。
      • 假设一个内网 IP 监听了 TCP 80 端口,映射到公网 IP 的 TCP 80 端口。其它内网 IP 虽然可以同时使用这个公网 IP ,但只能映射不同的 TCP 端口。