change(openvpn): Openvpn 2.4 no longer supported
This commit is contained in:
@@ -200,10 +200,6 @@ EXPOSE 8000/tcp 8888/tcp 8388/tcp 8388/udp
|
|||||||
HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /gluetun-entrypoint healthcheck
|
HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /gluetun-entrypoint healthcheck
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
RUN apk add --no-cache --update -l wget && \
|
RUN apk add --no-cache --update -l wget && \
|
||||||
apk add --no-cache --update -X "https://dl-cdn.alpinelinux.org/alpine/v3.12/main" openvpn==2.4.12-r0 && \
|
|
||||||
apk add --no-cache --update -X "https://dl-cdn.alpinelinux.org/alpine/v3.16/main" openssl\~1.1 && \
|
|
||||||
mv /usr/sbin/openvpn /usr/sbin/openvpn2.4 && \
|
|
||||||
apk del openvpn && \
|
|
||||||
apk add --no-cache --update openvpn ca-certificates iptables ip6tables unbound tzdata && \
|
apk add --no-cache --update openvpn ca-certificates iptables ip6tables unbound tzdata && \
|
||||||
mv /usr/sbin/openvpn /usr/sbin/openvpn2.5 && \
|
mv /usr/sbin/openvpn /usr/sbin/openvpn2.5 && \
|
||||||
# Fix vulnerability issue
|
# Fix vulnerability issue
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
|
|||||||
|
|
||||||
## Quick links
|
## Quick links
|
||||||
|
|
||||||
- [Setup](#Setup)
|
- [Setup](#setup)
|
||||||
- [Features](#Features)
|
- [Features](#features)
|
||||||
- Problem?
|
- Problem?
|
||||||
- [Check the Wiki](https://github.com/qdm12/gluetun/wiki)
|
- [Check the Wiki](https://github.com/qdm12/gluetun/wiki)
|
||||||
- [Start a discussion](https://github.com/qdm12/gluetun/discussions)
|
- [Start a discussion](https://github.com/qdm12/gluetun/discussions)
|
||||||
@@ -57,7 +57,7 @@ Lightweight swiss-knife-like VPN client to multiple VPN service providers
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Based on Alpine 3.17 for a small Docker image of 42MB
|
- Based on Alpine 3.17 for a small Docker image of 39.1MB
|
||||||
- Supports: **AirVPN**, **Cyberghost**, **ExpressVPN**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Perfect Privacy**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **SlickVPN**, **Surfshark**, **TorGuard**, **VPNSecure.me**, **VPNUnlimited**, **Vyprvpn**, **WeVPN**, **Windscribe** servers
|
- Supports: **AirVPN**, **Cyberghost**, **ExpressVPN**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Perfect Privacy**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **SlickVPN**, **Surfshark**, **TorGuard**, **VPNSecure.me**, **VPNUnlimited**, **Vyprvpn**, **WeVPN**, **Windscribe** servers
|
||||||
- Supports OpenVPN for all providers listed
|
- Supports OpenVPN for all providers listed
|
||||||
- Supports Wireguard both kernelspace and userspace
|
- Supports Wireguard both kernelspace and userspace
|
||||||
|
|||||||
@@ -264,7 +264,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
|
|
||||||
err = printVersions(ctx, logger, []printVersionElement{
|
err = printVersions(ctx, logger, []printVersionElement{
|
||||||
{name: "Alpine", getVersion: alpineConf.Version},
|
{name: "Alpine", getVersion: alpineConf.Version},
|
||||||
{name: "OpenVPN 2.4", getVersion: ovpnConf.Version24},
|
|
||||||
{name: "OpenVPN 2.5", getVersion: ovpnConf.Version25},
|
{name: "OpenVPN 2.5", getVersion: ovpnConf.Version25},
|
||||||
{name: "Unbound", getVersion: dnsConf.Version},
|
{name: "Unbound", getVersion: dnsConf.Version},
|
||||||
{name: "IPtables", getVersion: func(ctx context.Context) (version string, err error) {
|
{name: "IPtables", getVersion: func(ctx context.Context) (version string, err error) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
// OpenVPN contains settings to configure the OpenVPN client.
|
// OpenVPN contains settings to configure the OpenVPN client.
|
||||||
type OpenVPN struct {
|
type OpenVPN struct {
|
||||||
// Version is the OpenVPN version to run.
|
// Version is the OpenVPN version to run.
|
||||||
// It can only be "2.4" or "2.5".
|
// It can only be "2.5".
|
||||||
Version string
|
Version string
|
||||||
// User is the OpenVPN authentication username.
|
// User is the OpenVPN authentication username.
|
||||||
// It cannot be nil in the internal state if OpenVPN is used.
|
// It cannot be nil in the internal state if OpenVPN is used.
|
||||||
@@ -88,7 +88,7 @@ var ivpnAccountID = regexp.MustCompile(`^(i|ivpn)\-[a-zA-Z0-9]{4}\-[a-zA-Z0-9]{4
|
|||||||
|
|
||||||
func (o OpenVPN) validate(vpnProvider string) (err error) {
|
func (o OpenVPN) validate(vpnProvider string) (err error) {
|
||||||
// Validate version
|
// Validate version
|
||||||
validVersions := []string{openvpn.Openvpn24, openvpn.Openvpn25}
|
validVersions := []string{openvpn.Openvpn25}
|
||||||
if !helpers.IsOneOf(o.Version, validVersions...) {
|
if !helpers.IsOneOf(o.Version, validVersions...) {
|
||||||
return fmt.Errorf("%w: %q can only be one of %s",
|
return fmt.Errorf("%w: %q can only be one of %s",
|
||||||
ErrOpenVPNVersionIsNotValid, o.Version, strings.Join(validVersions, ", "))
|
ErrOpenVPNVersionIsNotValid, o.Version, strings.Join(validVersions, ", "))
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||||
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/providers"
|
"github.com/qdm12/gluetun/internal/constants/providers"
|
||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
@@ -170,13 +169,6 @@ func (s Settings) Warnings() (warnings []string) {
|
|||||||
|
|
||||||
if helpers.IsOneOf(*s.VPN.Provider.Name, providers.SlickVPN) &&
|
if helpers.IsOneOf(*s.VPN.Provider.Name, providers.SlickVPN) &&
|
||||||
s.VPN.Type == vpn.OpenVPN {
|
s.VPN.Type == vpn.OpenVPN {
|
||||||
if s.VPN.OpenVPN.Version == openvpn.Openvpn24 {
|
|
||||||
warnings = append(warnings, "OpenVPN 2.4 uses OpenSSL 1.1.1 "+
|
|
||||||
"which allows the usage of weak security in today's standards. "+
|
|
||||||
"This can be ok if good security is enforced by the VPN provider. "+
|
|
||||||
"However, "+*s.VPN.Provider.Name+" uses weak security so you should use "+
|
|
||||||
"OpenVPN 2.5 to enforce good security practices.")
|
|
||||||
} else {
|
|
||||||
warnings = append(warnings, "OpenVPN 2.5 uses OpenSSL 3 "+
|
warnings = append(warnings, "OpenVPN 2.5 uses OpenSSL 3 "+
|
||||||
"which prohibits the usage of weak security in today's standards. "+
|
"which prohibits the usage of weak security in today's standards. "+
|
||||||
*s.VPN.Provider.Name+" uses weak security which is out "+
|
*s.VPN.Provider.Name+" uses weak security which is out "+
|
||||||
@@ -186,12 +178,6 @@ func (s Settings) Warnings() (warnings []string) {
|
|||||||
"Once this is done, you will have to let the Gluetun maintainers know "+
|
"Once this is done, you will have to let the Gluetun maintainers know "+
|
||||||
"by creating an issue, attaching the new certificate and we will update Gluetun.")
|
"by creating an issue, attaching the new certificate and we will update Gluetun.")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if s.VPN.OpenVPN.Version == openvpn.Openvpn24 {
|
|
||||||
warnings = append(warnings, "OpenVPN 2.4 will be removed in release v3.34.0 (around June 2023). "+
|
|
||||||
"Please create an issue if you have a compelling reason to keep it.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return warnings
|
return warnings
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package openvpn
|
package openvpn
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Openvpn24 = "2.4"
|
|
||||||
Openvpn25 = "2.5"
|
Openvpn25 = "2.5"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
var ErrVersionUnknown = errors.New("OpenVPN version is unknown")
|
var ErrVersionUnknown = errors.New("OpenVPN version is unknown")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
binOpenvpn24 = "openvpn2.4"
|
|
||||||
binOpenvpn25 = "openvpn2.5"
|
binOpenvpn25 = "openvpn2.5"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,8 +21,6 @@ func start(ctx context.Context, starter command.Starter, version string, flags [
|
|||||||
stdoutLines, stderrLines chan string, waitError chan error, err error) {
|
stdoutLines, stderrLines chan string, waitError chan error, err error) {
|
||||||
var bin string
|
var bin string
|
||||||
switch version {
|
switch version {
|
||||||
case openvpn.Openvpn24:
|
|
||||||
bin = binOpenvpn24
|
|
||||||
case openvpn.Openvpn25:
|
case openvpn.Openvpn25:
|
||||||
bin = binOpenvpn25
|
bin = binOpenvpn25
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Configurator) Version24(ctx context.Context) (version string, err error) {
|
|
||||||
return c.version(ctx, binOpenvpn24)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configurator) Version25(ctx context.Context) (version string, err error) {
|
func (c *Configurator) Version25(ctx context.Context) (version string, err error) {
|
||||||
return c.version(ctx, binOpenvpn25)
|
return c.version(ctx, binOpenvpn25)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch settings.Version {
|
switch settings.Version {
|
||||||
case openvpn.Openvpn24:
|
|
||||||
providerSettings.Ciphers = []string{openvpn.AES256cbc}
|
|
||||||
case openvpn.Openvpn25:
|
case openvpn.Openvpn25:
|
||||||
providerSettings.Ciphers = []string{
|
providerSettings.Ciphers = []string{
|
||||||
openvpn.AES256gcm, openvpn.AES256cbc, openvpn.AES192gcm,
|
openvpn.AES256gcm, openvpn.AES256cbc, openvpn.AES192gcm,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func modifyConfig(lines []string, connection models.Connection,
|
|||||||
}
|
}
|
||||||
modified = append(modified, "verb "+strconv.Itoa(*settings.Verbosity))
|
modified = append(modified, "verb "+strconv.Itoa(*settings.Verbosity))
|
||||||
if len(settings.Ciphers) > 0 {
|
if len(settings.Ciphers) > 0 {
|
||||||
modified = append(modified, utils.CipherLines(settings.Ciphers, settings.Version)...)
|
modified = append(modified, utils.CipherLines(settings.Ciphers)...)
|
||||||
}
|
}
|
||||||
if *settings.Auth != "" {
|
if *settings.Auth != "" {
|
||||||
modified = append(modified, "auth "+*settings.Auth)
|
modified = append(modified, "auth "+*settings.Auth)
|
||||||
|
|||||||
@@ -28,13 +28,11 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.Version == openvpn.Openvpn25 {
|
|
||||||
// SlickVPN's certificate is sha1WithRSAEncryption and sha1 is now
|
// SlickVPN's certificate is sha1WithRSAEncryption and sha1 is now
|
||||||
// rejected by openssl 3.x.x which is used by OpenVPN >= 2.5.
|
// rejected by openssl 3.x.x which is used by OpenVPN >= 2.5.
|
||||||
// We lower the security level to 3 to allow this algorithm,
|
// We lower the security level to 3 to allow this algorithm,
|
||||||
// see https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
|
// see https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
|
||||||
providerSettings.TLSCipher = "DEFAULT:@SECLEVEL=0"
|
providerSettings.TLSCipher = "DEFAULT:@SECLEVEL=0"
|
||||||
}
|
|
||||||
|
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,15 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func CipherLines(ciphers []string, version string) (lines []string) {
|
func CipherLines(ciphers []string) (lines []string) {
|
||||||
if len(ciphers) == 0 {
|
if len(ciphers) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch version {
|
|
||||||
case openvpn.Openvpn24:
|
|
||||||
return []string{
|
|
||||||
"cipher " + ciphers[0],
|
|
||||||
"ncp-ciphers " + strings.Join(ciphers, ":"),
|
|
||||||
}
|
|
||||||
default: // 2.5 and above
|
|
||||||
return []string{
|
return []string{
|
||||||
"data-ciphers-fallback " + ciphers[0],
|
"data-ciphers-fallback " + ciphers[0],
|
||||||
"data-ciphers " + strings.Join(ciphers, ":"),
|
"data-ciphers " + strings.Join(ciphers, ":"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,14 +20,6 @@ func Test_CipherLines(t *testing.T) {
|
|||||||
"data-ciphers AES",
|
"data-ciphers AES",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"2.4": {
|
|
||||||
ciphers: []string{"AES", "CBC"},
|
|
||||||
version: "2.4",
|
|
||||||
lines: []string{
|
|
||||||
"cipher AES",
|
|
||||||
"ncp-ciphers AES:CBC",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"2.5": {
|
"2.5": {
|
||||||
ciphers: []string{"AES", "CBC"},
|
ciphers: []string{"AES", "CBC"},
|
||||||
version: "2.5",
|
version: "2.5",
|
||||||
@@ -42,7 +34,7 @@ func Test_CipherLines(t *testing.T) {
|
|||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
lines := CipherLines(testCase.ciphers, testCase.version)
|
lines := CipherLines(testCase.ciphers)
|
||||||
|
|
||||||
assert.Equal(t, testCase.lines, lines)
|
assert.Equal(t, testCase.lines, lines)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ func OpenVPNConfig(provider OpenVPNProviderSettings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ciphers := defaultStringSlice(settings.Ciphers, provider.Ciphers)
|
ciphers := defaultStringSlice(settings.Ciphers, provider.Ciphers)
|
||||||
cipherLines := CipherLines(ciphers, settings.Version)
|
cipherLines := CipherLines(ciphers)
|
||||||
lines.addLines(cipherLines)
|
lines.addLines(cipherLines)
|
||||||
|
|
||||||
auth := defaultString(*settings.Auth, provider.Auth)
|
auth := defaultString(*settings.Auth, provider.Auth)
|
||||||
@@ -198,7 +198,6 @@ func OpenVPNConfig(provider OpenVPNProviderSettings,
|
|||||||
|
|
||||||
if *settings.EncryptedKey != "" {
|
if *settings.EncryptedKey != "" {
|
||||||
encryptedBase64DERKey := *settings.EncryptedKey
|
encryptedBase64DERKey := *settings.EncryptedKey
|
||||||
if settings.Version != openvpn.Openvpn24 {
|
|
||||||
// OpenVPN above 2.4 does not support old encryption schemes such as
|
// OpenVPN above 2.4 does not support old encryption schemes such as
|
||||||
// DES-CBC, so decrypt and reencrypt the key.
|
// DES-CBC, so decrypt and reencrypt the key.
|
||||||
// This is a workaround for VPN secure.
|
// This is a workaround for VPN secure.
|
||||||
@@ -208,7 +207,6 @@ func OpenVPNConfig(provider OpenVPNProviderSettings,
|
|||||||
// TODO return an error instead.
|
// TODO return an error instead.
|
||||||
panic(fmt.Sprintf("upgrading encrypted key: %s", err))
|
panic(fmt.Sprintf("upgrading encrypted key: %s", err))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
lines.add("askpass", openvpn.AskPassPath)
|
lines.add("askpass", openvpn.AskPassPath)
|
||||||
lines.addLines(WrapOpenvpnEncryptedKey(encryptedBase64DERKey))
|
lines.addLines(WrapOpenvpnEncryptedKey(encryptedBase64DERKey))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package vpnunlimited
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||||
)
|
)
|
||||||
@@ -20,13 +19,11 @@ func (p *Provider) OpenVPNConfig(connection models.Connection,
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.Version != openvpn.Openvpn24 {
|
|
||||||
// VPN Unlimited's certificate is sha1WithRSAEncryption and sha1 is now
|
// VPN Unlimited's certificate is sha1WithRSAEncryption and sha1 is now
|
||||||
// rejected by openssl 3.x.x which is used by OpenVPN >= 2.5.
|
// rejected by openssl 3.x.x which is used by OpenVPN >= 2.5.
|
||||||
// We lower the security level to 0 to allow this algorithm,
|
// We lower the security level to 0 to allow this algorithm,
|
||||||
// see https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
|
// see https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html
|
||||||
providerSettings.TLSCipher = `"DEFAULT:@SECLEVEL=0"`
|
providerSettings.TLSCipher = `"DEFAULT:@SECLEVEL=0"`
|
||||||
}
|
|
||||||
|
|
||||||
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
return utils.OpenVPNConfig(providerSettings, connection, settings, ipv6Supported)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user