📋 教學概述
本教學以自建NAS(FN-60)為例,使用
kylemanna/openvpn Docker 映像,
在家中 NAS 上架設完整的 OpenVPN 伺服器。完成後可從外網透過 VPN 安全連回家中任何裝置。
SSH連線
Docker準備
PKI憑證
啟動VPN
客戶端
DDNS
Port轉發
連線測試
📦
環境需求
| 項目 | 說明 | 本教學使用值 |
|---|---|---|
| NAS 型號 | 自建 NAS(任意品牌) | FN-60 |
| NAS 區網 IP | 固定 IP 或 DHCP 保留 | 192.168.1.51 |
| Docker 映像 | OpenVPN 容器 | kylemanna/openvpn |
| 通訊協定/Port | UDP,OpenVPN 預設 | UDP 1194 |
| VPN 網段 | 隔離的虛擬子網 | 10.8.0.0/24 |
| DNS 服務 | 動態 IP 對應域名 | Cloudflare + DDNS |
| 域名 | VPN 連線用的域名 | vpn.ouwinner.com |
🗂️
架構示意圖
網路架構
外網裝置 (手機/筆電)
│
│ OpenVPN 連線 (UDP 1194)
▼
vpn.ouwinner.com ←─── Cloudflare DNS (動態A記錄)
│ ↑
│ DDNS 腳本每5分鐘更新
▼
路由器 :1194 ──Port Forward──▶ NAS 192.168.1.51:1194
│
Docker openvpn
(kylemanna/openvpn)
│
VPN 網段 10.8.0.0/24
│
┌───────────┴────────────┐
家中裝置A 家中裝置B
192.168.1.x 192.168.1.x
✅
完成後你能做到
- 從任何外網位置用 VPN 安全連回家中
- 存取家中 NAS、電腦、IoT 裝置
- 動態 IP 自動更新,域名永遠有效
- 多個客戶端設備同時連線
- 憑證認證,比帳號密碼更安全
- VPN 流量加密,公共 WiFi 也安全
1
SSH 連線到自建 NAS
🔐 前置準備
首先要開啟自建 NAS 的 SSH 功能並連線進去,才能執行後續的 Docker 指令。
⚠️ 先確認
自建 NAS 控制台 → 系統 → 終端機與 SNMP → 確認 SSH 已啟用(預設 Port 22)
Terminal — 從電腦連線到 NAS
# 替換成你的 NAS 區網 IP
ssh your_username@192.168.1.51
# 輸入密碼後進入 NAS 終端機
💡 建議
建議在路由器為 NAS 設定「DHCP 保留」,確保 NAS 的區網 IP 固定不變。
2
確認 Docker 並建立資料目錄
🐳 Docker
確認 NAS 上已安裝 Docker,並建立 OpenVPN 設定檔的儲存目錄。
確認 Docker 版本
docker --version
# 應該顯示類似:Docker version 24.x.x
建立 OpenVPN 資料目錄
# 自建 NAS 的 Volume 通常在 /vol1
mkdir -p /vol1/docker/openvpn
# 確認目錄建立成功
ls -la /vol1/docker/
拉取 OpenVPN Docker 映像
# kylemanna/openvpn 是最廣泛使用的 OpenVPN Docker 映像
docker pull kylemanna/openvpn
# 確認映像已下載
docker images | grep openvpn
📁 目錄說明
/vol1/docker/openvpn 將存放所有 PKI 憑證、設定檔、CRL 等,
這個目錄會被 Docker volume 掛載到容器內。
3
初始化 OpenVPN 設定與 PKI 憑證
🔑 PKI
OpenVPN 使用 PKI(公鑰基礎設施)進行身份驗證,比帳號密碼更安全。 這步驟會建立 CA(憑證授權)、伺服器金鑰、DH 參數等。
⚠️ 重要
以下指令中的
vpn.ouwinner.com 請替換成你的實際域名或公共 IP。
這個值會被寫入客戶端 .ovpn 設定檔,必須是外網可到達的位址。
步驟 3-1:初始化設定檔
# 初始化 OpenVPN 設定,指定你的域名
docker run --rm \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
ovpn_genconfig -u udp://vpn.ouwinner.com
# 完成後會顯示設定內容
步驟 3-2:初始化 PKI(建立 CA)
# 初始化 PKI,nopass = CA 私鑰不加密(方便自動化)
docker run --rm -it \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
ovpn_initpki nopass
# 過程中會詢問 CA 名稱,直接按 Enter 使用預設值即可
# 這個步驟會花幾分鐘(DH 參數計算)
💡 DH 參數說明
DH(Diffie-Hellman)參數計算可能需要 2-5 分鐘,這是正常的。
計算完成後會在
/vol1/docker/openvpn/pki/ 目錄下看到各憑證檔案。
確認憑證已建立
# 確認 PKI 目錄結構
ls /vol1/docker/openvpn/pki/
# 應該看到:
# ca.crt dh.pem issued/ private/ reqs/ serial ...
4
啟動 OpenVPN 容器
🚀 啟動服務
PKI 初始化完成後,啟動 OpenVPN 容器,讓它在背景持續運行。
啟動 OpenVPN 容器
docker run -d \
--name openvpn \
--restart always \
-v /vol1/docker/openvpn:/etc/openvpn \
-p 1194:1194/udp \
--cap-add NET_ADMIN \
kylemanna/openvpn
📋 參數說明
| 參數 | 說明 |
|---|---|
| -d | 背景執行 |
| --name openvpn | 容器名稱,方便管理 |
| --restart always | NAS 重開機後自動重啟 |
| -v /vol1/docker/openvpn:/etc/openvpn | 掛載憑證目錄 |
| -p 1194:1194/udp | 開放 UDP 1194 Port |
| --cap-add NET_ADMIN | 網路管理權限(建立 tun 介面必要) |
確認容器運行狀態
# 查看容器狀態(應顯示 Up)
docker ps | grep openvpn
# 查看啟動日誌
docker logs openvpn
# 應看到:Initialization Sequence Completed
5
建立客戶端憑證並匯出 .ovpn
📄 客戶端
每個要連線的裝置(手機、筆電)都需要一個客戶端憑證。
kylemanna/openvpn 會把所有設定打包成一個 .ovpn 檔案,非常方便。
步驟 5-1:建立客戶端憑證
# client1 是客戶端名稱,可自定義(如 phone、laptop)
docker run --rm -it \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
easyrsa build-client-full client1 nopass
# nopass = 客戶端憑證不加密(方便連線,若要更安全可移除 nopass)
步驟 5-2:匯出 .ovpn 設定檔
# 匯出包含所有憑證的 .ovpn 設定檔
docker run --rm \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
ovpn_getclient client1 > /vol1/docker/openvpn/client1.ovpn
# 確認檔案已建立
ls -la /vol1/docker/openvpn/client1.ovpn
步驟 5-3:下載 .ovpn 到本機
# 在你的電腦上執行(不是在 NAS 上)
scp your_username@192.168.1.51:/vol1/docker/openvpn/client1.ovpn ~/Desktop/
# 或用 WinSCP / Cyberduck 等 SFTP 工具下載
🔒 安全提醒
.ovpn 檔案包含私鑰,請妥善保管,不要公開分享或上傳到雲端。
每個客戶端裝置使用獨立的 .ovpn 檔案,方便日後撤銷單一裝置存取權。
💡 新增更多裝置
重複步驟 5-1 和 5-2,換個名稱(如
phone、laptop2),
即可為不同裝置建立獨立憑證。
6
設定 DDNS — 動態 IP 自動更新 Cloudflare
🌐 DDNS
家用網路通常是動態 IP,每次重新撥號 IP 就會改變。
我們用腳本每 5 分鐘自動偵測公共 IP,並透過 Cloudflare API 更新 DNS 記錄,
確保域名 vpn.ouwinner.com 永遠指向正確 IP。
步驟 6-1:Cloudflare 準備事項
# 需要從 Cloudflare 取得以下資訊:
# 1. Global API Key(帳號 → API Tokens → Global API Key)
# 2. Zone ID(網域頁面右下角)
# 3. 你的 Cloudflare 帳號 Email
步驟 6-2:建立 DDNS 更新腳本
cat > /usr/local/bin/ddns_update.sh << 'EOF'
#!/bin/bash
# ── 請修改以下設定 ──
CF_EMAIL="your_email@example.com"
CF_API_KEY="your_cloudflare_global_api_key"
CF_ZONE_ID="your_zone_id"
CF_RECORD_NAME="vpn.ouwinner.com"
# ────────────────────
# 取得目前公共 IP
CURRENT_IP=$(curl -s https://api.ipify.org)
# 取得 Cloudflare 上的 Record ID 和目前 IP
RECORD_INFO=$(curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records?type=A&name=${CF_RECORD_NAME}" \
-H "X-Auth-Email: ${CF_EMAIL}" \
-H "X-Auth-Key: ${CF_API_KEY}" \
-H "Content-Type: application/json")
RECORD_ID=$(echo $RECORD_INFO | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
CF_IP=$(echo $RECORD_INFO | grep -o '"content":"[^"]*"' | head -1 | cut -d'"' -f4)
# 只有 IP 改變時才更新
if [ "$CURRENT_IP" != "$CF_IP" ]; then
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records/${RECORD_ID}" \
-H "X-Auth-Email: ${CF_EMAIL}" \
-H "X-Auth-Key: ${CF_API_KEY}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"${CF_RECORD_NAME}\",\"content\":\"${CURRENT_IP}\",\"ttl\":60,\"proxied\":false}"
echo "$(date): IP 已更新 ${CF_IP} → ${CURRENT_IP}"
else
echo "$(date): IP 未變更 (${CURRENT_IP})"
fi
EOF
chmod +x /usr/local/bin/ddns_update.sh
步驟 6-3:測試腳本
# 先手動執行一次確認正常
/usr/local/bin/ddns_update.sh
# 應顯示:IP 已更新 舊IP → 新IP
# 或:IP 未變更 (目前IP)
步驟 6-4:設定 Cron 每 5 分鐘自動執行
# 編輯 crontab
crontab -e
# 加入以下這行(每 5 分鐘執行一次)
*/5 * * * * /usr/local/bin/ddns_update.sh >> /var/log/ddns_update.log 2>&1
📋 Cloudflare DNS 記錄設定
若是首次設定(DNS 記錄不存在),需先到 Cloudflare 手動建立:
類型
A,名稱 vpn,
內容填入目前公共 IP,TTL 設為 60秒,
Proxy 設為 DNS only(灰色雲朵),OpenVPN UDP 不能走 Proxy。
7
路由器 Port Forwarding
🔀 路由器
外網的 VPN 連線封包會先到路由器,路由器需要把 UDP 1194 Port 的流量轉發到 NAS 的內網 IP。 這個步驟需要登入你的路由器管理介面完成。
⚠️ 此步驟需手動在路由器操作
不同路由器品牌介面不同,請找「虛擬伺服器」、「Port Forwarding」或「端口轉發」設定。
| 設定項目 | 值 |
|---|---|
| 服務名稱 | OpenVPN(自定義,僅供識別) |
| 通訊協定 | UDP |
| 外部 Port | 1194 |
| 內部 IP | 192.168.1.51(你的 NAS IP) |
| 內部 Port | 1194 |
💡 常見路由器設定位置
| 路由器品牌 | 設定路徑 |
|---|---|
| ASUS | WAN → 虛擬伺服器/Port Forwarding |
| TP-Link | 進階 → NAT 轉送 → 虛擬伺服器 |
| Netgear | 進階 → 進階設定 → Port Forwarding |
| 中華電信 MOD | 進階設定 → 應用程式和遊戲 → 單一Port |
| BUFFALO | 詳細設定 → 網際網路 → 封包過濾 |
確認 Port Forwarding 是否生效
# 使用線上工具檢測
# 瀏覽器開啟:https://www.yougetsignal.com/tools/open-ports/
# 輸入你的公共 IP 和 Port 1194,選 UDP 測試
# 或在 NAS 上確認 openvpn 容器正在監聽
docker exec openvpn netstat -tulnp | grep 1194
8
客戶端安裝與連線測試
✅ 完成
將 client1.ovpn 匯入到你的裝置,就能從外網連回家中 VPN。
建議先用手機行動網路(關 WiFi)測試,確認外網連線正常。
📱 各平台 OpenVPN 客戶端
| 平台 | 推薦 App / 軟體 | 匯入方式 |
|---|---|---|
| Windows | OpenVPN Connect | 開啟 .ovpn 檔案或拖入 App |
| macOS | Tunnelblick 或 OpenVPN Connect | 雙擊 .ovpn 或拖入 |
| iPhone/iPad | OpenVPN Connect(App Store) | AirDrop 或 iTunes 傳入 |
| Android | OpenVPN Connect(Play Store) | 傳入 .ovpn 後匯入 |
| Linux | NetworkManager 或 openvpn 指令 | sudo openvpn --config client1.ovpn |
Linux/Mac 指令行連線
# 安裝 openvpn 客戶端(如尚未安裝)
# macOS: brew install openvpn
# Ubuntu: sudo apt install openvpn
# 連線
sudo openvpn --config ~/Desktop/client1.ovpn
# 成功後會顯示:Initialization Sequence Completed
# 此時你的流量已透過 VPN 走家中網路
確認 VPN 連線成功
# 連上 VPN 後,在終端機執行:
curl https://api.ipify.org
# 顯示的 IP 應該是你家的公共 IP(不是你目前位置的 IP)
# 也可以嘗試 ping 家中裝置的區網 IP
ping 192.168.1.1 # 路由器
ping 192.168.1.51 # NAS
💡 常見問題排查
| 問題 | 可能原因 | 解決方式 |
|---|---|---|
| 連不上 | Port Forwarding 未設定 | 確認路由器 UDP 1194 轉發 |
| 連線超時 | 防火牆封鎖 | 確認 NAS 防火牆允許 1194 |
| DNS 解析失敗 | DDNS 未更新 | 手動執行 ddns_update.sh |
| 容器崩潰 | NET_ADMIN 權限問題 | 確認啟動時有加 --cap-add NET_ADMIN |
| IP 不對 | 連到了 Split Tunneling | 確認 .ovpn 有 redirect-gateway def1 |
🎉
設定完成!常用管理指令
OpenVPN 容器管理指令
# 查看容器狀態
docker ps | grep openvpn
# 查看連線日誌
docker logs -f openvpn
# 重啟 OpenVPN
docker restart openvpn
# 停止 OpenVPN
docker stop openvpn
# 新增客戶端(替換 newclient 為名稱)
docker run --rm -it \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
easyrsa build-client-full newclient nopass
# 匯出新客戶端設定
docker run --rm \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
ovpn_getclient newclient > /vol1/docker/openvpn/newclient.ovpn
# 撤銷客戶端存取(替換 client1)
docker run --rm -it \
-v /vol1/docker/openvpn:/etc/openvpn \
kylemanna/openvpn \
easyrsa revoke client1
💬 留言板 — 分享你的 VPN 設定心得
登入 Google 帳號即可留言