openVPN HOWTO
时间:2006-05-31 来源:snowtty
英文原版
作者:James Yonan([email protected])
24th July 2003
翻译:threehair
2004.11.16
原文:http://openvpn.sourceforge.net/vpn-howto.pdf
内容
1 介绍
2 其它文档
3 路由IP隧道HOWTO
4 Home和Office的IP网络参数
5 OpenVPN安装
5.1 tarball安装
5.2 RPM安装
6 TUN/TAP驱动配置
6.1 只安装一次配置
6.2 每次重启重新配置的安装
7 防火墙和NAT配置
8 创建 RSA 证书和密钥
9 使用商业证书注意事项
10 使用SSL/TLS模式和RSA 证书/密钥配置文件
11 创建预分享静态密钥
12 使用预分享静态密钥配置文件
13 用SSL/TLS模式启动VPN
14 用静态密钥启动VPN
15 测试VPN
16 make VPN DHCP-aware
17 重启机器自动启动VPN
18 启动和停止多个OpenVPN隧道的管理
19 使用inetd或者xinetd实例化一个OpenVPN守护进程
1 介绍
本文描述在典型的Home到Office的远程通讯中OpenVPN的配置。 OpenVPN可以创建两种基本类型隧道:
-路由IP隧道:无需广播,用于路由点对点IP通信。比以太网桥隧道更为有效和更易于配置。 此howto涵盖路由IP隧道
-以太网桥隧道:可以用于IP和非ip协议隧道。这种隧道适用于基于广播的应用,如windows网络和局域网游戏。配置更为复杂。 2 其它文档
其它文档和howtos(http://openvpn.sourceforge.net/links.html)有不同配置的OpenVPN 3 路由IP隧道howto
我们尝试描述一个完整系统的配置,给出互相关联的包括防火墙、VPNs和NAT配置而不是孤立探讨VPN设置。
例子中,Home和Office所在私有网络分别通过具有公网IP地址的网关连接到internet。每个网关机器包含2块网卡,一块连到私有网络,另一块连到internet。网关为内网每台机器提供NAT、防火墙和VPN服务。除了Office网关有固定IP地址Home机器IP是DHCP动态获得之外,两端机器配置大致一样。
在下面的例子中,显示的所有配置文件在OpenVPN发布版本中都是有效的。 4Home和Office的IP网络参数
CODE
home office
本地以太子网(内网地址) 10.0.1.0/24 10.0.0.0/24
隧道端(内网地址) 10.1.0.2 10.1.0.1
OpenVPN 网关(公网地址) DHCP客户端,外部指定 1.2.3.4
表一 home和office IP网络参数 5 安装OpenVPN
如果系统没有OpenSSL库,下载并安装(http://www.openssl.org)
如果想让VPN链接压缩,或者用RPM包安装OpenVPN,安装LZO库(http://www.oberhumer.com/opensource/lzo)
如果使用Linux2.2或者更早版本,下载TUN/TAP驱动(http://vtun.sourceforge.net/tun).
Linux2.4.7或者以上版本用户可以发现TUN/TAP驱动已经捆绑到内核中。Linux2.4.0->2.4.6的用户应当注意INSTALL文件的最后的注意信息(http://openvpn.sourceforge.net/install.html).
现在下载OpenVPN的最新版本:
http://prdownloads.sourceforge.net/openvpn...pn-1.4.2.tar.gz 5.1 使用tarball安装
解压:
gzip -dc openvpn-1.4.2.tar.gz|tar xvf
创建OpenVPN
cd openvpn-1.4.2
./configure
make
make install
如果没有下载LZO库,configure命令增加-disable-lzo。允许使用其它选项如pthread(./configure -enable-pthread)用于提高SSL/TLS动态密钥交换的响应时间。命令
./configure --help
显示所有配置选项。 5.2 从 RPM安装
首先,创建RPM文件。要求存在OpenSSL,pthread和LZO库(http://www.oberhumer.com/opensource/lzo)。正常地,只有LZO库要求直接下载安装;在Linux版本上,其他库文件默认存在
rpm -tb openven-1.4.2.tar.gz
RPM创建过程会产生许多输出。如果创建成功,输出快结束时,会有一个提示信息说明生成的二进制RPM文件名字。用如下命令安装:
rpm -Uvh binary-RPM-file
6 配置TUN/TAP 驱动
6.1 一次配置步骤
如果使用的是LINUX 2.4.7或者更高版本,运气很好,因为TUN/TAP驱动早已捆绑到核心。可以用以下命令确认:
locate if_tun.h
会显示诸如/usr/include/linux/if_tun.h这样的文件。
对LINUX2.4.7或者更高版本,如果从tarball安装,则用下面的命令配置TUN/TAP设备节点(如果用RPM安装,则可以忽略这一步,因为RPM会创建):
mknod /dev/net/tun c 10 200
如果使用LINUX2.2,可以从http//vtun.sourceforge.net/tun获得TUN/TAP内核模块的1.1版本,按照安装步骤安装. 6.2 每次系统重启需要执行一次的配置LINUX上,使用OpenVPN或者任何其他用到TUN/TAP设备的程序之前,需要装载TUN/TAP核心模块:
modprobe tun
并允许IP转发:
echo 1>/proc/sys/net/ipv4/ip_forward 7 配置防火墙和NAT
本节假定使用的是带iptables防火墙的LINUX 2.4。这有一个为内网机器提供NAT使其可以访问internet和规定连到外网的策略以及OpenVPN支持的防火墙配置样例:
sample-config-files/firewall.sh
#!/bin/bash
#OpenVPN-aware防火墙例子
#eth0 接入互联网
#eth1 接入内网 #改变子网地址,使之对应其他子网
#Home 使用10.0.1.0/24
#Office使用10.0.0.0/24
PRIVATE=10.0.0.0/24 #Loopback地址
LOOP=127.0.0.1
#删除旧的iptables规则
#并临时阻塞网络通信
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables _F #设置缺省策略
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP #阻止外部数据包使用loopback地址
iptables -A INPUT -i eth0 -s $LOOP -j DROP
iptables -A FORWARD -i eth0 -S $LOOP -j DROP
iptables -A INPUT -i etho -d $LOOP -j DROP
iptables -A FORWARD -i eth0 -d $LOOP -j DROP #任何来自internet数据包应当使用真实internet地址
iptables -A FORWARD -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A FORWARD -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A FORWARD -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -eth0 -s 10.0.0.0/8 -j DROP #阻塞netbios数据包流出 (如果私网内有windows机器运行)。
#不会影响VPN 隧道上任意的NetBios通信
#但是会阻止本地windows机器向internet广播自己
iptables -A FORWARD -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A FORWARD -p udp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p udp --sport 137:139 -o eth0 -j DROP #检查流向互联网的数据包中源地址的合法性
iptables -A FORWARD -s ! $PRIVATE -i eth1 -j DROP #允许本地loopback
iptables -A INPUT -s $LOOP -j ACCEPT
iptables -A INPUT -d $LOOP -j ACCEPT #允许向内ping(可以禁止)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT #允许www和ssh服务(可以禁止)
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -P tcp --dport ssh -j ACCEPT #允许流入OpenVPN数据包,每个OpenVPN隧道要重复以下各行
#把 --dport n改为OpenVPN UDP实际端口. #OpenVPN中,端口号由--port n选项控制。如果让此项出现在配置文件中,可以删除前面的“--” #如果你使用的是状态路由器方法(参看OpenVPN HOWTO),那么注释掉下行
iptables -A INPUT -p udp --dport 5000 -j ACCEPT #允许来自tun/tap设备的包。当OpenVPN以安全模式运行,在数据包到达tun或者tap
#接口之前,OpenVPN会验证包。因此,这里没必要增加任何过滤,除非你想限制
#有可能溢出隧道的数据包类型。 iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT #允许来自内网的数据包
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT #保持来自本机和内网的连接状态
iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT #管理本地子网
iptables -t nat -A POSTROUTING -s $PRIVATE -o eth0 -j MASQUERADE OpenVPN提供的一些关于防火墙设置的附加选项
-如果OpenVPN的两端均直接使用-remote选项参考另一端,并且提供UDP连接跟踪的状态防火墙存在于端点之间,如果对端之间产生规则的ping以保持连接,无需任何直接的防火墙规则运行OpenVPN是可能的。为了达到这点,只需以-remote peer 选项运行OpenVPN,并制定-ping 15 以确保隧道上至少每15秒有数据包流过.
-以上选项在端点频繁改变其Ip地址比如DHCP或者拨号的时候显得不够方便。这种情况下,以上的防火墙配置例子将允许来自任意IP地址通过UDP端口5000(OpenVPN的缺省UDP端口)的数据包,这在任意的OpenVPN安全模式下认为是安全的,因为所有流入隧道的数据包必须通过授权验证或者被丢弃。
-如果你象以上的防火墙配置例子那样选择完全打开OpenVPN的接收端口,你也许想要充分利用-tls-auth 选项在TLS控制通道上双倍验证,并使用RSA密钥和预分享密码(secret passphrase)作为防御DoS或者active攻击的第二道防线.关于-tls-auth更多信息,参考the openvpn man page(http://openvpn.sourceforge.net/man.html). 8创建SA证书和密钥
OpenVPN有两种安全模式,一种基于使用证书和密钥的SSL/TLSsecurity,另一种使用预分享的静态密钥。由于SSL/TLS+RSA密钥证明是最安全选择,静态密钥优势是最简洁。如果你想采用RSA密钥,请继续看。对静态密钥,跳到创建预分享静态密钥这一节。(http://openvpn.sourceforge.net/howto.html#preshared).
我们将使用openssl命令创建RSA证书和密钥,该命令包含在OpenSSL库的发布程序中。RSA证书是公开密钥,其中还有其他安全域如证书持有者的Common name和Email地址.OpenVPN有能力在认证之前写脚本以测试这些域。更多信息参考OpenVPN man page的-tls-verify选项
(http;//openvpn.sourceforge.net/man.html).
在例子中,我们依照apache规定,用.crt的文件扩展名表示证书文件,用.key扩展名表示私有密钥文件。私钥文件必须保证安全。证书文件可以自由发布和共享。
选择一台机器如Office作为密钥管理机器。
首先,编辑/usr/share/ssl/openssl.cnf文件。(这个文件也许在其它的地方,此用locate openssl.cnf可以找到它)
你也许想对这个文件作些改变:
-建立一个目录作为密钥的工作目录并改变dir使其指向该路径。
-考虑增加默认期限以免VPN在工作一年之后不至于莫名其妙停止工作。
-设置certificate和private_key,使其指向根证书和马上要产生的私钥文件。在以下例子中,假定证书文件为my-ca.crt和私钥文件为my-ca.key。
-注意index.txt和serial文件。初始时,index.txt是空的,serial包含象01这样的初始序列号。
-如果你关注密钥长度,则可把default_bits增加到2048。如果支持pthread的OpenVPN处理2048位的RSA密钥使没有问题的。甚至也可以更长的密钥却不用pthread,但是你会看到当SSL/TLS密钥协商时,感觉到响应时间延迟。选择RSA密钥长度方面的好文章,可以参看Bruce Schneier2002年4月发表的Crypto-Gram Newsletter。(http://www.counterpane.com/crypto-gram-0204.html)
编辑了openssl.cnf之后,创建配套的根证书和私钥。
-openssl req -nodes -new -x509 -keyout my-ca.key -out my-ca.crt -days 3650
将会创建一对有效期10年的根证书/密钥。
现在为Home和Office创建证书和密钥对:
-openssl req -nodes -new -keyout office.key -out office.csr
-openssl ca -out office.crt -in office.csr
-openssl req -nodes -new -keyout home.key -out home.csr
-openssl ca -out home.crt -in home.csr
现在以安全的途径,把home.crt,home.key和my-ca.crt拷贝到Home主机上,尽管实际上只有.key文件是保密的。
现在用以下命令在Office机器上创建Diffie Hellman参数
openssl dhparam -out dh1024.pem 1024
如果在openssl.cnf中增加了密钥位数,相应的这里也把大小也从1024加到2048。
对于更狂热的追求者,可以考虑在上面的openssl命令中忽略-nodes选项。这使私钥用密码加密。如果有人潜入服务器偷走私钥文件仍可以保证密钥一定的安全。这种方法不方便之处的就是每次运行OpenVPN,需要输入密码。更详细的信息看http;//openvpn.sourceforge.net/man.html的askpass选项。
如果对手工管理RSA密钥管理觉得困惑,注意OpenVPN可以和任何X509证书管理工具或服务包括象Thawte(http://www.thawte.com)或者Verisign(http://www.verisign.com)这样的商业CAs一起使用。检索 OpenCA 项目可以查看有哪些同证书/密钥管理工具 配合良好的开源项目。
另外,OpenVPN发布版本包含一组可以简化RSA证书和密钥管理的脚本。(http;//openvpn.sourceforge.net/easyrsa.html). 9 OpenVPN的商业证书授权(CAs)使用的重要注意事项
注意到使用SSL/TLS模式的OpenVPN安全模块是面向用户的,用户可以产生他们自己的根证书,因此成为自己CA.在SSL/TLS模式中,OpenVPN通过检查对端提供的证书是否是-ca选项指定的CA证书验证它。正如基于SSL安全的web,SSL/TLS模式的OpenVPN的安全依赖于伪造根证书的不可能性特征。
如果已经生成自己的根证书,验证过程工作良好,但是如果希望使用如Thawte这种商业CA则会有问题。举个例子,如果用-ca选项指定Thawte的根证书,任意由Thawte指定的证书可以用OpenVPN peer授权,这当然不是你所要的。
幸运的是,使用-tls-verify可以解决这个问题。这个选项允许执行命令以检查证书内容,从而分离选择出允许的证书和不允许的证书。如何做看sample-script子目录下的verify-an脚本的例子,也可以看-tls-verify选项的man。 10 用SSL/TLS模式和RSA证书/密钥配置文件
例子中,我们使用OpenVPN的配置文件。OpenVPN允许选项以命令行或者一个或者多个配置文件指定参数。配置文件中的选项可以忽略前面的"-",在命令行选项中则需要。
建立下面的配置文件:
sample-config-files/tls-office.conf #使用SSL/TLS模式和RSA证书/密钥的OpenVPN的office配置文件样本
#‘#’或者‘;’用作注释
#使用动态tun设备
#Linux 2.2或者非Linux操作系统
#你可能想使用显式指明设备号,如tun1
#OpenVPN也支持虚拟的以太tap设备
dev tun #10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
ifconfig 10.1.0.1 10.1.0.2 #up脚本建立路由
up ./office.up
#SSL/TLS密钥交换时,office假设为server,home假设为client
tls-server #Diffie-Hellman 参数(仅在tls-server)
dh dh1024.pem #证书文件
ca my-ca.crt #自己的证书/公钥
cert office.crt #自己的私钥
key office.crt #OpenVPN默认使用UDP端口5000
#每个OpenVPN隧道必须使用不同的端口号。
#lport或者rport分别用作表示本地和远程的不同端口号
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody #如果使用LZO压缩,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping
#状态防火墙连接状态alive
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是显示非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/office.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 sample-config-files/tls-home.conf
#使用SSL/TLS模式和RSA证书/密钥的OpenVPN的home配置文件样本
#‘#’或者‘;’用作注释
#使用动态tun设备
#Linux 2.2或者非Linux操作系统
#你可能想使用显式指明设备号,如tun1
#OpenVPN也支持虚拟的以太tap设备
dev tun #OpenVPN peer是一个office网关
remote 1.2.3.4 #10.1.0.2是本地VPN端点(home)
#10.1.0.1是远程VPN端点(office)
ifconfig 10.1.0.2 10.1.0.1 #一旦VPN激活,up脚本将建立路由
up ./home.up #SSL/TLS密钥交换,office假定为server,home假定为client
tls-client #证书授权文件
ca my-ca.crt #证书/公钥
cert home.crt #私钥
key home.key #OpenVPN UDP默认使用UDP端口5000。
#每个OpenVPN隧道必须使用不同的端口号
#lport或者rport可以分别用于表示本地和远程的端口号
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody
#如果用LZO压缩编译链接OpenVPN,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping
#状态防火墙连alive,如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是显示非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/home.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 11 创建预分享静态密钥
和RSA密钥管理相反,使用预分享静态密钥更为简单。使用静态密钥的主要不足之处是放弃了让安全机制更完美的想法。也就是说,如果攻击者窃取了你的静态密钥,所有用其加密的都会被危及安全。
用下列命令生成静态密钥:
openvpn --genkey -secret static.key
这个静态文件是ascii形式的,看起来象这样:
-----BEGIN OpenVPN Static key V1-----
e5e4d6af39289d53
171ecc237a8f996a
97743d146661405e
c724d5913c550a0c
30a48e52dfbeceb6
e2e7bd4a8357df78
4609fe35bbe99c32
bdf974952ade8fb9
71c204aaf4f256ba
eeda7aed4822ff98
fd66da2efa9bf8c5
e70996353e0f96a9
c94c9f9afb17637b
283da25cc99b37bf
6f7e15b38aedc3e8
e6adb40fca5c5463
-----END OpenVPN Static key V1----- 一个OpenVPN静态密钥包含足够的熵值,512位为加密键,512位为身份验证的HMAC。通过安全媒介如使用scp或者ssh的拷贝粘贴把static.key拷贝到对端。 12 使用预分享的静态密钥配置文件
例子中,我们将使用OpenVPN的配置文件。OpenVPN允许选项用在命令行或者一个或对多个配置文件中指定参数。配置文件的选项可以忽略前面的用于命令行选项的"-"。
建立下面的配置文件:
sample-config-files/static-office.conf #使用预分享的静态密钥的OpenVPN的office配置文件样例。
#‘#’或者‘;’用作注释
#使用动态tun设备
#针对lINUX2.2或者非LINUX操作系统
#也许想用显式的设备号,如tun1
#OpenVPN也可以支持虚拟以太"tap"设备
dev tun
#10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
ifconfig 10.1.0.1 10.1.0.2 #一旦VPN激活,这个up脚本将建立路由
up ./office.up #预分享的静态密钥
secret static.key #OpenVPN UDP默认使用UDP端口号5000
#每个OpenVPN隧道必须使用不同的端口号
#lport和rport分别表示本地和远程的端口
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody #如果用LZO压缩编译链接OpenVPN,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping以保持状态防火墙连接alive。
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是输出非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/office.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 sample-config-files/static-home.conf #使用预分享的静态密钥的OpenVPN的home配置文件样例。
#‘#’或者‘;’用作注释
#使用动态tun设备
#针对lINUX2.2或者非LINUX操作系统
#也许想用显式的设备号,如tun1
#OpenVPN也可以支持虚拟以太"tap"设备
dev tun #我们OpenVPN对端是office网关
ifconfig 10.1.0.2 10.1.0.1 #10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
remote 1.2.3.4 #一旦VPN激活,这个up脚本将建立路由
up ./home.up #预分享的静态密钥
secret static.key #OpenVPN UDP默认使用UDP端口号为5000
#每个OpenVPN隧道必须使用不同的端口号
#lport和rport分别表示本地和远程的端口
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody
#如果用LZO压缩,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping 以状态保持防火墙连接状态alive
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是输出非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/home.up
#!/bin/bash
route add -net 10.0.0.0 netmask 255.255.255.0 gw $5
13 以SSL/TLS模式运行VPN
home端,用这个命令运行VPN
openvpn --config tls-home.conf
office端,用这个命令运行VPN
openvpn --config tls-office.conf
14 以静态密钥模式运行VPN
home端,用这个命令运行VPN
openvpn --config static-home.conf
office端,用这个命令运行VPN
openvpn --config static-office.cof 15测试VPN
在home端,经由隧道ping office来测试VPN
ping 10.1.0.1
在office端,经由隧道ping home测试VPN
ping 10.1.0.2
如果这些测试失败却没有输出信息,可能要重新编辑配置文件设置错误级别为8使其可以生成更多详细调试输出。同样可以咨询FAQ更多关于故障的信息(http://openvpn.sourceforge.net/faq.html#cantping)
如果测试成功,尝试通过隧道ping私网的机器(不是OpenVPN网关机器)来测试路由,基本上任何在10.0.1.0/24子网的机器能够访问10.0.0.0/24的任何机器和代理,反之亦然.
如果可以了,祝贺你。否则,你可能要检查OpenVPN邮件列表的档案(http://sourceforge/mail?group_id=48978)看看是否其他人遇到类似的问题。如果你在这没有找到问题的解决方法,考虑贴在openvpn-users 16make the VPN DHCP-aware
回忆网络配置的例子,home是动态地址,没有警告就可以改变。如果客户端使用dhcped,建立一个客户端地址改变就可以运行的脚本是很容易的。这个脚本命名有些类似/etc/dhcpc/dhcp-cd-eth0.exe.
基本上,可以在这个脚本中增加这样一行以发送SIGUSR1或者SIGHUP信号给OpenVPN守护进程:
killall -HUP openvpn
当OpenVPN收到信号,就会关闭连接然后用DHCP指定的IP地址重新打开与对端的连接。
如果你连接到可能由于DHCP重置而改变地址的对端,你应当用-float选项。
也能用SIGUSER1信号处理DHCP重置,SIGUSER1有些象SIGHUP除了它在OpenVPN子系统重置时提供更多进程回收控制。SIGUSER1信号也可以用内部基于-ping 和-ping-restart生成。
-persist-tun选项允许无需关闭和重新打开tun设备即可重置(为DHCP上的隧道提供无缝连接).
-persist-remotr-ip选项允许穿过DHCP重置保留远程IP地址。允许OpenVPN隧道两端都可以作为DHCP客户端
-persist-key选项重启的时候不用重读密钥文件(即使-user或者-group已经降低权限也允许OpenVPN守护进程重启)
关于动态IP下的openvpn的更多信息参考FAQ(http;//openvpn.sourceforge.net/faq.html#dynamic).
17重启时自动启动VPN
首先,建立一个目录如/etc/openvpn以保存OpenVPN密钥和配置文件。
选择使用TLS还是静态密钥模式,拷贝适当的.conf,.up,.key,.pem和.crt文件到/etc/openvpn
保护.key文件
chmod go-rwx /etc/openvpn/*.key
如果使用Linux iptables,编辑防火墙配置文件firewall.sh,改变它使之接近你的环境并拷到/etc/openvpn下。
创建类似下面的开始脚本:
sample-config-files/openvpn-startup.sh
#!/bin/bash
#LINUX下,OpenVPN启动脚本样例
#openvpn配置文件路径
dir=/etc/openvpn
#装载防火墙
$dir/firewall.sh
#装载TUN/TAP内核模块
modprobe tun
#允许IP转发
echo 1>/pro/sys/net/ipv4/ip_forward #每个VPN隧道用守护进程模式调用openvpn。
#你可以在命令行去掉--damen并在配置文件中增加"daemon"
#每个隧道应当运行在独立udp端口,使用"port"选项控制它
#正如所有的OpenVPN选项,你可以在命令行用--port 8000指定或者在配置文件中用port 8000
openvpn --cd $dir --daemon --config vpn1.conf
openvpn --cd $dir --daemon --config vpn2.conf
openvpn --cd $dir --daemon --config vpn2.conf1 增加如下关闭脚本:
sample-config-files/openvpn-shutdown.sh
#!/bin/bash
#stop all openvpn processes
killall -TERM openvpn 最后,在系统的开机和关机脚本分别增加调用openvpn-startup.sh和openvpn-shutdown.sh或者直接加到/etc/init.d目录 18 管理多个OpenVPN隧道的启动和关闭
这有一个/etc/init.d脚本例子,这个可以自动为/etc/openvpn的每个.conf文件生成一个隧道。
sample-scripts/openvpn.init
#!/bin/sh
#openvpn 这个shell脚本用于启动和停止openvpn
#chkconfig;345 80 30
#描述:OpenVPN是一个健壮、高度灵活的隧道应用,可以使
#用OpenSSL库的所有加密、授权和证书特色以保证在单一udp
#端口上隧道的ip层安全
#由Douglas keller的OpenVPN#项目提供 2002.05.15
#安装:
#拷贝文件到/etc/rc.d/init.d/openvpn
#shell>chkconfig --add openvpn
#shell>mkdir /etc/openvpn
#make .conf or .sh file in /etc/openvpn(见下文)
#卸载:
#run: chkconfig --del openvpn
#作者注释:
#我已经生成一个/etc/init.d的初始化脚本,并在初始化脚
#本中,并修改openvpn.spec使之可以自动注册该脚本.只要安装了RPM,#就可以用"service openvpn start"和"service openvpn stop"启动和停止openvpn #初始化脚本如下:
#为/etc/openvpn下的每个.conf文件启动一个openvpn进程
#如果存在对应xxx.conf的 /etc/openvpn/XXX.sh文件
#那么在启动OpenVPN之前执行它(作openvpn --mktun时很有用...).
#除 start/stop外还可以执行:
#service openvpn reload -SIGHUP
#service openvpn reopen -SIGUSR1
#service openvpn status -SIGUSR2 #修改于 2003.05.02
#changed ==to =for sh cpmpliance(Bishop Clark)
#if condrestart|reload|reopen|status,check that we #were actually started(James Yonan).
#added lock,piddir,and work variabled(James Yonan).
#if start is attempted twice,without an intervening #stop,or if start is attempted when previous start was #not properly shut down,then kill any previously #started processes,before commencing new start #operation(James Yonan).
#do a better job of flagging errors on start,and #properly returning success or failure status to #caller(James Yonan). #可执行OpenVPN的位置
openvpn="/usr/sbin/openvpn" #lockfile
lock="/var/lock/subsys/openvpn" #PID目录
piddir="/var/run/openvpn" #工作目录
work=/etc/openvpn #源程序函数库
./etc/rc.d/init.d/functions #源网络配置
./etc/sysconfig/network #检查网络是否起了
[${NETWORKING}="no"]&&exit 0
[-f $openvpn]||exit 0 #调用
case "$1" in
start)
echo -n $"starting openvpn:" /sbin/modprobe tun>/dev/null 2>&1
echo 1>/proc/sys/net/ipv4/ip_forward if[!-d $piddir];then
mkdr $piddir
fi if[-f $lock];then
#we were not shut down correctly
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill 'cat $pidf'>/dev/null 2>&1
fi
rm -f $pidf
done
rm -f $lock
sleep 2
fi rm -f $piddir/*.pid
cd $work #start every .conf in $work and run .sh if exists
errors=0
successes=0
for c in '/bin/ls *.conf 2>/dev/null';do
bn=${c%%.conf}
if [-f "$bn.sh"];then
. $bn.sh
fi
rm -f $piddir/$bn.pid
$openvpn --daemon --writepid $piddir/$bn.pd --config $c --cd $work
if [$?=0];then
successes=1
else
errors=1
fi
done if[$errors=1];then
failure;echo
else
success;echo
fi if[$successes=1];then
touch $lock
fi
;;
stop) echo -n $"shutting down openvpn:"
for pidf in'/bin/ls $piddir/*pid 2>/dev/null';do
if[-s $pidf];then
kill 'cat $pidf'>/dev/null 2>&1
fi
rm -f $pidf
done
success;echo
rm -f $lock
;;
restart)
$0 stop
sleep 2
$0 start
;;
reload)
if [-f $lock];then
for pidf in '/bin/ls $piddir/*pid 2>/dev/null';do
if [-s $pidf];then
kill -HUP 'cat $pidf'>/dev/null 2>&1
fi
done
else
echo "openvpn:service not started"
exit 1
fi
;;
reopen)
if [-f $locj];then
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill -USER1 'cat $pidf'>/dev/null 2>&1
fi
done
else
echo "openvpn:service not started"
exit 1
fi
;;
condrestart)
if [-f $locj];then
$0 stop
#avoid race
sleep 2
$0 start
fi
;;
status)
if [-f $lock]; then
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill -USR2 'cat $pidf'>/dev/null 2>&1
fi
done
echo "status written to /var/log/messages"
else
echo "openvpn:service not started"
exit 1
fi
;;
*)
echo "usuage;openvpn {start|stop|restart|condrestart|reload|reopen|status}"
exit 1
esac exit 0 19 使用inetd或者xinetd实例化一个OpenVPN守护进程
通用xinetd服务可以用作在接受来自远端的初始数据报文之前自动实例化一个OpenVPN守护进程。
此xinetd配置使xinetd进程监听UDP端口5000 ,对流入OpenVPN会话的初始数据包,(使用预分享密钥),xinetd 会自动实例化一个OpenVPN守护进程以处理会话.注意使用 -inactive 开关会使OpenVPN daemon闲置10分钟之后超时退出。无论什么原因一旦守护进程退出,xinetd服务会继续监听端口,并将再次实例化一个OpenVPN守护进程以处理另外的连接.另外注意xinetd会用root权限初始实例化OpenVPN 守护进程,但是随后,OpenVPN (读取受保护的密钥文件)会把权限降为nobody,
密钥文件可以用下列命令生成:
openvpn --genkey --secret key
请注意,每个OpenVPN隧道都需要运行在自己独立的端口上并需要自己的xinetd配置文件。这是因为OpenVPN需要每个可能到来的连接的详细信息包括密钥文件,tun/tap设备,隧道端点和路由配置。基于这点,在OpenVPN的发展中],从不使用单个配置文件来处理大批类似的潜在接入者,因为OpenVPN作为UDP server实现以来,不具有TCP server可监听固定端口同时fork一个新的守护进程来处理每个客户端会话的特点.尽管如此,接入连接模板已经进入计划,如果开发者和最终用户社区足够兴趣和支持,一定会是实现。
sample-config-files/xinetd-server-config #关于OpenVPN的inetd配置文件
#这个文件可以重命名为OpenVPN或适合描述和拷贝/etc/xinetd.d目录下的一些名字.
#重启或者发送一个SIGHUP信号时,xinetd能够认识这个文件
#对每个潜在的接入客户端,用唯一的端口号生成单独的配置文件。同样,注意到每个客户端的密钥文件和ifconfig端点应当唯一.这个配置文件假定OpenVPN可执行并且密钥存在于/root/openvpn。修改使之适合你的环境。
service openvpn_1
{
type =UNLISTED
port =5000
socket_type =dgram
protocol =udp
wait =yes
user =root
server =/root/openvpn/openvpn
server_args =--inetd --dev tun --ifconfig 10.4.0.2 10.4.0.1 --secret /root/open
} sample-config-files/xinetd-client-config
#这个是相对xinetd-server-config的OpenVPN客户端配置文件
dev tun
ifconfig 10.4.0.1 10.4.0.2
remote my-server
port 5000
user nobody
secret /root/openvpn/key
inactive 600
作者:James Yonan([email protected])
24th July 2003
翻译:threehair
2004.11.16
原文:http://openvpn.sourceforge.net/vpn-howto.pdf
内容
1 介绍
2 其它文档
3 路由IP隧道HOWTO
4 Home和Office的IP网络参数
5 OpenVPN安装
5.1 tarball安装
5.2 RPM安装
6 TUN/TAP驱动配置
6.1 只安装一次配置
6.2 每次重启重新配置的安装
7 防火墙和NAT配置
8 创建 RSA 证书和密钥
9 使用商业证书注意事项
10 使用SSL/TLS模式和RSA 证书/密钥配置文件
11 创建预分享静态密钥
12 使用预分享静态密钥配置文件
13 用SSL/TLS模式启动VPN
14 用静态密钥启动VPN
15 测试VPN
16 make VPN DHCP-aware
17 重启机器自动启动VPN
18 启动和停止多个OpenVPN隧道的管理
19 使用inetd或者xinetd实例化一个OpenVPN守护进程
1 介绍
本文描述在典型的Home到Office的远程通讯中OpenVPN的配置。 OpenVPN可以创建两种基本类型隧道:
-路由IP隧道:无需广播,用于路由点对点IP通信。比以太网桥隧道更为有效和更易于配置。 此howto涵盖路由IP隧道
-以太网桥隧道:可以用于IP和非ip协议隧道。这种隧道适用于基于广播的应用,如windows网络和局域网游戏。配置更为复杂。 2 其它文档
其它文档和howtos(http://openvpn.sourceforge.net/links.html)有不同配置的OpenVPN 3 路由IP隧道howto
我们尝试描述一个完整系统的配置,给出互相关联的包括防火墙、VPNs和NAT配置而不是孤立探讨VPN设置。
例子中,Home和Office所在私有网络分别通过具有公网IP地址的网关连接到internet。每个网关机器包含2块网卡,一块连到私有网络,另一块连到internet。网关为内网每台机器提供NAT、防火墙和VPN服务。除了Office网关有固定IP地址Home机器IP是DHCP动态获得之外,两端机器配置大致一样。
在下面的例子中,显示的所有配置文件在OpenVPN发布版本中都是有效的。 4Home和Office的IP网络参数
CODE
home office
本地以太子网(内网地址) 10.0.1.0/24 10.0.0.0/24
隧道端(内网地址) 10.1.0.2 10.1.0.1
OpenVPN 网关(公网地址) DHCP客户端,外部指定 1.2.3.4
表一 home和office IP网络参数 5 安装OpenVPN
如果系统没有OpenSSL库,下载并安装(http://www.openssl.org)
如果想让VPN链接压缩,或者用RPM包安装OpenVPN,安装LZO库(http://www.oberhumer.com/opensource/lzo)
如果使用Linux2.2或者更早版本,下载TUN/TAP驱动(http://vtun.sourceforge.net/tun).
Linux2.4.7或者以上版本用户可以发现TUN/TAP驱动已经捆绑到内核中。Linux2.4.0->2.4.6的用户应当注意INSTALL文件的最后的注意信息(http://openvpn.sourceforge.net/install.html).
现在下载OpenVPN的最新版本:
http://prdownloads.sourceforge.net/openvpn...pn-1.4.2.tar.gz 5.1 使用tarball安装
解压:
gzip -dc openvpn-1.4.2.tar.gz|tar xvf
创建OpenVPN
cd openvpn-1.4.2
./configure
make
make install
如果没有下载LZO库,configure命令增加-disable-lzo。允许使用其它选项如pthread(./configure -enable-pthread)用于提高SSL/TLS动态密钥交换的响应时间。命令
./configure --help
显示所有配置选项。 5.2 从 RPM安装
首先,创建RPM文件。要求存在OpenSSL,pthread和LZO库(http://www.oberhumer.com/opensource/lzo)。正常地,只有LZO库要求直接下载安装;在Linux版本上,其他库文件默认存在
rpm -tb openven-1.4.2.tar.gz
RPM创建过程会产生许多输出。如果创建成功,输出快结束时,会有一个提示信息说明生成的二进制RPM文件名字。用如下命令安装:
rpm -Uvh binary-RPM-file
6 配置TUN/TAP 驱动
6.1 一次配置步骤
如果使用的是LINUX 2.4.7或者更高版本,运气很好,因为TUN/TAP驱动早已捆绑到核心。可以用以下命令确认:
locate if_tun.h
会显示诸如/usr/include/linux/if_tun.h这样的文件。
对LINUX2.4.7或者更高版本,如果从tarball安装,则用下面的命令配置TUN/TAP设备节点(如果用RPM安装,则可以忽略这一步,因为RPM会创建):
mknod /dev/net/tun c 10 200
如果使用LINUX2.2,可以从http//vtun.sourceforge.net/tun获得TUN/TAP内核模块的1.1版本,按照安装步骤安装. 6.2 每次系统重启需要执行一次的配置LINUX上,使用OpenVPN或者任何其他用到TUN/TAP设备的程序之前,需要装载TUN/TAP核心模块:
modprobe tun
并允许IP转发:
echo 1>/proc/sys/net/ipv4/ip_forward 7 配置防火墙和NAT
本节假定使用的是带iptables防火墙的LINUX 2.4。这有一个为内网机器提供NAT使其可以访问internet和规定连到外网的策略以及OpenVPN支持的防火墙配置样例:
sample-config-files/firewall.sh
#!/bin/bash
#OpenVPN-aware防火墙例子
#eth0 接入互联网
#eth1 接入内网 #改变子网地址,使之对应其他子网
#Home 使用10.0.1.0/24
#Office使用10.0.0.0/24
PRIVATE=10.0.0.0/24 #Loopback地址
LOOP=127.0.0.1
#删除旧的iptables规则
#并临时阻塞网络通信
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables _F #设置缺省策略
iptables -P OUTPUT ACCEPT
iptables -P INPUT DROP
iptables -P FORWARD DROP #阻止外部数据包使用loopback地址
iptables -A INPUT -i eth0 -s $LOOP -j DROP
iptables -A FORWARD -i eth0 -S $LOOP -j DROP
iptables -A INPUT -i etho -d $LOOP -j DROP
iptables -A FORWARD -i eth0 -d $LOOP -j DROP #任何来自internet数据包应当使用真实internet地址
iptables -A FORWARD -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A FORWARD -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A FORWARD -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -eth0 -s 10.0.0.0/8 -j DROP #阻塞netbios数据包流出 (如果私网内有windows机器运行)。
#不会影响VPN 隧道上任意的NetBios通信
#但是会阻止本地windows机器向internet广播自己
iptables -A FORWARD -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A FORWARD -p udp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p tcp --sport 137:139 -o eth0 -j DROP
iptables -A OUTPUT -p udp --sport 137:139 -o eth0 -j DROP #检查流向互联网的数据包中源地址的合法性
iptables -A FORWARD -s ! $PRIVATE -i eth1 -j DROP #允许本地loopback
iptables -A INPUT -s $LOOP -j ACCEPT
iptables -A INPUT -d $LOOP -j ACCEPT #允许向内ping(可以禁止)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT #允许www和ssh服务(可以禁止)
iptables -A INPUT -p tcp --dport http -j ACCEPT
iptables -A INPUT -P tcp --dport ssh -j ACCEPT #允许流入OpenVPN数据包,每个OpenVPN隧道要重复以下各行
#把 --dport n改为OpenVPN UDP实际端口. #OpenVPN中,端口号由--port n选项控制。如果让此项出现在配置文件中,可以删除前面的“--” #如果你使用的是状态路由器方法(参看OpenVPN HOWTO),那么注释掉下行
iptables -A INPUT -p udp --dport 5000 -j ACCEPT #允许来自tun/tap设备的包。当OpenVPN以安全模式运行,在数据包到达tun或者tap
#接口之前,OpenVPN会验证包。因此,这里没必要增加任何过滤,除非你想限制
#有可能溢出隧道的数据包类型。 iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT #允许来自内网的数据包
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT #保持来自本机和内网的连接状态
iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT #管理本地子网
iptables -t nat -A POSTROUTING -s $PRIVATE -o eth0 -j MASQUERADE OpenVPN提供的一些关于防火墙设置的附加选项
-如果OpenVPN的两端均直接使用-remote选项参考另一端,并且提供UDP连接跟踪的状态防火墙存在于端点之间,如果对端之间产生规则的ping以保持连接,无需任何直接的防火墙规则运行OpenVPN是可能的。为了达到这点,只需以-remote peer 选项运行OpenVPN,并制定-ping 15 以确保隧道上至少每15秒有数据包流过.
-以上选项在端点频繁改变其Ip地址比如DHCP或者拨号的时候显得不够方便。这种情况下,以上的防火墙配置例子将允许来自任意IP地址通过UDP端口5000(OpenVPN的缺省UDP端口)的数据包,这在任意的OpenVPN安全模式下认为是安全的,因为所有流入隧道的数据包必须通过授权验证或者被丢弃。
-如果你象以上的防火墙配置例子那样选择完全打开OpenVPN的接收端口,你也许想要充分利用-tls-auth 选项在TLS控制通道上双倍验证,并使用RSA密钥和预分享密码(secret passphrase)作为防御DoS或者active攻击的第二道防线.关于-tls-auth更多信息,参考the openvpn man page(http://openvpn.sourceforge.net/man.html). 8创建SA证书和密钥
OpenVPN有两种安全模式,一种基于使用证书和密钥的SSL/TLSsecurity,另一种使用预分享的静态密钥。由于SSL/TLS+RSA密钥证明是最安全选择,静态密钥优势是最简洁。如果你想采用RSA密钥,请继续看。对静态密钥,跳到创建预分享静态密钥这一节。(http://openvpn.sourceforge.net/howto.html#preshared).
我们将使用openssl命令创建RSA证书和密钥,该命令包含在OpenSSL库的发布程序中。RSA证书是公开密钥,其中还有其他安全域如证书持有者的Common name和Email地址.OpenVPN有能力在认证之前写脚本以测试这些域。更多信息参考OpenVPN man page的-tls-verify选项
(http;//openvpn.sourceforge.net/man.html).
在例子中,我们依照apache规定,用.crt的文件扩展名表示证书文件,用.key扩展名表示私有密钥文件。私钥文件必须保证安全。证书文件可以自由发布和共享。
选择一台机器如Office作为密钥管理机器。
首先,编辑/usr/share/ssl/openssl.cnf文件。(这个文件也许在其它的地方,此用locate openssl.cnf可以找到它)
你也许想对这个文件作些改变:
-建立一个目录作为密钥的工作目录并改变dir使其指向该路径。
-考虑增加默认期限以免VPN在工作一年之后不至于莫名其妙停止工作。
-设置certificate和private_key,使其指向根证书和马上要产生的私钥文件。在以下例子中,假定证书文件为my-ca.crt和私钥文件为my-ca.key。
-注意index.txt和serial文件。初始时,index.txt是空的,serial包含象01这样的初始序列号。
-如果你关注密钥长度,则可把default_bits增加到2048。如果支持pthread的OpenVPN处理2048位的RSA密钥使没有问题的。甚至也可以更长的密钥却不用pthread,但是你会看到当SSL/TLS密钥协商时,感觉到响应时间延迟。选择RSA密钥长度方面的好文章,可以参看Bruce Schneier2002年4月发表的Crypto-Gram Newsletter。(http://www.counterpane.com/crypto-gram-0204.html)
编辑了openssl.cnf之后,创建配套的根证书和私钥。
-openssl req -nodes -new -x509 -keyout my-ca.key -out my-ca.crt -days 3650
将会创建一对有效期10年的根证书/密钥。
现在为Home和Office创建证书和密钥对:
-openssl req -nodes -new -keyout office.key -out office.csr
-openssl ca -out office.crt -in office.csr
-openssl req -nodes -new -keyout home.key -out home.csr
-openssl ca -out home.crt -in home.csr
现在以安全的途径,把home.crt,home.key和my-ca.crt拷贝到Home主机上,尽管实际上只有.key文件是保密的。
现在用以下命令在Office机器上创建Diffie Hellman参数
openssl dhparam -out dh1024.pem 1024
如果在openssl.cnf中增加了密钥位数,相应的这里也把大小也从1024加到2048。
对于更狂热的追求者,可以考虑在上面的openssl命令中忽略-nodes选项。这使私钥用密码加密。如果有人潜入服务器偷走私钥文件仍可以保证密钥一定的安全。这种方法不方便之处的就是每次运行OpenVPN,需要输入密码。更详细的信息看http;//openvpn.sourceforge.net/man.html的askpass选项。
如果对手工管理RSA密钥管理觉得困惑,注意OpenVPN可以和任何X509证书管理工具或服务包括象Thawte(http://www.thawte.com)或者Verisign(http://www.verisign.com)这样的商业CAs一起使用。检索 OpenCA 项目可以查看有哪些同证书/密钥管理工具 配合良好的开源项目。
另外,OpenVPN发布版本包含一组可以简化RSA证书和密钥管理的脚本。(http;//openvpn.sourceforge.net/easyrsa.html). 9 OpenVPN的商业证书授权(CAs)使用的重要注意事项
注意到使用SSL/TLS模式的OpenVPN安全模块是面向用户的,用户可以产生他们自己的根证书,因此成为自己CA.在SSL/TLS模式中,OpenVPN通过检查对端提供的证书是否是-ca选项指定的CA证书验证它。正如基于SSL安全的web,SSL/TLS模式的OpenVPN的安全依赖于伪造根证书的不可能性特征。
如果已经生成自己的根证书,验证过程工作良好,但是如果希望使用如Thawte这种商业CA则会有问题。举个例子,如果用-ca选项指定Thawte的根证书,任意由Thawte指定的证书可以用OpenVPN peer授权,这当然不是你所要的。
幸运的是,使用-tls-verify可以解决这个问题。这个选项允许执行命令以检查证书内容,从而分离选择出允许的证书和不允许的证书。如何做看sample-script子目录下的verify-an脚本的例子,也可以看-tls-verify选项的man。 10 用SSL/TLS模式和RSA证书/密钥配置文件
例子中,我们使用OpenVPN的配置文件。OpenVPN允许选项以命令行或者一个或者多个配置文件指定参数。配置文件中的选项可以忽略前面的"-",在命令行选项中则需要。
建立下面的配置文件:
sample-config-files/tls-office.conf #使用SSL/TLS模式和RSA证书/密钥的OpenVPN的office配置文件样本
#‘#’或者‘;’用作注释
#使用动态tun设备
#Linux 2.2或者非Linux操作系统
#你可能想使用显式指明设备号,如tun1
#OpenVPN也支持虚拟的以太tap设备
dev tun #10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
ifconfig 10.1.0.1 10.1.0.2 #up脚本建立路由
up ./office.up
#SSL/TLS密钥交换时,office假设为server,home假设为client
tls-server #Diffie-Hellman 参数(仅在tls-server)
dh dh1024.pem #证书文件
ca my-ca.crt #自己的证书/公钥
cert office.crt #自己的私钥
key office.crt #OpenVPN默认使用UDP端口5000
#每个OpenVPN隧道必须使用不同的端口号。
#lport或者rport分别用作表示本地和远程的不同端口号
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody #如果使用LZO压缩,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping
#状态防火墙连接状态alive
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是显示非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/office.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 sample-config-files/tls-home.conf
#使用SSL/TLS模式和RSA证书/密钥的OpenVPN的home配置文件样本
#‘#’或者‘;’用作注释
#使用动态tun设备
#Linux 2.2或者非Linux操作系统
#你可能想使用显式指明设备号,如tun1
#OpenVPN也支持虚拟的以太tap设备
dev tun #OpenVPN peer是一个office网关
remote 1.2.3.4 #10.1.0.2是本地VPN端点(home)
#10.1.0.1是远程VPN端点(office)
ifconfig 10.1.0.2 10.1.0.1 #一旦VPN激活,up脚本将建立路由
up ./home.up #SSL/TLS密钥交换,office假定为server,home假定为client
tls-client #证书授权文件
ca my-ca.crt #证书/公钥
cert home.crt #私钥
key home.key #OpenVPN UDP默认使用UDP端口5000。
#每个OpenVPN隧道必须使用不同的端口号
#lport或者rport可以分别用于表示本地和远程的端口号
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody
#如果用LZO压缩编译链接OpenVPN,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping
#状态防火墙连alive,如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是显示非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/home.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 11 创建预分享静态密钥
和RSA密钥管理相反,使用预分享静态密钥更为简单。使用静态密钥的主要不足之处是放弃了让安全机制更完美的想法。也就是说,如果攻击者窃取了你的静态密钥,所有用其加密的都会被危及安全。
用下列命令生成静态密钥:
openvpn --genkey -secret static.key
这个静态文件是ascii形式的,看起来象这样:
-----BEGIN OpenVPN Static key V1-----
e5e4d6af39289d53
171ecc237a8f996a
97743d146661405e
c724d5913c550a0c
30a48e52dfbeceb6
e2e7bd4a8357df78
4609fe35bbe99c32
bdf974952ade8fb9
71c204aaf4f256ba
eeda7aed4822ff98
fd66da2efa9bf8c5
e70996353e0f96a9
c94c9f9afb17637b
283da25cc99b37bf
6f7e15b38aedc3e8
e6adb40fca5c5463
-----END OpenVPN Static key V1----- 一个OpenVPN静态密钥包含足够的熵值,512位为加密键,512位为身份验证的HMAC。通过安全媒介如使用scp或者ssh的拷贝粘贴把static.key拷贝到对端。 12 使用预分享的静态密钥配置文件
例子中,我们将使用OpenVPN的配置文件。OpenVPN允许选项用在命令行或者一个或对多个配置文件中指定参数。配置文件的选项可以忽略前面的用于命令行选项的"-"。
建立下面的配置文件:
sample-config-files/static-office.conf #使用预分享的静态密钥的OpenVPN的office配置文件样例。
#‘#’或者‘;’用作注释
#使用动态tun设备
#针对lINUX2.2或者非LINUX操作系统
#也许想用显式的设备号,如tun1
#OpenVPN也可以支持虚拟以太"tap"设备
dev tun
#10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
ifconfig 10.1.0.1 10.1.0.2 #一旦VPN激活,这个up脚本将建立路由
up ./office.up #预分享的静态密钥
secret static.key #OpenVPN UDP默认使用UDP端口号5000
#每个OpenVPN隧道必须使用不同的端口号
#lport和rport分别表示本地和远程的端口
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody #如果用LZO压缩编译链接OpenVPN,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping以保持状态防火墙连接alive。
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是输出非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/office.up
#!/bin/bash
route add -net 10.0.1.0 netmask 255.255.255.0 gw $5 sample-config-files/static-home.conf #使用预分享的静态密钥的OpenVPN的home配置文件样例。
#‘#’或者‘;’用作注释
#使用动态tun设备
#针对lINUX2.2或者非LINUX操作系统
#也许想用显式的设备号,如tun1
#OpenVPN也可以支持虚拟以太"tap"设备
dev tun #我们OpenVPN对端是office网关
ifconfig 10.1.0.2 10.1.0.1 #10.1.0.1是本地VPN端点(office)
#10.1.0.2是远程VPN端点(home)
remote 1.2.3.4 #一旦VPN激活,这个up脚本将建立路由
up ./home.up #预分享的静态密钥
secret static.key #OpenVPN UDP默认使用UDP端口号为5000
#每个OpenVPN隧道必须使用不同的端口号
#lport和rport分别表示本地和远程的端口
;port 5000 #为了安全,初始化之后,把UID和GID降低到nobody
;user nobody
;group nobody
#如果用LZO压缩,不要注释下面这行
;comp-lzo #每15秒发送一个UDP ping 以状态保持防火墙连接状态alive
#如果使用的是状态防火墙则去掉注释
;ping 15 # 取消这节注释用作当系统失去连接时,获得更可靠的探测。
#举个例子,trave到其他地方的dial-ups或者laptops
;ping 15
;ping-restard 45
;ping-timer-rem
;persist-tun
;persist-key #信息级别(verbosity level)
#0--除严重错误以外都不提示
#1--大部分不提示,但是输出非严重的网络错误
#3--中等输出,包括一些友好的正常操作信息
#9--详细输出,有利于解决故障
verb 3 sample-config-files/home.up
#!/bin/bash
route add -net 10.0.0.0 netmask 255.255.255.0 gw $5
13 以SSL/TLS模式运行VPN
home端,用这个命令运行VPN
openvpn --config tls-home.conf
office端,用这个命令运行VPN
openvpn --config tls-office.conf
14 以静态密钥模式运行VPN
home端,用这个命令运行VPN
openvpn --config static-home.conf
office端,用这个命令运行VPN
openvpn --config static-office.cof 15测试VPN
在home端,经由隧道ping office来测试VPN
ping 10.1.0.1
在office端,经由隧道ping home测试VPN
ping 10.1.0.2
如果这些测试失败却没有输出信息,可能要重新编辑配置文件设置错误级别为8使其可以生成更多详细调试输出。同样可以咨询FAQ更多关于故障的信息(http://openvpn.sourceforge.net/faq.html#cantping)
如果测试成功,尝试通过隧道ping私网的机器(不是OpenVPN网关机器)来测试路由,基本上任何在10.0.1.0/24子网的机器能够访问10.0.0.0/24的任何机器和代理,反之亦然.
如果可以了,祝贺你。否则,你可能要检查OpenVPN邮件列表的档案(http://sourceforge/mail?group_id=48978)看看是否其他人遇到类似的问题。如果你在这没有找到问题的解决方法,考虑贴在openvpn-users 16make the VPN DHCP-aware
回忆网络配置的例子,home是动态地址,没有警告就可以改变。如果客户端使用dhcped,建立一个客户端地址改变就可以运行的脚本是很容易的。这个脚本命名有些类似/etc/dhcpc/dhcp-cd-eth0.exe.
基本上,可以在这个脚本中增加这样一行以发送SIGUSR1或者SIGHUP信号给OpenVPN守护进程:
killall -HUP openvpn
当OpenVPN收到信号,就会关闭连接然后用DHCP指定的IP地址重新打开与对端的连接。
如果你连接到可能由于DHCP重置而改变地址的对端,你应当用-float选项。
也能用SIGUSER1信号处理DHCP重置,SIGUSER1有些象SIGHUP除了它在OpenVPN子系统重置时提供更多进程回收控制。SIGUSER1信号也可以用内部基于-ping 和-ping-restart生成。
-persist-tun选项允许无需关闭和重新打开tun设备即可重置(为DHCP上的隧道提供无缝连接).
-persist-remotr-ip选项允许穿过DHCP重置保留远程IP地址。允许OpenVPN隧道两端都可以作为DHCP客户端
-persist-key选项重启的时候不用重读密钥文件(即使-user或者-group已经降低权限也允许OpenVPN守护进程重启)
关于动态IP下的openvpn的更多信息参考FAQ(http;//openvpn.sourceforge.net/faq.html#dynamic).
17重启时自动启动VPN
首先,建立一个目录如/etc/openvpn以保存OpenVPN密钥和配置文件。
选择使用TLS还是静态密钥模式,拷贝适当的.conf,.up,.key,.pem和.crt文件到/etc/openvpn
保护.key文件
chmod go-rwx /etc/openvpn/*.key
如果使用Linux iptables,编辑防火墙配置文件firewall.sh,改变它使之接近你的环境并拷到/etc/openvpn下。
创建类似下面的开始脚本:
sample-config-files/openvpn-startup.sh
#!/bin/bash
#LINUX下,OpenVPN启动脚本样例
#openvpn配置文件路径
dir=/etc/openvpn
#装载防火墙
$dir/firewall.sh
#装载TUN/TAP内核模块
modprobe tun
#允许IP转发
echo 1>/pro/sys/net/ipv4/ip_forward #每个VPN隧道用守护进程模式调用openvpn。
#你可以在命令行去掉--damen并在配置文件中增加"daemon"
#每个隧道应当运行在独立udp端口,使用"port"选项控制它
#正如所有的OpenVPN选项,你可以在命令行用--port 8000指定或者在配置文件中用port 8000
openvpn --cd $dir --daemon --config vpn1.conf
openvpn --cd $dir --daemon --config vpn2.conf
openvpn --cd $dir --daemon --config vpn2.conf1 增加如下关闭脚本:
sample-config-files/openvpn-shutdown.sh
#!/bin/bash
#stop all openvpn processes
killall -TERM openvpn 最后,在系统的开机和关机脚本分别增加调用openvpn-startup.sh和openvpn-shutdown.sh或者直接加到/etc/init.d目录 18 管理多个OpenVPN隧道的启动和关闭
这有一个/etc/init.d脚本例子,这个可以自动为/etc/openvpn的每个.conf文件生成一个隧道。
sample-scripts/openvpn.init
#!/bin/sh
#openvpn 这个shell脚本用于启动和停止openvpn
#chkconfig;345 80 30
#描述:OpenVPN是一个健壮、高度灵活的隧道应用,可以使
#用OpenSSL库的所有加密、授权和证书特色以保证在单一udp
#端口上隧道的ip层安全
#由Douglas keller的OpenVPN#项目提供 2002.05.15
#安装:
#拷贝文件到/etc/rc.d/init.d/openvpn
#shell>chkconfig --add openvpn
#shell>mkdir /etc/openvpn
#make .conf or .sh file in /etc/openvpn(见下文)
#卸载:
#run: chkconfig --del openvpn
#作者注释:
#我已经生成一个/etc/init.d的初始化脚本,并在初始化脚
#本中,并修改openvpn.spec使之可以自动注册该脚本.只要安装了RPM,#就可以用"service openvpn start"和"service openvpn stop"启动和停止openvpn #初始化脚本如下:
#为/etc/openvpn下的每个.conf文件启动一个openvpn进程
#如果存在对应xxx.conf的 /etc/openvpn/XXX.sh文件
#那么在启动OpenVPN之前执行它(作openvpn --mktun时很有用...).
#除 start/stop外还可以执行:
#service openvpn reload -SIGHUP
#service openvpn reopen -SIGUSR1
#service openvpn status -SIGUSR2 #修改于 2003.05.02
#changed ==to =for sh cpmpliance(Bishop Clark)
#if condrestart|reload|reopen|status,check that we #were actually started(James Yonan).
#added lock,piddir,and work variabled(James Yonan).
#if start is attempted twice,without an intervening #stop,or if start is attempted when previous start was #not properly shut down,then kill any previously #started processes,before commencing new start #operation(James Yonan).
#do a better job of flagging errors on start,and #properly returning success or failure status to #caller(James Yonan). #可执行OpenVPN的位置
openvpn="/usr/sbin/openvpn" #lockfile
lock="/var/lock/subsys/openvpn" #PID目录
piddir="/var/run/openvpn" #工作目录
work=/etc/openvpn #源程序函数库
./etc/rc.d/init.d/functions #源网络配置
./etc/sysconfig/network #检查网络是否起了
[${NETWORKING}="no"]&&exit 0
[-f $openvpn]||exit 0 #调用
case "$1" in
start)
echo -n $"starting openvpn:" /sbin/modprobe tun>/dev/null 2>&1
echo 1>/proc/sys/net/ipv4/ip_forward if[!-d $piddir];then
mkdr $piddir
fi if[-f $lock];then
#we were not shut down correctly
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill 'cat $pidf'>/dev/null 2>&1
fi
rm -f $pidf
done
rm -f $lock
sleep 2
fi rm -f $piddir/*.pid
cd $work #start every .conf in $work and run .sh if exists
errors=0
successes=0
for c in '/bin/ls *.conf 2>/dev/null';do
bn=${c%%.conf}
if [-f "$bn.sh"];then
. $bn.sh
fi
rm -f $piddir/$bn.pid
$openvpn --daemon --writepid $piddir/$bn.pd --config $c --cd $work
if [$?=0];then
successes=1
else
errors=1
fi
done if[$errors=1];then
failure;echo
else
success;echo
fi if[$successes=1];then
touch $lock
fi
;;
stop) echo -n $"shutting down openvpn:"
for pidf in'/bin/ls $piddir/*pid 2>/dev/null';do
if[-s $pidf];then
kill 'cat $pidf'>/dev/null 2>&1
fi
rm -f $pidf
done
success;echo
rm -f $lock
;;
restart)
$0 stop
sleep 2
$0 start
;;
reload)
if [-f $lock];then
for pidf in '/bin/ls $piddir/*pid 2>/dev/null';do
if [-s $pidf];then
kill -HUP 'cat $pidf'>/dev/null 2>&1
fi
done
else
echo "openvpn:service not started"
exit 1
fi
;;
reopen)
if [-f $locj];then
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill -USER1 'cat $pidf'>/dev/null 2>&1
fi
done
else
echo "openvpn:service not started"
exit 1
fi
;;
condrestart)
if [-f $locj];then
$0 stop
#avoid race
sleep 2
$0 start
fi
;;
status)
if [-f $lock]; then
for pidf in '/bin/ls $piddir/*.pid 2>/dev/null';do
if [-s $pidf];then
kill -USR2 'cat $pidf'>/dev/null 2>&1
fi
done
echo "status written to /var/log/messages"
else
echo "openvpn:service not started"
exit 1
fi
;;
*)
echo "usuage;openvpn {start|stop|restart|condrestart|reload|reopen|status}"
exit 1
esac exit 0 19 使用inetd或者xinetd实例化一个OpenVPN守护进程
通用xinetd服务可以用作在接受来自远端的初始数据报文之前自动实例化一个OpenVPN守护进程。
此xinetd配置使xinetd进程监听UDP端口5000 ,对流入OpenVPN会话的初始数据包,(使用预分享密钥),xinetd 会自动实例化一个OpenVPN守护进程以处理会话.注意使用 -inactive 开关会使OpenVPN daemon闲置10分钟之后超时退出。无论什么原因一旦守护进程退出,xinetd服务会继续监听端口,并将再次实例化一个OpenVPN守护进程以处理另外的连接.另外注意xinetd会用root权限初始实例化OpenVPN 守护进程,但是随后,OpenVPN (读取受保护的密钥文件)会把权限降为nobody,
密钥文件可以用下列命令生成:
openvpn --genkey --secret key
请注意,每个OpenVPN隧道都需要运行在自己独立的端口上并需要自己的xinetd配置文件。这是因为OpenVPN需要每个可能到来的连接的详细信息包括密钥文件,tun/tap设备,隧道端点和路由配置。基于这点,在OpenVPN的发展中],从不使用单个配置文件来处理大批类似的潜在接入者,因为OpenVPN作为UDP server实现以来,不具有TCP server可监听固定端口同时fork一个新的守护进程来处理每个客户端会话的特点.尽管如此,接入连接模板已经进入计划,如果开发者和最终用户社区足够兴趣和支持,一定会是实现。
sample-config-files/xinetd-server-config #关于OpenVPN的inetd配置文件
#这个文件可以重命名为OpenVPN或适合描述和拷贝/etc/xinetd.d目录下的一些名字.
#重启或者发送一个SIGHUP信号时,xinetd能够认识这个文件
#对每个潜在的接入客户端,用唯一的端口号生成单独的配置文件。同样,注意到每个客户端的密钥文件和ifconfig端点应当唯一.这个配置文件假定OpenVPN可执行并且密钥存在于/root/openvpn。修改使之适合你的环境。
service openvpn_1
{
type =UNLISTED
port =5000
socket_type =dgram
protocol =udp
wait =yes
user =root
server =/root/openvpn/openvpn
server_args =--inetd --dev tun --ifconfig 10.4.0.2 10.4.0.1 --secret /root/open
} sample-config-files/xinetd-client-config
#这个是相对xinetd-server-config的OpenVPN客户端配置文件
dev tun
ifconfig 10.4.0.1 10.4.0.2
remote my-server
port 5000
user nobody
secret /root/openvpn/key
inactive 600
相关阅读 更多 +