首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Linux Netfilter实现机制和扩展技术-案例:用Netfilter实现VPN

Linux Netfilter实现机制和扩展技术-案例:用Netfilter实现VPN

虚拟专用网的关键就是隧道(Tunnel)技术,即将报文封装起来通过公用网络。利用Netfilter-iptables对报文的强大处理能力,完全可以以最小的开发成本实现一个高可配置的VPN。
本文第一部分即描述了IP Tunnel技术中报文的流动过程,从中可见,IP Tunnel技术的特殊之处有两点:
  • 一个特殊的网络设备tunl0~tunlx--发送时,用指定路由的办法将需要封装的内网报文交给该网络设备来处理,在"网卡驱动程序"中作封装,然后再作为正常的IP报文交给真正的网络设备发送出去;
  • 一个特殊的IP层协议IPIP--从外网传来的封装报文拥有一个特殊的协议号(IPIP),报文最终在该协议的处理程序(ipip_rcv())中解封,恢复内网IP头后,将报文注入IP协议栈底层(netif_rx())重新开始收包流程。
从中不难看出,在报文流出tunlx设备之后(即完成封装之后)需要经过OUTPUT的Netfilter HOOK点,而在报文解封之前(ipip_rcv()得到报文之前),也要经过Netfilter的INPUT HOOK点,因此,完全有可能在这两个HOOK上做文章,完成报文的封装和解封过程。报文的接收过程可以直接沿用IPIP的处理方法,即自定义一个专门的协议,问题的关键即在于如何获得需要封装的外发报文,从而与正常的非VPN报文相区别。我们的做法是利用Netfilter-iptables对IP头信息的敏感程度,在内网中使用标准的内网专用IP段(如192.168.xxx.xxx),从而通过IP地址将其区分开。基于IP地址的VPN配置既方便现有系统管理、又便于今后VPN系统升级后的扩充,而且可以结合Netfilter-iptables的防火墙设置,将VPN和防火墙有机地结合起来,共同维护一个安全的专用网络。
在我们的方案中,VPN采用LAN-LAN方式(当然,Dial-in方式在技术上并没有什么区别),在LAN网关处设置我们的VPN管理组件,从而构成一个安全网关。LAN内部的节点既可以正常访问防火墙限制以外非敏感的外网(如Internet的大部分站点),又可以通过安全网关的甄别,利用VPN访问其他的专用网LAN。
由于本应用与原有的三个表在功能和所关心的HOOK点上有所不同,因此我们仿照filter表新建了一个vpn表,VPN功能分布在以下四个部分中:
  • iptables ENCRYPT Target:对于发往安全子网的报文,要求经过ENCRYPT target处理,加密原报文,产生认证码,并将报文封装在公网IPIP_EXT报文头中。ENCRYPT Target配置在vpn表的OUTPUT和FORWARD HOOK点上,根据目的方IP地址来区分是否需要经过ENCRYPT target加密处理。
  • IPIP_EXT协议:在接收该协议报文的处理函数IPIP_EXT_rcv()中用安全子网的IP地址信息代替公网间传输的隧道报文头中的IP地址,然后重新注入IP协议栈底层。
  • iptables IPIP_EXT Match:匹配报文头的协议标识是否为自定义的IPIP_EXT。经过IPIP_EXT_rcv()处理之后的报文必须是IPIP_EXT协议类型的,否则应丢弃。
  • iptables DECRYPT Target:对于接收到的来自安全子网的报文,经过IPIP_EXT协议处理之后,将IP头恢复为安全子网之间通信的IP头,再进入DECRYPT target处理,对报文进行完全解密和解封。
整个报文传输的流程可以用下图表示:
图8 VPN报文流动过程对于外出报文(源于本地或内网),使用内部地址在FORWARD/OUTPUT点匹配成功,执行ENCRYPT,从Netfilter中返回后作为本地IPIP_EXT协议的报文继续往外发送。
对于接收到的报文,如果协议号为IPPROTO_IPIP_EXT,则匹配IPIP_EXT的Match成功,否则将在INPUT点被丢弃;继续传送的报文从IP层传给IPIP_EXT的协议处理代码接收,在其中恢复内网IP的报文头后调用netif_rx()重新流入协议栈。此时的报文将在INPUT/FORWARD点匹配规则,并执行DECRYPT,只有通过了DECRYPT的报文才能继续传送到本机的上层协议或者内网。
附:iptables设置指令(样例):
1
2
3
4
5
iptables -t vpn -P FORWARD DROP
iptables -t vpn -A OUTPUT -d 192.168.0.0/24 -j ENCRYPT
iptables -t vpn -A INPUT -s 192.168.0.0/24 -m ipip_ah -j DECRYPT
iptables -t vpn -A FORWARD -s 192.168.0.0/24 -d 192.168.1.0 -j DECRYPT
iptables -t vpn -A FORWARD -s 192.168.1.0/24 -d 192.168.0.0/24 -j ENCRYPT




其中192.168.0.0/24是目的子网,192.168.1.0/24是本地子网
返回列表