fix(settings): read PEM files but b64 env vars
- Extract base64 data from PEM files and secret files - Environment variables are not PEM encoded and only the base64 data - Affects OpenVPN certificate, key and encrypted key
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package settings
|
package settings
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -193,7 +194,7 @@ func validateOpenVPNClientCertificate(vpnProvider,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = extract.PEM([]byte(clientCert))
|
_, err = base64.StdEncoding.DecodeString(clientCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -215,7 +216,7 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = extract.PEM([]byte(clientKey))
|
_, err = base64.StdEncoding.DecodeString(clientKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -232,9 +233,9 @@ func validateOpenVPNEncryptedKey(vpnProvider,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = extract.PEM([]byte(encryptedPrivateKey))
|
_, err = base64.StdEncoding.DecodeString(encryptedPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("extracting encrypted key: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
10
internal/configuration/sources/env/helpers.go
vendored
10
internal/configuration/sources/env/helpers.go
vendored
@@ -1,7 +1,6 @@
|
|||||||
package env
|
package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -133,15 +132,6 @@ func lowerAndSplit(csv string) (values []string) {
|
|||||||
return strings.Split(csv, ",")
|
return strings.Split(csv, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeBase64(b64String string) (decoded string, err error) {
|
|
||||||
b, err := base64.StdEncoding.DecodeString(b64String)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("cannot decode base64 string %q: %w",
|
|
||||||
b64String, err)
|
|
||||||
}
|
|
||||||
return string(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unsetEnvKeys(envKeys []string, err error) (newErr error) {
|
func unsetEnvKeys(envKeys []string, err error) (newErr error) {
|
||||||
newErr = err
|
newErr = err
|
||||||
for _, envKey := range envKeys {
|
for _, envKey := range envKeys {
|
||||||
|
|||||||
31
internal/configuration/sources/env/openvpn.go
vendored
31
internal/configuration/sources/env/openvpn.go
vendored
@@ -31,20 +31,9 @@ func (r *Reader) readOpenVPN() (
|
|||||||
openVPN.Auth = &auth
|
openVPN.Auth = &auth
|
||||||
}
|
}
|
||||||
|
|
||||||
openVPN.Cert, err = readBase64OrNil("OPENVPN_CERT")
|
openVPN.Cert = envToStringPtr("OPENVPN_CERT")
|
||||||
if err != nil {
|
openVPN.Key = envToStringPtr("OPENVPN_KEY")
|
||||||
return openVPN, fmt.Errorf("environment variable OPENVPN_CERT: %w", err)
|
openVPN.EncryptedKey = envToStringPtr("OPENVPN_ENCRYPTED_KEY")
|
||||||
}
|
|
||||||
|
|
||||||
openVPN.Key, err = readBase64OrNil("OPENVPN_KEY")
|
|
||||||
if err != nil {
|
|
||||||
return openVPN, fmt.Errorf("environment variable OPENVPN_KEY: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPN.EncryptedKey, err = readBase64OrNil("OPENVPN_ENCRYPTED_KEY")
|
|
||||||
if err != nil {
|
|
||||||
return openVPN, fmt.Errorf("environment variable OPENVPN_ENCRYPTED_KEY: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPN.KeyPassphrase = r.readOpenVPNKeyPassphrase()
|
openVPN.KeyPassphrase = r.readOpenVPNKeyPassphrase()
|
||||||
|
|
||||||
@@ -111,20 +100,6 @@ func (r *Reader) readOpenVPNKeyPassphrase() (passphrase *string) {
|
|||||||
return passphrase
|
return passphrase
|
||||||
}
|
}
|
||||||
|
|
||||||
func readBase64OrNil(envKey string) (valueOrNil *string, err error) {
|
|
||||||
value := getCleanedEnv(envKey)
|
|
||||||
if value == "" {
|
|
||||||
return nil, nil //nolint:nilnil
|
|
||||||
}
|
|
||||||
|
|
||||||
decoded, err := decodeBase64(value)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &decoded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reader) readPIAEncryptionPreset() (presetPtr *string) {
|
func (r *Reader) readPIAEncryptionPreset() (presetPtr *string) {
|
||||||
_, preset := r.getEnvWithRetro(
|
_, preset := r.getEnvWithRetro(
|
||||||
"PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET",
|
"PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET",
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package files
|
package files
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadFromFile reads the content of the file as a string.
|
// ReadFromFile reads the content of the file as a string.
|
||||||
@@ -32,3 +35,21 @@ func ReadFromFile(filepath string) (s *string, err error) {
|
|||||||
content = strings.TrimSuffix(content, "\n")
|
content = strings.TrimSuffix(content, "\n")
|
||||||
return &content, nil
|
return &content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readPEMFile(filepath string) (base64Ptr *string, err error) {
|
||||||
|
pemData, err := ReadFromFile(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pemData == nil {
|
||||||
|
return nil, nil //nolint:nilnil
|
||||||
|
}
|
||||||
|
|
||||||
|
base64Data, err := extract.PEM([]byte(*pemData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("extracting base64 encoded data from PEM content: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &base64Data, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,17 +15,16 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) {
|
func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) {
|
||||||
settings.Key, err = ReadFromFile(OpenVPNClientKeyPath)
|
settings.Key, err = readPEMFile(OpenVPNClientKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("client key: %w", err)
|
return settings, fmt.Errorf("client key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Cert, err = ReadFromFile(OpenVPNClientCertificatePath)
|
settings.Cert, err = readPEMFile(OpenVPNClientCertificatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("client certificate: %w", err)
|
return settings, fmt.Errorf("client certificate: %w", err)
|
||||||
}
|
}
|
||||||
|
settings.EncryptedKey, err = readPEMFile(openVPNEncryptedKey)
|
||||||
settings.EncryptedKey, err = ReadFromFile(openVPNEncryptedKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return settings, fmt.Errorf("reading encrypted key file: %w", err)
|
return settings, fmt.Errorf("reading encrypted key file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package secrets
|
package secrets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
||||||
|
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
||||||
)
|
)
|
||||||
|
|
||||||
// getCleanedEnv returns an environment variable value with
|
// getCleanedEnv returns an environment variable value with
|
||||||
@@ -25,3 +27,22 @@ func readSecretFileAsStringPtr(secretPathEnvKey, defaultSecretPath string) (
|
|||||||
}
|
}
|
||||||
return files.ReadFromFile(path)
|
return files.ReadFromFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readPEMSecretFile(secretPathEnvKey, defaultSecretPath string) (
|
||||||
|
base64Ptr *string, err error) {
|
||||||
|
pemData, err := readSecretFileAsStringPtr(secretPathEnvKey, defaultSecretPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading secret file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pemData == nil {
|
||||||
|
return nil, nil //nolint:nilnil
|
||||||
|
}
|
||||||
|
|
||||||
|
base64Data, err := extract.PEM([]byte(*pemData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("extracting base64 encoded data from PEM content: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &base64Data, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func readOpenVPN() (
|
|||||||
return settings, fmt.Errorf("cannot read password file: %w", err)
|
return settings, fmt.Errorf("cannot read password file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Key, err = readSecretFileAsStringPtr(
|
settings.Key, err = readPEMSecretFile(
|
||||||
"OPENVPN_CLIENTKEY_SECRETFILE",
|
"OPENVPN_CLIENTKEY_SECRETFILE",
|
||||||
"/run/secrets/openvpn_clientkey",
|
"/run/secrets/openvpn_clientkey",
|
||||||
)
|
)
|
||||||
@@ -32,7 +32,7 @@ func readOpenVPN() (
|
|||||||
return settings, fmt.Errorf("cannot read client key file: %w", err)
|
return settings, fmt.Errorf("cannot read client key file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.EncryptedKey, err = readSecretFileAsStringPtr(
|
settings.EncryptedKey, err = readPEMSecretFile(
|
||||||
"OPENVPN_ENCRYPTED_KEY_SECRETFILE",
|
"OPENVPN_ENCRYPTED_KEY_SECRETFILE",
|
||||||
"/run/secrets/openvpn_encrypted_key",
|
"/run/secrets/openvpn_encrypted_key",
|
||||||
)
|
)
|
||||||
@@ -48,7 +48,7 @@ func readOpenVPN() (
|
|||||||
return settings, fmt.Errorf("reading key passphrase file: %w", err)
|
return settings, fmt.Errorf("reading key passphrase file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Cert, err = readSecretFileAsStringPtr(
|
settings.Cert, err = readPEMSecretFile(
|
||||||
"OPENVPN_CLIENTCRT_SECRETFILE",
|
"OPENVPN_CLIENTCRT_SECRETFILE",
|
||||||
"/run/secrets/openvpn_clientcrt",
|
"/run/secrets/openvpn_clientcrt",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
"github.com/qdm12/gluetun/internal/constants/openvpn"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OpenVPNProviderSettings struct {
|
type OpenVPNProviderSettings struct {
|
||||||
@@ -191,21 +190,15 @@ func OpenVPNConfig(provider OpenVPNProviderSettings,
|
|||||||
|
|
||||||
if *settings.EncryptedKey != "" {
|
if *settings.EncryptedKey != "" {
|
||||||
lines.add("askpass", openvpn.AskPassPath)
|
lines.add("askpass", openvpn.AskPassPath)
|
||||||
keyData, err := extract.PEM([]byte(*settings.EncryptedKey))
|
lines.addLines(WrapOpenvpnEncryptedKey(*settings.EncryptedKey))
|
||||||
panicOnError(err, "cannot extract PEM encrypted key")
|
|
||||||
lines.addLines(WrapOpenvpnEncryptedKey(keyData))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if *settings.Cert != "" {
|
if *settings.Cert != "" {
|
||||||
certData, err := extract.PEM([]byte(*settings.Cert))
|
lines.addLines(WrapOpenvpnCert(*settings.Cert))
|
||||||
panicOnError(err, "cannot extract OpenVPN certificate")
|
|
||||||
lines.addLines(WrapOpenvpnCert(certData))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if *settings.Key != "" {
|
if *settings.Key != "" {
|
||||||
keyData, err := extract.PEM([]byte(*settings.Key))
|
lines.addLines(WrapOpenvpnKey(*settings.Key))
|
||||||
panicOnError(err, "cannot extract OpenVPN key")
|
|
||||||
lines.addLines(WrapOpenvpnKey(keyData))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.addLines(provider.ExtraLines)
|
lines.addLines(provider.ExtraLines)
|
||||||
@@ -254,14 +247,6 @@ func defaultStringSlice(value, defaultValue []string) (
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func panicOnError(err error, context string) {
|
|
||||||
if err == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panicMessage := fmt.Sprintf("%s: %s", context, err)
|
|
||||||
panic(panicMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
func WrapOpenvpnCA(certificate string) (lines []string) {
|
func WrapOpenvpnCA(certificate string) (lines []string) {
|
||||||
return []string{
|
return []string{
|
||||||
"<ca>",
|
"<ca>",
|
||||||
|
|||||||
Reference in New Issue
Block a user