章節
- 概述
- 使用openvpn實現訪問遠程網絡
- 吊銷證書
- 故障及排錯
一、概述
VPN (Virtual Private Network) 是虛擬私有網,它通過在公網上創建一個專用並且加密的網絡通道(隧道)進行通訊,在實際的應用中可以幫助遠程用戶、公司分支機構、商業伙伴及供應商等之間建立一個安全可信的網絡連接.
實際上使用VPN的目的及作用就是從網絡層面打通兩個或多個異地網絡,就好像在同一個局域網一樣,並且是加密安全的.
使用vpn的一些場景:
- 穿牆,看外面的世界
- 本地網絡訪問公司內網資源,比如在家里或出差的同事要訪問到公司內部的網絡設備、服務器資源
- 兩個或以上的異地網絡互通,比如多個IDC機房、多個分支機構之間內網互通以及數據傳輸
VPN軟件有很多,有商業的、開源的,openvpn就是其中一個非常好的開源vpn軟件,在生產環境中使用也非常穩定及可靠,其主要特點:開源、跨平台、易於使用、穩定與安全性,對於中小型企業來說用openvpn架設vpn服務器是個不錯的選擇,而不去考慮商業的vpn軟件,有一定成本優勢。呵呵,做運維就是這樣,總是用一些開源的軟件搭建一套還不錯的系統.
二、使用openvpn實現訪問遠程網絡
有這樣的需求:有些同事不在公司或在外面出差但又要訪問公司內網的服務器資源,一般的做法是做端口映射,但是隨着端口映射的數量越來越多帶來一些問題:管理比較麻煩、不是很安全、配置繁瑣。
對於這種需求可以使用vpn打通自己(本地)的網絡與公司的網絡,這樣就像是在公司內網訪問服務器一樣並且是安全的.
因此用openvpn來搭建vpn服務器,規划如下:
環境說明:
- 目的是讓你所在的本地網絡能夠通過vpn服務器訪問公司內網(172.16.0.0/24、172.16.2.0/24、10.10.10.0/24)中的主機
- 用公司內網中的一台(172.16.0.100)作為openvpn服務器,然后在防火牆上做外網端口映射, 發布在外網(因為沒有公網地址,只能這樣做)
- 公司網絡中的172.16.0.0/24、172.16.2.0/24、10.10.10.0/24網段已經是互通的
IP | 作用 | 說明 |
172.16.0.100 | openvpn | 監聽在內網1999端口,映射為外網183.16.133.212的1999端口 |
10.10.10.2 | 公司內網服務器 | |
172.16.2.22 | 公司內網服務器 |
1、部署openvpn服務端(172.16.0.100)
openvpn需要tun模塊支持,所以先檢查是否支持tun模塊
# ls /dev/net/tun /dev/net/tun # 如果有表示支持
停掉selinux
# setenforce 0 setenforce: SELinux is disabled
開啟路由轉發,編輯 /etc/sysctl.conf 文件將 net.ipv4.ip_forward = 0 改為 net.ipv4.ip_forward = 1,然后執行:
# sysctl -p
安裝openvpn及相關包
# curl http://mirrors.aliyun.com/repo/epel-6.repo -o /etc/yum.repos.d/epel-6.repo --silent # 添加阿里的EPEL源
# yum install openssl openvpn easy-rsa lzo -y
- openssl包 程序包
- lzo包 用來進行數據壓縮
- easy-ras包, 提供了一些證書生成腳本、模板配置文件等
可以看下裝了哪些東西
# rpm -ql openvpn
# rpm -ql easy-rsa
創建相關目錄
# mkdir /var/log/openvpn # 放openvpn相關日志文件 # mkdir /etc/openvpn/easy-rsa # 放easy-rsa包提供的相關工具 # mkdir /etc/openvpn/ccd # openvpn客戶端的配置目錄,后面會用到
將easy-ras包提供的工具復制到 /etc/openvpn/easy-rsa
# cp /usr/share/easy-rsa/2.0/* /etc/openvpn/easy-rsa/ -r # cd /etc/openvpn/easy-rsa # ls // 可以看到就是一堆腳本,主要是用來生成證書 build-ca build-key build-key-server clean-all list-crl openssl-1.0.0.cnf sign-req whichopensslcnf build-dh build-key-pass build-req inherit-inter openssl-0.9.6.cnf pkitool vars build-inter build-key-pkcs12 build-req-pass keys openssl-0.9.8.cnf revoke-full
修改 openssl-1.0.0.cnf 文件中 default_crl_days值,調大為3650或者更大,默認是30,單位是天, 3650天也就是表示為10年。這步不做的話如果服務端開啟了crl-verify(吊銷證書)功能,30天后全部客戶端會連不上,因為有效期默認是30天,這個坑其它地方不會告訴你
vim openssl-1.0.0.cnf
找到 並改成 default_crl_days = 3650
編輯 /etc/openvpn/easy-rsa/vars文件,找到下面的變量修改成你指定的值,后面生成證書的時候會應用這些變量值 (不做這步也可以,它會應用默認的變量值)
export KEY_COUNTRY="CN" # 國家 export KEY_PROVINCE="GD" # 省份 export KEY_CITY="GZ" # 城市 export KEY_ORG="MY_ORG" # 組織/公司 export KEY_EMAIL="vpn@qq.com" # 郵箱 export KEY_OU="vpn" # 單位 export KEY_NAME="openvpn" # 服務器名稱
然后執行
# source vars # 這一步會導入vars文件中的變量作為當前的環境變量
# ./clean-all # 清除舊的keys目錄下的文件
生成CA(證書頒發機構),一直回車即可
# ./build-ca Generating a 2048 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) [GD]: Locality Name (eg, city) [GZ]: Organization Name (eg, company) [MY_ORG]: Organizational Unit Name (eg, section) [vpn]: Common Name (eg, your name or your server's hostname) [openvpn CA]: Name [openvpn]: Email Address [vpn@qq.com]:
會在 /etc/openvpn/easy-rsa/keys 目錄下生成ca.crt、ca.key兩個證書文件
# ls /etc/openvpn/easy-rsa/keys/ | grep ca
ca.crt
ca.key
生成服務器證書
./build-key-server vpnserver # 起個名字叫vpnserver,后面會用到 (注:必須是唯一的、盡量是有意義的名稱) Generating a 2048 bit RSA private key ................................+++ .....+++ writing new private key to 'vpnserver.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) [GD]: Locality Name (eg, city) [GZ]: Organization Name (eg, company) [MY_ORG]: Organizational Unit Name (eg, section) [vpn]: Common Name (eg, your name or your server's hostname) [vpnserver]: Name [vpn]: Email Address [vpn@qq.com]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: # 這里是設置連接vpn的時候要不要輸入賬號和密碼,如果不設置就直接回車(可選) An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'GD' localityName :PRINTABLE:'GZ' organizationName :PRINTABLE:'MY_ORG' organizationalUnitName:PRINTABLE:'vpn' commonName :PRINTABLE:'vpnserver' name :PRINTABLE:'vpn' emailAddress :IA5STRING:'vpn@qq.com' Certificate is to be certified until Apr 29 06:26:49 2026 GMT (3650 days) Sign the certificate? [y/n]:y # 輸入y 1 out of 1 certificate requests certified, commit? [y/n]y # 輸入y Write out database with 1 new entries Data Base Updated
它會在 /etc/openvpn/easy-ras/keys 目錄下生成三個證書文件
# ls /etc/openvpn/easy-rsa/keys/ | grep vpnserver vpnserver.crt vpnserver.csr vpnserver.key
生成客戶端證書,客戶端會用證書來連接服務端
./build-key vpnclient --- 表示為vpnclient這個客戶端生成證書,后面會用到 (注:必須是唯一的、盡量是有意義的名稱) Generating a 2048 bit RSA private key .......+++ ....................+++ writing new private key to 'vpnclient.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) [GD]: Locality Name (eg, city) [GZ]: Organization Name (eg, company) [MY_ORG]: Organizational Unit Name (eg, section) [vpn]: Common Name (eg, your name or your server's hostname) [vpnclient]: Name [vpn]: Email Address [vpn@qq.com]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'GD' localityName :PRINTABLE:'GZ' organizationName :PRINTABLE:'MY_ORG' organizationalUnitName:PRINTABLE:'vpn' commonName :PRINTABLE:'vpnclient' name :PRINTABLE:'vpn' emailAddress :IA5STRING:'vpn@qq.com' Certificate is to be certified until Apr 29 06:30:42 2026 GMT (3650 days) Sign the certificate? [y/n]:y --- 輸入y 1 out of 1 certificate requests certified, commit? [y/n]y --- 輸入y Write out database with 1 new entries Data Base Updated
它會在 /etc/openvpn/easy-ras/keys 目錄下生成三個證書文件
# ls /etc/openvpn/easy-rsa/keys/ | grep vpnclient vpnclient.crt vpnclient.csr vpnclient.key
上面是交互式的生成證書,還可以使用非交互式的方式生成證書

