歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

如何在linux上實現Openvpn

一,OpenVPN的工作原理

VPN技術通過密鑰交換、封裝、認證、加密手段在公共網絡上建立起私密的隧道,保障傳輸數據的完整性、私密性和有效性。OpenVPN是近年來新出現的開放源碼項目,實現了SSLVPN的一種解決方案。

傳統SSL VPN通過端口代理的方法實現,代理服務器根據應用協議的類型(如http,telnet等)做相應的端口代理,客戶端與代理服務器之間建立SSL安全連接,客戶端與應用服務器之間的所有數據傳輸通過代理服務器轉發。這種實現方式煩瑣,應用范圍也比較窄:僅適用於用TCP固定端口進行通信的應用系統,且對每個需要代理的端口進行單獨配置;對於每個需要用到動態端口的協議都必須重新開發,且在代理中解析應用協議才能實現代理,如FTP協議;不能對TCP以外的其它網絡通信協議進行代理;代理服務器前端的防火牆也要根據代理端口的配置變化進行相應調整。

OpenVPN以一種全新的方式實現了SSLVPN的功能,克服了傳統SSLVPN的一些缺陷,擴展了應用領域,並且防火牆上只需開放TCP或UDP協議的一個端口。

1,虛擬網卡

在Linux2.4版本以上,操作系統支持一個名為tun的設備,tun設備的驅動程序中包含兩個部分,一部分是字符設備驅動,一部分是網卡驅動。網卡的驅動把從TCP/IP協議棧收到的數據包結構skb放於tun設備的讀取隊列,用戶進程通過調用字符設備接口read獲得完整的IP數據包,字符驅動read函數的功能是從設備的讀取隊列讀取數據,將核心態的skb傳遞給用戶;反過來字符驅動write函數給用戶提供了把用戶態的數據寫入核心態的接口,write函數把用戶數據寫入核心空間並穿入TCP/IP協議棧。該設備既能以字符設備的方式被讀寫,作為系統的虛擬網卡,也具有和物理網卡相同的特點:能夠配置IP地址和路由。對虛擬網卡的使用是OpenVPN實現其SSLVPN功能的關鍵。

2,地址池以及路由

OpenVPN服務器一般需要配置一個虛擬IP地址池和一個自用的靜態虛擬IP地址(靜態地址和地址池必須在同一個子網中),然後為每一個成功建立SSL連接的客戶端動態分配一個虛擬IP地址池中未分配的地址。這樣,物理網絡中的客戶端和OpenVPN服務器就連接成一個虛擬網絡上的星型結構局域網,OpenVPN服務器成為每個客戶端在虛擬網絡上的網關。OpenVPN服務器同時提供對客戶端虛擬網卡的路由管理。當客戶端對OpenVPN服務器後端的應用服務器的任何訪問時,數據包都會經過路由流經虛擬網卡,OpenVPN程序在虛擬網卡上截獲數據IP報文,然後使用SSL協議將這些IP報文封裝起來,再經過物理網卡發送出去。OpenVPN的服務器和客戶端在虛擬網卡之上建立起一個虛擬的局域網絡,這個虛擬的局域網對系統的用戶來說是透明的。

3,客戶端與服務端安全連接的建立

OpenVPN的服務器和客戶端支持tcp和udp兩種連接方式,只需在服務端和客戶端預先定義好使用的連接方式(tcp或udp)和端口號,客戶端和服務端在這個連接的基礎上進行SSL握手。連接過程包括SSL的握手以及虛擬網絡上的管理信息,OpenVPN將虛擬網上的網段、地址、路由發送給客戶端。連接成功後,客戶端和服務端建立起SSL安全連接,客戶端和服務端的數據都流入虛擬網卡做SSL的處理,再在tcp或udp的連接上從物理網卡發送出去。

4,數據包的處理過程

4.1發送數據流程

應用層的外出數據,經過系統調用接口傳入核心TCP/IP層做處理,在TCP/IP經過路由到虛擬網卡,虛擬網卡的網卡驅動發送處理程序hard_start_xmit()將數據包加入skb表並完成數據包從核心區到用戶區的復制,OpenVPN調用虛擬網卡的字符處理程序tun_read(),讀取到設備上的數據包,對讀取的數據包使用SSL協議做封裝處理後,通過socket系統調用發送出去。

4.2接收數據流程

