OpenVPN笔记

来源:百度文库 编辑:神马文学网 时间:2024/04/27 14:33:53
OpenVPN笔记
一、建立CA和PKI
PKI包括:ca,key(用于给用户签名),public key,private key
openvpn支持双向认证,意思是说在互信关系建立以前用户必须认证服务器的证书,服务器也必须认证用户的证书。
服务器和用户首先会校验现有的证书是否经过主CA的签名,然后会测试now-authenticated的证书头,例如certificate common name or certificate type (client or server).
步骤:
1.生成主CA的证书和key
OpenVPN提供了一套证书管理脚本,linux下在/usr/share/doc/openvpn-2.0.7/easy-rsa/2.0下面,将2.0目录复制到/root,以免将来升级时覆盖掉生成的key
cp /usr/share/doc/openvpn-2.0.7/easy-rsa/2.0 -r /root
cd /root/2.0
chmod +x *
然后修改基本参数,在vars文件中,修改如下参数,并确保没有参数为空!
KEY_COUNTRY,
KEY_PROVINCE
KEY_CITY
KEY_ORG
KEY_EMAIL
接下来开始初始化PKI.
../vars
./clean-all
./build-ca
build-ca脚本会调用交互式的openssl命令生成ca和key。
[root@yyy 2.0]# ./build-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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server‘s hostname) [Fort-Funston CA]:OpenVPN-CA-Master
Email Address [me@myhost.mydomain]:rwen@corp.netease.com
过程中大部分的参数可以按回车采用在vars文件中定义的默认值,只有Common Name是最重要的,必须明确输入!!!!!!!
过程结束后会在当前目录下生成keys目录,在keys目录中生成ca.crt,ca.key两个文件。
2.生成VPN服务器端的ca和key
./build-key-server server
[root@yyy 2.0]# ./build-key-server server
Generating a 1024 bit RSA private key
.................++++++
.........++++++
writing new private key to ‘server.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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server‘s hostname) [server]:server
Email Address [me@myhost.mydomain]:rwet@corp.netease.com
Please enter the following ‘extra‘ attributes
to be sent with your certificate request
A challenge password []:12345678
An optional company name []:
Using configuration from /root/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject‘s Distinguished Name is as follows
countryName           :PRINTABLE:‘US‘
stateOrProvinceName   :PRINTABLE:‘CA‘
localityName          :PRINTABLE:‘SanFrancisco‘
organizationName      :PRINTABLE:‘Fort-Funston‘
commonName            :PRINTABLE:‘server‘
emailAddress          :IA5STRING:‘rwet@corp.netease.com‘
Certificate is to be certified until Aug  6 16:06:03 2016 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
像上一步一样大多数参数可以采用默认值,当提示输入Common Name时输入"server"。
另外两个需要明确回答的是:
Sign the certificate? [y/n]:
1 out of 1 certificate requests certified, commit? [y/n]
过程结束后会在keys目录生成server.crt,server.csr,server.key,01.pem四个文件。
3.生成VPN客户端的ca和key
./build-key client1
./build-key client2
./build-key client3
如果需要给私钥设置密码,使用build-key-pass脚本代替build-key,即:
./build-key-pass client1
./build-key-pass client2
./build-key-pass client3
[root@yyy 2.0]# ./build-key-pass client1
Generating a 1024 bit RSA private key
..++++++
..........++++++
writing new private key to ‘client1.key‘
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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) [US]:
State or Province Name (full name) [CA]:
Locality Name (eg, city) [SanFrancisco]:
Organization Name (eg, company) [Fort-Funston]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server‘s hostname) [client1]:client1
Email Address [me@myhost.mydomain]:
Please enter the following ‘extra‘ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /root/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject‘s Distinguished Name is as follows
countryName           :PRINTABLE:‘US‘
stateOrProvinceName   :PRINTABLE:‘CA‘
localityName          :PRINTABLE:‘SanFrancisco‘
organizationName      :PRINTABLE:‘Fort-Funston‘
commonName            :PRINTABLE:‘client1‘
emailAddress          :IA5STRING:‘me@myhost.mydomain‘
Certificate is to be certified until Aug  6 16:20:06 2016 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
像上一步一样大多数参数可以采用默认值,当提示输入Common Name时输入"client1",每个client的Common Name必须是唯一的,即互不相同。
另外还有两个需要明确回答的是:
Sign the certificate? [y/n]:
1 out of 1 certificate requests certified, commit? [y/n]
过程结束后会在keys目录生成client1.crt,client1.csr,client1.key,02.pem四个文件。
4.生成Diffie Hellman参数
./build-dh
[root@yyy 2.0]# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.................................................+.............+.................+..........................................................................+..................................................................+.............+.......................+.............................................................................................................................................+...........................................+...+.......+......+.+..
过程结束后会在keys目录生成dh1024.pem文件。
5.将server和client需要的文件复制到各自的机器上。keys目录中文件的用途如下:
Filename    Needed By              Purpose               Secret
---------------------------------------------------------------------------
ca.crt         server + all clients  Root CA certificate         NO
ca.key       key signing machine only  Root CA key                 YES
dh{n}.pem  server only          Diffie Hellman parameters      NO
server.crt  server only          Server Certificate         NO
server.key  server only          Server Key                 YES
client1.crt  client1 only          Client1 Certificate         NO
client1.key  client1 only          Client1 Key                 YES
---------------------------------------------------------------------------
二、创建Server的配置文件
可以参考系统自带的示例配置文件,在其上更改。目录在:
/usr/share/doc/openvpn-2.0.7/sample-config-files
文件名分别是server.conf和client.conf
server.conf中提供一个VPN的设置,该VPN使用TUN设备,在UDP 1194端口监听,分发给客户端的地址为10.8.0.0/24。
在使用sample的配置之前,需要更改ca, cert, key, dh这几个参数为你上一步生成的那些key文件。
在修改过以上参数以后这已经是一个可用的配置文件了。当然你可以自己订制你的配置,常用的参数有如下:
1.如果使用桥模式,必须将server和dev tun这两项改为
server-bridge
dev tap
2.如果使用TCP协议监听,需要将proto udp改成proto tcp。如果需要同时监听UDP和TCP,则需要独立运行两个实例。
3.如果想更改分配给用户的地址,需要更改server选项。注意服务器地址会是10.8.0.1
server 10.8.0.0 255.255.255.0
4.如果允许多个VPN客户端通过Server互相通信,请将client-to-client前的注释去掉。默认情况下每个client只能Server通讯。
5.如果使用Linux系统,可以将下面两行前的;注释去掉,可以提高安全性。
;user nobody
;group nobody
6.如果在通一台机器上运行多个VPN实例,需要确保他们使用不同的UDP端口监听。
还要修改每个实例的输出文件,以免互相覆盖,参数有:
log, log-append, status, 和ifconfig-pool-persist
三、创建Client的配置文件
client的配置文件基本上是server配置文件的镜像,同样需要更改的地方有:
1.ca, cert, key这几个参数为你上一步生成的client自己的key文件,ca文件是server和client公用的。
2.更改remote参数为Server的ip地址和相应的端口。
3.必须确保dev和proto参数与server的配置保持一致,如果起用了压缩还要确保comp-lzo和fragment都保持一致。
四、启动VPN,测试连接
1.首先应确认VPN服务器的地址可以在Internet上访问到。
2.确认TUN/TAP接口上没有启用防火墙规则,否则用户会出现“Connection Initiated with x.x.x.x”但是没有回应的错误。
iptables -A INPUT -i tun+ -j ACCEPT
# Allow TUN interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tun+ -j ACCEPT
# Allow TAP interface connections to OpenVPN server
iptables -A INPUT -i tap+ -j ACCEPT
# Allow TAP interface connections to be forwarded through other interfaces
iptables -A FORWARD -i tap+ -j ACCEPT
3.为了除错简单,直接在命令行启动server
/usr/sbin/openvpn server.conf
会看到如下信息:
[root@yyy keys]# openvpn /usr/share/doc/openvpn-2.0.7/sample-config-files/server.conf
Wed Aug  9 14:03:44 2006 OpenVPN 2.0.7 i386-redhat-linux-gnu [SSL] [LZO] [EPOLL] built on Apr 29 2006
Wed Aug  9 14:03:44 2006 Diffie-Hellman initialized with 1024 bit key
Wed Aug  9 14:03:44 2006 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Wed Aug  9 14:03:45 2006 TUN/TAP device tun0 opened
Wed Aug  9 14:03:45 2006 /sbin/ip link set dev tun0 up mtu 1500
Wed Aug  9 14:03:45 2006 /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
Wed Aug  9 14:03:45 2006 /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Wed Aug  9 14:03:45 2006 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Wed Aug  9 14:03:45 2006 UDPv4 link local (bound): [undef]:1194
Wed Aug  9 14:03:45 2006 UDPv4 link remote: [undef]
Wed Aug  9 14:03:45 2006 MULTI: multi_init called, r=256 v=256
Wed Aug  9 14:03:45 2006 IFCONFIG POOL: base=10.8.0.4 size=62
Wed Aug  9 14:03:45 2006 IFCONFIG POOL LIST
Wed Aug  9 14:03:45 2006 Initialization Sequence Completed
然后ifconfig查看会看到tun0这个设备
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
4.在客户端用命令行启动client
/usr/sbin/openvpn client.conf
客户端的输出与服务器端类似,在输出的最后应该有"Initialization Sequence Completed"
然后Ping 10.8.0.1 即VPN服务器的地址,如果能ping通,那么恭喜你,VPN已经连通了!
======================================================================
五、扩展VPN的范围,以包含更多的机器在服务器端和客户端
1.在路由模式下在服务器端包含多个主机(网桥模式不需做任何配置即可达到网络互通的目的)
VPN一般是点对点的连接,但是它的范围是可以扩展,可以使客户端除了直接与vpn server通讯以外还可与其他在服务器端网络中的主机通讯。
下面举个例子,假定服务器端的子网是10.66.0.0/24,它在配置中用server参数定义的vpn地址池是10.8.0.0/24。
首先,你必须通知客户端10.66.0.0/24这个网络可以通过VPN访问到,要实现这一点可以在服务器端的配置文件(server.conf)中增加如下:
push "route 10.66.0.0 255.255.255.0"
然后,需要在服务器端的网关上增加一条路由,使服务器端网络访问10.8.0.0/24的路由指向VPN Server。(如果网关和VPN Server是同一台主机则不需要作此步)
2.在路由模式下在客户端包含多个主机
一般来说客户端连接到服务器的只是一台主机,但假如客户端主机是客户网络的网关的话,你也许希望客户端网络中的每台主机都能通过VPN访问服务器端主机。
举例来说,假定客户端的局域网使用192.168.4.0/24这段地址,而VPN Client使用的证书的common name是client2,我们的目标是建立起VPN,使得192.168.4.0/24网络中的每台主机都能与VPN Server端网络中的主机通讯。
在配置这个VPN之前,有两个先决条件必须满足:
1)客户端局域网地址(本例中为192.168.4.0/24)必须不同于服务器端的局域网地址,也不能与任何其他VPN Client端的局域网地址相同!!即每个通过路由加入VPN的子网地址必须是互不相同的!
2)每个客户端必须具有互不相同的Common Nam(本例中是client2),另外配置文件中不能使用duplicate-cn标志!
配置步骤如下:
-----1----首先在客户端打开IP和TUN/TAP转发。echo "1" > /proc/sys/net/ipv4/ip_forward
-----2----然后对服务器端配置作相应修改,在server.conf中增加客户端配置文件目录:
client-config-dir ccd
在上边的语句中,ccd是在OpenVPN server daemon运行的目录中(通常为/etc/openvpn)预先创建好的目录名(本例为/etc/openvpn/ccd)。当一个新客户端开始连接OpenVPN server的时候,守护进程会再次目录中查找符合正在连接的客户端Common Name的文件,一旦找到匹配的文件它会浏览并执行附加的配置文件。
-----3----在ccd目录中创建一个名为client2的文件,文件中包含以下内容:
iroute 192.168.4.0 255.255.255.0
这会告诉VPN服务器192.168.4.0/24这个子网应该被路由到客户端client2!
-----4----在服务器配置文件(server.conf)中加入到192.168.4.0/24的路由信息,注意不是ccd/client2中!!
route 192.168.4.0 255.255.255.0
注释:为什么要在两个地方加入路由?因为服务器配置中的route控制从内核到VPN server的路由(通过TUN接口),而ccd/client2中的iroute控制从VPN Server到VPN Client的路由,两者缺一不可!!!!
-----5----如果你还需要client2局域网中的主机与其它连接在VPN server上的client通讯的话,在服务器配置(server.conf)中加入下面的语句:
client-to-client
push "route 192.168.4.0 255.255.255.0"
这样会将192.168.4.0/24通告给其他客户端。
-----6----最后,一个经常被遗忘的步骤!!!!!!!
最后需要在局域网的网关上加入返回路由,即将所有去往192.168.4.0/24的包路由到VPN Server。(如果网关与VPN Server是同一台主机,则不要作此步)
类似的,如果VPN client不是客户端的网关的话,需要在客户端的网关上将所有需要通过VPN才能访问到的子网的地址路由到运行VPN Client的那台主机上。
=====================================================================
六、向客户端推送DHCP参数
Openvpn Server可以向客户端推送一些dhcp参数如DNS,WINS信息。windows可以直接接收该信息,非windows机器需要使用额外的脚本。要实现该功能,在server.conf加入如下信息:
push "dhcp-option DNS 10.66.0.4"
push "dhcp-option DNS 10.66.0.5"
push "dhcp-option WINS 10.66.0.8"
在windows中使用ipconfig /all可以在TAP-Win32接口上看到相应的信息。
======================================================================
七、撤销证书
撤销证书的意思是使一个先前签名过的证书变成无效,这样该证书就无法用于认证了。
典型的撤销证书的原因有:私钥被盗或泄漏;用户忘记了加过密的私钥的密码;你想终结一个VPN用户的访问。
例子:撤销client2的证书
进入easy-rsa目录
. ./vars
./revoke-full client2
将会产生类似下面的输出:
Using configuration from /root/openvpn/20/openvpn/tmp/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
Revoking Certificate 04.
Data Base Updated
Using configuration from /root/openvpn/20/openvpn/tmp/easy-rsa/openssl.cnf
DEBUG[load_index]: unique_subject = "yes"
client2.crt:
error 23 at 0 depth lookup:certificate revoked
最后一行的"error 23"说明该证书已经被撤销。
revoke-full脚本会在keys目录中产生一个CRL (certificate revocation list)文件,名字为crl.pem。将这个文件复制到服务器上,然后修改服务器的配置文件,加入:
crl-verify crl.pem
这样服务器将会将客户端的ca与crl.pem比对,如果有符合的将关闭该条连接。
=====================================================================
八、路由所有客户端流量(包括web访问)通过VPN
默认情况下,当VPN客户端连接到VPN服务器后,只有与VPN服务器间的通讯会通过VPN隧道传输,而其他的互联网访问会直接通过本地的互联网连接进行,不会通过VPN隧道。
在某些特殊情况下,你可能会希望用户所有的网络流量都通过VPN隧道传输,包括web访问。这种配置形式可以很精确的控制客户端的访问,当用户处于同时访问互联网和VPN的时候,VPN管理员可以通过安全策略进行更多的控制。
操作步骤:
在服务器的配置中加入如下语句:
push "redirect-gateway def1"
当应用redirect-gateway给所有客户端的时候,会导致客户端发生的所有网络流量都会通过VPN server,VPN Server必须能够正确处理这些流量,例如将之NAT到互联网,或者把它路由到服务器端的HTTP Proxy上。下面是一个NAT的例子:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
当redirect-gateway启用以后,客户端的DNS解析请求都会被路由到VPN server,因此VPN server必须处理这些请求。这个需求可以通过给客户端推送一个DNS服务器来解决。当VPN连通时这个推送的DNS服务器会取代客户端原来的DNS服务器设置。例如:
push "dhcp-option DNS 10.8.0.1"
这条语句将会把客户端的DNS服务器设置成10.8.0.1。上边语句中的DNS服务器可以是任何客户端可以访问到的地址。
特别提示!!!----将所有网络流量重定向到VPN不是一个完全没有问题的方式,典型的问题有:
1.redirect-gateway 会导致客户端不能从本地DHCP服务器获得租约。(因为DHCP消息被路由到了VPN上)
2.web浏览会明显感觉到变慢
=====================================================================
九、配置客户端分类规则和访问策略
假设我们正在建立一个企业的VPN,该企业的用户权限分为三类:
1.普通雇员    只允许通过VPN访问samba/email服务器,不允许访问其他主机。
2.系统管理员  可以通过VPN访问所有服务器。
3.合作伙伴    只可以通过VPN访问contractor服务器,不允许访问其他主机。
基本处理的方法是:a)对不同分类的用户分配各不相同的虚拟地址段 b)通过防火墙规则来禁止或允许客户端访问特定主机
在我们的例子中,普通雇员的数量是不定的,系统管理员只有一个,合作伙伴只有两个。我们的地址分配方案是将所有普通雇员分配到一个地址池中,系统管理员和合作伙伴分配固定的IP地址。下表是分配的方案:
Class      Virtual IP Range      Allowed LAN Access        Common Names
---------------------------------------------------------------------------------
普通雇员 10.8.0.0/24 Samba/email服务器(10.66.4.4)      [variable]
系统管理员 10.8.1.0/24 整个10.66.4.0/24 子网              sysadmin1
合作伙伴 10.8.2.0/24 Contractor服务器(10.66.4.12)      contractor1, contracter2
下面我们将上边的分配方案写成Openvpn的配置文件。在开始之前你要确定已经按照第五节所写的方法使得所有用户都可以访问到10.66.4.0/24这个子网,之后我们会用防火墙规则来禁止或允许客户端访问特定主机。
第一步,给TUN接口分配一个静态的名字,以便之后在iptables规则中用来指定。
dev tun0
第二步,定义普通雇员的地址池
server 10.8.0.0 255.255.255.0
增加管理员和合作伙伴的地址路由
route 10.8.1.0 255.255.255.0
route 10.8.2.0 255.255.255.0
因为我们需要为管理员和合作伙伴分配固定IP,因此需要用到用户配置目录。
client-config-dir ccd
在ccd目录中建立以下三个文件:sysadmin1,contractor1, contracter2分别对应一个管理员和两个合作伙伴,在配置文件里边定义静态的IP地址。
ccd/sysadmin1 管理员配置
ifconfig-push 10.8.1.1 10.8.1.2
ccd/contractor1 合作伙伴1配置
ifconfig-push 10.8.2.1 10.8.2.2
ccd/contractor2 合作伙伴2配置
ifconfig-push 10.8.2.5 10.8.2.6
每一个ipconfig-push地址对声明了一个VPN client和服务器端的ip地址。这两个地址必须是连续的,掩码是/30。因此每对ip地址的最后一位一定是下面列表中的:
[  1,  2] [  5,  6] [  9, 10] [ 13, 14] [ 17, 18]
[ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] [ 37, 38]
[ 41, 42] [ 45, 46] [ 49, 50] [ 53, 54] [ 57, 58]
[ 61, 62] [ 65, 66] [ 69, 70] [ 73, 74] [ 77, 78]
[ 81, 82] [ 85, 86] [ 89, 90] [ 93, 94] [ 97, 98]
[101,102] [105,106] [109,110] [113,114] [117,118]
[121,122] [125,126] [129,130] [133,134] [137,138]
[141,142] [145,146] [149,150] [153,154] [157,158]
[161,162] [165,166] [169,170] [173,174] [177,178]
[181,182] [185,186] [189,190] [193,194] [197,198]
[201,202] [205,206] [209,210] [213,214] [217,218]
[221,222] [225,226] [229,230] [233,234] [237,238]
[241,242] [245,246] [249,250] [253,254]
到此VPN的设置已经完成,接下来需要使用iptables设置访问的规则。本例中的规则如下:
# Employee rule
iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -d 10.66.4.4 -j ACCEPT
# Sysadmin rule
iptables -A FORWARD -i tun0 -s 10.8.1.0/24 -d 10.66.4.0/24 -j ACCEPT
# Contractor rule
iptables -A FORWARD -i tun0 -s 10.8.2.0/24 -d 10.66.4.12 -j ACCEPT
=====================================================================
from: http://hi.baidu.com/jacklow/blog/item/4227ad01fe7916061c958355.html