Blog

home category

非对称加密算法RSA和应用III - OPENVPN

24 Jun 2014

VPN

虚拟专用网(Virtual Private Network)是一种常用于连接中、大型企业或团体与团体间的私人网络的通讯方法。VPN可以实现通过不安全的网络架构(如因特网),利用身份认证、加密等技术安全可靠的传输信息。常用的VPN协议有

PPTP

点对点隧道协议(PPTP)是微软、3Com等公司开发的虚拟隧道协议。PPTP使用TCP创建控制通道来发送控制命令,以及利用通用路由封装(GRE)通道来封装点对点协议(PPP)数据包以发送数据。PPTP本身不提供加密和身份验证功能,需配合微软点对点加密(MPPE)

L2TP

第二层隧道协议(Layer Two Tunneling Protocol)是由IETF根据PPTP提出的虚拟隧道协议,2005年L2TPv3通过RFC 3931发布。L2TP自身也不提供加密与身份验证,通常配合IPSec实现,称为L2TP/IPsec。L2TP是数据链路层协议,实现时不局限于IP网络,同时还支持ATM、帧中继、X.25在内的多种网络。

IPSec

互联网安全协定(Internet Protocol Security)是通过对IP协议的分组进行加密和认证来保护IP协议的网络传输协议族。IPSec属于网络层,通过加密封装IP数据包,可用于保护更高层的协议,如TCP、UDP等;而其他加密协议,如SSL位于应用层,则只能加密TCP信息流。但处于更低层则相应的必须处理可靠性和分片的问题,也使复杂性和处理开销较SSL高。

若用于构建VPN(IPSec的主要用途),由于处于网络层,数据包到达内部网络即解密,因此在内部局域网中是明文传输。而处于应用层的SSL能保证应用间的安全传输。

开源软件Openswan可提供IPsec功能。

SSLVPN

对比IPSec和SSL可以看出两者各自的优势,在某些情况下需要构建使用SSL加密的VPN。

OpenVPN是一个用于创建VPN的软件包,大量使用OpenSSL加密库中的SSLv3/TLSv1协议函数库。其技术核心是虚拟网卡和SSL。虚拟网卡是使用网络底层编程技术实现的一个驱动软件,运行后主机多出现一个网卡,可像其他网卡一样配置,数据包都需通过此虚拟网卡处理。

OpenVPN必须双向验证,也提供了多种验证方式,包括预享密钥(仅用于点对点VPN)、第三方证书、用户名密码组合(2.0起提供)。由于OpenVPN使用通用网络协议(TCP等),因此可以防止ISP等过滤特定VPN协议,如IPSec。

搭建OpenVPN

整理这些内容实际是希望搭建一个VPN,在了解OpenVPN后引出了RSA算法和OpenSSL,于是就先做些准备,也方便之后使用HTTPS。

服务器端操作

Ubuntu 14.04,首先安装,OpenVPN2.3开始不捆绑easy-rsa(简化生成证书),因此也需手动安装

apt-get update
apt-get install openvpn easy-rsa

由之前内容知道ssl运行需要密钥和数字证书,因此需先生成这些内容,包括创建自己的根证书(CA),然后签发服务器和客户端证书用以身份认证。

cp -r /usr/share/easy-rsa/ /etc/openvpn
mkdir /etc/openvpn/easy-rsa/keys

cd /etc/openvpn/easy-rsa

使用easy-rsa简化证书创建,然后创建密钥存储文件夹

vim vars

# 配置,必填
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Example Company"
export KEY_EMAIL="[email protected]"
export KEY_OU="MyOrganizationalUnit"

export KEY_NAME="server"

配置用于证书的基本参数

source vars
./clean-all
./build-ca

载入修改后的配置,清理旧CA,并创建新CA;创建中要求确认基本的配置信息,Enter即可

生成Server和Client证书和密钥,每个Client有各自不同的证书。另外,可选添加”HMAC firewall”来阻止Dos和UDP port flooding攻击,原理是在TLS/SSL更高层添加一个安全层,先过滤HMAC特征不符的UDP包,也起到加快处理作用,因为TLS/SSL操作比较消耗时间。期间需做和./build-ca相同的选择

# 服务器证书,名称server与vars中KEY_NAME一致
./build-key-server server

# 客户端证书
./build-key client1
./build-key client2

# 服务器必须生成Diffie-Hellman参数
# 也可使用命令 openssl dhparam -out /etc/openvpn/dh2048.pem 2048
./build-dh

# 添加"HMAC firewall",记得之后的配置
openvpn --genkey --secret ta.key

结束后,除ta.key位于/etc/openvpn外,其他生成的内容都位于./keys目录,其中包括

  • ca.crt,Root CA certificate,服务器和所有客户端都需要一份,因此不需保密
  • ca.key,Root CA key,用于签发私钥,保密
  • dh{n}.pem,Diffie-Hellman参数
  • server.crt,服务器证书,由根证书签发,其中包含服务器公钥,不需保密
  • server.key,服务器私钥,必须保密
  • client{n}.crt,客户端证书
  • client{n}.key,客户端私钥
  • ta.key,服务器和客户端都需要一份,但必须保密,因此必须在已存在的安全通道中传输

