目录
PPTP简介
PPTP工作流程
建立连接
数据传输
直接穿越NAT会有什么问题
NAT44 NAT64
NAT66
NAT ALG PPTP实现方法
1. NAT 设置一个 call-id pool
2. 建立连接时
3. 数据传输时
结语
PPTP全称Point to Point Tunneling Protocol,点对点隧道协议。
本质上就是个隧道, GRE头包裹加密数据,常用于VPN。
PPTP建立连接是要client主动connect 到PPTP Server,经过一系列交互后完成。
大致交互过程如下
1. client 生成一个Client-call-id,发送给Server
2. Server 也为这个client生成一个server-call-id, 发送给Client. 针对每个client,server都会分配一个server-call-id.
3. Server对client的校验(用户名、密码 or 秘钥等)
4. Server 为client分配 PPTP IP address
5. client已连入Server的虚拟局域网,连接完成。
IP header1 | GRE Header | PPP payload | |
IP header2 | data |
IP header1, src: client ip, dst: server ip, 无tcp udp port
GRE Header, 带有对端call-id.
IP header2, src: pptp client ip, dst: pptp server ip... 这是虚拟局域网中client和server的地址
Client ---> Server
GRE header里面带上 Server-call-id,Server通过这个Server-call-id识别是哪个client.Client ----> Server
Server ----> Client
GRE header里面带上Client-call-id
数据传输时是GRE包,无Port。
内网多个ip 映射一个外网ip,有GRE里的call-id, 从client 到server 看起来没什么问题。
从server回client就有问题了,根据回包call-id,理论上NAT也可以找到对应的client,但是不同的主机的call-id是极有可能重复的,它们之间是没有协商的。
当有2个主机的call-id一样时,NAT是无法分辨回包是去到哪里的。
内网IP和外网IP一一对应,很好溯源,这种情况下,PPTP是可以顺利穿越的。
针对不同主机Client-call-id重复导致PPTP无法穿越NAT, 可以通过NAT分配client-call-id来避免重复,完美溯源。
下面是一种简单的设计:
pptp_session {
ip address
local-call-id
nat-call-id
server-call-id
}
2.1 Client向Server请求连接,记录client-call-id至pptp_session的local-call-id,再为每一个Client 分配一个 nat-call-id,并建立map表,nat-call-id映射到该pptp_session。
2.2 Server回复Client, 记录 Server-call-id至pptp_session, 再建立一张map表,server-call-id映射到该pptp_session
Client-->Server, 貌似什么也不用做,直接转换IP就出去了, GRE头里的call-id也自然是对端server-call-id.
Server-->Client, 根据GRE头里的call-id, 查询nat-call-id映射表,找到pptp_session, 更换call-id为local-call-id, 转换IP地址即可。
通过call-id pool 对client call-id重新赋值,就可以让PPTP顺利穿越NAT.
关于NAT ALG有N种协议,如果想实现大部分,也是路漫漫其修远兮。