穿墙有术之企业级云上网络解决方案_docker

 

混合云

在“互联网+”国家战略的驱动下,越来越多的业务应用需要通过互联网来提供服务,公有云因此受到越来越多的用户亲睐,然而对于传统IT的核心数据与业务,受安全性、兼容性等多方面因素的影响,无法采用公有云来承载,此因混合云成为企业云架构的不二之选。

混合云对于已有自建IDC的企业实现云化有很大的好处:按需定制,满足业务的个性化需求;多级容灾,能够规避单一的采购商风险;兼得私有环境安全独立的优势和公有云弹性伸缩、快速编排定制的优势;最后,对已有的IT重资产最大化的保护和利用,极大降低成本。

穿墙有术之企业级云上网络解决方案_内网_02

解决方案

穿墙有术之企业级云上网络解决方案_docker_03

产品对比

混合云私网通信包括两类产品:专线(高速通道)和VPN,两者没有绝对的优劣,只是所针对的客户定义不同。

穿墙有术之企业级云上网络解决方案_服务器_04

专线就是自建高速公路,具有网络带宽高、时延低的优点,但是建设周期长,成本更高;VPN就是在公有网络上承包一条线路作为专用,价格更为经济便宜,而且即开即用,但是时延相对专线来说更高。

高速通道 (物理专线)

帮助不同网络环境间实现高速、稳定、安全的私网通信,包括云上跨地域/跨用户的VPC内网互通、云下IDC专线接入云上等场景,提高网络拓扑灵活性和跨网通信质量。

网络整体架构

穿墙有术之企业级云上网络解决方案_服务器_05

通用方案 (云购VPN)

VPN网关是一款基于Internet,通过加密通道将企业数据中心、企业办公网络、或internet终端和阿里云专有网络(VPC)安全可靠连接起来的服务。阿里云VPN网关在国家相关政策法规下提供服务,不提供访问Internet功能。

云上网络架构

基于阿里云VPC和相关产品,用户可自主规划并搭建满足各种业务场景下的网络架构。

本架构能够解决

  • 云上网络安全隔离

  • 应对海量访问流量

  • 云上云下数据互通

  • 多业务共享带宽

网络整体架构

穿墙有术之企业级云上网络解决方案_封装_06

通用方案(自建VPN)

穿墙有术之企业级云上网络解决方案_封装_07

云上VPC和私有IDC是如何实现IPSEC-VPN对接的。如上图所示,右边边为云上VPC,且VPC上有多台ECS,左边是私有IDC,IDC里包含传统的服务器,两端都是私网口。

IPsec VPN 服务器

Docker 上的 IPsec VPN 服务器,使用这个 Docker 镜像快速搭建 IPsec VPN 服务器。支持 IPsec/L2TP 和 Cisco IPsec 协议。本镜像以 Debian 9 (Stretch) 为基础,并使用 Libreswan (IPsec VPN 软件) 和 xl2tpd (L2TP 服务进程)。

安装 Docker

首先,在你的 Linux 服务器上 安装并运行 Docker。

  1. yum update

  2. yum install docker -y

下载镜像

预构建的可信任镜像可在 Docker Hub registry 下载:

  1. docker pull hwdsl2/ipsec-vpn-server

如何使用镜像

环境变量

这个 Docker 镜像使用以下三个变量,可以在一个 env 文件中定义。执行以下命令,vim vpn.env:

  1. Define your own values for these variables

  2. # - DO NOT put "" or '' around values, or add space around =

  3. # - DO NOT use these special characters within values: \ " '

  4. VPN_IPSEC_PSK=your_ipsec_pre_shared_key

  5. VPN_USER=your_vpn_username

  6. VPN_PASSWORD=your_vpn_password

这将创建一个用于 VPN 登录的用户账户,它可以在你的多个设备上使用 。 IPsec PSK (预共享密钥) 由 VPNIPSECPSK 环境变量指定。 VPN 用户名和密码分别在 VPNUSER 和 VPNPASSWORD 中定义。

注: 在你的 env 文件中,不要为变量值添加 "" 或者 '',或在 = 两边添加空格。不要在值中使用这些字符: \ " '。

运行 IPsec VPN 服务器

重要: 首先在 Docker 主机上加载 IPsec NETKEY 内核模块:

  1. sudo modprobe af_key