物理網卡接收數據包,經過核心TCP/IP上傳到OpenVPN,OpenVPN通過link_socket_read()接收數據包,使用SSL協議進行解包處理,經過處理的數據包OpenVPN調用虛擬網卡的字符處理程序tun_write()寫入虛擬網卡的字符設備,設備驅動程序完成數據從用戶區到核心區的復制,並將數據寫入skb鏈表,然後調用網卡netif_rx()接收程序,數據包再次進入系統TCP/IP協議棧,傳到上層應用程序。

5,數據包的封裝

OpenVPN提供tun和tap兩種工作模式。在tun模式下,從虛擬網卡上收到的是不含物理幀頭IP數據包,SSL處理模塊對IP包進行SSL封裝;在tap模式下,從虛擬網卡上收到的是包含物理幀頭的數據包,SSL處理模塊對整個物理幀進行SSL封裝。Tap模式稱為網橋模式,整個虛擬的網絡就像網橋方式連接的物理網絡。這種模式可以傳輸以太網幀、IPX、NETBIOS等數據包,應用范圍更廣。

6,OpenVPN與Openssl

OpenVPN軟件包需要和openssl軟件一起安裝,因為OpenVPN調用了Openssl函數庫,OpenVPN的客戶端和服務端建立SSL鏈接的過程是通過調用Openssl來實現的。通過bio_write()/函數把數據寫入Openssl的狀態機通道,bio_read()從Openssl讀取結果。OpenVPN還調用Openssl的加解密函數處理轉發的數據包。

二,OpenVPN的應用

OpenVPN能夠運行於大多常見的系統平台,是一個基於SSL/TLS的VPN解決方案。OpenVPN能夠基於TAP/TUN虛擬設備驅動實現2層及3層的鏈接,提供基於SSL/TLS的工業級別加密功能,並且實現了大多數常見VPN解決方案的全部特性。但目前提供整合了OpenVPN的VPN硬件廠商還不太多。

1,安裝openvpn軟件包

lzo提供了一種數據加密的算法,這裡openvpn會用到lzo算法,所以要安裝lzo

解壓及安裝
# tar xvf lzo-2.04.tar.gz
# cd lzo-2.04
# ./configure  --prefix=/usr/local/lzo
# make && make install
# cd ../
# tar xvf openvpn-2.1.4.tar.gz
# cd openvpn-2.1.4
# ./configure  --prefix=/usr/local/openvpn  --with-lzo-headers=/usr/local/lzo/include/  --with-lzo-lib=/usr/local/lzo/lib/ --with-ssl-headers=/usr/include/openssl/ --with-ssl-lib=/usr/lib
# make && make install
# cd ../

2,openvpn設置

2.1用easy-rsa生成服務器證書客戶端證書

[root@test1 ~]# mkdir  /etc/openvpn
[root@test1 ~]# cp /root/openvpn-2.1.4/easy-rsa/  /etc/openvpn/ -r
[root@test1 ~]# cd /etc/openvpn/easy-rsa/2.0/
[root@test1 2.0]# cat vars |grep -v '^$'|grep -v '^#'
export EASY_RSA="`pwd`"        RSA在當前目錄
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
     這個是一個很特別的參數沒有“”, openssl的配置文件
export KEY_DIR="$EASY_RSA/keys"   密鑰的位置
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
export KEY_SIZE=1024     密鑰的大小長度
export CA_EXPIRE=3650    CA證書的過期時間天數
export KEY_EXPIRE=3650   密鑰的時間過期天數
export KEY_COUNTRY="CN"  國家
export KEY_PROVINCE="HB"  省份
export KEY_CITY="WH"     城市
export KEY_ORG="test.com" 組織
export KEY_EMAIL="root@localhost" 郵箱

2.2下面這個命令在第一次安裝時可以運行,以後在添加客戶端時千萬別運行,這個命令 會清除所有已經生成的證書密鑰。

# ./clean-all

2.3建立根證書

[root@test1 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) [CN]:CN
State or Province Name (full name) [HB]:HUB
Locality Name (eg, city) [WH]:WH
Organization Name (eg, company) [test.com]:test.com
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [test.com CA]:test1.test.com
Name []:
Email Address [root@localhost]:

2.4生成服務器端密鑰key, 後面這個server-name就是服務器名,可以自定義

