Feature: OPENVPN_VERSION which can be 2.4 or 2.5

This commit is contained in:
Quentin McGaw (desktop)
2021-05-31 18:54:36 +00:00
parent 7002bf8e34
commit b829490aac
12 changed files with 71 additions and 23 deletions

View File

@@ -65,6 +65,7 @@ LABEL \
ENV VPNSP=pia \ ENV VPNSP=pia \
VERSION_INFORMATION=on \ VERSION_INFORMATION=on \
PROTOCOL=udp \ PROTOCOL=udp \
OPENVPN_VERSION=2.5 \
OPENVPN_VERBOSITY=1 \ OPENVPN_VERBOSITY=1 \
OPENVPN_ROOT=yes \ OPENVPN_ROOT=yes \
OPENVPN_TARGET_IP= \ OPENVPN_TARGET_IP= \
@@ -145,7 +146,10 @@ ENV VPNSP=pia \
ENTRYPOINT ["/entrypoint"] ENTRYPOINT ["/entrypoint"]
EXPOSE 8000/tcp 8888/tcp 8388/tcp 8388/udp EXPOSE 8000/tcp 8888/tcp 8388/tcp 8388/udp
HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /entrypoint healthcheck HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /entrypoint healthcheck
RUN apk add -q --progress --no-cache --update openvpn ca-certificates iptables ip6tables unbound tzdata && \ RUN apk add --no-cache --update -X "https://dl-cdn.alpinelinux.org/alpine/v3.12/main" openvpn==2.4.11-r0 && \
mv /usr/sbin/openvpn /usr/sbin/openvpn2.4 && \
apk del openvpn && \
apk add --no-cache --update openvpn ca-certificates iptables ip6tables unbound tzdata && \
rm -rf /var/cache/apk/* /etc/unbound/* /usr/sbin/unbound-* /etc/openvpn/*.sh /usr/lib/openvpn/plugins/openvpn-plugin-down-root.so && \ rm -rf /var/cache/apk/* /etc/unbound/* /usr/sbin/unbound-* /etc/openvpn/*.sh /usr/lib/openvpn/plugins/openvpn-plugin-down-root.so && \
deluser openvpn && \ deluser openvpn && \
deluser unbound && \ deluser unbound && \

View File

@@ -38,7 +38,7 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
## Features ## Features
- Based on Alpine 3.13 for a small Docker image of 52MB - Based on Alpine 3.13 for a small Docker image of 54MB
- Supports: **Cyberghost**, **FastestVPN**, **HideMyAss**, **IVPN**, **Mullvad**, **NordVPN**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **Surfshark**, **TorGuard**, **Vyprvpn**, **Windscribe** servers - Supports: **Cyberghost**, **FastestVPN**, **HideMyAss**, **IVPN**, **Mullvad**, **NordVPN**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **Surfshark**, **TorGuard**, **Vyprvpn**, **Windscribe** servers
- Supports Openvpn only for now - Supports Openvpn only for now
- DNS over TLS baked in with service provider(s) of your choice - DNS over TLS baked in with service provider(s) of your choice

View File

@@ -150,7 +150,8 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
if err := printVersions(ctx, logger, []printVersionElement{ if err := printVersions(ctx, logger, []printVersionElement{
{name: "Alpine", getVersion: alpineConf.Version}, {name: "Alpine", getVersion: alpineConf.Version},
{name: "OpenVPN", getVersion: ovpnConf.Version}, {name: "OpenVPN 2.4", getVersion: ovpnConf.Version24},
{name: "OpenVPN 2.5", getVersion: ovpnConf.Version25},
{name: "Unbound", getVersion: dnsConf.Version}, {name: "Unbound", getVersion: dnsConf.Version},
{name: "IPtables", getVersion: firewallConf.Version}, {name: "IPtables", getVersion: firewallConf.Version},
}); err != nil { }); err != nil {
@@ -165,8 +166,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
} }
logger.Info(allSettings.String()) logger.Info(allSettings.String())
allSettings.OpenVPN.Version, _ = ovpnConf.Version(ctx)
if err := os.MkdirAll("/tmp/gluetun", 0644); err != nil { if err := os.MkdirAll("/tmp/gluetun", 0644); err != nil {
return err return err
} }

View File

@@ -21,7 +21,7 @@ type OpenVPN struct {
Auth string `json:"auth"` Auth string `json:"auth"`
Provider Provider `json:"provider"` Provider Provider `json:"provider"`
Config string `json:"custom_config"` Config string `json:"custom_config"`
Version string `json:"-"` // injected at runtime Version string `json:"version"`
} }
func (settings *OpenVPN) String() string { func (settings *OpenVPN) String() string {
@@ -31,6 +31,8 @@ func (settings *OpenVPN) String() string {
func (settings *OpenVPN) lines() (lines []string) { func (settings *OpenVPN) lines() (lines []string) {
lines = append(lines, lastIndent+"OpenVPN:") lines = append(lines, lastIndent+"OpenVPN:")
lines = append(lines, indent+lastIndent+"Version: "+settings.Version)
lines = append(lines, indent+lastIndent+"Verbosity level: "+strconv.Itoa(settings.Verbosity)) lines = append(lines, indent+lastIndent+"Verbosity level: "+strconv.Itoa(settings.Verbosity))
if settings.Root { if settings.Root {
@@ -98,6 +100,12 @@ func (settings *OpenVPN) read(r reader) (err error) {
} }
} }
settings.Version, err = r.env.Inside("OPENVPN_VERSION",
[]string{constants.Openvpn24, constants.Openvpn25}, params.Default(constants.Openvpn25))
if err != nil {
return err
}
settings.Verbosity, err = r.env.IntRange("OPENVPN_VERBOSITY", 0, 6, params.Default("1")) settings.Verbosity, err = r.env.IntRange("OPENVPN_VERBOSITY", 0, 6, params.Default("1"))
if err != nil { if err != nil {
return err return err

View File

@@ -52,7 +52,8 @@ func Test_OpenVPN_JSON(t *testing.T) {
"filepath": "" "filepath": ""
} }
}, },
"custom_config": "" "custom_config": "",
"version": ""
}`, string(data)) }`, string(data))
var out OpenVPN var out OpenVPN
err = json.Unmarshal(data, &out) err = json.Unmarshal(data, &out)

View File

@@ -17,6 +17,7 @@ func Test_Settings_lines(t *testing.T) {
"default settings": { "default settings": {
settings: Settings{ settings: Settings{
OpenVPN: OpenVPN{ OpenVPN: OpenVPN{
Version: constants.Openvpn25,
Provider: Provider{ Provider: Provider{
Name: constants.Mullvad, Name: constants.Mullvad,
}, },
@@ -25,6 +26,7 @@ func Test_Settings_lines(t *testing.T) {
lines: []string{ lines: []string{
"Settings summary below:", "Settings summary below:",
"|--OpenVPN:", "|--OpenVPN:",
" |--Version: 2.5",
" |--Verbosity level: 0", " |--Verbosity level: 0",
" |--Provider:", " |--Provider:",
" |--Mullvad settings:", " |--Mullvad settings:",

View File

@@ -14,3 +14,8 @@ const (
SHA256 = "sha256" SHA256 = "sha256"
SHA512 = "sha512" SHA512 = "sha512"
) )
const (
Openvpn24 = "2.4"
Openvpn25 = "2.5"
)

View File

@@ -9,16 +9,42 @@ import (
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
) )
func (c *configurator) Start(ctx context.Context) ( var ErrVersionUnknown = errors.New("OpenVPN version is unknown")
const (
binOpenvpn24 = "openvpn2.4"
binOpenvpn25 = "openvpn"
)
func (c *configurator) Start(ctx context.Context, version string) (
stdoutLines, stderrLines chan string, waitError chan error, err error) { stdoutLines, stderrLines chan string, waitError chan error, err error) {
c.logger.Info("starting openvpn") var bin string
return c.commander.Start(ctx, "openvpn", "--config", constants.OpenVPNConf) switch version {
case constants.Openvpn24:
bin = binOpenvpn24
case constants.Openvpn25:
bin = binOpenvpn25
default:
return nil, nil, nil, fmt.Errorf("%w: %s", ErrVersionUnknown, version)
}
c.logger.Info("starting OpenVPN " + version)
return c.commander.Start(ctx, bin, "--config", constants.OpenVPNConf)
}
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) {
return c.version(ctx, binOpenvpn25)
} }
var ErrVersionTooShort = errors.New("version output is too short") var ErrVersionTooShort = errors.New("version output is too short")
func (c *configurator) Version(ctx context.Context) (string, error) { func (c *configurator) version(ctx context.Context, binName string) (version string, err error) {
output, err := c.commander.Run(ctx, "openvpn", "--version") output, err := c.commander.Run(ctx, binName, "--version")
if err != nil && err.Error() != "exit status 1" { if err != nil && err.Error() != "exit status 1" {
return "", err return "", err
} }

View File

@@ -157,7 +157,7 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
openvpnCtx, openvpnCancel := context.WithCancel(context.Background()) openvpnCtx, openvpnCancel := context.WithCancel(context.Background())
stdoutLines, stderrLines, waitError, err := l.conf.Start(openvpnCtx) stdoutLines, stderrLines, waitError, err := l.conf.Start(openvpnCtx, settings.Version)
if err != nil { if err != nil {
openvpnCancel() openvpnCancel()
l.signalCrashedStatus() l.signalCrashedStatus()

View File

@@ -12,12 +12,13 @@ import (
) )
type Configurator interface { type Configurator interface {
Version(ctx context.Context) (string, error) Version24(ctx context.Context) (version string, err error)
Version25(ctx context.Context) (version string, err error)
WriteAuthFile(user, password string, puid, pgid int) error WriteAuthFile(user, password string, puid, pgid int) error
CheckTUN() error CheckTUN() error
CreateTUN() error CreateTUN() error
Start(ctx context.Context) (stdoutLines, stderrLines chan string, Start(ctx context.Context, version string) (
waitError chan error, err error) stdoutLines, stderrLines chan string, waitError chan error, err error)
} }
type configurator struct { type configurator struct {

View File

@@ -1,10 +1,12 @@
package utils package utils
import "strings" import (
"github.com/qdm12/gluetun/internal/constants"
)
func CipherLines(cipher, version string) (lines []string) { func CipherLines(cipher, version string) (lines []string) {
switch { switch version {
case strings.HasPrefix(version, "2.4"): case constants.Openvpn24:
return []string{"cipher " + cipher} return []string{"cipher " + cipher}
default: // 2.5 and above default: // 2.5 and above
return []string{ return []string{

View File

@@ -18,12 +18,12 @@ func Test_CipherLines(t *testing.T) {
"data-ciphers AES", "data-ciphers AES",
}, },
}, },
"2.4.5": { "2.4": {
version: "2.4.5", version: "2.4",
lines: []string{"cipher AES"}, lines: []string{"cipher AES"},
}, },
"2.5.3": { "2.5": {
version: "2.5.3", version: "2.5",
lines: []string{ lines: []string{
"data-ciphers-fallback AES", "data-ciphers-fallback AES",
"data-ciphers AES", "data-ciphers AES",