使用本镜像创建一个新的 Docker 容器 (将 ./vpn.env 替换为你自己的 env 文件):

  1. docker run \

  2.    --name ipsec-vpn-server \

  3.    --env-file ./vpn.env \

  4.    --restart=always \

  5.    -p 500:500/udp \

  6.    -p 4500:4500/udp \

  7.    -v /lib/modules:/lib/modules:ro \

  8.    -d --privileged \

  9.    hwdsl2/ipsec-vpn-server

获取 VPN 登录信息

如果你在上述 docker run 命令中没有指定 env 文件,VPNUSER 会默认为 vpnuser,并且 VPNIPSECPSK 和 VPNPASSWORD 会被自动随机生成。要获取这些登录信息,可以查看容器的日志:

  1. docker logs ipsec-vpn-server

穿墙有术之企业级云上网络解决方案_封装_08

查看服务器状态

如需查看你的 IPsec VPN 服务器状态,可以在容器中运行 ipsec status 命令:

  1. docker exec -it ipsec-vpn-server ipsec status

或者查看当前已建立的 VPN 连接:

  1. docker exec -it ipsec-vpn-server ipsec whack --trafficstatus

脚本一键安装

首先,在你的 Linux 服务器* 上全新安装一个 Ubuntu LTS, Debian 或者 CentOS 系统。

使用以下命令快速搭建 IPsec VPN 服务器:

  1. wget https://git.io/vpnsetup -O vpnsetup.sh && sudo sh vpnsetup.sh

如果使用 CentOS,请将上面的地址换成 https://git.io/vpnsetup-centos。 你的 VPN 登录凭证将会被自动随机生成,并在安装完成后显示在屏幕上。

你也可以将你自己的 VPN 登录凭证定义为环境变量:

  1. # 所有变量值必须用 '单引号' 括起来

  2. # *不要* 在值中使用这些字符:  \ " '

  3. wget https://git.io/vpnsetup -O vpnsetup.sh && sudo \

  4. VPN_IPSEC_PSK='你的IPsec预共享密钥' \

  5. VPN_USER='你的VPN用户名' \

  6. VPN_PASSWORD='你的VPN密码' sh vpnsetup.sh

IPsec/L2TP VPN 客户端

Linux(CentOS )

首先安装以下软件包:

  1. yum -y install epel-release

  2. yum -y install strongswan xl2tpd

配置 strongSwan

编辑/etc/strongswan/ipsec.conf文件

  1. # ipsec.conf - strongSwan IPsec configuration file

  2. # basic configuration

  3. config setup

  4.  # strictcrlpolicy=yes

  5.  # uniqueids = no

  6. # Add connections here.

  7. # Sample VPN connections

  8. conn %default

  9.  ikelifetime=60m

  10.  keylife=20m

  11.  rekeymargin=3m

  12.  keyingtries=1

  13.  keyexchange=ikev1

  14.  authby=secret

  15.  ike=aes128-sha1-modp1024,3des-sha1-modp1024!

  16.  esp=aes128-sha1-modp1024,3des-sha1-modp1024!

  17. conn myvpn

  18.  keyexchange=ikev1

  19.  left=%defaultroute

  20.  auto=add

  21.  authby=secret

  22.  type=transport

  23.  leftprotoport=17/1701

  24.  rightprotoport=17/1701

  25.  right=VPN服务器IP

编辑/etc/strongswan/ipsec.secrets文件

  1. : PSK "你的PSK"

配置 xl2tpd

编辑/etc/xl2tpd/xl2tpd.conf文件

  1. [lac myvpn]

  2. lns = VPN服务的IP

  3. ppp debug = yes

  4. pppoptfile = /etc/ppp/options.xl2tpd.client

  5. length bit = yes

编辑/etc/ppp/options.xl2tpd.client文件

  1. ipcp-accept-local

  2. ipcp-accept-remote

  3. refuse-eap

  4. require-chap

  5. noccp

  6. noauth

  7. mtu 1280

  8. mru 1280

  9. noipdefault

  10. defaultroute

  11. usepeerdns

  12. connect-delay 5000

  13. name 你的帐户

  14. password 你的密码

  1. chmod 600 /etc/ppp/options.l2tpd.client

至此 VPN 客户端配置已完成。按照下面的步骤进行连接。

