β

VPN杂谈

运维军团 25 阅读
VPN对各位来说肯定是非常熟悉的,比如在家里加密访问公司后台,或者在特殊场景做权限控制,还有就是可以让移动设备拨vpn之后利用tc做弱网模拟,或者是在国内访问google服务等,不过听说google学术已经开始重返中国,以后可以在国内直接访问到了。
VPN技术可以做的远不止如此,今天我们来随便聊聊VPN身边的那些事情。

1 概述

我们这里说的VPN主要是关于企业应用常见相关,不涉及到非法跨网。

VPN有很多种,比如Linux上最常用的pptp类型的vpn,稍微复杂点的openvpn,还有学cisco时候实验用的EASY VPN,还有些看起来高大上的Juniper VPN。

其实远远不止这些,在实际环境下如果要兼容各个网络运营商和终端设备的话,就非常推荐SoftEtherVPN这个vpn盒子了。

下面来挑点东西和大家分享下。

2 VPN实现

2.1 GRE隧道

这个gre隧道是Linux上一个最简单的”vpn”,远远比pptp简单,但是并不那么出名,因为他不直接和用户接触,一般是属于服务器或者网络设备之间的”vpn网络”。

在A、B两个异地机房,有两个内网需要连接起来,我们不需要用vpn,直接用Linux自带属性即可完成。

首先在A、B服务器上互加IP白名单,然后在A服务器上操作:

#加载ip_gre模块 modprobe ip_gre ip tunnel add gre1 mode gre remote B_IP  local  A_IP ttl 255 ip link set gre1 up ip addr add 192.10.10.2 peer 192.10.10.1 dev gre1

在B服务器上操作:

#加载ip_gre模块 modprobe ip_gre ip tunnel add gre1 mode gre remote A_IP  local  B_IP ttl 255 ip link set gre1 up ip addr add 192.10.10.1 peer 192.10.10.2 dev gre1

两边都敲完的话就有个隧道网段生成了,红色地方是本段和对端的公网IP,下面两个就是生成的隧道网段的IP了:

然后在这两个服务器互相用route命令加上对方内网的路由表走这个对端IP就可以了。

要断掉这个隧道网络的话直接删掉这个隧道网卡即可:

ip tunnel del gre1

在服务器之间用这个的话,比pptp搭建个vpn方便点点。 -_-

2.2 Socket代理

简单介绍下web的代理,如果无法访问vpn的时候,这个可能有用武之地,比如某后台只允许了某台服务器的IP,我们可以在这个服务器上临时搭建个代理服务,然后终端用户可以通过这个跳板来访问后台了。

这个代理我们一般是用于访问web流量,比如用squid或者ssh新建一条隧道,这里普及下,原先可能大家都认为squid做代理的时候因为没有目的站点的证书,是无法代理https流量,但其实不是这样,可以利用stunnel结合来做https流量的代理,或者sniproxy也行。

不过squid搭建起来也比较麻烦,这里简单介绍下ssh一条命令来创建代理:

ssh -p 22  -qTfnN -D 0.0.0.0:7070 test@127.0.0.1

在目的服务器上运行之后会监听7070端口,在浏览器设置这个代理之后,web流量的出口就可以是这个服务器了。

这个可以快速在多台服务器上创建多个用于频繁改变用户出口IP的代理,在某些场合下可能用得到,比如“帮朋友投下票”。

2.3 PPP协议

PPP协议的vpn有几种实现方式,勉强归类一下,包括pptp、sstp、l2tp。

大家接触linux时候一般都是用这个pptp类型的vpn,也很简便,但我们在某些特殊场合下面把这个vpn的功能给升级了。

这个vpn有别的打开方式能让我们点赞。

首先是认证控制,原先认证只可以用帐号和密码认证,但是其实还可以加上源IP校验。

再有的是权限的自动化控制,强调自动化是因为我们的场景是在后台管理帐号、用户源IP和拨vpn之后对应的权限甚至是进行抓包备案。

实现这两个功能利用的是/etc/ppp/ip-up这个文件,这个是在校验帐号密码之后调用的一个脚本文件,我们在这里可以自定义一些逻辑来实现我们需要的功能。

通过加入sh -x来调试这个脚本,可以发现会传入6个参数,其中就有我们需要的变量信息:

  • 第一个参数是网卡名称
  • 第五个参数是vpn获取的ip
  • 第六个参数是用户的来源IP
  • PEERNAME变量代表用户的帐号

有了这些我们就可以另外写一个提供复杂逻辑的脚本来给ip-up调用。

比如先在ip-up里面加入日志,然后调用add_iptables.sh来做复杂的认证和权限控制,到最后放入一个tcpdump来在后台抓包做备用审计。

add_iptables.sh逻辑也比较简单,利用传入的参数来跟我们后台提供的数据进行对比然后调用IPTABLES处理相关的复杂权限控制即可。

同理,还有另外一个/etc/ppp/ip-down的脚本是在用户断开vpn的时候自动调用的一个脚本,在这里可以删除掉之前IPTABLES做的控制,然后还可以自动分析之前的tcpdump数据包然后写入mysql。

上面说的是pptp类型的vpn,但是自从IOS设备已经弃用了pptp,在这个场景下我们可以再加入l2tp的vpn。同样是在/etc/ppp目录,我们只需要再安装配置ipsec(libreswan)和xl2tpd即可。

注意l2tp对外开放端口时候需要加多个,有udp的500、4500、1701这3个端口和esp协议,而且l2tp和pptp的逻辑和帐号文件是同一套,所以非常顺利就兼容了之前的那些方案,具体搭建方案就不再多阐述了。

