OpenVPN是一個用於創建虛擬專用網絡加密通道的軟件包,允許創建的VPN使用公開密鑰、數字證書、或者用戶名/密碼來進行身份驗證。OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X與Windows 2000/XP/Vista/7以及Android和iOS上運行,幷包含了許多安全性的功能。
配置OpenVPN 2.0的第一步是建立一個PKI(public key infrastructure 公鑰基礎設施)。PKI包括:
- 服務端和每個客戶端都有一個證書(也稱做公鑰)和私鑰
- 一個認證機構(CA)的證書和私鑰,用來爲每一個服務端和客戶端頒發證書(sign each of the server and client certificates)。
OpenVPN 支持基於證書的雙向認證,也就是說客戶端需認證服務端,服務端也要認證客戶端,
服務端和客戶端驗證對方的第一步是驗證對方提供的證書是由認證機構(CA)頒發的。然後測試第一步認證通過的證書的頭部信息,如:證書的common name,證書的類型(客戶端還是服務端)。
從VPN的觀點來看,這一安全模式滿足一系列要求:
- 服務端僅僅需要它自己的證書/私鑰對 – 它不需要知道客戶端的證書。
- 服務端僅僅接受擁有CA頒發的證書的客戶端。因爲服務端檢查證書是否由CA頒發時並不需要訪問 CA的私鑰,這樣就可以將CA的私鑰(整個PKI中最重要的私鑰)放在另一臺機子上。
- 如果一個私鑰(is compromised),通過將它的證書加入CRL(證書吊銷列表)可以禁止這一私鑰。 CRL允許有選擇地拒絕compromised 證書而不需要重建整個PKI。
- 基於嵌入的證書域比如Vommon Name,服務端能夠加強客戶端待定(client-specific)訪問權限 (access fights)。
生成認證機構(master Certificate Authority(CA))證書 & 私鑰
在這一節我們生成一個認證機構(master CA)證書/私鑰,一個服務端證書/私鑰,兩個客戶端的證書/私鑰。
我們使用OpenVPN捆綁的一組腳本。
在Linux下打開一個Sehll,進入OpenVPN下的easy-rsa目錄。如果OpenVPN是從RPM包安裝的,easy-rsa目錄通常在/usr/share/doc/packages/openvpn或/usr/share/doc/openvpn-2.0目錄下(最好在改動之前將這一目錄拷到別的地方,比如/etc/openvpn,以免以後OpenVPN的升級覆蓋所做的改動)。
在Windows下,打開一個命令行窗口進入\Program Files\OpenVPN\easy-rsa目錄,運行下面的批處理文件將配置文件拷到正確的位置(這一命令會覆蓋先前存在的vars.bat和openssl.cnf文件)。
init-config
編輯vars文件(在Windows下是vars.bat)設置KEY_COUNTRY、KEY_PROVINCE、 KEY_CITY, KEY_ORG和KEY_EMAIL參數,這些參數不能有一個是空白。
下一步,初始化PKI,Linux下:
. ./vars
./clean-all
./build-ca
Windows下:
vars
clean-all
build-ca
最後命令(build-ca)通過調用交互地openssl命令生成認證機構(CA)的證書和私鑰。
ai:easy-rsa # ./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) [KG]:
State or Province Name (full name) [NA]:
Locality Name (eg, city) [BISHKEK]:
Organization Name (eg, company) [OpenVPN-TEST]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:OpenVPN-CA
Email Address [[email protected]]:
上面的序列中,大多數詢問參數的默認值是在vars或vars.bat文件中設定的值。唯一一個需要明確輸入的參數是Common Name,上面的例子中輸入的是”OpenVPN-CA”。
爲服務端生成證書&私鑰
爲服務端生成證書和私鑰。Linux/BSD/Unix:
./build-key-server server
Windows:
build-key-server server
和前面的一步類似,大多數參數可以保持默認值。當詢問Common Name時,輸入”server” 。另外兩個回答”y”的問題,”Sign the certificate? [y/n]”和”1 out of 1 certificate requests certified, commit? [y/n]”。
Two other queries require positive responses, “Sign the certificate? [y/n]” and “1 out of 1 certificate requests certified, commit? [y/n]”.
爲3個客戶端生成證書&私鑰
生成客戶端證書和前一步類似。Linux/BSD/Unix:
./build-key client1
./build-key client2
./build-key client3
Windows:
build-key client1
build-key client2
build-key client3
如果你想使用口令保護你的客戶端私鑰,則使用build-key-pass腳本而不是build-key。
爲每個客戶端輸入適合的Common Name,也就是”client1”, “client2”, “client3”。總是爲每個客戶端指定一個獨一無二的名字。
生成 Diffie Hellman 參數
必須爲OpenVPN服務端生成 Diffie Hellman 參數。Linux/BSD/Unix:
./build-dh
Windows:
build-dh
輸出:
ai:easy-rsa # ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.................+...........................................
...................+.............+.................+.........
......................................
密鑰文件
在keys目錄下生成的私鑰和證書。下面是這些文件的解釋:
文件名 | 需要者 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 | Clinet1的證書 Client1 Certificate | 否 NO |
client1.key | client1 only | Clinet1的私鑰 Client1 Key | 是 YES |
client2.crt | client2 only | Client2的證書 Client2 Certificate | 否 NO |
client2.key | client2 only | Client2的私鑰 Client2 Key | 是 YES |
client3.crt | client3 only | Client3的證書 Client3 Certificate | 否 NO |
client3.key | client3 only | Client3的私鑰 Client3 Key | 是 YES |
生成密鑰的最後一步是將密鑰文件拷到需要它們的機器上。
爲服務端和客戶端創建配置文件
得到例子配置文件 Getting the sample config files
最好用OpenVPN的例子配置文件作爲你自己配置文件的起點。 這些文件在以下目錄
- OpenVPN源代碼包的sample-config-files目錄
- 如果從RPM安裝,/usr/share/doc/packages/openvpn 或 /usr/share/doc/openvpn-2.0目錄下的 sample-config-files目錄
- Windows,Start Menu -> All Programs -> OpenVPN -> OpenVPN Sample Configuration Files
在Linux, BSD, or unix操作系統中,樣例配置文件是server.conf和client.conf。 在Windows下是server.ovpn and client.ovpn。
編寫服務端配置文件
樣例配置文件使用虛擬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。
編寫客戶端配置文件
客戶端配置文件的例子(client.conf Linux/BSD/Unix或client.ovpn Windows) 和服務端配置文件的例子相對應。
-
象服務端配置文件一樣,首先編輯ca、cert和key 參數使之指向你在上一節PKI生成的文件。每一個客戶端有自己的cert/key對。只有ca文件在服務端和所有客戶端之間是通用的。
-
下一步,編輯remote指令使之指向服務端的主機名/IP地址和端口號。 (如果OpenVPN服務端運行在firewall/NAT-gateway之後的一臺單網卡機子上,則使用網關的公用IP地址,和你在網關上配置的向OpenVPN服務端轉發的端口)。
-
最後,確保客戶端配置文件和服務端配置文件中指令的的一致性。主要檢查的是 dev(tun/tap)和proto(udp/tcp)。還有comp-lzo和 fragment(如果使用了)則在客戶端和服務端的配置文件中都必須提供。
啓動並測試VPN的初始連接
啓動服務端
首先,確保OpenVPN服務端能從internet訪問。這意味着:
- 防火牆打開UDP端口1194(或者你配置的任意TCP/UDP端口)。
- 設置一個端口轉發規則,將UDP端口1194從防火牆/網關轉發到運行OpenVPN服務端的機子。
下一步,確保TUN/TAP虛擬網卡沒有被屏蔽。
爲了減少錯誤,最好從命令行啓動OpenVPN服務端(或者在Windows下,右擊.ovpn文件), 不要將其作爲後臺或服務運行。
一個服務端的啓動過程:
Sun Feb 6 20:46:38 2005 OpenVPN 2.0_rc12 i686-suse-linux [SSL] [LZO] [EPOLL] built on Feb 5 2005
Sun Feb 6 20:46:38 2005 Diffie-Hellman initialized with 1024 bit key
Sun Feb 6 20:46:38 2005 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Sun Feb 6 20:46:38 2005 TUN/TAP device tun1 opened
Sun Feb 6 20:46:38 2005 /sbin/ifconfig tun1 10.8.0.1 pointopoint 10.8.0.2 mtu 1500
Sun Feb 6 20:46:38 2005 /sbin/route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.2
Sun Feb 6 20:46:38 2005 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:23 ET:0 EL:0 AF:3/1 ]
Sun Feb 6 20:46:38 2005 UDPv4 link local (bound): [undef]:1194
Sun Feb 6 20:46:38 2005 UDPv4 link remote: [undef]
Sun Feb 6 20:46:38 2005 MULTI: multi_init called, r=256 v=256
Sun Feb 6 20:46:38 2005 IFCONFIG POOL: base=10.8.0.4 size=62
Sun Feb 6 20:46:38 2005 IFCONFIG POOL LIST
Sun Feb 6 20:46:38 2005 Initialization Sequence Completed
啓動客戶端
和服務端一樣,最好從命令行(或在Windows下右擊client.ovpn文件)啓動OpenVPN。
Windows下客戶端的啓動和上面的服務端啓動類似,並且最後以 Initialization Sequence Completed 消息結束。
現在,從客戶端通過VPN發送ping包,如果你使用路由模式(服務端配置文件裏是dev tun),輸入下面命令:
如果使用橋接模式(服務端配置文件是dev tap),嘗試ping服務端所在子網的某臺機子的IP地址。
如果ping成功,祝賀你!你已經有了一個能正常工作的VPN。
常見問題
如果ping失敗,或者OpenVPN客戶端初始化失敗,請檢查下列現象和解決辦法:
-
錯誤信息: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity). 這個錯誤表示客戶端不能和服務端建立網絡連接。
解決方法:
- 保證客戶端使用允許其訪問到OpenVPN服務端的主機名/IP地址和端口號。
- 如果OpenVPN服務端是受保護的LAN內的單網卡機子,確保在服務端網關防火牆上使用了正確的端口轉發規則。假如你的OpenVPN的IP地址是防火牆內的192.168.4.4,在UDP端口1194上監聽客戶端連接。服務於192.168.4.x子網上的NAT網關應該有一條端口轉發規則: forward UDP port 1194 from my public IP address to 192.168.4.4。
- 打開服務端的防火牆允許到UDP端口1194(或者別的你在服務端配置文件中指定的TCP/UDP端口)的連接。
-
錯誤信息: Initialization Sequence Completed with errors – 這一錯誤可能出現在windows 下,(a)DHCP客戶端服務沒有運行,(b)在XP SP2上使用了第三方的個人防火牆。
解決辦法: 啓動DHCP客戶端服務,確保使用的個人防火牆和XP SP2能正常工作。
-
得到了Initialization Sequence Completed消息,但是ping失敗了 – 這通常是服務端或客戶端上的防火牆過濾了TUN/TAP網絡接口從而阻止了VPN網絡的流量。
解決辦法: 禁止客戶端的防火牆(如果有的話)過濾TUN/TAP網絡接口。例如在Windows下,你可以到Windows Security Center -> Windows Firewall -> Advanced取消對應於TAP-Win32網卡的選擇(禁止客戶端防火牆過濾TUN/TAP網卡從安全角度來看通常是合理的,因爲你本來已經告訴防火牆不要阻止授權的VPN流量)。同樣確保服務端TUN/TAP接口沒有被防火牆過濾,
-
當使用proto udp時,連接在啓動時停止,服務端的日誌文件中有如下一行:
TLS: Initial packet from x.x.x.x:x, sid=xxxxxxxx xxxxxxxx
但是在客戶端的日誌中卻並沒有等價的一行。
解決辦法: 你有客戶端到服務端的單向連接。服務端到客戶端的連接被防火牆(通常是在客戶端一側)阻止了。防火牆可能是(a)客戶端上運行個人軟件防火牆,或者(b)是對客戶端的NAT路由網關。修改防火牆設置允許服務端返回的UDP包到達客戶端。
來源:guest_server投稿。