创建xl2tpd控制文件

  1. mkdir -p /var/run/xl2tpd

  2. touch /var/run/xl2tpd/l2tp-control

启动脚本vpnc.sh
  1. #!/bin/bash

  2. SUDO=''

  3. if [ "$USER" != "root" ]

  4. then

  5.  SUDO='sudo'

  6. fi

  7. $SUDO systemctl restart strongswan.service

  8. $SUDO systemctl restart xl2tpd.service

  9. sleep 1

  10. $SUDO strongswan up myvpn

  11. $SUDO tee /var/run/xl2tpd/l2tp-control > /dev/null <<< "c myvpn"

  12. while ! $(ip route | grep -i ppp0 &>/dev/null)

  13. do

  14. sleep 1

  15. done

  16. ip link | grep -i ppp0

  17. # 检查你现有的默认路由 ip route 在输出中查找以下行: default via X.X.X.X ...。记下这个网关IP # 并且在下面的两个命令中使用。

  18. $SUDO route add 你的VPN服务器IP gw x.x.x.x

  19. # 如果你的 VPN 客户端是一个远程服务器,则必须从新的默认路由中排除你的本地电脑的公有 IP,以避免

  20. # SSH 会话被断开 (替换为实际值):

  21. $SUDO route add 你的本地电脑的公有IP gw x.x.x.x

  22. $SUDO route add default dev ppp0

  23. ip route | grep -i ppp0

  24. ip address | grep -i ppp0

  25. # 检查 VPN 是否正常工作,以上命令应该返回 你的 VPN 服务器 IP。

  26. wget -qO- http://ipv4.icanhazip.com; echo

停止脚本 vpnd.sh
  1. #!/bin/bash

  2. SUDO=''

  3. if [ "$USER" != "root" ]

  4. then

  5.  SUDO='sudo'

  6. fi

  7. $SUDO route del default dev ppp0

  8. # 删除掉VPN服务器IP 和 本地电脑公网IP

  9. $SUDO ip route del x.x.x.x

  10. $SUDO ip route del x.x.x.x

  11. $SUDO tee /var/run/xl2tpd/l2tp-control > /dev/null <<< "d vultr"

  12. $SUDO strongswan down myvpn

  13. ip link | grep -i ppp0

  14. ip route | grep -i ppp0

  15. $SUDO systemctl stop strongswan.service

  16. $SUDO systemctl stop xl2tpd.service

启动脚本命令,测试一下VPN服务器内网地址是否连通:

  1. [root@iz2ze7tgu9zb2gr6av1tysz vpn]# ping 172.17.120.102

  2. PING 172.17.120.102 (172.17.120.102) 56(84) bytes of data.

  3. 64 bytes from 172.17.120.102: icmp_seq=1 ttl=63 time=1.96 ms

  4. 64 bytes from 172.17.120.102: icmp_seq=2 ttl=63 time=2.01 ms

  5. 64 bytes from 172.17.120.102: icmp_seq=3 ttl=63 time=1.92 ms

  6. 64 bytes from 172.17.120.102: icmp_seq=4 ttl=63 time=1.94 ms

  7. ^C

  8. --- 172.17.120.102 ping statistics ---

  9. 4 packets transmitted, 4 received, 0% packet loss, time 3003ms

  10. rtt min/avg/max/mdev = 1.926/1.961/2.010/0.062 ms

启动脚本命令,以上命令可以ping通,说明安装配置成功。

知识补充

内网定义

内网IP有3种:

  • 第一种10.0.0.0~10.255.255.255

  • 第二种172.16.0.0~172.31.255.255

  • 第三种192.168.0.0~192.168.255.255

相关端口

穿墙有术之企业级云上网络解决方案_内网_09IPSEC/L2TP方式的VPN基础

IPSec VPN是目前VPN技术中点击率非常高的一种技术,同时提供VPN和信息加密两项技术。