# ./build-key --batch vpnclient Generating a 2048 bit RSA private key .....................................................+++ ..........+++ writing new private key to 'vpnclient.key' ----- Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'GD' localityName :PRINTABLE:'GZ' organizationName :PRINTABLE:'weconex.inc' organizationalUnitName:PRINTABLE:'test' commonName :PRINTABLE:'vpnclient' name :PRINTABLE:'TEMP' emailAddress :IA5STRING:'weconex@weconex.com' Certificate is to be certified until Oct 8 17:33:15 2027 GMT (3650 days) Write out database with 1 new entries Data Base Updated
最后創建Diffie Hellman文件,這步需要一點時間,等它執行完就行
# ./build-dh
查看生成的Diffie hellman秘鑰文件
# ls /etc/openvpn/easy-rsa/keys | grep 'dh' dh2048.pem
配置openvpn,編輯/etc/openvpn/server.conf文件,添加如下:
local 172.16.0.100 # 監聽的ip port 1999 # 監聽的端口,默認1194,我設置1999,根據你的需求改就行 proto tcp # 使用的協議,默認udp,因為經常要通過vpn傳文件對可靠性要求比較高,所以用tcp dev tun # 使用tun(隧道)模式,openvpn有兩種模式,一種是TUN,另一種是TAP ca /etc/openvpn/easy-rsa/keys/ca.crt # 這四條都是指定證書的路徑,要確保路徑存在或文件能夠訪問 cert /etc/openvpn/easy-rsa/keys/vpnserver.crt key /etc/openvpn/easy-rsa/keys/vpnserver.key dh /etc/openvpn/easy-rsa/keys/dh2048.pem server 10.8.0.0 255.255.255.0 # 設置成server模式並給客戶端分配的ip段,服務端會用其中.1和.2兩個ip,這個網段不要和你的內網沖突 ifconfig-pool-persist ipp.txt # 當vpn斷開或重啟后,可以利用該文件重新建立相同的IP地址連接 push "route 172.16.0.0 255.255.255.0" # 這三條是給客戶端推的路由,客戶端連上后會根據這個添加路由,vpn服務器后端有幾個網段就寫幾個 push "route 172.16.2.0 255.255.255.0" # 這些路由的作用是告訴客戶端去另一個子網都轉發給TUN接口,類似於靜態路由 push "route 10.10.10.0 255.255.255.0" client-config-dir /etc/openvpn/ccd # 客戶端的個性配置目錄,比如針對每個客戶端推送不同的路由、配置不同的ip keepalive 10 120 # 每10秒ping一次,如果超過120s認為對方已經down了,需要重連commpress lz4-v2 # 在vpn鏈接上啟用壓縮,服務端開啟客戶端也必須開啟 max-clients 100 # 最多有幾個vpn客戶端可以連 user nobody # 啟動openvpn的用戶和組,建議用nobody group nobody client-to-client # 允許vpn客戶端之間通信 duplicate-cn # 允許多個客戶端使用同一個證書登陸,生產環境建議為每個用戶都生成自己的證書 persist-key # 通過keepalived檢測后重新啟動vpn,不重新讀取keys,保留第一次使用的keys persist-tun # 通過keepalived檢測后重新啟動vpn,一直保持tun或tap設備是linkup status /var/log/openvpn/openvpn-status.log # openvpn的狀態日志文件 log /var/log/openvpn/openvpn.log # openvpn的日志文件
writepid /var/run/openvpn/server.pid # pid文件 verb 3 # 日志級別 mute 20 # 如果連續出現20條相同的日志,只記錄一條
然后啟動openvpn
# service openvpn start # chkconfig --add openvpn # chkconfig --level 35 openvpn on
會看到有個tun0接口並且添加了兩條路由
# 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:2499142 errors:0 dropped:0 overruns:0 frame:0 TX packets:2719489 errors:0 dropped:45 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:895142072 (853.6 MiB) TX bytes:1093625277 (1.0 GiB)
# route -n | grep tun0 10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
- 啟動了一個tun0網絡接口,ip是10.8.0.1,P-t-P:10.8.0.2 是點到點的意思
- 添加了兩條路由,一個是主機路由 (UH),另一個是靜態路由 (UG),表示去10.8.0.0網段的數據包下一跳是10.8.0.2
添加一條SNAT規則,讓源地址是10.8.0.0/24網段的地址進來轉換成vpn服務器的內網地址(172.16.0.100),這樣vpn客戶端訪問公司內網服務器的時候偽裝成vpn服務器去訪問
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source 172.16.0.100 # service iptables save # service iptables start # chkconfig --level 35 iptables on
如果不用上面的SNAT方式,還有種做法是在所有公司內網中的主機或服務器上添加回程路由,這樣才能回包給vpn客戶端
# route add 10.8.0.0 MASK 255.255.255.0 172.16.0.100 // 如果是windows # ip route add 10.8.0.0/24 via 172.16.0.100 // 如果是linux
如果數量少還好,但很多的話就比較麻煩,所以推薦用SNAT的方式,到了這里openvpn服務端已經配好了,客戶端可以連了。
2、客戶端連接vpn服務器
openvpn支持linux、window、mac等多種客戶端,
如果是windows客戶端
先安裝openvpn-gui,一直下一步就行,默認會安裝在C:\Program Files\OpenVPN
進到config目錄,創建一個vpnclient目文件夾,把服務器上的 /etc/openvpn/easy-rsa/keys下的ca.crt、vpnclient.crt、vpnclient.key三個證書文件拉下來放進去
然后添加一個vpnclient.ovpn的文件,這個文件用來連接openvpn服務端
vpnclient.ovpn文件的內容是
client # 設置為client模式 dev tun # 設置為tun模式,必須和服務端一致 proto tcp # 使用的協議,必須和服務端一致 remote 183.6.133.212 1999 # 指定openvpn服務器的地址和端口 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert vpnclient.crt key vpnclient.key remote-cert-tls server auth-nocache # 不在內存中緩存密碼 commpress lz4-v2 # 啟動壓縮,必須和服務端一致 verb 3
然后連接openvpn,點擊運行 選 Connect ,如果出現綠色圖標
說明vpn連接成功了.
連接成功后會啟一個網絡連接,可以看到分配的ip地址是10.8.0.10 / 30
以太網適配器 本地連接 2: 連接特定的 DNS 后綴 . . . . . . . : 描述. . . . . . . . . . . . . . . : TAP-Windows Adapter V9 物理地址. . . . . . . . . . . . . : 00-FF-0A-6B-5D-9D DHCP 已啟用 . . . . . . . . . . . : 是 自動配置已啟用. . . . . . . . . . : 是 本地鏈接 IPv6 地址. . . . . . . . : fe80::bca0:7a3d:716c:5769%17(首選) IPv4 地址 . . . . . . . . . . . . : 10.8.0.10(首選) 子網掩碼 . . . . . . . . . . . . : 255.255.255.252 獲得租約的時間 . . . . . . . . . : 2017年10月18日 3:43:41 租約過期的時間 . . . . . . . . . : 2018年10月18日 3:43:41 默認網關. . . . . . . . . . . . . : DHCP 服務器 . . . . . . . . . . . : 10.8.0.9 DHCPv6 IAID . . . . . . . . . . . : 469827338 DHCPv6 客戶端 DUID . . . . . . . : 00-01-00-01-1C-F4-C8-B2-34-E6-D7-6C-5E-88
........
客戶端還會添加路由,可以看下路由表,下面這些是服務端配置推送給客戶端的路由,其實就是告訴客戶端去這些網段都通過vpn服務器,類似於靜態路由
> route PRINT -4
IPv4 路由表 =========================================================================== 活動路由: 網絡目標 網絡掩碼 網關 接口 躍點數 10.8.0.0 255.255.255.0 10.8.0.9 10.8.0.10 20 10.8.0.8 255.255.255.252 在鏈路上 10.8.0.10 276 10.8.0.10 255.255.255.255 在鏈路上 10.8.0.10 276 10.8.0.11 255.255.255.255 在鏈路上 10.8.0.10 276 10.10.10.0 255.255.255.0 10.8.0.9 10.8.0.10 20 172.16.0.0 255.255.255.0 10.8.0.9 10.8.0.10 20 172.16.2.0 255.255.255.0 10.8.0.9 10.8.0.10 20
測試,ping下公司內網中的主機,看下是否能夠訪問,如果可以說明ok了
C:\Users\Administrator ping 172.16.0.104 正在 Ping 172.16.0.104 具有 32 字節的數據: 來自 172.16.0.104 的回復: 字節=32 時間=6ms TTL=63 172.16.0.104 的 Ping 統計信息: 數據包: 已發送 = 1,已接收 = 1,丟失 = 0 (0% 丟失), 往返行程的估計時間(以毫秒為單位): 最短 = 6ms,最長 = 6ms,平均 = 6ms C:\Users\Administrator> ping 172.16.2.1 正在 Ping 172.16.2.1 具有 32 字節的數據: 來自 172.16.2.1 的回復: 字節=32 時間=7ms TTL=253 172.16.2.1 的 Ping 統計信息: 數據包: 已發送 = 1,已接收 = 1,丟失 = 0 (0% 丟失), 往返行程的估計時間(以毫秒為單位): 最短 = 7ms,最長 = 7ms,平均 = 7ms C:\Users\Administrator> ping 10.10.10.2 正在 Ping 10.10.10.2 具有 32 字節的數據: 來自 10.10.10.2 的回復: 字節=32 時間=6ms TTL=126 10.10.10.2 的 Ping 統計信息: 數據包: 已發送 = 1,已接收 = 1,丟失 = 0 (0% 丟失), 往返行程的估計時間(以毫秒為單位): 最短 = 6ms,最長 = 6ms,平均 = 6ms
如果是linux客戶端
和windows一樣,先安裝openvpn
# curl http://mirrors.aliyun.com/repo/epel-6.repo -o /etc/yum.repos.d/epel-6.repo --silent # 添加阿里的EPEL源,有的話不用做. # yum install openvpn -y
創建相關目錄
# mkdir /etc/openvpn/keys # 放客戶端的相關證書 # mkdir /var/log/openvpn # 放日志的目錄
將服務器上 /etc/openvpn/easy-rsa/keys 下的ca.crt、vpnclient.crt、vpnclient.key這些證書文件拉下來放到 /etc/openvpn/keys
# ls /etc/openvpn/keys ca.crt vpnclient.crt vpnclient.key
編輯客戶端的配置文件/etc/openvpn/client.conf,內容如下
client # 設置為clinet模式 dev tun # 使用tun模式,必須和服務端一致 proto tcp # 使用的協議,必須和服務端一致 remote 183.6.133.212 1999 # 指定openvpn服務端的ip和端口,有需要可以使用多個做高可用. resolv-retry infinite nobind persist-key persist-tun ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/vpnclient.crt key /etc/openvpn/keys/vpnclient.key remote-cert-tls server
auth-nocache user nobody group nobody status /var/log/openvpn/openvpn-status.log log /var/log/openvpn/openvpn.log writepid /var/run/openvpn/client.pid # 指定pid文件 commpress lz4-v2 # 壓縮數據,必須和服務端配置一樣 verb 3
mute 20
啟動openvpn客戶端
# service openvpn start # chkconfig --add openvpn # chkconfig --level 35 openvpn on
客戶端啟動后只有進程,因為它作為客戶端去連服務端,不需要提供端口
# ps aux | grep vpn nobody 4236 0.1 0.3 46916 3232 ? Ss 01:36 0:00 /usr/sbin/openvpn --daemon --writepid /var/run/openvpn/client.pid
--cd /etc/openvpn --config client.conf --script-security 2
同樣也會有個tun0網絡接口
# 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.14 P-t-P:10.8.0.13 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)
此時我們可以看下路由表,下面這些路由就是根據服務器的配置(push)推送過來的,目的是通知客戶端根據這個來添加路由,實際上就是告訴客戶端去這些網段都轉發給tun0接口,也就是vpn服務器,類似靜態路由
# route -n | grep tun0 10.8.0.13 0.0.0.0 255.255.255.255 UH 0 0 0 tun0 # 主機路由 172.16.2.0 10.8.0.13 255.255.255.0 UG 0 0 0 tun0 # 去172.16.2.0 下一跳(網關)是10.8.0.13 10.8.0.0 10.8.0.13 255.255.255.0 UG 0 0 0 tun0 # 去10.8.0.0 下一跳(網關)是10.8.0.13 172.16.0.0 10.8.0.13 255.255.255.0 UG 0 0 0 tun0 # 去172.16.0.0 下一跳(網關)是10.8.0.13 10.10.10.0 10.8.0.13 255.255.255.0 UG 0 0 0 tun0 # 去10.10.10.0 下一跳(網關)是10.8.0.13
最后測試,ping下公司內網中的主機,看下是否能夠訪問,如果可以說明ok了
# ping 172.16.0.104 # 可以通公司內網172.16.0.0段中的主機 PING 172.16.0.104 (172.16.0.104) 56(84) bytes of data. 64 bytes from 172.16.0.104: icmp_seq=1 ttl=63 time=7.52 ms ^C --- 172.16.0.104 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 327ms rtt min/avg/max/mdev = 7.524/7.524/7.524/0.000 ms # ping 172.16.2.1 # 可以通公司內網172.16.2.1段中的主機 PING 172.16.2.1 (172.16.2.1) 56(84) bytes of data. 64 bytes from 172.16.2.1: icmp_seq=1 ttl=253 time=205 ms --- 172.16.2.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 768ms rtt min/avg/max/mdev = 205.701/205.701/205.701/0.000 ms # ping 10.10.10.2 # 可以通公司內網10.10.10.0段中的主機 PING 10.10.10.2 (10.10.10.2) 56(84) bytes of data. 64 bytes from 10.10.10.2: icmp_seq=1 ttl=126 time=5.86 ms ^C --- 10.10.10.2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 755ms rtt min/avg/max/mdev = 5.865/5.865/5.865/0.000 ms
數據包的走向是:客戶端訪問公司內網主機 ----- 通過路由轉發 ---- vpn服務器(tun0) ---- SNAT ----- 公司內網主機
要點小結:
- vpn的作用就是讓兩個網絡可以互通,就好像在同一個局域網里面一樣
- openvpn配置好了后可以把它看成一個路由器,需要有點網絡方面的知識才好理解
其它功能及需求:
1、如何給客戶端指定配置,比如不同的客戶端不同的ip地址、推送不同路由等
先在server.conf中指定 client-config-dir目錄,能夠讓openvpn訪問的到
client-config-dir /etc/openvpn/ccd # 確保/etc/openvpn/ccd存在
在/etc/openvpn/ccd目錄下編輯一個與客戶端同名的文件,比如想給vpnclient的這個客戶端指定配置,那么就是/etc/openvpn/ccd/vpnclient,這些配置可以是
ifconfig-push 10.8.0.9 10.8.0.10 # 指定客戶端的IP地址,如果想固定客戶端的ip可以這樣做 push "route 172.16.0.0 255.255.255.0" # 推送指定的路由,不同的客戶端推送不同的路由可以這樣做 iroute 172.16.20.0 255.255.255.0 # 忽略路由 push "dhcp-option DNS 202.96.128.166" # 推送DNS
..........
2、openvpn服務端怎么做高可用
如果vpn服務器只有一台的話就是個單點,如果有需求可以做高可用,做法是准備兩台openvpn服務器,它們相關證書、配置都一樣(可以做一個然后復制到另一個),然后在客戶端的配置文件中指定兩個remote
remote 第一個vpn服務器ip 端口
remote 第二個vpn服務器ip 端口
然后測試下模擬掛掉一個,能不能用、對使用有沒有什么影響
3、怎么給客戶端推送指定的DNS
可以在服務端server.conf或者ccd下面配置文件指定推送給客戶端的dns
push "dhcp-option DNS 202.96.128.166"
push "dhcp-option DNS 202.96.128.167"
這種場景一般是要用到遠程內網中的dns,用的不多
4、怎么給客戶端生成證書

