8. 示例
HTTP 中的 IP 代理支持许多可从 IP 分组代理和隧道化中受益的不同用例. 本节示例用于帮助说明 HTTP 中 IP 代理的一些使用方式.
8.1. 远程访问 VPN
以下示例展示点到网络 VPN 设置, 其中客户端接收一组本地地址, 并可通过 IP 代理向任意远程主机发送流量. 这类 VPN 设置可以是 full-tunnel, 也可以是 split-tunnel.
+--------+ IP A IP B +--------+ +---> IP D
| +--------------------+ IP | IP C |
| Client | IP Subnet C <--> ? | Proxy +-----------+---> IP E
| +--------------------+ | |
+--------+ +--------+ +---> IP ...
图 14: VPN 隧道设置
在这种情况下, 客户端在请求中不指定任何范围. IP 代理向客户端分配一个 IPv4 地址 (192.0.2.11), 以及覆盖所有 IPv4 地址的 full-tunnel 路由 (0.0.0.0/0). 随后客户端可以使用被分配地址作为源地址, 向任意 IPv4 主机发送流量.
[[ From Client ]] [[ From IP Proxy ]]
SETTINGS
H3_DATAGRAM = 1
SETTINGS
ENABLE_CONNECT_PROTOCOL = 1
H3_DATAGRAM = 1
STREAM(44): HEADERS
:method = CONNECT
:protocol = connect-ip
:scheme = https
:path = /vpn
:authority = proxy.example.com
capsule-protocol = ?1
STREAM(44): HEADERS
:status = 200
capsule-protocol = ?1
STREAM(44): DATA
Capsule Type = ADDRESS_REQUEST
(Request ID = 1
IP Version = 4
IP Address = 0.0.0.0
IP Prefix Length = 32)
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 1
IP Version = 4
IP Address = 192.0.2.11
IP Prefix Length = 32)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 4
Start IP Address = 0.0.0.0
End IP Address = 255.255.255.255
IP Protocol = 0) // Any
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IP Packet
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IP Packet
图 15: VPN Full-Tunnel 示例
split-tunnel VPN (客户端只能访问特定私有子网集合的情况) 的设置非常类似. 在这种情况下, 所通告路由被限制为 192.0.2.0/24, 而不是 0.0.0.0/0.
[[ From Client ]] [[ From IP Proxy ]]
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 0
IP Version = 4
IP Address = 192.0.2.42
IP Prefix Length = 32)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 4
Start IP Address = 192.0.2.0
End IP Address = 192.0.2.41
IP Protocol = 0) // Any
(IP Version = 4
Start IP Address = 192.0.2.43
End IP Address = 192.0.2.255
IP Protocol = 0) // Any
图 16: VPN Split-Tunnel 示例
8.2. 站点到站点 VPN
以下示例展示如何把分支办公室网络连接到企业网络, 使这些网络上的所有机器都能通信. 在此示例中, IP 代理客户端连接到分支办公室网络 192.0.2.0/24, IP 代理连接到企业网络 203.0.113.0/24. 分支办公室网络中存在一些旧客户端, 它们只允许来自其所在子网中机器的维护请求, 因此 IP 代理被配置了来自该子网的 IP 地址.
192.0.2.1 <--+ +--------+ +-------+ +---> 203.0.113.9
| | +-------------+ IP | |
192.0.2.2 <--+---+ Client | IP Proxying | Proxy +---+---> 203.0.113.8
| | +-------------+ | |
192.0.2.3 <--+ +--------+ +-------+ +---> 203.0.113.7
图 17: 站点到站点 VPN 示例
在这种情况下, 客户端在请求中不指定任何范围. IP 代理向客户端分配一个 IPv4 地址 (203.0.113.100), 以及到企业网络的 split-tunnel 路由 (203.0.113.0/24). 客户端向 IP 代理分配一个 IPv4 地址 (192.0.2.200), 以及到分支办公室网络的 split-tunnel 路由 (192.0.2.0/24). 这允许两个网络上的主机彼此通信, 并允许 IP 代理对分支办公室中的旧主机执行维护. 注意, IP 代理端点在封装被转发分组时会递减 IP Hop Count (或 TTL), 因此要求该字段设置为 255 的协议将无法工作.
[[ From Client ]] [[ From IP Proxy ]]
SETTINGS
H3_DATAGRAM = 1
SETTINGS
ENABLE_CONNECT_PROTOCOL = 1
H3_DATAGRAM = 1
STREAM(44): HEADERS
:method = CONNECT
:protocol = connect-ip
:scheme = https
:path = /corp
:authority = proxy.example.com
capsule-protocol = ?1
STREAM(44): HEADERS
:status = 200
capsule-protocol = ?1
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 0
IP Version = 4
IP Address = 192.0.2.200
IP Prefix Length = 32)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 4
Start IP Address = 192.0.2.0
End IP Address = 192.0.2.255
IP Protocol = 0) // Any
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 0
IP Version = 4
IP Address = 203.0.113.100
IP Prefix Length = 32)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 4
Start IP Address = 203.0.113.0
End IP Address = 203.0.113.255
IP Protocol = 0) // Any
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IP Packet
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IP Packet
图 18: 站点到站点 VPN Capsule 示例
8.3. IP Flow 转发
以下示例展示一个 IP flow 转发设置, 其中客户端请求使用 Stream Control Transmission Protocol (SCTP) (IP protocol 132) 建立到 target.example.com 的转发隧道, 并收到一个可用于传输分组的本地地址和远程地址. 类似方法可用于任何不容易通过现有 HTTP 方法代理的其他 IP 协议, 例如 ICMP, Encapsulating Security Payload (ESP) 等.
+--------+ IP A IP B +--------+
| +-------------------+ IP | IP C
| Client | IP C <--> D | Proxy +---------> IP D
| +-------------------+ |
+--------+ +--------+
图 19: 被代理 Flow 设置
在这种情况下, 客户端在其请求范围中同时指定目标主机名和 Internet Protocol Number, 表明它只需要与单个主机通信. IP 代理能够代表客户端执行 DNS 解析, 并为客户端分配一个特定出站 socket, 而不是向客户端分配整个 IP 地址. 从这个角度看, 该请求类似于常规 CONNECT 代理请求.
IP 代理向客户端分配单个 IPv6 地址 (2001:db8🔢:a), 以及限定于 SCTP 的到单个 IPv6 主机 (2001:db8:3456::b) 的路由. 客户端可以向远程主机发送和接收 SCTP IP 分组.
[[ From Client ]] [[ From IP Proxy ]]
SETTINGS
H3_DATAGRAM = 1
SETTINGS
ENABLE_CONNECT_PROTOCOL = 1
H3_DATAGRAM = 1
STREAM(44): HEADERS
:method = CONNECT
:protocol = connect-ip
:scheme = https
:path = /proxy?target=target.example.com&ipproto=132
:authority = proxy.example.com
capsule-protocol = ?1
STREAM(44): HEADERS
:status = 200
capsule-protocol = ?1
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 0
IP Version = 6
IP Address = 2001:db8:1234::a
IP Prefix Length = 128)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 6
Start IP Address = 2001:db8:3456::b
End IP Address = 2001:db8:3456::b
IP Protocol = 132)
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated SCTP/IP Packet
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated SCTP/IP Packet
图 20: 被代理 SCTP Flow 示例
8.4. 被代理连接竞速
以下示例展示一种设置, 其中客户端通过 IP 代理代理 UDP 分组, 以便按 Happy Eyeballs [HEv2] 的定义控制通过 IP 代理进行的连接建立竞速. 此示例是被代理 flow 的一种变体, 但突出了 IP 级代理如何启用新能力, 即使对于 TCP 和 UDP 也是如此.
+--------+ IP A IP B +--------+ IP C
| +-------------------+ |<------------> IP E
| Client | IP C <--> E | IP |
| | D <--> F | Proxy |
| +-------------------+ |<------------> IP F
+--------+ +--------+ IP D
图 21: 被代理连接竞速设置
与被代理 flow 一样, 客户端在其请求范围中同时指定目标主机名和 Internet Protocol Number. 当 IP 代理代表客户端执行 DNS 解析时, 它可以把各种远程地址选项作为独立路由发送给客户端. 它还可以确保客户端同时被分配 IPv4 和 IPv6 地址.
IP 代理向客户端同时分配 IPv4 地址 (192.0.2.3) 和 IPv6 地址 (2001:db8🔢:a), 以及 IPv4 路由 (198.51.100.2) 和 IPv6 路由 (2001:db8:3456::b). 这些路由表示目标主机名解析得到的地址, 并限定于 UDP. 客户端可以向任一 IP 代理地址发送和接收 UDP IP 分组, 以通过 IP 代理启用 Happy Eyeballs.
[[ From Client ]] [[ From IP Proxy ]]
SETTINGS
H3_DATAGRAM = 1
SETTINGS
ENABLE_CONNECT_PROTOCOL = 1
H3_DATAGRAM = 1
STREAM(44): HEADERS
:method = CONNECT
:protocol = connect-ip
:scheme = https
:path = /proxy?target=target.example.com&ipproto=17
:authority = proxy.example.com
capsule-protocol = ?1
STREAM(44): HEADERS
:status = 200
capsule-protocol = ?1
STREAM(44): DATA
Capsule Type = ADDRESS_ASSIGN
(Request ID = 0
IP Version = 4
IP Address = 192.0.2.3
IP Prefix Length = 32),
(Request ID = 0
IP Version = 6
IP Address = 2001:db8::1234:1234
IP Prefix Length = 128)
STREAM(44): DATA
Capsule Type = ROUTE_ADVERTISEMENT
(IP Version = 4
Start IP Address = 198.51.100.2
End IP Address = 198.51.100.2
IP Protocol = 17),
(IP Version = 6
Start IP Address = 2001:db8:3456::b
End IP Address = 2001:db8:3456::b
IP Protocol = 17)
...
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IPv6 Packet
DATAGRAM
Quarter Stream ID = 11
Context ID = 0
Payload = Encapsulated IPv4 Packet
图 22: 被代理连接竞速示例