微软的PPTP协议是非常流行的技术,它的指令控制部分使用1723端口上的TCP连接传输,而实际的数据则使用GRE协议封装。如果你在一个防火墙的后面使用PPTP协议,那么你的防火墙必须支持PPTP穿隧才能正常使用。这是因为一般的防火墙都使用UDP或者TCP端口号的方式来生成和记录NAT对应关系,而GRE协议没有端口号。不过好在微软在GRE协议之上加了个东西,那就是PPP数据的Channel ID,利用这个东西,防火墙就可以根据它来记录NAT对应关系,把GRE报文转交给正确的内网主机。

现代的路由器一般都支持PPTP穿隧技术,所以基本无需自己设置就可以在防火墙后访问公网上的PPTP服务器建立连接。另一方面,现在的商用路由器几乎都能识别1723端口,如果你在公司的路由上对1723端口做了DNAT映射,那么来自外网的PPTP请求也能正确地和防火墙后的服务器建立连接。

如果使用Linux的iptables做软件防火墙,而没有使用路由器,我们依然可以建立起一个DNAT通到内网的PPTP服务器。这首先需要Linux内核加载ip_nat_pptpip_conntrack_pptp两个模块。可以用lsmod命令检查是否已经载入。

# lsmod | grep pptp

如果没有载入,可以使用modprobe加载内核模块

# modprobe ip_nat_pptp
# modprobe ip_conntrack_pptp

当然,为了做NAT,把IPv4 Forward打开也是非常必要的

# sysctl -w net.ipv4.ip_forward=1

接下来可以设置允许PPTP的TCP协议和GRE协议连入

# iptables -A INPUT -d $FIREWALL_IP -p tcp --dport 1723 -j ACCEPT
# iptables -A INPUT -d $FIREWALL_IP -p gre -j ACCEPT
# iptables -A FORWARD -d $PPTPD_IP -p tcp --dport 1723 -j ACCEPT
# iptables -A FORWARD -d $PPTPD_IP -p gre -j ACCEPT

最后配置DNAT规则完成转发,当然为了识别DNAT后的地址对应关系,转换地址后还需要把它加入MASQUERADE里。

# iptables -t nat -A PREROUTING -d $FIREWALL_IP -p tcp --dport 1723 -j DNAT --to-destination $PPTPD_IP
# iptables -t -A POSTROUTING -d $PPTPD_IP -p tcp --dport 1723 -j MASQUERADE

这样,当PPTP客户端拨号到$FIREWALL_IP上的时候,实际是后面的$PPTPD_IP服务器在提供服务。运行iptables的机器也可以视为PPTP中继服务器,向后面的服务转发数据。

Last modification:June 11, 2023
如果觉得我的文章对你有用,请随意赞赏