穿墙有术之企业级云上网络解决方案_封装_10

 IPSec VPN的应用场景分为3种:

  • Site-to-Site(站点到站点或者网关到网关):如弯曲评论的3个机构分布在互联网的3个不同的地方,各使用一个商务领航网关相互建立VPN隧道,企业内网(若干PC)之间的数据通过这些网关建立的IPSec隧道实现安全互联。

  • End-to-End(端到端或者PC到PC): 两个PC之间的通信由两个PC之间的IPSec会话保护,而不是网关。

  • End-to-Site(端到站点或者PC到网关):两个PC之间的通信由网关和异地PC之间的IPSec进行保护。VPN只是IPSec的一种应用方式,IPSec其实是IP Security的简称,它的目的是为IP提供高安全性特性,VPN则是在实现这种安全特性的方式下产生的解决方案。IPSec是一个框架性架构,具体由两类协议组成:

  1. AH协议(Authentication Header,使用较少):可以同时提供数据完整性确认、数据来源确认、防重放等安全特性;AH常用摘要算法(单向Hash函数)MD5和SHA1实现该特性。

  2. ESP协议(Encapsulated Security Payload,使用较广):可以同时提供数据完整性确认、数据加密、防重放等安全特性;ESP通常使用DES、3DES、AES等加密算法实现数据加密,使用MD5或SHA1来实现数据完整性。

为何AH使用较少呢?因为AH无法提供数据加密,所有数据在传输时以明文传输,而ESP提供数据加密;其次AH因为提供数据来源确认(源IP地址一旦改变,AH校验失败),所以无法穿越NAT。当然,IPSec在极端的情况下可以同时使用AH和ESP实现最完整的安全特性,但是此种方案极其少见。

IPSec封装模式介绍完IPSec VPN的场景和IPSec协议组成,再来看一下IPSec提供的两种封装模式(传输Transport模式和隧道Tunnel模式) 穿墙有术之企业级云上网络解决方案_数据_11

 上图是传输模式的封装结构,再来对比一下隧道模式: 穿墙有术之企业级云上网络解决方案_内网_12

可以发现传输模式和隧道模式的区别:

  • 传输模式在AH、ESP处理前后IP头部保持不变,主要用于End-to-End的应用场景。

  • 隧道模式则在AH、ESP处理之后再封装了一个外网IP头,主要用于Site-to-Site的应用场景。

从上图我们还可以验证上一节所介绍AH和ESP的差别。下图是对传输模式、隧道模式适用于何种场景的说明。

穿墙有术之企业级云上网络解决方案_内网_13

从这张图的对比可以看出:

  • 隧道模式可以适用于任何场景

  • 传输模式只能适合PC到PC的场景

隧道模式虽然可以适用于任何场景,但是隧道模式需要多一层IP头(通常为20字节长度)开销,所以在PC到PC的场景,建议还是使用传输模式。

为了使大家有个更直观的了解,我们看看下图,分析一下为何在Site-to-Site场景中只能使用隧道模式:

穿墙有术之企业级云上网络解决方案_封装_14

如上图所示,如果发起方内网PC发往响应方内网PC的流量满足网关的兴趣流匹配条件,发起方使用传输模式进行封装:

  • IPSec会话建立在发起方、响应方两个网关之间。

  • 由于使用传输模式,所以IP头部并不会有任何变化,IP源地址是192.168.1.2,目的地址是10.1.1.2。

  • 这个数据包发到互联网后,其命运注定是杯具的,为什么这么讲,就因为其目的地址是10.1.1.2吗?这并不是根源,根源在于互联网并不会维护企业网络的路由,所以丢弃的可能性很大。

  • 即使数据包没有在互联网中丢弃,并且幸运地抵达了响应方网关,那么我们指望响应方网关进行解密工作吗?凭什么,的确没什么好的凭据,数据包的目的地址是内网PC的10.1.1.2,所以直接转发了事。

  • 最杯具的是响应方内网PC收到数据包了,因为没有参与IPSec会话的协商会议,没有对应的SA,这个数据包无法解密,而被丢弃。

  • 我们利用这个反证法,巧妙地解释了在Site-to-Site情况下不能使用传输模式的原因。并且提出了使用传输模式的充要条件:兴趣流必须完全在发起方、响应方IP地址范围内的流量。比如在图中,发起方IP地址为6.24.1.2,响应方IP地址为2.17.1.2,那么兴趣流可以是源6.24.1.2/32、目的是2.17.1.2/32,协议可以是任意的,倘若数据包的源、目的IP地址稍有不同,对不起,请使用隧道模式。

IPSec协商 

穿墙有术之企业级云上网络解决方案_内网_15

