How-To:Linux 架設 OpenVPN 伺服器
操作環境:
- 伺服端:CentOS 7.6
- 客戶端:Fedora 28
- OpenVPN 2.4.7
- Easy-RSA 3.0.3
VPN(Virtual Private Network)服務可以有多重用途,不過本文的起因僅是因為 DR 想要在有地區限制的網站上購物……於是 DR 利用手上既有的 Amazon EC2 主機(位在美國)來架設 VPN 服務,讓自己的電腦可以藉由 VPN 連線存取網站來跨過這道限制。
OpenVPN 算是相當流行的 VPN 軟體,雖然網路上已經有很多相關的教學文章了,不過 DR 仍想要針對自己的需求及環境整理出一篇簡潔且直接的操作流程。由於 DR 偏好直接使用伺服器本身的使用者帳號及密碼,作為 OpenVPN 的登入驗證(藉由 PAM 模組)而無需客戶端金鑰,因此本文會針對這項需求進行設定。
1. 安裝 OpenVPN
CentOS 的 OpenVPN 套件可從 Fedora 社群所維護的 EPEL 套件庫中取得,如果還未安裝該套件庫,請執行以下 yum 指令進行安裝:
- yum install epel-release
安裝套件庫後,接著便安裝以下套件:
- yum install openvpn easy-rsa
2. 設定 OpenVPN 伺服器
首先將設定檔範本複製到正確的路徑,其中可以看到,範本所在位置會因安裝的 OpenVPN 版本而異:
- cp /usr/share/doc/openvpn-2.4.7/sample/sample-config-files/server.conf /etc/openvpn/
編輯 /etc/openvpn/server.conf,移除下列設定開頭的分號(;)使其生效:
push "redirect-gateway def1 bypass-dhcp"
接著在設定檔中新增以下三行設定並儲存:
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so login
verify-client-cert none
username-as-common-name
如果要啟用 LZ4 壓縮功能,移除下列設定的分號:
compress lz4-v2
push "compress lz4-v2"
儘管 DR 主要使用的客戶端系統為 Linux,但如果有使用 Windows 客戶端連線的需求,需再新增兩行設定,指定可用的 DNS 服務,以避免 Windows 客戶端連線後無法解析域名:
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
3. 產生憑證及金鑰
一氣呵成執行以下動作:
- cp -R /usr/share/easy-rsa/3/* /etc/openvpn/easy-rsa/
- cd /etc/openvpn/easy-rsa/
- ./easyrsa init-pki
- ./easyrsa build-ca nopass
- ./easyrsa build-server-full server nopass
- ./easyrsa gen-dh
- cp pki/ca.crt /etc/openvpn/
- cp pki/dh.pem /etc/openvpn/dh2048.pem
- cp pki/private/server.key /etc/openvpn/
- cp pki/issued/server.crt /etc/openvpn/
- cd /etc/openvpn/
- openvpn --genkey --secret ta.key
完成上述動作後,/etc/openvpn/ 目錄下應該要存在五個檔案,分別是 ca.crt、dh2048.pem、server.key、server.crt 及 ta.key,也就是 server.conf 設定檔內所指定需載入的檔案名稱:
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
tls-auth ta.key 0
此外請將 ca.crt 及 ta.key 複製一份到需要連線的客戶端電腦上。
4. 網路與防火牆設定
啟用封包轉遞,編輯 /etc/sysctl.conf,並加入以下內容:
net.ipv4.ip_forward = 1
然後使其生效:
- sysctl -p
接著,使用 firewall-cmd 來啟用 IP 偽裝及放行 UDP 1194 連接埠:
- firewall-cmd --permanent --zone=public --add-port=1194/udp
- firewall-cmd --permanent --zone=public --add-masquerade
- firewall-cmd --reload
5. 啟動 OpenVPN
- systemctl enable openvpn@server
- systemctl start openvpn@server
若啟動失敗,請參閱系統日誌(journalctl -xe)中的錯誤訊息進行故障排除。
6. 客戶端連線
就以上的設定方式,客戶端進行 VPN 連線需符合以下三項需求:
- 同樣需安裝 OpenVPN。
- 來自伺服器的 CA 憑證(ca.crt)及金鑰(ta.key)。
- 正確的使用者帳號及密碼。
如果是使用 NetworkManager 設定 OpenVPN 連線,則相關的認證檔案預設會被 SELinux 擋下來,因此需要先執行以下指令(假設檔案的存放目錄為 /home/username/openvpn):
- sudo semanage fcontext -a -t home_cert_t /home/username/openvpn/ca.crt(必須是絕對路徑)
- sudo semanage fcontext -a -t home_cert_t /home/username/openvpn/ta.key(必須是絕對路徑)
- sudo restorecon -Rv /home/username/openvpn
然後便新增 OpenVPN 連線,依序設定以下項目:
- 【General】→【Gateway】:輸入 OpenVPN 伺服器的 IP 位址
-
【Authentication】
- 【Type】:選擇「Password」
- 【User name】:輸入帳號
- 【Password】:輸入密碼
- 【CA Certificate】:選取 ca.crt 憑證
-
【Advanced...】→【TLS Authentication】
- 勾選【Verify peer (server) certificate usage signature】,並選擇「Server」
-
接著在【Additional TLS authentication or encryption】項目下:
- 【Mode】:選擇「TLS-Auth」
- 【Key file】:選取 ta.key 金鑰
- 【Key Direction】:選擇「1」
完成後便可進行連線,若連線失敗則同樣須參閱系統日誌中登載的錯誤訊息做故障排除。另一方面,如果是採用命令行的連線方式,則是新增一支 client.conf,並寫入以下內容:
client
dev tun
proto udp
remote xxx.xxx.xxx.xxx 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
tls-auth ta.key 1
auth-user-pass
auth-nocache
remote-cert-tls server
verb 3
其中的 remote 設定便是輸入 OpenVPN 伺服器的 IP 位址,寫入上述內容後將 ca.crt、ta.key 及 client.conf 皆存放至相同目錄,然後在該目錄中執行:
- sudo openvpn --config client.conf
執行時會要求輸入帳號及密碼,接著便會進行連線程序,完成連線後若要關閉連線可使用 Ctrl + C 組合鍵。
7. 其它參考資料