Open ICKelin opened 6 years ago
@ICKelin 讲的很通俗易懂,点个👍,但是有问题想请教一下,我在两台ubuntu服务器下分别启动服务端以及客户端的程序,并且设置好了客户端的虚拟网卡路由,然后我ping服务端的网段,流量已经成功转发到服务端,但是ping请求一直阻塞,并没有获得响应,能解答一下嘛?
@stone-98 可以抓包看看,我猜测可能是你有一条iptables命令没加上
iptables -t nat -I POSTROUTING -j MASQUERADE
@ICKelin 还是没有成功,但是我使用抓包查看发现请求并没有转发到服务端 客户端ip:116.62.129.179 服务端ip:167.179.89.137 我的步骤如下:
accept gtun client
,服务端和客户端的网络是互通的。gtun
网卡设置IP
sudo ip addr add 167.179.89.136/24 dev gtun
gtun
的状态设为up
sudo ip link set gtun up
gtun
网卡路由,将167.179.89.0/24网段的请求转发到167.179.89.137
route add -net 167.179.89.0/24 gw 167.179.89.137 gtun
这是我大致遇到的问题,我之前的描述有误其实流量并没有转发到服务端,所以应该不是iptables的原因吧,能给我一点思路嘛?
接触过VPN相关技术的基本都会接触过虚拟网卡,tun,tap等字眼,因为大部分vpn都或多或少使用有类似技术。本文会对tun/tap设备的基本原理进行说明,并且对其如何应用在vpn上进行了分析,最后提供一个简单的tun的vpn的实现代码。
TUN/TAP设备的基本原理
首先需要明确一点,tun和tap是两种类型的虚拟设备,其一大区别是从tun设备读取数据,你将能够拿到三层包,从tap网卡获取数据,你将能拿到二层包。
在了解虚拟网卡之前,应该先简单了解下真实网卡是如何进行工作的。 首先,网卡介于物理网络和内核协议栈之间,接受协议栈外出的数据并将数据往物理网络发出,同时,也接受外部数据并交付给内核协议栈进行处理。(在这里先将内核协议栈当成一个整体,一个黑盒来看待。)
了解物理网卡所处的位置以及网络数据包的流动之后,再看看虚拟网卡有什么不一样的地方。 从最直观的使用来看,用户是可以直接读写虚拟网卡的,也就是说,从内核协议栈发出的数据在选定以虚拟网卡发出之后,数据将会被用户层程序直接读取,这点与物理网卡不一样,物理网卡直接就往外发。虚拟网卡告知用户程序数据可读。
在写方面,用户进程往虚拟网卡写数据会直接从网卡写出去 一图胜千言:
TUN/TAP与VPN
了解了TUN与TAB的基本原理之后,可以明确的知道,用户层通过虚拟网卡具备有读写二层,三层数据包的能力,这种读写与原始套接字还不一样,原始套套接字做的事旁路拷贝,这个是直接截取数据包到用户层,用户层自己处理。
有了这类技术底子之后,再看看vpn,很多人一提到vpn就想到翻墙,vpn并不等于翻墙,vpn的一个目的是为不同地区模拟出一个局域网环境,让A地区的员工能够像访问局域网一样访问位于总部B的服务器或者其他比如打印机,这是vpn。
一图胜千言:
ping经过内核协议栈,路由选择从虚拟网卡发出
虚拟网卡的另外一端,也就是用户进程,将这一ping包读取出来
将ping的payload通过真实网卡发出,经过一系列的传输,到达目的主机,
目的主机收到数据包之后,将其写入虚拟网卡。
Ping reply返回类似,上图的左右两端是等价的,能够收发数据包。
为了方便说明这一原理,编写一个简单的基于tun设备的vpn——gtun
gtun客户端:
gtun_srv,中间转发服务
这里示例程序为了简化Demo,中间转发服务器将收到的数据包广播给所有的客户端,具体gtun实现当中会有一个协议的解码,根据目的地址来做转发。
后续将会往路由选择方面靠拢,逐步将内核协议栈这一黑盒慢慢打开。