IPSec除了一些协议原理外,我们更关注的是协议中涉及到方案制定的内容:

  • 兴趣流:IPSec是需要消耗资源的保护措施,并非所有流量都需要IPSec进行处理,而需要IPSec进行保护的流量就称为兴趣流,最后协商出来的兴趣流是由发起方和响应方所指定兴趣流的交集,如发起方指定兴趣流为192.168.1.0/24à10.0.0.0/8,而响应方的兴趣流为10.0.0.0/8à192.168.0.0/16,那么其交集是192.168.1.0/24ßà10.0.0.0/8,这就是最后会被IPSec所保护的兴趣流。

  • 发起方:Initiator,IPSec会话协商的触发方,IPSec会话通常是由指定兴趣流触发协商,触发的过程通常是将数据包中的源、目的地址、协议以及源、目的端口号与提前指定的IPSec兴趣流匹配模板如ACL进行匹配,如果匹配成功则属于指定兴趣流。指定兴趣流只是用于触发协商,至于是否会被IPSec保护要看是否匹配协商兴趣流,但是在通常实施方案过程中,通常会设计成发起方指定兴趣流属于协商兴趣流。

  • 响应方:Responder,IPSec会话协商的接收方,响应方是被动协商,响应方可以指定兴趣流,也可以不指定(完全由发起方指定)。

  • 发起方和响应方协商的内容主要包括:双方身份的确认和密钥种子刷新周期、AH/ESP的组合方式及各自使用的算法,还包括兴趣流、封装模式等。

  • SA:发起方、响应方协商的结果就是曝光率很高的SA,SA通常是包括密钥及密钥生存期、算法、封装模式、发起方、响应方地址、兴趣流等内容。

我们以最常见的IPSec隧道模式为例,解释一下IPSec的协商过程:

穿墙有术之企业级云上网络解决方案_数据_16

上图描述了由兴趣流触发的IPSec协商流程,原生IPSec并无身份确认等协商过程,在方案上存在诸多缺陷,如无法支持发起方地址动态变化情况下的身份确认、密钥动态更新等。伴随IPSec出现的IKE(Internet Key Exchange)协议专门用来弥补这些不足:

  • 发起方定义的兴趣流是源192.168.1.0/24目的10.0.0.0/8,所以在接口发送发起方内网PC发给响应方内网PC的数据包,能够得以匹配。

  • 满足兴趣流条件,在转发接口上检查SA不存在、过期或不可用,都会进行协商,否则使用当前SA对数据包进行处理。

  • 协商的过程通常分为两个阶段,第一阶段是为第二阶段服务,第二阶段是真正的为兴趣流服务的SA,两个阶段协商的侧重有所不同,第一阶段主要确认双方身份的正确性,第二阶段则是为兴趣流创建一个指定的安全套件,其最显著的结果就是第二阶段中的兴趣流在会话中是密文。

IPSec中安全性还体现在第二阶段SA永远是单向的: 穿墙有术之企业级云上网络解决方案_数据_17

从上图可以发现,在协商第二阶段SA时,SA是分方向性的,发起方到响应方所用SA和响应放到发起方SA是单独协商的,这样做的好处在于即使某个方向的SA被破解并不会波及到另一个方向的SA。这种设计类似于双向车道设计。 IPSec虽然只是5个字母的排列组合,但其所涉及的协议功能众多、方案又极其灵活。

参考文档

https://github.com/hwdsl2/setup-ipsec-vpn

https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/docs/clients-zh.md

http://en.wikipedia.org/wiki/Point-to-PointTunnelingProtocol

http://en.wikipedia.org/wiki/Layer2Tunneling_Protocol

https://baike.baidu.com/item/L2TP/609253?fr=aladdin

http://en.wikipedia.org/wiki/Point-to-PointTunnelingProtocol

http://en.wikipedia.org/wiki/IPsec

http://bbs.51cto.com/viewthread.php?tid=1119459

https://baike.baidu.com/item/ipsec/2472311?fr=aladdin

https://baike.baidu.com/item/strongSwan/2873029?fr=aladdin

http://www.unixwiz.net/techtips/iguide-ipsec.html

http://en.wikipedia.org/wiki/GenericRoutingEncapsulation

https://www.cloudcracker.com/blog/2012/07/29/cracking-ms-chap-v2/

https://www.strongswan.org/docs/OSTD_2013.pdf

http://security.hsr.ch/lectures/InformationSecurity2/Vorlesungsunterlagen/04.6-IKE_Notes.pdf