家裏的老路由器挪去當 AP 用了,躲在 DMZ 後的服務器,需要直接用 PPPoE 聯網, 才能取得公網 IP。然而發現,其他的 網路服務沒問題,但 Openvpn 服務會因衝突無法連接, 網上爬文說可以透過 Ducker 處理。。。。於是開始了新的折騰。。。

由於一些原因,我需要更換OpenVPN預設的端口。透過 Ducker 的 port forwarding,可以不影響預設的 Ducker 鏡像/容器的工作設計。

官方 OpenVPN-AS 的免費設置只提供2個注冊賬戶,不符合我的多人多裝置連接到家需求,嘗試后放棄。

kylemanna/docker-openvpn 項目驗證後符合需求,就是他了。。。

設置完成再用 docker-compose 帶起 docker。

0. Build OpenVPN Image (x86 可跳過)

因為項目在 dockerhub 上只有 x86 image,若服務器是 arm 平台, 需要自己 build。。。

下次要用樹莓派當服務器的話我再嘗試。下面是網上的説明方法:

repo + build

 git clone https://github.com/kylemanna/docker-openvpn
 cd docker-openvpn
 docker build -t kylemanna/openvpn -f Dockerfile.aarch64 .

若找不到 aarch64/alpine:3.5 的錯誤,修改 Dockerfile 中的 Alpine 的版本為 3.15.4 以上:

 FROM alpine:3.15.4

1. 生成 docker 服務器的設定項 與 加密設置

主機需要提供 docker /etc/openvpn 目錄,其中放置openvpn 的設置内容與密鑰。這裏在目前工作目錄(~/ovpn) 下建立一個子目錄 data 擺放這些内容。

  • 在工作目錄下,新建空的設置目錄給容器挂載。
  • 用 docker 鏡像提供的 ovpn_genconfig 命令提供服務器網址與協議 (udp) 設置。
  • 用 docker 鏡像提供的 ovpn_initpki 命令設置加密。添加 -it 參數 以設定密碼。
 # 1. 將要 mount 到 docker 的目錄 data,將被 mount 到容器的 /etc/openvpn.
 mkdir data
 # 2. 用 ovpn_genconfig 初始化 /etc/openvpn, 提供服務器的關聯網址.
 docker run -v $PWD/data:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://$my_hostname
 # 3. 用 ovpn_initpki 設置密鑰 (需要加 `-it` 參數,因為建立 certificate 需要設定密碼)
 docker run -v $PWD/data:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki

注意: $my_hostname 請提供真實的 外網可連接的 hostname 或 ip address。

2. 製作 docker-compose 啟動設置文件

設置文件

使用以下 docker-compose.yml 檔案啓動 OpenVPN container 作為 VPN service的設置。

其中幾個參數比較重要:

  1. cap_add: - NET_ADMIN
  2. ports: - "$outport:1194/udp",使用 UDP,並做 port forwarding,把自定的 $outport 轉給容器的標準 1194 port。注意: $outport 請提供防火墻允許的真實數字。
  3. restart: always ,需要自動啓動服務。
  4. volumes: - .data:/etc/openvpn, 需要挂載剛剛設置好的 data 子目錄到容器的 /etc/openvpn
  5. 其他參數依需求自由調整。。。
 version: '2.3'
 services:
  openvpn-service:
    image: kylemanna/openvpn
    container_name: openvpn-service
    cap_add:
      - NET_ADMIN
    restart: always
    mem_limit: 64M
    logging:
      driver: "json-file"
      options:
        max-size: "1m"
        max-file: "3"
    ports:
      - "$outport:1194/udp"
    networks:
      - openvpn-service
    volumes:
      - ./data:/etc/openvpn
 ​
 networks:
  openvpn-service:
    name: openvpn-service-network
    driver: bridge

注意: $outport 請提供防火墻允許的真實數字。

3. 執行 docker-compose 啓動

啓動執行 docker-compose 環境設置:

 docker-compose up -d

輸出:

 WARN[0000] /home/cyue/ovpn/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
 [+] Running 2/2
  ✔ Network openvpn-service-network Created 0.2s
  ✔ Container openvpn-service       Started 2.4s

服務器就完成了。。。

4. 產生 Client 端的設置文件

整理目前需要連綫的裝置 XXXX,整批或單獨新增對應的 tw0-XXXX.ovpn 設定檔。

注意: 由於我做了 port forwarding,需要用 sed 指令把 docker 生成的設置文件中的 port number,改成 host端的 port number。

a. 批量生成固定需要的設置文件:

 for u in cyue cyuePad cyuePC cyueRPi5 shari shariPC shariPad tony tonyPC tonyPad11 tonyMBP johnny johnnyMBP johnnyPad johnnyPC yuhan yuhanPC yuhanSamsung yezi yanling yuchen yuchenPC
 ​
 do
  echo "tw0-$u"
  # 建立一個 client 的憑證 (nopass,使用設置文件不須密碼)
  docker run -v $PWD/data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full tw0-$u nopass
  # 將 client 的憑證匯出
  docker run -v $PWD/data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient tw0-$u > tw0-$u.ovpn
  # 對外修改 port 為 $outport
  sed -i "s/1194 udp/$outport udp/g" tw0-$u.ovpn
 done

對每個裝置設定,要提供之前設定服務器的密碼,以正確生成裝置設置文件。

注意: $outport 需要與前面定義的數字相同。

b. 單獨生成 ovpnadd.sh

script 采用第一個輸入參數當裝置名:

 echo "tw0-$1"
 # 建立一個 client 的憑證 (nopass,使用設置文件不須密碼)
 docker run -v $PWD/data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full tw0-$1 nopass
 # 將 client 的憑證匯出
 docker run -v $PWD/data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient tw0-$1 > tw0-$1.ovpn
 # 對外修改 port 為 $outport
 sed -i "s/1194 udp/$outport udp/g" tw0-$1.ovpn

注意: $outport 需要與前面定義的數字相同。

5. 用 OpenVPN Connect App 測試連線

Windows / iOS / Android / Linux / macOS / Chrome 下都有 OpenVPN Connect App,將設定檔提供給 APP 即可。

參考: OpenVPN Connect – VPN For Your Operating System | OpenVPN ,或以下 鏈接:

這個作者很懶,Index of /info/app 提供的鏡像很久沒更新了。。。

image-20250330163451729
image-20250330163556975