OpenVPN简介
- VPN(Virtual Private Network)即虚拟专用网。
- 原理
OpenVpn的技术核心是虚拟网卡,其次是SSL协议实现,由于SSL协议在这不做介绍,这里重点对虚拟网卡及其在OpenVpn的中的工作机理进行介绍:
虚拟网卡是使用网络底层编程技术实现的一个驱动软件,安装后在主机上多出现一个网卡,可以像其它网卡一样进行配置。服务程序可以在应用层打开虚拟网卡,如果应用软件(如IE)向虚拟网卡发送数据,则服务程序可以读取到该数据,如果服务程序写合适的数据到虚拟网卡,应用软件也可以接收得到。虚拟网卡在很多的操作系统下都有相应的实现,这也是OpenVpn能够跨平台一个很重要的理由。
在OpenVpn中,如果用户访问一个远程的虚拟地址(属于虚拟网卡配用的地址系列,区别于真实地址),则操作系统会通过路由机制将数据包(TUN模式)或数据帧(TAP模式)发送到虚拟网卡上,服务程序接收该数据并进行相应的处理后,通过SOCKET从外网上发送出去,远程服务程序通过SOCKET从外网上接收数据,并进行相应的处理后,发送给虚拟网卡,则应用软件可以接收到,完成了一个单向传输的过程,反之亦然。
- 加密
OpenVPN使用OpenSSL库加密数据与控制信息:它使用了OpenSSL的加密以及验证功能,意味着,它能够使用任何OpenSSL支持的算法。它提供了可选的数据包HMAC功能以提高连接的安全性。此外,OpenSSL的硬件加速也能提高它的性能。
- 验证
OpenVPN提供了多种身份验证方式,用以确认参与连接双方的身份,包括:预享私钥,
第三方证书以及用户名/密码组合。预享密钥最为简单,但同时它只能用于建立点对点的VPN;基于PKI的第三方证书提供了最完善的功能,但是需要额外的精力去维护一个PKI证书体系。OpenVPN2.0后引入了用户名/口令组合的身份验证方式,它可以省略客户端证书,但是仍有一份服务器证书需要被用作加密。
- 网络
OpenVPN所有的通信都基于一个单一的IP端口,默认且推荐使用UDP协议通讯,同时TCP也被支持。OpenVPN连接能通过大多数的代理服务器,并且能够在NAT的环境中很好地工作。服务端具有向客户端"推送"某些网络配置信息的功能,这些信息包括:IP地址、路由设置等。OpenVPN提供了两种虚拟网络接口:通用Tun/Tap驱动,通过它们,可以建立三层IP隧道,或者虚拟二层以太网,后者可以传送任何类型的二层以太网络数据。传送的数据可通过LZO算法压缩。IANA(Internet Assigned Numbers Authority)指定给OpenVPN的官方端口为1194。OpenVPN 2.0以后版本每个进程可以同时管理数个并发的隧道。
OpenVPN使用通用网络协议(TCP与UDP)的特点使它成为IPsec等协议的理想替代,尤其是在ISP(Internet service provider)过滤某些特定VPN协议的情况下。
在选择协议时候,需要注意2个加密隧道之间的网络状况,如有高延迟或者丢包较多的情况下,请选择TCP协议作为底层协议,UDP协议由于存在无连接和重传机制,导致要隧道上层的协议进行重传,效率非常低下。
TCP:有重传机制,端口固定,相比UDP会更加稳定。
UDP:无连接、无重传机制,端口不固定,不易受攻击。
服务器端安装部署
-
安装前准备
[[email protected] tools]# uname -r
2.6.18-194.el5
[[email protected] tools]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.5 (Tikanga)
[[email protected] etc]# ntpdate pool.ntp.org #=>时间同步,很多软件因为时间不同步安装会报错
20 Aug 15:17:12 ntpdate[32021]: step time server 202.112.31.197 offset 22.427442 sec
-
下载安装包并安装
[[email protected] tools]# ll
总计 1924
drwxrwxrwx 13 postfix users 4096 08-20 11:08 lzo-2.02
-rw-r--r-- 1 root root 599387 2005-10-18 lzo-2.02.tar.gz
drwxrwxrwx 16 root root 4096 08-20 12:42 openvpn-2.0.9
-rw-r--r-- 1 root root 669076 08-20 10:20 openvpn-2.0.9.tar.gz
Lzo编译安装
./configure
make && make install
openvpn编译安装
./configure --with-lzo-headers=/usr/local/include --with-lzo-lib=/usr/local/lib
make && make install
-
生成证书
[[email protected] easy-rsa]# pwd
/root/tools/openvpn-2.0.9/easy-rsa/2.0
[[email protected] 2.0]# vim vars #=>修改vars文件,方便后面生成证书
export KEY_COUNTRY="CN"
export KEY_PROVINCE="BJ"
export KEY_CITY="Beijing"
export KEY_ORG="Thunder"
export KEY_EMAIL=[email protected]
[[email protected] 2.0]# source vars #=>使证书生效
NOTE: If you run ./clean-all, I will be doing a rm -rf on /root/tools/openvpn-2.0.9/easy-rsa/2.0/keys
[[email protected] 2.0]# ./clean-all
[[email protected] 2.0]# ./build-ca #=>生成CA证书
Generating a 1024 bit RSA private key
.++++++
..++++++
writing new private key to ‘ca.key‘
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.‘, the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BJ]:
Locality Name (eg, city) [Beijing]:
Organization Name (eg, company) [thunder]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server‘s hostname) [thunder CA]: #=>不能为空
Email Address [[email protected]]:
[[email protected] 2.0]# ./build-key-server #=>生成服务器端证书
[[email protected] 2.0]# ./build-key #=>生成不加密码的客户端证书
[[email protected] 2.0]# ./build-key-pass #=>生成加密码的客户端证书
[[email protected] 2.0]# ./build-dh #=>生成 Diffie Hellman 参数,必须为OpenVPN服务端生成此参数
-
配置server.conf
[[email protected] tools]# cp openvpn-2.0.9/sample-config-files/server.conf /etc/openvpn/
[[email protected] sample-config-files]# egrep -v "^#|^$|;" server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3
#需要加入的内容
push "route 192.168.0.0 255.255.0.0" #=>需要访问的内网网段
client-to-client
log /var/log/openvpn.log
配置说明:
样例配置文件使用虚拟TUN网络接口(路由模式for routing)创建一个VPN,它在 UDP端口1194(OpenVPN的官方端口)上监听客户端连接请求,并且从10.8.0.0/24 子网为连接的客户端分配虚拟地址。
使用样例配置文件之前,首先要编辑ca、cert、key 和dh 参数,使之指向你在上一节PKI中生成的文件。
这时服务端配置文件就可以使用了,也可以进一步修改它:
如果你使用以太网桥,则必须使用 server-bridge和dev tap而不是 server和dev tun。
如果想让OpenVPN服务端监听一个TCP端口而不是UDP端口, 使用proto tcp而不是proto udp。
如果你想使用不同于10.8.0.0/24的一个虚拟IP地址范围,则修改 server项。记住这一虚拟IP地址范围必须是在你的网络上没有使用的。
如果想让连接的客户端可以通过VPN互相访问,将client-to-client的注释去掉。 默认情况下客户端只能访问服务端。
如果你使用的是Linux、BSD或Unix,则可以将user nobody和group nobody 的注释去掉以增强安全性。
如果想在同一台机器上运行多个OpenVPN,每个VPN使用一个不同的配置文件, 是可以做到的:
每个VPN实例使用一个不同的port号(UDP和TCP使用不同的端口空间,所以 可以让一个VPN监听UDP-1194,另一个监听TCP-1194)。
如果在Windows下运行,则每一个OpenVPN配置都需要有一个自己的TAP-Win32虚拟网卡。可以使用Start Menu -> All Programs -> OpenVPN -> Add a new TAP-Win32 virtual ethernet adapter来增加TAP-Win32虚拟网卡。
如果你运行了多个OpenVPN,记住编辑指定输出文件的指令,避免一个VPN覆盖另一个VPN 的输出文件。这些指令包括log、log-append、 status和ifconfig-pool-persist。
-
启动openvpn服务
[[email protected] openvpn]# sed -i ‘s/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/‘ /etc/sysctl.conf #=>开启内核转发功能
[[email protected] openvpn]# sysctl p =>使修改的内核参数生效
net.ipv4.ip_forward = 1
[[email protected] openvpn]# iptables L #=>检查iptables防火墙策略是否有阻止访问
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[[email protected] openvpn]# /usr/local/sbin/openvpn --config /etc/openvpn/server.conf & #=>指定配置文件启动
[[email protected] openvpn]#iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
到此,服务器端配置完毕。
客户端配置
-
下载安装客户端
分32位和64位版本
下载地址: https://openvpn.net/index.php/open-source/downloads.html
-
配置客户端
安装完成后,把客户端证书文件和客户端配置文件放到安装路径\openvpn\conf\下面。
客户端配置文件在服务器安装目录下:
[[email protected] sample-config-files]# pwd
/root/tools/openvpn-2.0.9/sample-config-files
[[email protected] sample-config-files]# ll
总计 72
-rw-r--r-- 1 root root 3427 2005-11-01 client.conf
[[email protected] sample-config-files]# egrep -v "^#|^$|;" client.conf
client
dev tun
proto udp
remote my-server-1 1194 #=>openvpn服务器地址及端口号,端口映射环境即为映射后公网的地址
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt #=>CA证书名称,一般不用动
cert client.crt #=>客户端证书名称
key client.key #=>客户端私钥名称
comp-lzo
verb 3
客户端配置文件说明:
象服务端配置文件一样,首先编辑ca、cert和key 参数使之指向你在上一节PKI生成的文件。每一个客户端有自己的cert/key对。只有ca文件在服务端和所有客户端之间是通用的。
下一步,编辑remote指令使之指向服务端的主机名/IP地址和端口号。 (如果OpenVPN服务端运行在firewall/NAT-gateway之后的一台单网卡机子上,则使用网关的公用IP地址,和你在网关上配置的向OpenVPN服务端转发的端口)。 (if your OpenVPN server will be running on a single-NIC machine behind a firewall/NAT- gateway, use the public IP address of the gateway, and a port number which you have configured the gateway to forward to the OpenVPN server).
最后,确保客户端配置文件和服务端配置文件中指令的的一致性。主要检查的是 dev(tun/tap)和proto(udp/tcp)。还有comp-lzo和 fragment(如果使用了)则在客户端和服务端的配置文件中都必须提供。
重要:修改完配置文件后,把配置文件后缀名为ovpn
最后应有以下内容文件
-
启动客户端并连接
以管理员身份运行客户端,(不用管理员运行连接到vpn后,可能会ping不通通内网地址)
在通知区域打到openvpn图标并右击,点击连接,图标变绿后即代表连接成功。