聊聊不一样的代理设计

现有的代理设计大多数都是代理整个IP范围的所有数据报,但不能实现指定IP+Port的代理且支持自定义协议头,今天就聊聊在macOS上的如何实现完整的应用层端口代理设计一块做探讨,欢迎投币、点赞、转发。不不不欢迎拍砖

现状

现有实现VPN解决方案通常是使用虚拟网卡形式,比如开源软件openvpn、下一代VPN wireguard等,这样就可以直接在应用层实现流量劫持并代理转发。因虚拟网卡作用于网络层网络协议栈无法过滤具体的端口,来实现指定端口的流量劫持并代理。
通过网络内核驱动形式作用于内核态,实现了更加灵活地流量劫持,比如套接字过滤器、IP过滤器等。但其作用于内核态已经不能满足苹果决心弃用网络内核驱动扩展的大势所趋,苹果提供的新的系统网络扩展方案才是现在及未来实现代理的主要选择。

透明代理方案

对于现在比较火的“零信任”领域,为了满足零信任最小权限控制的原则,需要实现指定端口范围流量的劫持,从而通过应用层流量转发方案,比如HTTP代理、sock5代理等。苹果应该也考虑了这方面的需求,从而提供了有效实现透明代理的方案,即透明代理扩展相关类NEAppProxyProviderNEDNSProxyProvider。其实现原理如下图所示:

image-20210430124912678

通过指定NENetworkRule流量转发规则,来将TCP/UDP数据包转发至系统扩展进程来处理。其中转发规则可以指定IP+Port或者域名及流入/流出方向,因此可以实现指定的端口或者端口范围的流量转发,进而实现端口最小权限控制。不过上述方案也不是完美的,其无法完全实现DNS的流量劫持,比如命令行工具。但苹果已经帮你考虑完美了,其提供了DNS系统扩展代理,其实现方案如下图所示:

image-20210430125107482

其可以拦截所有的TCP/UDP形式的DNS查询数据包,并转发至应用层的DNS系统扩展进程,从而实现DNS代理。

透明代理方案问题及解决方案

上述透明代理方案堪称“完美”,其满足了TCP/UDP代理及DNS代理,并且规则细粒度小,不像虚拟网卡形式需要指定网络层IP规则来转发。但并不是所有方案都是完美无缺的,上述透明代理方案在应用层劫持获取的数据包,都是TCP/UDP payload数据包,不包含传输层协议头,因此若需要修改或者自定义协议头就难以满足需求。站在苹果的角度也是不会给你提供“一统天下”的系统扩展方案,因此苹果提供了包过滤系统扩展NEPacketTunnelProvider来帮你解决上述问题。其实现原理如下图所示:

具体原来实际就是“虚拟网卡”形式的代理方案,不过此虚拟网卡是由系统来帮你完成,并且提供了应用层封装接口来配置虚拟网卡(比如IP、MTU等),以及路由规则。从而在用户态包过滤系统扩展进程来拦截指定IP的流量,并且获取的是IP数据报(包括IP数据头),因此可以实现完成的网络层包的修改、封装及转发。既然我们可以拿到完整的IP数据报,就可以在此基础上做修改,比如实现TCP包头的修改,以及解析TCP/UDP协议头来实现端口过滤及代理转发。

端口代理实现方案

既然系统已经提供了IP数据报过滤机制,即可以实现完成的虚拟网卡的代理方案,这也是目前大多数VPN客户端实现方案。不过macOS系统也提供了用户态接口来创建虚拟网卡并配置,而不是通过系统封装的包过滤系统扩展。不过系统封装的包过滤系统扩展方案,相比自定义实现虚拟网卡存在更多的优势。从整个系统扩展的实现框架就可以看出,如下图所示:

image-20210430134441147

其提供了完成的系统扩展守护、规则管理及会话管理,相比自定义实现更容易实现及维护。因此后续的虚拟网卡基于包过滤系统扩展方案来实现。

虚拟网卡的问题

不过虚拟网卡是基于网络层来配置过滤规则,即只能配置过滤的IP,但无法做到透明代理方案中的端口过滤。因此若实现端口范围代理,或者再次基础上实现TCP协议头的修改并转发且不代理,需要再次基础上做进一步的优化及改进。

tap设备转发

由于模拟数据链路层的tap设备可以实现数据包路由功能,可以基于此来实现不需要的IP数据报转发。但苹果在应用层未开放相应的接口来创建tap设备,因此此方案在应用层实现端口范围代理存在系统上的弊端。

tun转发

image-20210430144533648

既然能获取所有的指定IP规则的完成IP数据报,可以对此进行完成的代理转发,由代理服务器来实现完整的端口过滤代理。但这种方案就违背了最小端口权限的原则,并且会造成代理服务器性能负担。

本地转发

为实现最小端口权限原则,将所有拦截的IP数据报进行本地解析,对不需要的端口包通过原始套接字的形式转发至物理网卡,由本机设备的物理网卡承担流量出口,即还原虚拟网卡拦截流量。具体的方案框架图如下所示:

image-20210430152542263

方案阐述

方案的关键环节在于过滤不需要的IP数据报进行转发至物理网卡,而不是通过代理服务器来实现过滤,比如端口过滤转发、DNS过滤转发、自定义TCP协议头以及实现IP数据报过滤。其实现的关键机制是基于macOS系统的“防火墙”技术–包过滤器(Packet Filter)

PF防火墙( 全称:Packet Filter )是unix系统上进行TCP/IP流量过滤和网络地址转换机制,同时也提供TCP/IP流量的整形和控制,并且提供带宽控制和数据包优先集控制。macOS底层系统继承自freebsd同时也继承了该防火墙机制,其在用户态提供了pfctl命令来进行过滤配置,比如实现重定向配置如下:

rdr pass on en1 proto tcp from 110.242.68.3 port 80 to en1:network -> (utun3)
复制代码

上述规则就是将流入物理网卡en1的TCP数据包(IP+Port:110.242.68.3:80)目的地址en1的IP地址,修改为虚拟网卡utun3的虚拟IP地址,默认包被通过不再经过过滤规则的过滤。

PF过滤器的重定向功能主要是解决外部流量穿过NAT设备流入内部网络,此处主要用于将外部流入物理网卡的流量转发至虚拟网卡的套接字,进而被本地应用所接收。

还可以用于包过滤,比如实现IP数据报过滤的配置如下:

block in proto tcp from 110.242.68.4 port 80 to any
复制代码

上述规则就可以实现将外部流量TCP 110.242.68.4.80阻断,也可以通过block out xxx来组织内部流量流出,进而实现数据包过滤功能。

好了,今天就聊这么多,有疑问的小伙伴或者探讨的小伙伴可以私信、留言

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享