Wireguard 是由 Jason A. Donenfeld 開發的,
基於 UDP 協定的 VPN (Virtual private network) 程式,
有著比 IPsec 與 OpenVPN 更高的效能,
但設定上有一些些小複雜,這篇教學就來釋疑關於 Wireguard 詳細伺服器與用戶端的設定。
安裝 (以下是 Ubuntu 的指令)
sudo apt install wireguard
這裡有各式系統版本安裝指令:https://www.wireguard.com/install/
建立伺服器 (Server) 金鑰
建立伺服器 (Server) 金鑰,
金鑰是非對稱式加密的金鑰,有公鑰與私鑰各一對,
產生金鑰很簡單,用一行指令完成:
$ wg genkey | tee server_privateKey | wg pubkey > server_publicKey
就會產生二個檔案:
server_privateKey
伺服器私鑰server_publicKey
伺服器公鑰
先留著備用。
建立用戶端 (Client) 的金鑰
建立用戶端 (Client) 的金鑰,指令相同:
$ wg genkey | tee client1_privateKey | wg pubkey > client1_publicKey
就會產生二個檔案:
- client1_privateKey 用戶01私鑰
- client1_publicKey 用戶01公鑰
留著備用。
建立共享密鑰 (PresharedKey) (非必要)
這選項非必要,如果你需要加強防護,可以再建立這個 共享密鑰 (PresharedKey) 來加強防護。
這個金鑰只需要產生 一個 就好。伺服器、用戶端 通通都是設定這一把。
如果要加共享密鑰,就通通都加,如果不加就通通不加。
wg genpsk > psk
留著備用。
設定值
接下來就是讓人有點混亂的地方了,撰寫設定檔。
以下分成三個部分,伺服器設定檔、 Client01 設定檔、 Client02 設定檔 來分別介紹。
伺服器 (Server) 設定檔
我們可以用 vi 來修改設定檔
$ vi /etc/wireguard/wg0.conf
有可能沒有這個資料夾,有可能沒有這個檔案,請自行建立。
大致會填入:
- 伺服器私鑰 Server PrivateKey
- 伺服器配發 IP 地址(假設為:192.168.100.1/24)
- 連接埠 (Port) (假設為:51820)
- 所有用戶的設定
- 該用戶配發的 IP 位址 (需事先指定好)
- 該用戶的公鑰 (PublicKey)
大致範例如下:
[Interface]
Address = 192.168.100.1/24
PrivateKey = IDnOe........(伺服器私鑰 Server PrivateKey)........xNFM=
MTU = 1500
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT && iptables -A FORWARD -o wg0 -j ACCEPT && iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT && iptables -D FORWARD -o wg0 -j ACCEPT && iptables -t nat -D POSTROUTING -o ens4 -j MASQUERADE
# Client01
[Peer]
AllowedIPs = 192.168.100.2/32
PublicKey = p58AA........(用戶01公鑰 Client01 PublicKey)........cK8AY=
# Client02
[Peer]
AllowedIPs = 192.168.100.3/32
PublicKey = JM5oVD........(用戶02公鑰 Client02 PublicKey)........Axjyc=
分成 [Interface]
段落與 [Peer]
段落
伺服器 (Server) 的 [Interface]
段落
伺服器的 [Interface]
段落,存放伺服器的設定
- Address:為 VPN 內網的 IP 位址
(範例是 IP 是 192.168.100.1,子網路遮罩 24 意思為 255.255.255.0) - PrivateKey:這邊填入剛剛產生的伺服器私鑰
- MTU:為 Maximum Transmission Unit (最大傳輸單元)
意指設定最大封包大小(這個值可不設定) - ListenPort:聆聽的連接埠 (Port)
- PostUp:當 VPN 服務啟動時要連帶執行的指令
- PostDown:恰巧跟前者相反,當 VPN 服務停止時要連帶執行的指令
伺服器 (Server) 的 [Peer]
段落
伺服器的 [Peer]
段落,是存放 能連進來的用戶 列表
有幾個用戶就設定幾段 [Peer]
段落
上面例子是設定二個能連進來的用戶
(Server 的 Peer 定義跟 Client 定義不一樣,要注意)
- PublicKey:這邊填入用戶的公鑰
- PresharedKey:填入產生共享密鑰之 psk 檔內容(該選項非必要)
- AllowedIPs:設定該用戶連進來配發的 IP 位址,每個人都必須唯一值,不可重複
用戶一號 Client01 設定檔
以下列出 Client 設定檔,可以參酌修改。
需要填入:
- 用戶01私鑰 Client01 PrivateKey
- 伺服器公鑰 Server PublicKey
- 配發用戶01的 IP (假設為:192.168.100.2/24)
- 伺服器位址 (假設為:vpn.example.com:51820)
- 共享密鑰 (如果有的話,本範例沒有)
[Interface]
PrivateKey = AOAHHE........(用戶01私鑰 Client01 PrivateKey)........7RDE0=
Address = 192.168.100.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = RNrgG........(伺服器公鑰 Server PublicKey)........EpJ0A=
AllowedIPs = 192.168.1.0/24
Endpoint = vpn.example.com:51820
PersistentKeepalive = 30
用戶二號 Client02 設定檔
跟 Client01 差不多,只是有小小的不同,故列出來給大家參考。
需要填入:
- 用戶02私鑰 Client02 PrivateKey
- 伺服器公鑰 Server PublicKey
- 配發用戶02的 IP (假設為:192.168.100.3/24)
- 伺服器位址 (假設為:vpn.example.com:51820)
- 共享密鑰 (如果有的話,本範例沒有)
[Interface]
PrivateKey = eWEo5G........(用戶02私鑰 Client02 PrivateKey)........0RBQc=
Address = 192.168.100.3/24
DNS = 1.1.1.1
[Peer]
PublicKey = RNrgG........(伺服器公鑰 Server PublicKey)........EpJ0A=
AllowedIPs = 192.168.1.0/24
Endpoint = vpn.example.com:51820
PersistentKeepalive = 30
二個用戶基本上大同小異,一併這邊做一個說明
用戶端 (Client) 的 [Interface]
段落
- PrivateKey:這邊填入該用戶的私鑰
- Address:填入與伺服器設定相同配發 IP 位址,一定要跟伺服器寫的一致
- DNS:給定指定的 DNS Server (範例為:1.1.1.1 也可以用 8.8.8.8 或者別的 DNS)
用戶端 (Client) 的 [Peer]
段落
這邊定義了伺服器的連線資訊
(Server 的 Peer 定義跟 Client 定義不一樣,要注意)
- PublicKey:填入伺服器的公鑰
- PresharedKey:填入產生共享密鑰之 psk 檔內容(該選項非必要)
- AllowedIPs:這邊設定比較特別,設定 哪些網段的流量會流向 VPN
如果設定 0.0.0.0/0 的話,意指所有對外連線都會流向 VPN(如果要透過跳板機來上網就可以如此設定)。
你可以設定特定的網段,例如伺服器群所在的網段,意指如果有連接伺服器群才會流向 VPN,否則直接對外,直接直連 Internet 而不透過 VPN。 - Endpoint:連線到伺服器的位址(可以用網址,也可以用 IP)
- PersistentKeepalive:保持連線的設定,範例設定 30 意指 30 秒會檢查一次連線。
啟動 Wireguard 伺服器
$ wg-quick up wg0
這樣可以把這個 VPN 伺服器啟動,你會發現多一個網路介面,名字就是我們命名的 wg0
。
可以用以下指令列出網路介面
$ ip a
啟動 Wireguard 用戶端 (Client) ,連線至伺服器
$ wg-quick up client1
然後測試
$ curl ipinfo.io/ip
看看 IP 有沒有變化?(如果全部對外流量都流進 VPN 的話,理論上 Public IP 位址一定會不一樣。)
或者 ping 看看你的伺服器群
(在 ping 沒有關的時候),測試看看有沒有正常回應 ping
Troubleshooting 疑難排解
設定 VPN 最難的就是除錯了。列出一些我遇到的問題。最多的情況就是連不上,
但連不上分成很多種情況,小弟這邊列出來可以一一檢查。
可以觀察
- Data received
- Data sent
- Lastest handshake
這幾個值還有 Log
問題:做不了 Handshake
如果 Data received 少的很可憐,Log 顯示沒有做到一次 Handshake,很有可能是被擋了。
請檢查防火牆 (Firewall) 有沒有開對應的 Port。
尤其是雲端主機(Amazon, GCP…等),他們後台有自帶一個防火牆,直接從他的後台做設定。
用戶端請檢查連線資訊是否有錯?欲連接的 IP 位址、連接埠 (Port) 是否有錯?
測試一下 DNS,是不是存粹 DNS 無法正確解析?
而或者你的 Nameserver 的 A 紀錄根本就是設錯的?
用 ping
跟 nslookup
查證。
問題:Handshake 有成功,但網路整個連不上
要檢查 Wireguard 伺服器 (Server) 設定的 PostUp
跟 PostDown
裡面的指令有沒有問題。
裡面有寫了二個介面 wg0
跟 ens4
wg0
:是 Wireguard 啟動時,會自動產生的介面名稱,這個 需跟你的檔名一致 。ens4
:是對外的介面名稱 (Interface),也有可能是eth0
或者別的名字。
用戶端 [Peer]
段落的 AllowedIPs 是不是設定了 0.0.0.0/0
?
意指所有對外連線都會流向 VPN,如果設定上去整個網路貌似斷線就是這個緣故。
伺服器端 (Server) 的 net.ipv4.ip_forward
與 net.ipv6.conf.all.forwarding
有沒有正確打開?
因為 Wireguard 伺服器設定的 PostUp
跟 PostDown
裡面有設定 FORWARD 必須打開。
問題:Handshake 有成功,但 ping 不到伺服器
如果是設定 VPN 來存取伺服器群的話,
可以測試連上 VPN 後,使用伺服器的 私人 IP (Private IP) 能不能正確 ping 到?
如果不行,請檢查用戶端 [Peer]
段落的 AllowedIPs 網段是不是設錯?
尤其是 子網路遮罩 (Subnet mask)
是不是有算對?
如果是 Class B 的 私人 IP
就不會是常見的 /24
(255.255.255.0)
而會是 /20
(255.255.240.0)
看你伺服器群的網路怎麼設計。
重點整理
最後統合幾個設定重點:
- 整套系統採非對稱式加密,會產生公鑰私鑰一對金鑰,
用公鑰加密、私鑰可解密
故需要二對金鑰 - 所有的用戶端 (Client) 需要預先指定好分配的 IP 位址
- 伺服器 (Server):填入伺服器自身的私鑰,與所有用戶端 (Client) 公鑰
- 用戶端 (Client):填入伺服器公鑰與自身的私鑰
- 記得查看 Log 來除錯 (debug) 並檢查設定檔問題
以上幾點供參考,祝設定順利。😊
很複雜?來,這有工具XD
很後來亂逛才看到的,直接幫你生好
https://www.wireguardconfig.com/