現在這個時代只要是登入驗證的東西都要加上 MFA (Multi-Factor Authentication) 才能勉強算的上是基本款的防護,尤其是像 OpenVPN 這種常用來當做跳板的 Service,至少權限可以鎖到個人的 device 不致於密碼太弱被破解
上週花了一點時間用 Ubuntu 16.04 安裝了 OpenVPN + Google authenticator 記錄一下這個安裝過程
Ubuntu 16.04 安裝 OpenVPN + Google authenticator
Step 1. 用 apt 安裝 openvpn、easy-rsa
$ sudo apt-get install openvpn easy-rsa
Step 2. 用 make-cadir 產生 easy-rsa 的工具
$ make-cadir ~/openvpn-ca $ cd ~/openvpn-ca
Step 3. 修改憑證資訊
$ vim vars ... export KEY_COUNTRY="US" export KEY_PROVINCE="NY" export KEY_CITY="New York City" export KEY_ORG="DigitalOcean" export KEY_EMAIL="admin@example.com" export KEY_OU="Community" ... export KEY_NAME="server" ...
Step 4. 產生 ca 憑證
$ cd ~/openvpn-ca $ source vars $ ./clean-all $ ./build-ca
Step 5. 建立在 OpenVPN Server 需要的金鑰
$ ./build-key-server server ... Certificate is to be certified until May 1 17:51:16 2026 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
記得最後要回答 y 來產生憑證
產生 Diffie-Hellman keys 密鑰
$ ./build-dh
產生驗證 HMAC 的 TLS 金鑰
$ openvpn --genkey --secret keys/ta.key
Step 6. 建立 Client 的金鑰
$ cd ~/openvpn-ca $ source vars $ ./build-key client
記得最後要回答 y 來產生憑證
如果要有密碼驗證的話可以用 build-key-pass
Step 7. 把需要用的 key 都放到 /etc/openvpn 下
$ cd ~/openvpn-ca/keys $ sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
Step 8. 設定 OpenVPN
$ sudo vim /etc/openvpn/server.conf .. server 192.168.0.0 255.255.255.0 dh dh2048.pem tls-auth ta.key 0 key-direction 0 cipher AES-128-CBC auth SHA256 user nobody group nogroup push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 208.67.222.222" push "dhcp-option DNS 208.67.220.220" cert server.crt key server.key ...
挑幾個重點出來說:
- redirect-gateway 這個會把 client 端的所有流量導入 VPN,如果沒有這個參數,預設不會將流量導入 VPN,必須自行設定
- 如果開啟 tls-auth 就必須要有 key-direction,0 代表 server,而 client 為 1。
- SHA256 拿來驗證。
Step 9. 設定 Forwarding
$ sudo vim /etc/sysctl.conf net.ipv4.ip_forward=1 # 立即生效 $ sudo sysctl -p
Step 10. 設定 ufw 的 nat 路由
$ sudo vim /etc/ufw/before.rules # START OPENVPN RULES # NAT table rules *nat :POSTROUTING ACCEPT [0:0] # Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!) -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE COMMIT # END OPENVPN RULES
讓 ufw 允許轉發封包
$ sudo vim /etc/default/ufw DEFAULT_FORWARD_POLICY="ACCEPT"
開啟 ufw allow 1194/udp、ssh
$ sudo ufw allow 1194/udp $ sudo ufw allow OpenSSH
重啟 ufw
$ sudo ufw disable $ sudo ufw enable
到這邊算是完成 OpenVPN 的設定,接下來要加入 Google authenticator
Google authenticator 設定
Step 1. 安裝 Google authenticator
$ sudo apt-get install libpam-google-authenticator -y
Step 2. 建立 google auth 的目錄
$ sudo mkdir /etc/google-auth
Step 3. 執行 google-authenticator 產生 QR-Code,拿出你的手機安裝 Google authenticator 掃一下
$ google-authenticator
你會拿到一張很大的 QR-code …
然後會在家目錄產生一個 .google_authenticator 的檔案,這是放在 Server 用來驗證 MFA,放到 /etc/google-auth 下並且命名為 user-name
$ sudo mv ~/.google_authenticator /etc/google-auth/shazi7804
Step 4. 設定 openvpn 的 pam,使用 openvpn 使用者權限。
$ sudo useradd openvpn $ sudo vim /etc/pam.d/openvpn auth requisite /lib/security/pam_google_authenticator.so secret=/etc/google-auth/${USER} user=openvpn account required pam_permit.so $ sudo chown -R openvpn /etc/google-auth
Step 5. 在 Openvpn 加入 google authenticator plugin
$ sudo vim /etc/openvpn/server.conf ... plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn
到這邊終於搞定 OpenVPN 的 Server 了,再來要產生 Client 的設定檔
產生 OpenVPN Client 的 ovpn
$ sudo tee client.ovpn <<EOF client dev tun proto udp remote vpn.server.com 1194 resolv-retry infinite nobind cipher AES-128-CBC auth SHA256 auth-user-pass auth-nocache reneg-sec 0 persist-key persist-tun comp-lzo verb 3 key-direction 1 <ca> -----BEGIN CERTIFICATE----- ... # ca.key </ca> <cert> -----BEGIN CERTIFICATE----- ... # client.crt </cert> <key> -----BEGIN PRIVATE KEY----- ... # client.key </key> <tls-auth> -----BEGIN OpenVPN Static key V1----- ... # ta.key </tls-auth> EOF
把 ovpn 匯入 Client 的 openvpn 設定,在一開始登入的時候你必須輸入 user-name 和 password
- user-name 就是在 /etc/google-auth/ 底下命名的 user-name
- password 則是 Google auth code
這樣就可以把安全性鎖到終端的 device 了,由於 Google authenticator 可以支援 pam,也有看到直接用 ssh + google auth 的作法也是一個選擇!
參考:
How To Set Up an OpenVPN Server on Ubuntu 16.04
How to enable 2-factor auth using Google Authenticator for .ovpn file based openVPN access?
您好,請問有多個使用者時該如何設定?
Hi sam
一樣先用 google-authenticator 產生 QR-code,把 .google_authenticator 放到 /etc/google-auth 並且 rename 成 user-name
感謝回覆,還想請教一下:
(1) Google authenticator 設定的step4及step5是否不需再重做?
(2) 您在設定不同的使用者時,是否為個別的使用者各自產生client key,還是全都使用相同的client key來產生ovpn檔?
很棒的教學! 超級感謝! 不過步驟3 有打錯
vim vers 應該是 vars (因為我是複製貼上才發現)
非常感謝提醒,有時候打文章很容易筆誤,不好意思。