[root@test1 2.0]# ./build-key-server test1.test.com
Generating a 1024 bit RSA private key
.......................................++++++
..........................++++++
writing new private key to 'test1.test.com.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]:CN
State or Province Name (full name) [HB]:HB
Locality Name (eg, city) [WH]:WH
Organization Name (eg, company) [test.com]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [test1.test.com]:
Name []:
Email Address [root@localhost]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :PRINTABLE:'HB'
localityName          :PRINTABLE:'WH'
organizationName      :PRINTABLE:'test.com'
commonName            :PRINTABLE:'test1.test.com'
emailAddress          :IA5STRING:'root@localhost'
Certificate is to be certified until Oct  6 03:30:01 2023 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

2.5生成客戶端 key

注意在進入 Common Name (eg, your name or your server's hostname) []: 的輸入時, 每個證書輸入的名字必須不同.

[root@test1 2.0]# ./build-key  test2.test.com
Generating a 1024 bit RSA private key
............................................................................................................................++++++
......................++++++
writing new private key to 'test2.test.com.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) [HB]:
Locality Name (eg, city) [WH]:
Organization Name (eg, company) [test.com]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [test2.test.com]:      每個client的hostname都不能一樣
Name []:
Email Address [root@localhost]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'CN'
stateOrProvinceName   :PRINTABLE:'HB'
localityName          :PRINTABLE:'WH'
organizationName      :PRINTABLE:'test.com'
commonName            :PRINTABLE:'test2.test.com'
emailAddress          :IA5STRING:'root@localhost'
Certificate is to be certified until Oct  6 03:36:48 2023 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

2.6生成Diffie Hellman參數,加強安全

[root@test1 2.0]# ./build-dh

Generating DH parameters, 1024 bit long safe prime, generator 2

This is going to take a long time

..............+...............+..+..............................................+..+..............+.......+.............

 

2.7創建服務端配置文件

local 192.168.55.25 #換成服務端的IP

[root@test1 2.0]# mkdir /etc/openvpn/easy-rsa/2.0/conf
[root@test1 2.0]# cp /root/openvpn-2.1.4/sample-config-files/server.conf  /etc/openvpn/easy-rsa/2.0/conf/
[root@test1 2.0]# cat /etc/openvpn/easy-rsa/2.0/conf/server.conf |grep -v '^$'|grep -v '^;'|grep -v '^#'
port 1194
proto udp
dev tun
ca  /etc/openvpn/easy-rsa/2.0/keys/ca.crt
cert /etc/openvpn/easy-rsa/2.0/keys/test1.test.com.crt
key  /etc/openvpn/easy-rsa/2.0/keys/test1.test.com.key  # This file should be kept secret
dh /etc/openvpn/easy-rsa/2.0/keys/dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 192.168.55.25"
push "dhcp-option DNS 8.8.8.8"
client-to-client
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log         openvpn.log
verb 3

2.8啟動openvpn

[root@test1 2.0]# /usr/local/openvpn/sbin/openvpn  --config  /etc/openvpn/easy-rsa/2.0/conf/server.conf &

[3] 11924

2.9打開服務器的路由功能

# vim /etc/sysctl.conf

修改以下內容:

net.ipv4.ip_forward = 1

2.10使sysctl.conf配置文件生效並添加iptables轉發規則:

# sysctl –p

# iptables -t nat -A POSTROUTING -o eth0 -s 10.8.0.0/24 -j MASQUERADE

# /etc/init.d/iptables save

四,測試openvpn的功能

4.1在windows7客戶端上安裝openvpn-2.1_rc22-install.exe

4.2將服務器上的/etc/openvpn/easy-rsa/2.0/keys下的文件拷貝到C:\Program Files (x86)\OpenVPN\config

4.3在windows7客戶端上將C:\Program Files (x86)\OpenVPN\sample-config\client.ovpn拷貝到C:\Program Files (x86)\OpenVPN\config下

4.4編輯client.ovpn 修改如下

remote 服務器IP 1194

4.5 運行client.ovpn測試是否可以ping通10.8.0.1,,也就是服務器的tun接口IP。

五,openvpn排錯

5.1連接openvpn時出現錯誤提示:

TLS_ERROR: BIO read tls_read_plaintext error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

TLS Error: TLS object -> incoming plaintext read error

TLS Error: TLS handshake failed

這個似乎是提示系統時間和證書時間不一致,具體解決措施為:

1.修改vps時間與本地時間一致

2.重啟vps

3.重新連接openvpn試試

4.如果依舊不能連接openvpn,可以在vps上重新生成一個新的證書。

5.2今天,部署了下VPN,部署完成連接的時候,總是提示連接失敗,很郁悶,貼出日志:

Sun Mar 18 20:25:54 2012 [jesse] Peer Connection Initiated with 10.0.0.200:5000

Sun Mar 18 20:25:55 2012 SENT CONTROL [jesse]: 'PUSH_REQUEST' (status=1)

Sun Mar 18 20:25:55 2012 PUSH: Received control message: 'PUSH_REPLY,route 172.16.1.0 255.255.255.0,route 10.0.1.0 255.255.255.0,topology net30,ping 10,ping-restart 120,ifconfig 10.0.1.6 10.0.1.5'

Sun Mar 18 20:25:55 2012 Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]:3: topology (2.0.9)

