Releases: passteque/gluetun
Release list
v3.41.3
This fixes a VPN server port forwarding deadlock bug introduced whilst back-porting a fix from the master branch (:latest image) to v3.41.2. Credits to @robinostlund for reporting the bug and even nailing down what it was! (#3416)
Refer to v3.41.2 fixes in case you haven't checked.
v3.41.2
Fixes
- Wireguard:
- support IPv6 address formatting from config files (#3273)
- ignore empty address strings
- skip tun device checks when using kernelspace
- OpenVPN:
- Custom openvpn: restrict custom openvpn config protocol to tcp or udp internally
- Firewall: shared mutex for both iptables and ip6tables to prevent race conditions
- Healthcheck:
- correct behavior when HEALTH_RESTART_VPN=off and startup check fails
- prevent race condition on the healthchecker (#3400)
- DNS:
- skip blocking if block lists download fails
- correct error wrapping for DNS listening address validation
- DNS over TLS pool behavior fixed
- handle timed out connections the same as closed connections
- close connection on TLS handshake failure
- improve mutex handling during connection renewal and retrieval
- VPN port forwarding:
- no longer stuck after failed port forwarding
- handle empty ports without panicing
- Updater: only uses DoH to cloudflare+google
- prevent dns plaintext manipulation both the periodic update and when running in cli mode
- possibly higher reliability on poor connections versus UDP
- drop
-dnsflag in update command - for now no configuration allowed since it makes everything rather complex
- Control server:
- use
portandportsfor both single port and multiple ports forwarded - authentication: return 404 or 405 depending on route
- use
- Increase global http client timeout to 35s and precise lower timeouts where needed
- Fix DNS blocklists slow downloads
- Leave 35s timeout for updaters
- Set timeouts to 1s for local calls
- Set timeouts to 5s for LAN VPN calls and small external calls
- Set timeouts to 10s external VPN API calls
- Kernel modules: probe searches for features built-in the kernel
- CI: set hash of PR commit instead of synthetic commit in docker build argument
internal/command: fix rare race condition on log line stream at command completion
Provider specific fixes
- AirVPN: update servers data (#3186)
- ExpressVPN:
- Privado:
- servers data updated using JSON API
- allow OpenVPN TCP protocol
- allow additional OpenVPN ports 443, 8080 and 8443 for both tcp and udp
- Private Internet Access:
- remove none encryption preset
- use AES-GCM for all presets
- allow ports 501 and 502 as custom ports given they are the defaults
- try x.y.128.1 and x.y.0.1 from the gateway IP to find the API IP address
- fix servers data updater and update servers data
- update default OpenVPN ports: 8080 for UDP, 8443 for TCP (according to pia-foss/manual-connections@8a75e46)
- handle "port is busy" messages and retry port forwarding logic
- ProtonVPN: fix updater code
- Vyprvpn: update OpenVPN configs zip URL (#3264)
PS:
- No time to make a video or a rant section yet, but will do for v3.42.0 for sure!
- v3.42 probably coming end of August/early September!
- Sorry for the spam, first few v3.41.2 release attempts decided to give me a bunch of surprises in the CI, so here it is again
v3.41.1
Fixes
- Healthcheck: prevent race condition making Gluetun hang completely (#3123)
- Wireguard kernelspace detection fixed in some cases
- OpenVPN 2.5 is not needed as long as it's not to be used, resolving some kernel incompatibilities
- HTTP proxy: remove info log when no Proxy-Authorization header is present
- ProtonVPN:
- update OpenVPN settings (#3120)
- support port 51820 for UDP OpenVPN connections
v3.41.0
Video of me reading out this release
Thank you all for your patience for this release which took its sweet time 🙏⏲️
I have been rather absent in a good part of 2025 due to work and life getting in the way, and I would like to thank many of you for helping out around in issues and discussions, and for the few code contributors whilst I was away.
On this release, many of the features you see are the result of behind-the-scene work of the last few years (notably on dns) and I'm super glad they are finally in Gluetun! A lot more to come in v3.42.0, there is already a pile of pull requests waiting 🚀
Final note, introducing the RANTING SECTION at the bottom of this changelog. This section might also be in the future releases (unfortunately)!
Happy holidays! 🎄 🎅 ❄️ ⛄
Features
- DNS
- (K8s users read this) Local network names resolution using private DNS resolvers found at container start (#2970)
- DNS over HTTPS support (see
DNS_UPSTREAM_RESOLVER_TYPEbelow) DNS_UPSTREAM_RESOLVER_TYPEoption which can bedot(DNS over TLS),doh(DNS over HTTPS) orplain(plaintext over UDP)- DNS over TLS re-uses TCP connections which should put less stress on TCP-connections-rate-limiting by the VPN server
- DNS requests blocked are logged with a reason
- DNS rebinding protection is always enabled, but hostnames can be excluded with
DNS_REBINDING_PROTECTION_EXEMPT_HOSTNAMES i/o timeouterrors are now logged at the debug level instead of warn level
- healthcheck system reworked: more robust and less impact on other applications (#2923)
- Three checks are performed:
- startup full check: when the VPN connection is first established, perform a TCP+TLS dial to
HEALTH_TARGET_ADDRESSESwith a timeout of 6 seconds - periodic full check: every 5 minutes, perform a TCP+TLS dial to
HEALTH_TARGET_ADDRESSES, with up to 3 tries of 10s, 15s, and 30s timeouts - periodic small check: every minute, perform ICMP pings to
HEALTH_ICMP_TARGET_IPS, with a fallback to plain DNS (UDP) lookups ofgithub.comto cloudflare+google, with up to 10 tries of 5s, 5s, 5s, 10s, 10s, 10s, 15s, 15s, 15s, and 30s timeouts
- startup full check: when the VPN connection is first established, perform a TCP+TLS dial to
- If any of these checks fail, the VPN connection is restarted
- Reduced impact on TCP to allow for higher bandwidth in TCP torrenting
- New option
HEALTH_TARGET_ADDRESSES=cloudflare.com:443,github.com:443to have a fallback address - New option
HEALTH_ICMP_TARGET_IPS=1.1.1.1,8.8.8.8to have8.8.8.8as a fallback address - New option
HEALTH_SMALL_CHECK_TYPEwhich can bednsoricmp. By default it uses icmp and falls back to dns if icmp isn't permitted. - New option
HEALTH_RESTART_VPN: you should really leave it toon, unless you have trust issues with the healthcheck.
- Three checks are performed:
- built-in servers data updates:
- Cyberghost
- ExpressVPN
- Mullvad
- Privado
- Private Internet Access
- SlickVPN (mere 29 hardcoded servers 🤷)
- ProtonVPN
- Surfshark
- Torguard
- control server:
HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLEoption (JSON encoded). For example:{"auth":"basic","username":"me","password":"pass"}or{"auth":"apiKey","apikey":"xyz"}or{"auth":"none"}.- log number of roles read from auth file
- VPN server side port forwarding:
- support
{{PORT}}template variable on top of{{PORTS}} - support
{{VPN_INTERFACE}}template variable which is by defaulttun0
- support
- Public IP data fetcher queries all data sources in parallel and picks the most popular result
- bump Alpine from 3.20 to 3.22
- wireguard: on error parsing
WIREGUARD_ENDPOINT_IP, mention it must be an IP address for the time being - new ascii logo logged out at program exit... did any of you spot it? 👀
Fixes
- Wireguard:
- specify IP family for new route (#2629)
WIREGUARD_ENDPOINT_IPregression (v3.39.0) fixed to override the IP address of a picked connection
- Providers specific:
- Cyberghost: log warnings from updater resolver but not for "no such host" which happen quite a lot
- ExpressVPN: update hardcoded servers data (#2888)
- ProtonVPN: authenticated servers data updating
- If updating servers data periodically, use
UPDATER_PROTONVPN_EMAILandUPDATER_PROTONVPN_PASSWORD - If using the CLI, use
-proton-emailand-proton-passwordflags
- If updating servers data periodically, use
- PureVPN:
- VPN Unlimited: update certificates value (#2835) and remove no longer valid hardcoded hosts
- VPN Secure updater fixed by allowing their website servers list to have "N / A" region/city
- WeVPN: removed since it decomissioned
- Servers storage: do not crash the container but log a warning if flushing merged servers to file fails
- VPN server side port forwarding:
- clear port file instead of removing it (see why)
- remove double log when clearing port forward file
- Control server:
- log out full URL path not just bottom request URI
- change route with retrocompatibility from
/v1/openvpn/portforwardedto/v1/portforward: this route has nothing to do with openvpn specifically, removed theedinportforwardedto accomodate future routes such as changing the state of port forwarding
PUBLICIP_ENABLEDis now respected- publicip/api/cloudflare: add now required
Refererheader (#3058) - cli
openvpnconfigcommand no longer panics due to missingSetDefaultscall - DNS:
- retry on next period if a blocklists update failed previously
- fix
DNS_KEEP_NAMESERVERbehavior (by the way, you should no longer need to use this option!)- no longer hangs the code when establishing the VPN connection
- no longer makes Gluetun panic when exiting
- Healthcheck:
- fix grammar issue in log (#2773)
Documentation
- Readme
- remove no longer valid LoC badge
- update Alpine version and image size
- warning on "official" websites which are scams
- add star history graph because it's fun
- Dockerfile: specify default PUID and PGID to avoid confusion, since both are already defaulted to 1000 in the Go code
- add pull request template (#2918)
- update provider issue template
Maintenance
- Code
- Change DNS option names with retro-compatibility:
DOTtoDNS_SERVERDOT_PROVIDERStoDNS_UPSTREAM_RESOLVERSDOT_PRIVATE_ADDRESStoDNS_PRIVATE_ADDRESSESDOT_CACHINGtoDNS_CACHINGDOT_IPV6toDNS_UPSTREAM_IPV6DOT_PRIVATE_ADDRESSsplit intoDNS_BLOCK_IPSandDNS_BLOCK_IP_PREFIXESUNBLOCKwithDNS_UNBLOCK_HOSTNAMES
- clear
DNS_BLOCK_IP_PREFIXESvalues since DNS rebinding protection is built-in the filter middleware - internal/vpn: rename
openvpn*tovpn*variables - internal/configuration/settings:
- merge DoT settings with DNS settings
- remove unneeded Health struct fields
internal/storage:- do not read/write to user file when updating in maintainer mode
- ignore persisted servers data with a timestamp in the future
internal/publicip/api/ip2location: rename countries to match standard country names from the mappingconstants.CountryCodes()`
- Change DNS option names with retro-compatibility:
- dependencies
- bump Go from 1.23 to 1.25
- bump github.com/breml/rootcerts from 0.2.19 to 0.3.3 (#2683, #2964)
- bump github.com/klauspost/compress from 1.17.11 to 1.18.1 (#2957)
- bump github.com/pelletier/go-toml/v2 from 2.2.3 to 2.2.4 (#2958)
- bump github.com/qdm12/dns from v2.0.0-rc8 to v2.0.0-rc10
- bump github.com/stretchr/testify from 1.10.0 to 1.11.1 (#2959)
- bump github.com/ulikunitz/xz from 0.5.11 to 0.5.15 (#2955)
- bump github.com/vishvananda/netlink from 1.2.1 to 1.3.1 (#2932)
- bump golang.org/x/crypto from 0.29.0 to 0.45.0 (#2619, #2999)
- bump golang.org/x/net from 0.31.0 to 0.47.0 (#2648, #2937, #2976)
- bump golang.org/x/sys from 0.29.0 to 0.38.0 (#2939, #2973)
- bump golang.org/x/text from 0.21.0 to 0.31.0 (#2938, #2975)
- upgrade linter to v2.4.0
- migrate configuration file
- fix existing code issues
- add exclusion rules
- update linter names
- CI
- run container and wait for it to connect for both Mullvad and ProtonVPN (#2956)
- bump github actions and use go.mod Go version (#2880)
- pull container images at build time from ghcr.io when possible
- reduce silly image pull rate limiting from docker hub registry
- still rely on docker hub registry to pull golang and alpine images since these are not on ghcr.io
- ignore .github/pull_request_template.md with markdown linter
- consider 429 as valid status code for markdown links
- bump actions/setup-go from 5 to 6 (#2929)
- bump actions/checkout from 5 to 6 (#3001)
- bump DavidAnson/markdownlint-cli2-action from 18 to 21 (#2632, #2984)
- bump github/codeql-action from 3 to 4 (#2935)
- bump peter-evans/create-or-update-comment from 4 to 5 (#2931)
- dev setup
- upgrade dev container to v0.21
- convert .vscode/launch.json to tasks.json
- add vscode
git remote addtask
The ranting section
🥀 this is a new section in which I'll share my rant among various Gluetun-related things 🌻 💁 expect a lot of uppercasing, heavy punctuation and no structure whatsoever. Enjoy the read ❗
ALPINE!!! STOP BREAKING IPTABLES ON EVERY TWO RELEASES! When I enter iptables -nL, -n means NUMERIC! Then why the hell did 0 become all on Alpine 3.22??!!!?!
Gluetun was configured like cl...
v3.40.4
Fixes
- DNS:
- prevent restart crash if
DOT=offandDNS_KEEP_NAMESERVER=off - retry on next period the blocklists update after a failed update
- prevent restart crash if
WIREGUARD_ENDPOINT_IPoverrides the IP address correctly (regression introduced in v3.39.0)- ExpressVPN hardcoded servers data updated (#2888 - huge thanks to the manual work of @Lobstrosity)
- PureVPN OpenVPN configuration updated (from #2991, credits to @mlapaj)
- SlickVPN updater: only keep 11 servers hardcoded and drop website scraping code
- VPNSecure updater fixed, with region and city data allowed to be set to
N / A - VPN Unlimited updater: no longer valid hardcoded hosts removed
v3.40.3
v3.40.2
Fixes
- DNS: fix
DNS_KEEP_NAMESERVERbehavior- no longer hangs the code when establishing the VPN connection
- no longer makes Gluetun panic when exiting
- ProtonVPN:
- updater authentication fixed for some accounts
- If updating servers data periodically, use
UPDATER_PROTONVPN_EMAILinstead ofUPDATER_PROTONVPN_USERNAME(retrocompatibility maintained) - If using the CLI, use
-proton-emailinstead of-proton-username(retrocompatibility maintained)
- If updating servers data periodically, use
- ProtonVPN servers data updated to include paid servers
- updater authentication fixed for some accounts
- Servers storage: do not crash the container but log a warning if flushing merged servers to file fails
v3.40.1
Bug-fix-only release on top of v3.40.0.
v3.41.0 coming soon 🎉 If you have any issues with v3.40.0 please report it rather soon please 🙏 !
Fixes
- Wireguard: specify IP family for new route (#2629)
PUBLICIP_ENABLEDis now respected- Port forwarding: clear port file instead of removing it (see why)
- Control server: log out full URL path not just bottom request URI
- cli
openvpnconfigcommand no longer panics due to missingSetDefaultscall - Providers specific:
PS: sorry for the double notification, CI failed on the first release try
v3.40.0
Happy holidays release time 🎄 🎅 🎁
💁 If anything doesn't work compared to previous release, please create an issue and revert to using v3.39.1 😉
ℹ️ Life is pretty busy all around currently (moving soon, new job, ill parent) so I might be even slower than usual until summer 2025, I'll do my best!
Features
- VPN: run
WaitForDNSbefore querying the public ip address (partly address #2325) - DNS: replace unbound with qdm12/dns@v2.0.0-rc8 (#1742 & later commits)
- Faster start up
- Clearer error messages
- Allow for more Gluetun-specific customization
- Port forwarding:
VPN_PORT_FORWARDING_UP_COMMANDoption (#2399)VPN_PORT_FORWARDING_DOWN_COMMANDoption
- Config allow irrelevant server filters to be set (see #2337)
- Disallow setting a server filter when there is no choice available
- Allow setting an invalid server filter when there is at least one choice available
- Log at warn level when an invalid server filter is set
- Firewall: support custom ICMP rules
- Healthcheck:
- log out last error when auto healing VPN
- run TLS handshake after TCP dial if address has 443 port
- Public IP:
- retry fetching information when
connection refusederror is encountered (partly address #2325) - support custom API url
echoip#https://...(#2529) - resilient public ip fetcher with backup sources (#2518)
- add
ifconfigcooption andcloudflareoption (#2502) PUBLICIP_ENABLEDreplacesPUBLICIP_PERIODPUBLICIP_ENABLED(on, off) can be set to enable or not public ip data fetching on VPN connectionPUBLICIP_PERIOD=0still works to indicate to disable public ip fetchingPUBLICIP_PERIOD!= 0 means to enable public ip fetching- Warnings logged when using
PUBLICIP_PERIOD
- retry fetching information when
STORAGE_FILEPATHoption (#2416)STORAGE_FILEPATH=disables storing to and reading from a local servers.json fileSTORAGE_FILEPATHdefaults to/gluetun/servers.json
- Netlink: debug rule logs contain the ip family
internal/tun: mention in 'operation not permitted' error the user should specify--device /dev/net/tun(resolves #2606)- Control server role based authentication system (#2434) (part of v3.39.1 as a bugfix)
- Parse toml configuration file, see https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication
- Retro-compatible with existing AND documented routes, until after this release
- Log a warning if an unprotected-by-default route is accessed unprotected
- Authentication methods: none, apikey, basic
genkeycommand to generate API keys
- FastestVPN: add
aes-256-gcmto OpenVPN ciphers list - Private Internet Access updater: use v6 API to get servers data
- IPVanish: update servers data
- PrivateVPN: native port forwarding support (#2285)
- Privado: update servers data
format-serverscommand supports the json format option
Fixes
- Wireguard: change default
WIREGUARD_MTUfrom1400to1320(partially address #2533) - OpenVPN: set default mssfix to 1320 for all providers with no default already set (partially address #2533)
- Control server: fix logged wiki authentication section link
- Firewall:
- iptables list uses
-nflag for testing iptables path (#2574) - deduplicate VPN address accept rule for multiple default routes with the same network interface
- deduplicate ipv6 multicast output accept rules
- ipv6 multicast output address value fixed
- log warning if ipv6 nat filter is not supported instead of returning an error (allow to port forward redirect for IPv4 and not IPv6 if IPv6 NAT is not supported and fixed #2503)
- iptables list uses
- Wireguard:
- Point to Kubernetes wiki page when encountering IP rule add file exists error (#2526)
- IPVanish:
- fix openvpn configuration by updating CA value and add
comp-lzooption - update openvpn zip file url for updater
- fix openvpn configuration by updating CA value and add
- Perfect Privacy: update openvpn expired certificates (#2542)
- Public IP: lock settings during entire update to prevent race conditions
Documentation
- Dockerfile
- add missing
OPENVPN_MSSFIXenvironment variable - add missing option definitions
STREAM_ONLYFREE_ONLY
- Document
PORT_FORWARD_ONLYis for both PIA and ProtonVPN
- add missing
Maintenance
Code quality
- Remove github.com/qdm12/golibs dependency
- Implement friendly duration formatting locally
- implement
github.com/qdm12/golibs/commandlocally (#2418)
internal/natpmp: fix determinism for testTest_Client_ExternalAddress- let system handle OS signals after first one to request a program stop
internal/routing: remove redundantrule ip rulein error messagesinternal/netlinkdebug log ip rule commands in netlink instead of routing packageinternal/server: move log middleware tointernal/server/middlewares/log- use
gofumptfor code formatting - Fix gopls govet errors
- Upgrade linter from v1.56.2 to v1.61.0
- Remove no longer needed exclude rules
- Add new exclude rules for printf govet errors
- Remove deprecated linters
execinqueryandexportloopref - Rename linter
goerr113toerr113andgomndtomnd - Add new linters and update codebase:
canonicalheader,copyloopvar,fatcontext,intrange
Dependencies
- Upgrade Go from 1.22 to 1.23
- Bump vishvananda/netlink from v1.2.1-beta.2 to v1.2.1
- Bump github.com/qdm12/gosettings from v0.4.3 to v0.4.4
- Better support for quote expressions especially for commands such as
VPN_PORT_FORWARDING_UP_COMMAND
- Better support for quote expressions especially for commands such as
- Bump github.com/breml/rootcerts from 0.2.18 to 0.2.19 (#2601)
- Bump golang.org/x/net from 0.25.0 to 0.31.0 (#2401, #2578)
- Bump golang.org/x/sys from 0.260.0 to 0.27.0 (#2404, #2573)
- Bump golang.org/x/text from 0.15.0 to 0.17.0 (#2400)
- Bump github.com/klauspost/compress from 1.17.8 to 1.17.11 (#2319, #2550)
- Bump github.com/pelletier/go-toml/v2 from 2.2.2 to 2.2.3 (#2549)
- Bump google.golang.org/protobuf from 1.30.0 to 1.33.0 (#2428)
- Bump github.com/stretchr/testify from 1.9.0 to 1.10.0 (#2600)
CI
- Linting: remove
canonicalheadersince it's not reliable - Use
--device /dev/net/tunfor test container - Bump DavidAnson/markdownlint-cli2-action from 16 to 18 (#2588)
- Bump docker/build-push-action from 5 to 6 (#2324)
Development setup
- dev container
- pin godevcontainer image to tag
:v0.20-alpine - drop requirement for docker-compose and use
devcontainer.jsonsettings directly - readme update
- remove Windows without WSL step
- update 'remote containers extension' to 'dev containers extension'
- remove invalid warning on directories creation
- simplify customizations section
- remove "publish a port" since it can be done at runtime now
- remove "run other services" since it's rather unneeded in this case
- expand documentation on custom welcome script and where to specify the bind mount
- use bullet points instead of subsections headings
- pin godevcontainer image to tag
- Github labels
- change "config problem" to "user error"
- add "performance", "investigation", "servers storage" and "nearly resolved" categories
v3.39.1
🎥 https://youtu.be/O09rP1DlcFU?si=qPdzWUWnzciNxAc7
Fixes
- Firewall: delete chain rules by line number (#2411)
- Control server: require authentication for vulnerable routes (#2434)
- NordVPN: remove commas from region values
- IVPN: split city into city and region
- Fix bad city values containing a comma
- update ivpn servers data
- Private Internet Access: support port forwarding using custom Wireguard (#2420)
- ProtonVPN: prevent using FREE_ONLY and PORT_FORWARD_ONLY together (see #2470)
internal/storage: add missing selection fields to buildnoServerFoundError(see #2470)