Web 开发需要掌握的网络知识
Web 开发需要掌握的网络知识
0x0 16进制了解
16进制(Hexadecimal,简称 Hex)是一种以16为基数的进位制。
它使用以下16个符号来表示数值:
| 十进制 | 十六进制 | 二进制 | 十进制 | 十六进制 | 二进制 |
|---|---|---|---|---|---|
| 0 | 0 | 0000 | 8 | 8 | 1000 |
| 1 | 1 | 0001 | 9 | 9 | 1001 |
| 2 | 2 | 0010 | 10 | A | 1010 |
| 3 | 3 | 0011 | 11 | B | 1011 |
| 4 | 4 | 0100 | 12 | C | 1100 |
| 5 | 5 | 0101 | 13 | D | 1101 |
| 6 | 6 | 0110 | 14 | E | 1110 |
| 7 | 7 | 0111 | 15 | F | 1111 |
为什么需要16进制?
在计算机中,最小存储单位是字节 (Byte),一个字节等于8个二进制位 (bit)。
| 表示法 | 值 | 特点 |
|---|---|---|
| 二进制 | 1010 1000 | 太长,不便阅读 |
| 十进制 | 168 | 可读性一般,无法与字节的二进制表示一一对应 |
| 十六进制 | 0xA8 | 最简洁,与字节的二进制表示一一对应 |
因此,十六进制最适合表示字节数据。
0x1 网络架构图
flowchart TB
%% 样式定义
classDef app fill:#d4f1f9,stroke:#3b82f6,stroke-width:2px,color:#1e3a8a;
classDef trans fill:#dcfce7,stroke:#22c55e,stroke-width:2px,color:#14532d;
classDef net fill:#fef9c3,stroke:#facc15,stroke-width:2px,color:#854d0e;
classDef link fill:#fce7f3,stroke:#ec4899,stroke-width:2px,color:#831843;
%% TCP/IP 四层模型
subgraph L4[应用层]
A1[HTTP]:::app
A2[TLS]:::app
A31[HTTP2]:::app
A32[GRPC]:::app
A4[FTP]:::app
A52[HTTP3]:::app
A51[QUIC]:::app
A6[DNS]:::app
end
subgraph L3[传输层]
B1[TCP]:::trans
B2[UDP]:::trans
end
subgraph L2[网络层]
C1[IP]:::net
C2[ICMP]:::net
C3[RIP/OSPF/BGP]:::net
C4[ARP]:::net
end
subgraph L1[物理层]
D1[Ethernet]:::link
D2[Wi-Fi]:::link
D3[4G/5G]:::link
end
%% 层级连接
A1 --> B1
A2 --> B1
A31 --> B1
A1 --> A2
A31 --> A2
A32 --> A31
A4 --> B1
A51 --> B2
A52 --> A51
A6 --> B2
B1 --> C1
B2 --> C1
C1 --> D1
C1 --> D2
C1 --> D3
0x2 物理层
Ethernet II 帧格式
| 前导码 | 帧开始符 | MAC 目标地址 | MAC 源地址 | 802.1Q 标签(可选) | 以太类型 | 负载 | 冗余校验 | 帧间距 |
|---|---|---|---|---|---|---|---|---|
| 10101010 (0xAA) 7个octet | 10101011 (0xAB) 1个octet | 6 octets | 6 octets | (4 octets) | 2 octets | 46–1500 octets | 4 octets | 12 octets |
| 64–1518 octets | ||||||||
MTU 不是以太网帧的字段。如果本机网卡发送的帧超过目标主机支持的 MTU,通常情况下目标主机会直接丢弃该帧。
0x3 网络层
IPv4 头部格式
| Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bit | 0-3 | 4-7 | 8-13 | 14-15 | 16-18 | 19-31 | ||||||||||||||||||||||||||
| 0 | 版本 | 首部长度 | 区分服务 | ECN | 报文总长(字节) | |||||||||||||||||||||||||||
| 32 | 标识符 | 标志 | 分片偏移 | |||||||||||||||||||||||||||||
| 64 | 存活时间 | 协议 | 首部检验和 | |||||||||||||||||||||||||||||
| 96 | 源IP地址 | |||||||||||||||||||||||||||||||
| 128 | 目标IP地址 | |||||||||||||||||||||||||||||||
| 160 | 可选项 | |||||||||||||||||||||||||||||||
| ⋮ | ||||||||||||||||||||||||||||||||
| 448 | ||||||||||||||||||||||||||||||||
私有 IPv4 地址
| IP地址区块 | IP数量 |
|---|---|
| 10.0.0.0 – 10.255.255.255 | 16,777,216 |
| 172.16.0.0 – 172.31.255.255 | 1,048,576 |
| 192.168.0.0 – 192.168.255.255 | 65,536 |
当一个 IP 数据包的大小超过物理层的 MTU 时,IP 层会把数据包切割成多个切片,每一片都带有相同的标识字段,并通过片偏移指明它在原始数据中的位置。
IPv6 头部格式
| Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bit | 0-3 | 4-11 | 12-15 | 16-23 | 24-31 | |||||||||||||||||||||||||||
| 0 | 版本 | 通信类 | 流标签 | |||||||||||||||||||||||||||||
| 32 | 有效载荷长度(字节) | 下一个头部 | 跃点限制 | |||||||||||||||||||||||||||||
| 64 | 源IP地址 | |||||||||||||||||||||||||||||||
| 96 | ||||||||||||||||||||||||||||||||
| 128 | ||||||||||||||||||||||||||||||||
| 160 | ||||||||||||||||||||||||||||||||
| 192 | 目标IP地址 | |||||||||||||||||||||||||||||||
| 224 | ||||||||||||||||||||||||||||||||
| 256 | ||||||||||||||||||||||||||||||||
| 288 | ||||||||||||||||||||||||||||||||
0x4 传输层
UDP 头部格式
| Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bit | 0-15 | 16-31 | ||||||||||||||||||||||||||||||
| 0 | 源端口 | 目标端口 | ||||||||||||||||||||||||||||||
| 32 | 报文总长(字节) | 校验和 | ||||||||||||||||||||||||||||||
TCP 头部格式
| Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bit | 0-3 | 4-6 | 7-15 | 16-31 | ||||||||||||||||||||||||||||
| 0 | 源端口 | 目标端口 | ||||||||||||||||||||||||||||||
| 32 | 序列号 | |||||||||||||||||||||||||||||||
| 64 | 确认号 | |||||||||||||||||||||||||||||||
| 96 | 头部长度(4字节) | 保留 | 标志 | 窗口大小 | ||||||||||||||||||||||||||||
| 128 | 校验和 | 紧急指针 | ||||||||||||||||||||||||||||||
| 160 | 可选项 | |||||||||||||||||||||||||||||||
| ⋮ | ||||||||||||||||||||||||||||||||
| 448 | ||||||||||||||||||||||||||||||||
0x5 路由
子网
子网(Subnet) 是对 IP 网络的一种划分方式。通过 子网掩码(Subnet Mask) 将一个大的网络划分为多个较小的网络,从而更高效地利用 IP 地址,并便于网络管理与安全控制。
- IP 地址分为两部分,网络地址和主机号。
- 将子网掩码于IP地址进行按位与(&)运算得到网络地址。
- 在 IPv4 中,常用十进制四组表示法表示子网掩码,例如 255.255.255.0。
- 更为简短的形式叫做CIDR(Classless Inter-Domain Routing)表示法,它给出的是一个地址加上一个斜杠以及网络掩码的二进制表示法中“1”的位数,即网络号中和网络掩码相关的是哪些位。例如,192.168.1.0/24 表示的是一个前24位被用作网络号的IP地址,等价与子网掩码 255.255.255.0。
- 一个子网中主机号最小的地址为网络地址,最大的地址为广播地址,两个地址不可被分配给主机。例如,192.168.0.0/20(子网掩码为 255.255.240.0)表示的子网中,192.168.0.0 为网络地址,192.168.15.255 为广播地址。
交换机
交换机(Switch)是一种工作在 物理层 的网络设备,主要用于在局域网(LAN)中转发数据包。
它工作在 物理层。
- 交换机通过 MAC 地址表 来识别并转发数据。
- 当数据帧到达交换机时,交换机会读取其 源 MAC 地址 并更新表项。
- 根据 目的 MAC 地址,交换机决定将数据帧转发到哪个端口,而不是像集线器一样进行广播。
路由器
路由器(Router) 是一种工作在 网络层 的网络设备,主要功能是负责在 不同网络之间 转发数据包。
它通过 IP 地址 来决定数据的转发路径,是实现互联网互联的重要设备。
- 路由器接收到数据包后,会读取其中的 目的 IP 地址。
- 根据内置的 路由表(Routing Table),选择最佳路径将数据包转发到下一跳设备。
- 若没有对应的路径,可以通过 默认网关 或 动态路由协议(如 RIP、OSPF、BGP)来找到转发方式。
详细的路由过程
A 给 B 发送包
- 首先通过 B 的 IP 地址判断,A 和 B 在同一个子网下
- 然后通过 ARP 获取 B 的 MAC 地址
ARP 是一种网络协议,用于在 已知 IP 地址的情况下,获取其对应的 MAC 地址。它工作在 网络层和物理层之间,是 IPv4 网络通信中必不可少的协议。当一台主机要向同一局域网内的另一台主机发送数据时,需要知道目标设备的 MAC 地址。若 ARP 缓存表中没有记录,主机会广播一个 ARP 请求,目标设备收到后会回应 ARP 响应。
- A 将目标 IP 地址和目标 MAC 地址都填为 B 后发送出去
- 交换机1 收到包后根据 MAC 地址判断为 B 将包转发给 B
A 给 C 发送包
- 首先通过 C 的 IP 地址判断,A 和 C 不在同一个子网下
- 然后通过 ARP 获取 A 的默认网关(即路由器1)的 MAC 地址
- A 将目标 IP 地址填为 C ,目标 MAC 地址填为 路由器1 后发出
- 路由器1 收到包后根据 IP 地址和路由表确定应该往交换机2方向发送
- 路由器1 通过 ARP 获取 C 的 MAC 地址
- 路由器1 将包的目标 MAC 地址填为 C 后发出
- 交换机2 收到包后根据 MAC 地址转发给 C
A 给 E 发送包
- 首先通过 E 的 IP 地址判断,A 和 C 不在同一个子网下
- 然后通过 ARP 获取 A 的默认网关(即路由器1)的 MAC 地址
- A 将目标 IP 地址填为 C ,目标 MAC 地址填为路由器1 后发出
- 路由器1 收到包后根据 IP 地址和路由表确定应该往路由器2 方向发送
- 路由器1 通过子网判段,E 不在它连接的子网内,目标 MAC 地址填为路由器后发出
- 路由器2 根据目标 IP 地址判断数据包是从内网发往公网的,此时会启用 NAT。路由器为该连接分配一个可用端口,并将数据包的源 IP 地址替换为其在公网中的 IP 地址,同时将源端口改为所分配的端口,再转发至公网。
NAT(Network Address Translation),又称 IP 动态伪装,是一种在 IP 数据包通过路由器或防火墙时重写来源或目的 IP 地址或端口的技术。这种技术普遍应用于有多台主机,但只通过一个公有 IP 地址访问互联网的私有网络中。NAT 部署简便,并且保证了对现有 TCP/IP 协议栈的兼容性,因此在实际应用中得到了广泛采用。然而,NAT 也让主机之间的通信变得复杂,导致了通信效率的降低。
- 当 E 收到数据包并发送响应时,返回的数据包会沿着 NAT 映射的路径回到内网。
0x6 网络安全
非对称加密算法与数字签名
非对称加密(Asymmetric Encryption),也称为 公钥加密,是一类使用 一对密钥(公钥与私钥)来实现加密与解密的算法。
使用公钥加密的信息,只能由对应的私钥解密。使用私钥签名的信息,可以用对应的公钥验证。
sequenceDiagram
participant Sender as 发送方
participant Receiver as 接收方
Sender->>Sender: 对消息做哈希运算
Sender->>Sender: 用私钥加密哈希值生成签名
Sender->>Receiver: 发送 [消息 + 签名]
Receiver->>Receiver: 对收到的消息做哈希运算
Receiver->>Receiver: 用发送方公钥解密签名得到原哈希
Receiver->>Receiver: 比较两者是否一致
X509 证书链示例
Google Trust Services R1 CA 证书
1 | |
Google Trust Services WR2 证书
1 | |
Google 域名证书
1 | |
X509 证书体系
flowchart TD
RootCA["根证书机构 (Root CA)"]
IntermediateCA["中级证书机构 (Intermediate CA)"]
EndEntity["终端实体 (服务器/用户证书)"]
Client["客户端 (浏览器/应用)"]
RootCA -->|签发证书| IntermediateCA
IntermediateCA -->|签发证书| EndEntity
EndEntity -->|提供证书给| Client
Client -->|验证证书链 & 根证书可信| RootCA
style RootCA fill:#f96,stroke:#333,stroke-width:1px
style IntermediateCA fill:#fc9,stroke:#333,stroke-width:1px
style EndEntity fill:#9cf,stroke:#333,stroke-width:1px
style Client fill:#cfc,stroke:#333,stroke-width:1px
TLS 握手
sequenceDiagram
participant C as Client
participant S as Server
C->>S: ClientHello (支持的协议版本、加密套件、随机数)
S->>C: ServerHello (选择的协议版本、加密套件、随机数)
S->>C: Certificate (服务器证书)
S->>C: ServerHelloDone
C->>S: ClientKeyExchange (预主密钥或公钥加密)
C->>S: ChangeCipherSpec
C->>S: Finished (握手摘要)
S->>C: ChangeCipherSpec
S->>C: Finished (握手摘要)
中间人攻击
sequenceDiagram
participant Client as 客户端
participant Attacker as 攻击者(中间人)
participant Server as 真实服务器
Client->>Attacker: 发起TLS握手 (请求example.com证书)
Note over Attacker: 拦截请求<br>并伪造证书<br>(由恶意CA或本地根证书信任)
Attacker->>Client: 返回伪造证书 (客户端验证通过)
Note over Client: 客户端以为自己<br>在和真实服务器通信
Client->>Attacker: 建立TLS会话 (与伪造证书)
Attacker->>Server: 建立真实TLS会话 (使用真实证书)
Client->>Attacker: 发送加密数据
Attacker->>Attacker: 解密并篡改/窃听
Attacker->>Server: 转发修改后的数据
Server->>Attacker: 返回响应数据
Attacker->>Attacker: 解密并修改
Attacker->>Client: 转发伪造响应
Note over Client,Server: 攻击者成功在双方之间解密并篡改数据
0x7 代理
应用层代理
sequenceDiagram
participant App as 应用
participant Proxy as 代理客户端
participant ProxyServer as 代理服务器
participant BlockedSite as 被墙网站
App->>Proxy: 通过代理协议建立连接
App->>Proxy: 通过代理客户端访问目标网站
Proxy->>ProxyServer: 将请求流量封装并发送给代理服务器
ProxyServer->>BlockedSite: 访问目标网站
BlockedSite-->>ProxyServer: 返回响应内容
ProxyServer-->>Proxy: 将响应流量封装并返回给代理客户端
Proxy-->>App: 将响应返回给应用
应用层代理不需要任何高级权限就能实现代理,但需要应用支持代理协议。
网络层代理
sequenceDiagram
participant App as 应用
participant Proxy as 代理客户端 (with Fake DNS)
participant ProxyServer as 代理服务器
participant TrueDNS as 真实 DNS 服务器
participant BlockedSite as 被墙网站
Note over App,Proxy: 客户端发起 DNS 查询
App->>Proxy: 查询 example.com 的 DNS
Proxy-->>App: 返回 Fake IP
Note over App: 客户端以为得到了真实 IP
App->>Proxy: 访问 Fake IP
Proxy->>ProxyServer: 将请求流量封装并发送给代理服务器
Note over ProxyServer: 代理服务器解析真实域名
ProxyServer->>TrueDNS: DNS 查询 example.com
TrueDNS-->>ProxyServer: 返回真实 IP
ProxyServer->>BlockedSite: 访问真实 IP
BlockedSite-->>ProxyServer: 返回响应
ProxyServer-->>Proxy: 将响应流量封装并返回给代理
Proxy-->>App: 将响应返回给应用
Note over App: 客户端通过 Fake IP 访问到了被屏蔽网站
网络层代理能够让所有应用的流量经过代理,而无需应用自身支持代理协议。由于网络层代理需要修改系统网络设置,因此需要管理员权限。