2.4 OpenVPN

曾经这个vpn类型在某些场合很流行,因为看起来比pptp那些高大上些,甚至是可以让每个用户必须有专有的证书才可以拨上这个openvpn,需要各种私钥、公钥、客户端,给人一种靠谱的感觉。

有很多经过二次开发的商业化的VPN客户端也是采用了类似的三层tun虚拟隧道或者tap的虚拟网卡原理来实现内部逻辑。

openvpn也比较灵活,比如可以用auth-user-pass-verify来调用权限控制脚本等,很长一段时间我们也在一些场合下用这个openvpn方案。

不过不打算深入讲下去,因为我们之后有更加实用的选择。

2.5 SoftEtherVPN盒子

这个vpn (地址:https://github.com/SoftEtherVPN/) 是集中了多个vpn协议的软件,兼容性非常强,有多强呢?看图:

几乎是所有类型的终端都可以找到合适的vpn协议来连接这个server。

同时支持用vpncmd命令行管理和客户端管理:

虽然他提供了很多功能,相当于傻瓜式地自动安装了,不过有几点建议:

  1. 不要用他自带的nat功能,自己用IPTABLES做nat好些
  2. 自带有dhcp功能,如果是要做复杂的网段控制,特别是vlan功能,建议另行搭建dhcpd服务并在/etc/sysconfig/dhcpd加入多个监听的网卡。
  3. 如果可行的话,建议导入正规的证书,因为如果是做sstp的话会在用户端校验证书,否则用户体验非常不好甚至是直接失败。
  4. 帐号认证可以使用radius服务器,方便和别的帐号系统联动,我们用的是CISCO的ISE设备。
  5. 由于各类网络运营商的限制,可以同时开启多个类型vpn给用户备用。

下面简单介绍下命令行的使用,因为想要自动化还得靠这个。

#进入命令行管理界面 ./vpncmd  server:port  /SERVER /HUB:hub_name /PASSWORD:password #在命令行管理界面的子命令: #查看帮助,每个命令都可以用help查看详细参数 help #查看当前用户和流量 SessionList #用户的增删查改 UserCreate UserDelete UserList UserSet

上面几个常用的命令基本可以满足我们的需求了,通过管道传入即可实现命令行自动化管理。

不过这个软件有个遗憾,多个vpn协议中不支持pptp类型。

3 应用场景

应用场景比较多,这里小列举下。

3.1 加密跨网访问

国际网络不好时候,用来翻墙访问github之类的地址,这个是最常见的用法。

还有个是被媒体揭秘过的借VPN方案利用运营商的定向免费流量来谋取暴利的跨网访问等,不过这个定向的免费流量利用方式不一定靠谱,不推荐。

3.2 网游加速器

基于国内的各种网络环境,特别是小运营商的网络质量很让人伤心,一些游戏运营商会开发些经过封装的“VPN软件”,取名XX加速器,比如可以通过本地路由把游戏服务器的网段通过vpn技术导向服务端,服务端那里再经过一些逻辑处理取就近资源或者直接使用高质量的BGP网络进行转发以提高用户访问质量。

3.3 特殊网络审计

这个也就是上面ppp协议那里的实现方法,用于一些特殊场合的精细化访问控制和审计。

3.4 随机出口IP方案

之前又说个改变用户出口IP的事情,这里顺带一个解决方案,比如可以在服务器上既做提供vpn给用户的服务端,同时也可以做全球不同地方的客户端,然后通过控制IPTABLES的nat来切换vpn用户的出口。

如果不方便在全球部署服务器的话可以在机房拉一条ADSL到服务器的另外一个网卡,然后通过pppoe-start来拨号,通过自动重拨来更改出口IP。大致框架如下:

注意这里设置默认网关往ADSL出口的时候需要针对原本机IP做策略路由才可以保证网络是通的。

在/etc/iproute2/rt_tables里面加入101 benji
然后本机策略路由:
/sbin/ip route add default via 原网关 dev em1 table benji
/sbin/ip rule add from 原IP table benji

这样才可以保证ADSL出口不影响原IP的访问。

3.5 弱网模拟

手游在弱网环境下的测试也可以用vpn加上tc来模拟,这个在游戏精细化运维时候有用得上。命令参考如下:

#添加root根
tc qdisc add dev eth0 root handle 1: prio
#配置这个id是丢包30%,上下浮动2%
tc qdisc add dev eth0 parent 1:1 handle 2: netem  loss 30% 2%
#或者是延迟500ms,上下浮动20ms
tc qdisc add dev eth0 parent 1:1 handle 2: netem delay 500ms 20ms
#然后设置
tc filter add dev eth0 parent 1:0 protocol ip pref 55 handle ::55 u32 match ip dst 目的IP flowid 2:1
#测试完之后,删除命令
tc qdisc del dev eth0 root

经过tc的控制,手机网络会控制地非常精准,用来做弱网模拟很不错。

4 小结

总的来说,经历过多个vpn之后发现juniper的防火墙提供的vpn是最繁琐和死板的,还有license限制,pptp/l2tp的最灵活,最后最实用的是同时可以提供多个vpn协议的softethervpn。

VPN给人的印象也不应停留在非法的领域,具体用处还是挺多的,不过尽量不要使用网络上公开的那种vpn,在vpn服务端那里可能存在各种中间人劫持甚至包括针对https的攻击。

END

作者:运维军团
运维技术与开源架构交流
原文地址:VPN杂谈, 感谢原作者分享。

发表评论