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

目錄
Routing traffic of Docker containers through a VPN container.
Gluetun,一款專為Docker設計的開源軟體,可讓特定容器走VPN連線上網。
容器為什麼沒事要連VPN?嗯,Ivon覺得下載BT就是個好理由。
試想:如果我們將下載BT的服務跑在Docker裡面,並透過專門的VPN連線,就可以達成跟主機分開上網的功效。也就是說,Linux電腦看網頁時仍透過正常網路上網,唯有容器部份的服務走VPN,而非電腦全域都是走VPN連線。
現在讓我們繼談談Gluetun,名字音近麩質,但其實應該是強力膠水的意思,或許可以解釋為「把TUN(虛擬網路裝置)黏在一起」。
開發者Quentin McGaw在
Github放的圖示是二個水管,好像在玩瑪莉歐,這裡進去那裡出來。
Gluetun本身是作為VPN客戶端兼代理伺服器,支援連線至許多商業VPN,所有您聽過名字的大牌VPN都支援。商業VPN多半支援OpenVPN或WireGuard協定,只要到他們網站下載帶有密鑰的設定檔,Gluetun就能夠連上該公司的VPN。
為防止洩漏IP,Gluetun還會在VPN連線有問題的時候啟動Kill Switch,自動斷線,使依賴它的容器跟著無法上網。
本文,Ivon使用ProtonVPN做示範,其他家VPN的設定大同小異。
1. 取得ProtonVPN的WireGuard設定檔 #
各大商業VPN應該都會有地方可以下載WireGuard設定檔,ProtonVPN請參閱 官方文件
進入Downloads頁面,下滑到WireGuard,填寫服務名稱
在下方列表選取負載低的伺服器,由於我是付費方案所以有更多伺服器可選。之後點選Create
下載設定檔,裡面含有公鑰與私鑰。
2. 架設Gluetun服務 #
- 新增docker-compose
cd ~
mkdir gluetun
cd gluetun
vim docker-compose.yml
- 填寫以下內容。參考剛才取得的WireGuard設定檔內容,依序填入
environment
的參數。如果有需要也可以設定固定IP。
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: # 按照ProtonVPN的WireGuard設定檔填寫
- VPN_SERVICE_PROVIDER=custom
- VPN_TYPE=wireguard
- VPN_ENDPOINT_IP=
- VPN_ENDPOINT_PORT=
- WIREGUARD_PUBLIC_KEY=
- WIREGUARD_PRIVATE_KEY=
- WIREGUARD_ADDRESSES=
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
由於等一下我們要讓容器走Gluetun的VPN,需要做些特別設定,先別急著啟動Gluetun服務。
3. 讓容器走Gluetun的VPN連線 #
欲使容器走Gluetun的VPN連線,只需讓其使用該網路即可。
如果容器服務跟Gluetun寫在同一個docker-compose:加入網路模式network_mode: "service:gluetun"
如果該容器跟Gluetun不是寫在同一個docker-compose:加入network_mode: "container:gluetun"
- 由於我的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
- 首先把qBittorrent暴露的通訊埠註解掉,因為這個會跟Gluetun網路衝突
#ports:
#- 8080:8080
#- 6881:6881
#- 6881:6881/udp
- 接著,在最下方加入Gluetun網路
network_mode: "container:gluetun"
- 現在還要處理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,左邊的可以自由改成想暴露的通訊埠,右邊則必須是容器本身的通訊埠
- 之後,依序啟動Gluetun和qBittorrent的服務
cd ~/gluetun
docker compose up -d
cd ~/qbittorrent
docker compose up -d
- 檢查容器有無連上VPN,用docker exec進入qBittorrent容器的shell:
docker exec -ti qbittorrent /bin/bash
- 檢查公共IP
curl ifconfig.io
- 容器公共IP應當跟您選擇的VPN伺服器一致:
4. 存取連上VPN的容器服務 #
以qBittorrent來說,連上Gluetun的VPN後,該容器就只能從http://localhost:8080
存取,打http://伺服器IP:8080
是無效的。
所幸,剛才我們已經將qBittorrent的8080通訊埠加到Gluetun的docker-compose,您應當可以打http://伺服器IP:8080
或http://Gluetun的容器IP:8080
存取qBittorrent的網頁界面!
(Gluetun容器的IP可以用docker inspect "gluetun" | grep "IPAddress"
取得)
實測在使用
內網穿透軟體的情況下依然可以存取qBittorrent。
如果同一網路下的其他容器服務要連線至qBittorrent的容器,那麼就是打http://伺服器IP:8080
或http://Gluetun的容器IP:8080
來連線。
不過BT管理軟體
Sonarr比較特別,其docker-compose相關的容器也必須使用network_mode: "container:gluetun"
才可以連線到qBittorrent。
當Gluetun偵測VPN無法連線後會讓網路斷線,您需要重新啟動Gluetun服務,以及使用Gluetun網路的容器。
參考資料 #
這篇文章有討論Gluetun反向代理與自動重啟容器服務的進階設定,但該名作者竟然一次幫兩家商業VPN打廣告😅
Gluetun Docker Guide – Easy VPN Killswitch for Docker Containers - SmartHomeBeginner