自建VPN並Google Authenticator MFA驗證
在 Linux 系統上自建 OpenVPN 伺服器,並結合 Google Authenticator 進行多重身份驗證(MFA),增強 VPN 連線的安全性。通過詳細步驟,您可以實現雙重驗證的 VPN 連接,為遠端訪問提供更高的保護層級。
關閉所有防火牆
systemctl disable --now firewalld
關閉SELinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
reboot now
加入 sysctl.conf
net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
安裝OpenVPN
首先安裝OpenVPN2.4 跟 easy-rsa 3
yum install epel-release -y
yum install openvpn easy-rsa -y
複製easy-rsa至/etc/openvpn底下
cp -r /usr/share/easy-rsa/3.0.8 /etc/openvpn/easy-rsa
產生金鑰
在easy-rsa下新增檔案vars
cd /etc/openvpn/easy-rsa
vim vars
set_var EASYRSA "$PWD"
set_var EASYRSA_PKI "$EASYRSA/pki"
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "TW"
set_var EASYRSA_REQ_PROVINCE "Taiwan"
set_var EASYRSA_REQ_CITY "New Taipei"
set_var EASYRSA_REQ_ORG "domain.com"
set_var EASYRSA_REQ_EMAIL "email@domain.com"
set_var EASYRSA_REQ_OU "Organizational Unit"
set_var EASYRSA_KEY_SIZE "4096"
set_var EASYRSA_ALGO rsa
set_var EASYRSA_CA_EXPIRE 7500
set_var EASYRSA_CERT_EXPIRE 365
set_var EASYRSA_NS_SUPPORT "no"
set_var EASYRSA_NS_COMMENT "HAKASE-LABS CERTIFICATE AUTHORITY"
set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-1.0.cnf"
set_var EASYRSA_DIGEST "sha256"
vars變更為可執行
chmod +x vars
Server 配置
清除所有的 PKI 設定
./easyrsa init-pki
建立 ca 資訊
./easyrsa build-ca
:::info
- CA證書密碼要記住,給server端和client端證書簽名時需要用到 根证书密码要记住, 给server端和客户端证书签名的时候会用到
- 如果不要有密碼的話後面可以加上
nopass
就可以不輸入密碼 :::
建立server.csr
./easyrsa gen-req server nopass
:::info
- Server端不要設密碼,不然啟動服務還要輸入密碼
- 如果不要有密碼的話後面可以加上
nopass
就可以不輸入密碼 :::
簽發server.crt
./easyrsa sign-req server server
- 對一些信息的確認,可以輸入yes,然後輸入build-ca時設定的密碼
- 可以用這指令驗證
openssl verify -CAfile pki/ca.crt pki/issued/server.crt
dh 是產生 Diffie-Hellman .pem file
./easyrsa gen-dh
時間有點長需要等待一段時間
創建吊銷列表crl.pem (/easyrsa revoke someone)
./easyrsa gen-crl
到期時直接重跑這指令就好
將Server Key搬到/etc/openvpn/server放
mkdir /etc/openvpn/server
cp pki/ca.crt /etc/openvpn/server/
cp pki/issued/server.crt /etc/openvpn/server/
cp pki/private/server.key /etc/openvpn/server/
將dh.pem和crl.pem搬到/etc/openvpn/server放
cp pki/dh.pem /etc/openvpn/server/
cp pki/crl.pem /etc/openvpn/server/
建立server設定檔
cd /etc/openvpn/server
vi server.ovpn
# OpenVPN Port, Protocol, and the Tun
port 1194
proto udp
dev tun
# OpenVPN Server Certificate - CA, server key and certificate
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
#DH and CRL key
dh /etc/openvpn/server/dh.pem
crl-verify /etc/openvpn/server/crl.pem
# Network Configuration - Internal network
# Redirect all Connection through OpenVPN Server
server 10.5.0.0 255.255.255.0
# 只有對外連34.83.44.187才會走VPN
push "route 34.83.44.187 255.255.255.255"
# Using the DNS from https://dns.watch
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
#Enable multiple clients to connect with the same certificate key
duplicate-cn
# TLS Security
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
auth SHA512
auth-nocache
# Other Configuration
keepalive 20 60
persist-key
persist-tun
compress lz4-v2
daemon
user nobody
group nobody
# OpenVPN Log
log-append /var/log/openvpn.log
verb 3
設定iptables
iptables -t nat -I POSTROUTING -d 34.83.44.187 -j MASQUERADE
[color=#efca0e]連 34.83.44.187 時會使用NAT的方式走VPN對外連線
Client 配置
建立client.csr
./easyrsa gen-req client nopass
簽發client.crt
./easyrsa sign-req client client
- 對一些信息的確認,可以輸入yes,然後輸入build-ca時設定的密碼
- 可以用這指令驗證
openssl verify -CAfile pki/ca.crt pki/issued/client.crt
將Client Key搬到/etc/openvpn/client放
mkdir /etc/openvpn/client
cp pki/ca.crt /etc/openvpn/client/
cp pki/issued/client.crt /etc/openvpn/client/
cp pki/private/client.key /etc/openvpn/client/
建立client設定檔
cd /etc/openvpn/client
vi client.ovpn
client
dev tun
proto udp
remote 34.80.209.29 1194
ca ca.crt
cert client.crt
key client.key
cipher AES-256-CBC
auth SHA512
auth-user-pass #沒有帳密請拿掉
auth-nocache
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
resolv-retry infinite
compress lz4-v2
nobind
persist-key
persist-tun
mute-replay-warnings
verb 3
key-direction 1
打包client設定檔及金鑰
tar -czvf polin-vpn.tar.gz client/*
加入 Google Authenticator
安裝Google Authenticator
git clone https://github.com/google/google-authenticator-libpam.git
cd google-authenticator-libpam
./bootstrap.sh
./configure
make && make install
設定openvpn使用google_authenticator登入
vi /etc/openvpn/server/server.conf
加入
/usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so
設定 openvpn 的 pam,使用 openvpn 使用者權限。
vi /etc/pam.d/openvpn
auth requisite /usr/local/lib/security/pam_google_authenticator.so secret=/etc/google-auth/${USER} user=openvpn
account required pam_permit.so
建立 google auth 的目錄
mkdir /etc/google-auth
執行 google-authenticator 產生 QR-Code
google-authenticator
Do you want authentication tokens to be time-based (y/n) y
Warning: pasting the following URL into your browser exposes the OTP secret to Google:
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@Test1%3Fsecret%3DSSY64ZPQHPEGFRQIU4YNPOZQEU%26issuer%3DTest1
這裏是生成的二維碼圖片
Your new secret key is: SSY64ZPQHPEGFRQIU4YNPOZQEU
Your verification code is: 輸入OTP
Your emergency scratch codes are:
60320384
44748688
51040059
54687098
43300392
Do you want me to update your "/root/.google_authenticator" file? (y/n) y
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y
QR-Code 請用 Authenticator APP掃描
連續輸入5個yes(第1個選no,基於計數的令牌,可選)
第1個:問你是否想做一個基於時間的令牌
第2個:是否更新你的google認證文件,由於第一次設置,所以一定選y 第3個:是否禁止口令多用,這裏選擇y,禁止它,以防止中間人欺騙 第4個:默認情況,1個口令的有效期是30s,這裏是爲了防止主機時間和口令客戶端時間不一致,設置的誤差,可以選擇y也可選n,看要求嚴謹程度 第5個:是否打開嘗試次數限制,默認情況,30s內不得超過3次登陸測試,防止別人暴力破解。
將家目錄的.google_authenticator移到/etc/google-auth
mv ~/.google_authenticator /etc/google-auth/test1234
test1234 為登入的username
測試
下載打包好的 client.tar.gz
scp root@xx.xx.xx.xx:/etc/openvpn/client.tar.gz .
下載Tunnelblick https://tunnelblick.net/
解壓縮後修改名稱
tar -xzvf client.tar.gz
mv client client.tblk
點擊 client.tblk 加入 Tunnelblick 設定檔
輸入username 跟 APP上的 OTP密碼就可以登入