Sun Mar 18 20:25:55 2012 OPTIONS IMPORT: timers and/or timeouts modified

Sun Mar 18 20:25:55 2012 OPTIONS IMPORT: --ifconfig/up options modified

Sun Mar 18 20:25:55 2012 OPTIONS IMPORT: route options modified

Sun Mar 18 20:25:55 2012 TAP-WIN32 device [本地連接 3] opened: \\.Global\\{2893A584-9C99-43FE-B17C-E1F7160BE530}.tap

解決方法

There are no TAP-Win32 adapters on this system. You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> OpenVPN -> Add a new TAP-Win32 virtual ethernet adapter.

5.3 All TAP-Win32 adapters on this system are currently in use

那麼很有可能是你的TAP虛擬網卡沒有打好驅動,那麼只能換其他的openvpn的gui軟件了

5.5官方的openvpn排錯

如果遇到OpenVPN初始化失敗,或者ping失敗,下面有一些共同的問題症狀和解決辦法:

1.你得到如下錯誤信息: TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity). 這個錯誤指出客戶端不能跟服務器建立網絡鏈接.

解決辦法:

a.請確認客戶端訪問的服務器的機器名/IP和端口是正確的.

b.如果你的OpenVPN服務器是單網卡,並處在受保護的局域網中,請確認你你的網關防火牆使用了正確的端口轉發規則。比如:你的OpenVPN機器的地址是192.168.4.4,但處在防火牆保護下,時刻監聽著UDP協議1194的連接請求,那麼負責維護192.168.4.x子網的網關就會有一個端口轉發策略,即所有訪問UDP協議1194端口的請求都被轉發到192.168.4.4 。

c.打開服務器的防火牆允許UDP協議1194端口連接進來,(或者不管是TCP還是UDP協議在服務器的配置文件中配置了)。

2.你得到如下錯誤信息: Initialization Sequence Completed with errors – 這個錯誤可能發生在windows下(a)你沒有啟用DHCP客戶端服務(b)你的XP SP2使用了某個第三方的個人防火牆。

解決辦法: 啟動DHCP客戶端服務或者你確認你的XP SP2正確使用了個人防火牆.

3.你雖然獲得了Initialization Sequence Completed 的信息,但ping測試還是失敗了,那就通常是在服務器或者客戶端的防火牆阻止過濾了在TUN/TAP設備結構上的網絡流量。

解決辦法: 關閉客戶端的防火牆,如果防火牆過濾了TUN/TAP設備端口的流量。比如在Windows XP SP2系統,你可以到Windows 安全中心 -> Windows 防火牆 -> 高級 然後不要選擇TAP-Win32 adapter設備 (即禁止TUN/TAP設備使用防火牆過濾 ,實質上就是告訴防火牆不要阻止VPN認證信息)。 同樣在服務器端也要確認TUN/TAP設備不實用防火牆過濾 (也就是說在TUN/TAP接口上選擇過濾是有一定的安全保障的. 具體請看下面一節的訪問策略).

4.當以udp協議的配置文件啟動的時候連接停止,服務器的日志文件顯示如下一行信息:

TLS: Initial packet from x.x.x.x:x, sid=xxxxxxxx xxxxxxxx

不管怎麼樣,這信息只在服務器端顯示,在客戶端是不會顯示相同的信息。

解決辦法: 你只擁有單向連接從客戶端到服務器,從服務器到客戶端的連接被防火牆擋住, 通常在客戶端這邊,防火牆(a)可能是個運行在客戶端的個人防火牆軟件(b)或者服務客戶端的NAT路由 網關被設置為從服務器端訪問客戶端的UDP協議包被阻擋返回。

查看FAQ能得到更多故障解決的信息.

本文出自 “好好活著” 博客,請務必保留此出處http://wolfword.blog.51cto.com/4892126/1305621

Copyright © Linux教程網 All Rights Reserved