快轉到主要內容

Gluetun:讓Docker容器走VPN連線,沒網路就斷線,使用教學

Linux系統 Self-hosting自架 Docker VPN Torrent
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

Routing traffic of Docker containers through a VPN container.

Gluetun,一款專為Docker設計的開源軟體,可讓特定容器走VPN連線上網。

容器為什麼沒事要連VPN?嗯,Ivon覺得下載BT就是個好理由。

BT梗圖

試想:如果我們將下載BT種子的qBittorrent服務跑在Docker裡面,並透過專門的VPN連線,就可以達成跟主機分開上網的功效。也就是說,Linux電腦看網頁時仍透過正常網路上網,電腦不會全域都是走VPN連線,唯有容器部份的服務走VPN。如此一來透過VPN做種就不會干擾正常電腦使用了。

現在讓我們繼續談Gluetun,名字音近麩質,但其實應該是強力膠水的意思,或許可以解釋為「把TUN(虛擬網路裝置)黏在一起」。

開發者Quentin McGaw在 Github放的圖示是二個水管,好像在玩瑪莉歐,這裡進去那裡出來。

Gluetun本身是作為VPN客戶端兼代理伺服器,支援連線至許多商業VPN,所有您聽過名字的大牌VPN都支援。商業VPN多半支援OpenVPN或WireGuard協定,只要到他們網站下載帶有密鑰的設定檔,Gluetun就能夠連上該公司的VPN。

為防止洩漏IP,Gluetun還會在VPN連線有問題的時候啟動Kill Switch,自動斷線,使依賴它的容器跟著無法上網。

1. 取得VPN供應商的設定檔
#

這裡Ivon使用ProtonVPN做示範,其他家VPN的設定大同小異,各大商業VPN應該都會有地方可以下載OpenVPN或WireGuard的設定檔。

OpenVPN
#

請參閱 ProtonVPN官方文件,到你的 Proton VPN帳號後台,取得OpenVPN帳號密碼。

WireGuard
#

  1. 請參閱 ProtonVPN官方文件,進入Downloads頁面,下滑到WireGuard,填寫服務名稱

  2. 在下方列表選取負載低的伺服器,由於我是付費方案所以有更多伺服器可選。點選Create。

  3. 下載WireGuard設定檔

2. 架設Gluetun服務
#

由於等一下我們要讓容器走Gluetun的VPN,需要做些特別設定,編輯完後先別急著啟動Gluetun服務。

  1. 參考 Gluetun文件,新增docker-compose
cd ~
mkdir gluetun
cd gluetun
vim docker-compose.yml
  1. 參考剛才取得的VPN設定檔內容,依序填入environment的參數。如果有需要也可以給容器設定固定IP。

OpenVPN
#

填入OpenVPN的帳號、密碼,並指定伺服器國家

version: "3"
services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp # HTTP proxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
    volumes:
      - /home/user/gluetun:/gluetun
    environment: # 按照VPN供應商的OpenVPN設定檔填寫
      - VPN_SERVICE_PROVIDER=protonvpn
      - VPN_TYPE=openvpn
      - OPENVPN_USER=
      - OPENVPN_PASSWORD=
      - SERVER_COUNTRIES=United Kingdom # 指定國家
     networks: # (選擇性) 固定Gluetun容器的IP
       network:
        ipv4_address: 172.27.0.5

networks: # (選擇性) 固定Gluetun容器的IP
  network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.27.0.0/16
          gateway: 172.27.0.5

WireGuard
#

按照VPN供應商的WireGuard設定檔填寫。

version: "3"
services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp # HTTP proxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
    volumes:
      - /home/user/gluetun:/gluetun
    environment:
      - VPN_SERVICE_PROVIDER=custom
      - VPN_TYPE=wireguard
      - VPN_ENDPOINT_IP=
      - VPN_ENDPOINT_PORT=
      - WIREGUARD_PUBLIC_KEY=
      - WIREGUARD_PRIVATE_KEY=
      - WIREGUARD_ADDRESSES= #只要填IPV4位址就好
     networks: # (選擇性) 固定Gluetun容器的IP
       network:
        ipv4_address: 172.27.0.5

networks: # (選擇性) 固定Gluetun容器的IP
  network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.27.0.0/16
          gateway: 172.27.0.5

3. 讓容器走Gluetun的VPN連線
#

欲使容器走Gluetun的VPN連線,只需讓其使用該網路上網即可。

如果容器服務跟Gluetun寫在同一個docker-compose:加入網路模式network_mode: "service:gluetun"

如果該容器跟Gluetun不是寫在同一個docker-compose:加入network_mode: "container:gluetun"

  1. 由於我的qBittorrent服務跟Gluetun不在同一個docker-compose,為此修改qBittorrent的docker-compose。下面是我位於~/qbittorrent目錄的檔案內容:
version: '3'
services:
qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Taipei
      - WEBUI_PORT=8080
    volumes:
      - /home/user/qbittorrent/config:/config
      - /home/user/qbittorrent/downloads:/downloads
    ports:
      - 8080:8080
      - 6881:6881
      - 6881:6881/udp
    restart: unless-stopped
  1. 首先把qBittorrent暴露的通訊埠註解掉,因為這個會跟Gluetun網路衝突
