IP 地址与内网外网

本文参考整理自《计算机网络(第5版)》(清华大学出版社,Adnrew S.Tanenbaum、David J.Wetherrall 著)

IP 地址与内网外网

由于学校项目需要,我需要学习服务器的相关知识,在这里做一个简单记录。本文主要涉及 IP 地址的格式、IP 地址的前缀、子网及子网掩码、IP 地址的分配、NAT 技术(内网与外网)。

IP 地址

IPv4 是一个32位地址,Internet 上每台主机与路由器都有一个 IP 地址,用于 IP 数据包的源地址(Source Address)和目标地址字段(Destination Address)。IP 地址并不指明具体的主机,而是代表一个网络对外显示的接口。路由器由于连接多个网络,故其有多个 IP 地址,而当大多数主机在一个网络中时,他们拥有相同的 IP 地址。

IP 地址的前缀

每一个 IP 地址可以划分成两个部分:高位的网络值和低位的主机值。对于在一个网络中的主机的 IP 地址而言,其网络值是相同的,而主机值是不同的。也就是说一个网络对应一块连续的 IP 地址空间,称此地址空间为地址的前缀
IP 地址采用点分十进制表示法,将32位二进制数表示为4个由点分割的十进制数。网络值决定了最低的 IP 地址以及块的大小(即 IP 地址空间的多少)。考虑 128.208.2.151,若其网络值为 128.208.2.0,即对应此 IP 地址的前24位,那么其最低 IP 地址位 128.208.2.0,块的大小为 2 的 8 次幂,易知块的大小都是 2 的整次幂。按照惯例,网络地址的书写格式是前缀 IP 地址后跟一个斜线,斜线后是网络部分的位长度,因此我们的例子可以表示为 128.208.2.0/24。
对于每个 IP 地址,我们提供一个前 k 位全部都是 1 的 32 位二进制数,将其与 IP 地址进行 AND 操作,即可得到该 IP 地址的网络值,我们将该二进制数称为子网掩码。若 128.208.2.151 的网络部分有 24 位,则其子网掩码就为 255.255.255.0。将两数进行“与”运算,即可得到 128.208.2.151。

子网

子网是为了解决一个网路块的地址划分问题而提出的。在内部将一个网络块分成几个部分供多个内部网络使用,但对外部世界表先的像一个网络一样,我们称之为子网划分,而分割一个大型网络所得到的一系列的网络我们称之为子网。其划分的大致流程大概是这样的,比如一所大学拥有 /16 的网络(网络值位数有16位),其需要进一步划分以将网络分配给若干学院使用,那么他可以把地址空间的一半(/17)分配个计算机学院,四分之一(/18)分配给自动化学院,八分之一(/19)分配给人文与艺术学院,剩下八分之一保留,那么我们可以写出每个学院对应的网络值以及子网掩码。假设 HIT 被分配的网络值为 128.208.0.0/24

学院 2进制网络值
计算机科学与技术学院 10000000 11010000 1xxxxxxx xxxxxxxx
自动化学院 10000000 11010000 01xxxxxx xxxxxxxx
人文与艺术学院 10000000 11010000 001xxxxx xxxxxxxx

其对应的网络值和子网掩码分别为

学院 网络值 子网掩码
计算机科学与技术学院 128.208.128.0 255.255.128.0
自动化学院 128.208.64.0 255.255.64.0
人文与艺术学院 128.208.32.0 128.208.32.0

对于每一个发先校园内部的数据包,路由器仅仅需要根据校园网的子网掩码来得到校园网的网络值(128.208.0.0),从而将数据包发向该地址所在的路由器,到达校园网之后,路由器将 IP 地址与不同的子网掩码进行“与”操作,从而得到一个网络值,将网络值与每个学院的网络值进行匹配,从而将数据包再发送到具体的某一个学院。因此采用子网划分的方法我们可以很好的进行数据包的分层发送。

NAT——网络地址转换(内网与外网)

随着网络使用人数爆炸性的增加,IP 地址已经出现了短缺的问题,对此现在普遍使用 NAT(Network Address Translation)技术以及动态分配策略来缓解目前的状况。
NAT 的基本思想是为每个公司或家庭分配一个 IP 地址,用这个 IP 地址来与外部连接,而在企业的内部网络,每台主机拥有唯一的内部 IP 地址,该地址用来路由内部流量。因此,当一个数据包离开客户网络时,其必须实现一个地址转换,将其内部的 IP 地址转换成企业共享的公共 IP 地址,地址转换由一个叫做NAT盒子的东西来实现。在 IP 地址中,保留有如下表三个范围的地址。

私有化的 IP 地址
10.0.0.0 - 10.255.255.255/8
172.16.0.0 - 172.31.255.255/12
192.168.0.0 - 192.168.255.255/16

这些地址已经被声明为私有化,任何网络都可以在内部随意使用这些地址,并且不允许包含这些地址的数据包出现在网络。
这样做会出现一个问题,当数据包返回时,当其到达公司的主路由器时,其如何知道原本的具体的主机呢?比如说公司内部的一台主机IP为 192.168.0.1 ,而公司对外的真正 IP 为 128.208.2.151,那么当这台主机将数据包发送出去时,其数据报的 SourceAddress 一项会被NAT盒子由 192.168.0.1 转换成 128.208.2.151,那么远程目标主机的应答数据包响应的也只会发送到地址为 128.208.2.151 的主机,而无法进一步发送到内部网络中地址为 192.168.0.1 的主机。
如何解决这个问题呢?由于大多数数据包携带的是 TCP 或 UDP载荷(两者类似,我们只讨论 TCP)NAT 的设计者使用 TCP 的一些特性来解决了这个问题。TCP 的协议头包含了一个端口号(0-65535)用于进程之间的通信,像 IP 地址一样,其也有源端口(source port)和目标端口(destination)。当一个数据包由主机经由 NAT 盒子发送出去时,其源端口号被一个索引值所替代,而索引值指向 NAT 盒子中的一个索引表,索引表中存储了该主机在内部网络中的 IP 地址以及进程的端口号。当应答数据包到达路由器准备发送至源主机时,NAT 盒子会检索其目标端口(由于这个是应答数据包,此时的目标端口号就是之前的源端口号),然后根据目标端口号(其实是一个索引)在索引表找到内部主机对应的 IP 地址以及进程端口号,从而可以继续发送数据包到真正的主机上。
大致流程是这样的:
IP 地址与内网外网

尽管 NAT 解决了 IP 资源短缺的问题,但是其仍然得到了不少反对意见。此处略举一二:

  1. 违反了 IP 结构模型。IP 结构模型声明每个 IP 地址唯一的标识了一台主机。

  2. 打破了端到端的连接模型。我们可以访问远程 Web 服务器,当远程的 Web 服务器却无法主动与我们建立连接(因为他们没有我们的具体 IP 地址)。这种情况需要特殊的配置技术或 NAT 穿越。

解决 IP 地址短缺的问题还有动态分配 IP 地址的方案。即当用户不活跃时收回其 IP 地址并将其分配给他人,但这样做无法满足长时间需要在线的客户的需要,并且容量也很有限。真正要解决这样的问题还是需要 IPv6 的普及。而那时我们可能已经年过半百了(此处手动狗头)