OpenVPN在目录/etc/openvpn查找密钥,为方便可

cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt,dh2048.pem} /etc/openvpn

若有ta.key也需复制到/etc/openvpn

配置

服务器端配置

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

vim /etc/openvpn/server.conf

部分配置

# 相关密钥和证书名称,确保写入配置文件
ca ca.crt
cert server.crt
key server.key 
dh dh2048.pem

# 其他自选配置;协议使用udp因为可更好的防止Dos和UDP port flooding攻击
prot 1194
proto udp
comp-lzo

# 若希望将服务器作为客户端的网关(目的很明确嘛)则需去除以下内容的注释
# 使用Google Public DNS或默认
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"

# 将OpenVPN作为非特权用户运行是很好的安全策略,取消两行注释
user nobody
group nogroup

# "HMAC firewall"配置,第二个参数在服务器端为0,客户端为1
tls-auth ta.key 0

# log地址
log-append /var/log/openvpn.log

log默认写入/var/log/syslog,可自定义;接着非常重要一步,路由转发配置

vim /etc/sysctl.conf

# 取消ip_forward注释
net.ipv4.ip_forward = 1

# 退出vim后重新载入sysctl
sysctl -p

直接修改iptables或配置ufw

# 直接修改iptables
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
service iptables save

# 使用ufw配置
# OpenVPN使用UDP端口
ufw allow 1194/udp

# 允许封包转发
vim /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"

# ufw规则修改规则
vim /etc/ufw/before.rules

# 以下内容需添加在"*filter"行前,就是添加在规则的最前端
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# 完成
ufw reload

服务器端任务完成

service openvpn start
service openvpn status

ifconfig tun0

启动服务和查看信息。一切正常,进入客户端操作

客户端操作

进入client1,将之前生成的client1.crt, client1.key, ca.crt, ta.key移至/etc/openvpn

scp newuser@SERVER_IP_ADDRESS:/etc/openvpn/easy-rsa/keys/client1.key Downloads/

使用SCP(Secure Copy)下载

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf \
   /etc/openvpn/

cd /etc/openvpn
vim client.conf

部分配置

# 确保以下内容写入配置文件
ca ca.crt
cert client1.crt
key client1.key

# 注意修改服务器地址,端口和协议必须与服务器相同,服务器开启压缩则客户端也必须开启
remote vpnserver.example.com 1194
prot 1194
proto udp
comp-lzo

# 将OpenVPN作为非特权用户运行是很好的安全策略,取消两行注释
user nobody
group nogroup

# "HMAC firewall"配置,第二个参数在服务器端为0,客户端为1
tls-auth ta.key 1

# log地址
log-append /var/log/openvpn.log

配置完成,可开启客户端

service openvpn start

ifconfig tun0

# 服务器是否在线
ping 10.8.0.1

# 查看路由信息确定是否连接成功
netstat -rn

开启服务和信息查询

DNS,系统使用/etc/resolv.conf配置DNS服务,用于所有服务的域名解析。若需openvpn使用server端DNS,需修改此配置。利用openresolv可实现多程序无碰撞的修改此配置

apt-get update && apt-get install openresolv

安装openresolv后重启网络,查看resolv.conf发现# Generated by resolvconf字样表明配置成功,openresolv会自动根据系统配置,因此无需更多手动配置。确定可执行文件地址正确,向client.conf添加

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

打开和关闭openvpn时查看resolv.conf反向修改

移动设备

下载官方OpenVPN Connect应用,编辑一份client.conf并重命名为client.ovpn。将各种证书和密钥以in-line方式写入ovpn文件,具体见此文。样例

client
dev tun
remote vpnserver.example.com 1194
proto udp
comp-lzo
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
verb 3

<ca>
-----BEGIN CERTIFICATE-----
copy ca.crt here
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
  infos
-----END CERTIFICATE-----
copy client.crt here
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
copy client.key here
-----END PRIVATE KEY-----
</key>
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
copy ta.key here
-----END OpenVPN Static key V1-----
</tls-auth>

想办法将此配置文件移入ios设备,如通过邮件或iTunes同步等。完成后使用OpenVPN打开,跳转到OpenVPN后会看到有发现新配置的信息,右下方点击绿色的加号便可完成导入。打开服务测试。

使用其他方式进行客户端身份认证

以上使用第三方证书方式认证,之前提到还有两种认证方式,静态密钥方式查看此文。另一种是OpenVPN2.0起可以选择的用户名/密码认证方式,简化认证

DNS污染

虽然server.conf配置redirect-gateway且将server的DNS结果push到client,但是依然受到DNS污染,导致https连接几乎全出现URL和证书的地址不符;可能的原因是,虽然设置server为默认网关,但同时会向两个网关查询DNS,使用先响应的

避免被防火墙拦截

SSL在握手过程中是明文传输的,且看了几篇文章都说OpenVPN报文特征明显。有提到使用静态证书认证的,可以防止交换密钥时由于明显特征被阻拦OpenVPN服务的防火墙识别。还有是可以通过另一种不被拦截的服务通道传输OpenVPN报文,如SSH。

参看