#ports:
      #- 8080:8080
      #- 6881:6881
      #- 6881:6881/udp
  1. 接著,在最下方加入Gluetun網路
  network_mode: "container:gluetun"
  1. 現在還要處理qBittorrent通訊埠的問題。開啟Gluetun的docker-compose檔案,把qBittorrent用到的8080通訊埠加回來:
version: "3"
services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - 8888:8888/tcp # HTTP proxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
      - 8080:8080 # qBittorrent,左邊的可以自由改成想暴露的通訊埠,右邊則必須是容器本身的通訊埠
  1. 之後,依序啟動Gluetun和qBittorrent的服務
cd ~/gluetun
docker compose up -d
cd ~/qbittorrent
docker compose up -d
  1. 檢查容器有無連上VPN,用docker exec進入qBittorrent容器的shell:
docker ps

docker exec -ti qbittorrent /bin/bash
  1. 檢查公共IP
curl ifconfig.io
  1. 容器公共IP應當跟您選擇的VPN伺服器一致:

  2. 如果你想測試Kill Switch有無運作,停掉Gluetun服務,再檢查qBittorrent能不能上網就知道了:

cd ~/gluetun
docker compose down

docker exec -ti qbittorrent /bin/bash
curl ifconfig.io

4. 設定通訊埠轉發
#

此為選擇性功能。

如果你要提昇BT下載速度,並讓別人從你這裡下載檔案(做種),最好設定通訊埠轉發(port forwarding)。

注意不是每一家VPN供應商都有提供此功能。且就算VPN供應商有提供通訊埠轉發,也不是每台伺服器都有此功能。

Gluetun支援Proton VPN和Private Internet Access,其他家的VPN請參閱官方網站的文件。

鑑於Gluetun取得轉發通訊埠的方法有缺失,似乎只能用OpenVPN方式連線,用WireGuard的話會找不到VPN供應商所轉發的通訊埠。

  1. 參考 Proton VPN官方文件,查看哪些國家伺服器支援P2P。

  2. 參考 Gluetun有關port forwarding的說明,按照Proton VPN提供的OpenVPN帳號,修改Gluetun的docker-compose.yml,在你的帳號名稱後面加上+pmp

  3. 加入以下環境變數:

    environment:
      - VPN_PORT_FORWARDING=on
      - VPN_PORT_FORWARDING_PROVIDER=protonvpn
  1. 加入這段,啟用的Gluetun的Conrol Server
    ports:
      - 8000:8000
  1. 重新啟動Gluetun服務。
cd ~/gluetun
docker compose down
docker compose up -d
  1. Proton VPN所轉發的通訊埠可從此網址得知。(Gluetun的docker log也會寫出來)
curl http://Gluetun容器IP:8000/v1/openvpn/portforwarded
  1. 在qBittorrent偏好設定 → 連線開啟通訊埠,填入Proton VPN所轉發的通訊埠,並關閉UPnP功能。

  2. 要知道通訊埠轉發有無成功,進入Gluetun容器,使用port-checker程式檢測。這裡假定轉發的通訊埠為61915

docker ps

docker exec -it gluetun /bin/sh

wget -qO port-checker https://github.com/qdm12/port-checker/releases/download/v0.3.0/port-checker_0.3.0_linux_amd64

chmod +x port-checker

./port-checker -port 61915
  1. 開啟瀏覽器,輸入http://VPN的公共IP:61915,應該就會印出你目前的IP位址了。回到終端機,按CTRL+C關閉,並輸入exit退出shell。

5. 存取連上VPN的容器服務
#

以qBittorrent來說,連上Gluetun的VPN後,該容器就只能從http://localhost:8080存取,打http://伺服器IP:8080是無效的。

所幸,剛才我們已經將qBittorrent的8080通訊埠加到Gluetun的docker-compose,您應當可以打http://伺服器IP:8080http://Gluetun的容器IP:8080存取qBittorrent的網頁界面!

(Gluetun容器的IP可以用docker inspect "gluetun" | grep "IPAddress"取得)

實測在使用 內網穿透軟體的情況下依然可以存取qBittorrent。


如果同一網路下的其他容器服務要連線至qBittorrent的容器,那麼就是打http://伺服器IP:8080http://Gluetun的容器IP:8080來連線。

不過BT管理軟體 Sonarr比較特別,其docker-compose相關的容器也必須使用network_mode: "container:gluetun"才可以連線到qBittorrent。

當Gluetun偵測VPN無法連線後會讓網路斷線,您需要重新啟動Gluetun服務,以及使用Gluetun網路的容器。

參考資料
#

官方文件 Gluetun Wiki - GitHub

下面這篇文章有討論Gluetun反向代理與自動重啟容器服務的進階設定,但該名作者竟然一次幫兩家商業VPN打廣告😅

Gluetun Docker Guide – Easy VPN Killswitch for Docker Containers - SmartHomeBeginner

相關文章

如何自架開源雲手機,用手機Scrcpy APP連線控制
Linux系統 Self-hosting自架 Cloud Gaming Android-X86 Scrcpy Docker
Linux設定通訊埠轉發方法 (port forwarding),以Ubuntu為例
Linux系統 Self-hosting自架 Port Forwarding DNS Torrent
qBittorrent:Linux BT種子下載器安裝教學與使用方法
Linux系統 Linux好用軟體 Torrent Docker

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。