# cd /etc/openvpn/easy-rsa # source ./vars NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys # ./build-key gz # 起個名字叫gz,表示為gz這個客戶端生成證書 Generating a 2048 bit RSA private key .........+++ ...........+++ writing new private key to 'gz.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) [GD]: Locality Name (eg, city) [GZ]: Organization Name (eg, company) [MY_ORG]: Organizational Unit Name (eg, section) [vpn]: Common Name (eg, your name or your server's hostname) [gz]: Name [vpn]: Email Address [vpn@qq.com]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CN' stateOrProvinceName :PRINTABLE:'GD' localityName :PRINTABLE:'GZ' organizationName :PRINTABLE:'MY_ORG' organizationalUnitName:PRINTABLE:'vpn' commonName :PRINTABLE:'gz' name :PRINTABLE:'vpn' emailAddress :IA5STRING:'vpn@qq.com' Certificate is to be certified until Oct 17 08:53:46 2027 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 # ls keys/ | grep 'gz' # 查看生成的證書 gz.crt gz.key gz.csr
對於生成證書需要考慮的問題:是為每個用戶生成證書、還是多個客戶端使用一個證書? 如果是多個客戶端用同一個證書登陸,優點是省事,缺點是如果想吊銷這個證書那么就會影響所有的用戶, 如果是每個用戶都有自己的證書,優點是管理方便,缺點是麻煩(官方推薦為每個用戶生成一個證書,每個用戶用自己的證書連接vpn,雖然麻煩了點)
5、如何把客戶端的默認網關指向vpn服務器
push "redirect-gateway def1 bypass-dhcp"
需要的注意的是,如果這樣配置會導致所有的流量都經過vpn服務器,這樣的vpn服務器的壓力會比較大,一般用的不是很多,除非必須要這么做
三、吊銷證書
吊銷證書是指讓客戶端的證書無效,那么被吊銷證書的用戶就不能連上vpn了。有這個樣的場景,某個同事之前給他分配了vpn客戶端,可以連vpn,現在它離職了,不想在讓他在用vpn了,這時可以吊銷它的證書。
例如:吊銷客戶端 ( vpnclient ) 的證書.
# cd /etc/openvpn/easy-rsa # source ./vars # ./revoke-full vpnclient # 通過revoke-full腳本吊銷證書, 吊銷vpnclient這個客戶端的證書
執行后將看到下面的提示,表示證書已經被吊銷
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf Revoking Certificate 03. Data Base Updated Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf client02.crt: C = US, ST = CA, L = SanFrancisco, O = Fort-Funston, OU = MyOrganizationalUnit, CN = client02, name = EasyRSA, emailAddress = me@myhost.mydomain error 23 at 0 depth lookup:certificate revoked # 出現error 23 表示證書已經被吊銷了
需要注意的是到這步還沒有徹底完成,此時客戶端仍然可以連上。
當通過 revoke-full 腳本吊銷客戶端的證書后它會在keys(我這里是/etc/openvpn/easy-rsa/keys)目錄生成一個crl.pem(吊銷證書列表 )文件,所以還需要在openvpn服務器的配置文件 /etc/openvpn/server.conf 添加:
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem # 指定crl.pem文件的路徑,必須存在並能夠被啟動openvpn的用戶有權限讀取,否則會報cannot read錯誤
然后重啟openvpn服務
# service openvpn restart
Shutting down openvpn: [ OK ]
Starting openvpn: [ OK ]
最后測試被吊銷證書的客戶端能不能連上vpn服務,如果不能連上說明成功.
此外,還可以通過查看/etc/openvpn/easy-ras/keys/index.txt文件,了解vpn客戶端的吊銷狀態.
- R 開頭的表示reovke,說明是吊銷狀態,V表示是正常的
- CN=vpnclient,表示客戶端vpnclient已經被吊銷
# cat /etc/openvpn/easy-rsa/keys/index.txt V 270929154610Z 01 unknown /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=vpnserver/name=EasyRSA/emailAddress=me@myhost.mydomain V 270929154708Z 02 unknown /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=client01/name=EasyRSA/emailAddress=me@myhost.mydomain R 271005070515Z 171008142938Z 03 unknown /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=MyOrganizationalUnit/CN=vpnclient/name=EasyRSA/emailAddress=me@myhost.mydomain
那么問題來了,又想恢復這個被吊銷的客戶端(vpnclient)呢? 同樣可以在openvpn服務器的配置文件/etc/openvpn/server.conf注釋或取消:
crl-verify /etc/openvpn/easy-rsa/keys/crl.pem # 注釋或取消掉這行
重啟openvpn,客戶端測試,如果能連上說明成功了,又可以連了
四、故障與排錯
如果不成功,需要從各個方面排查:
- 檢查openvpn服務器端口和進程是否正常
- 檢查tun0接口和路由表是否正常
- 檢查證書的路徑是否能夠正常訪問
- 查看openvpn服務器日志(重點)
- 檢查防火牆是否做了限制,是否放通了openvpn的ip或端口
- 使用tcpdump一節一節的抓包,看包到了那個環節