diff --git a/ldapauth.go b/ldapauth.go index 4f05ebf..8dc380d 100644 --- a/ldapauth.go +++ b/ldapauth.go @@ -24,6 +24,8 @@ import ( "github.com/gorilla/sessions" ) +const defaultCacheKey = "super-secret-key" + // nolint var ( store *sessions.CookieStore @@ -46,6 +48,7 @@ type Config struct { CacheCookiePath string `json:"cacheCookiePath,omitempty" yaml:"cacheCookiePath,omitempty"` CacheCookieSecure bool `json:"cacheCookieSecure,omitempty" yaml:"cacheCookieSecure,omitempty"` CacheKey string `json:"cacheKey,omitempty" yaml:"cacheKey,omitempty"` + CacheKeyLabel string `json:"cacheKeyLabel,omitempty" yaml:"cacheKeyLabel,omitempty"` StartTLS bool `json:"startTls,omitempty" yaml:"startTls,omitempty"` CertificateAuthority string `json:"certificateAuthority,omitempty" yaml:"certificateAuthority,omitempty"` InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty"` @@ -54,6 +57,7 @@ type Config struct { BaseDN string `json:"baseDn,omitempty" yaml:"baseDn,omitempty"` BindDN string `json:"bindDn,omitempty" yaml:"bindDn,omitempty"` BindPassword string `json:"bindPassword,omitempty" yaml:"bindPassword,omitempty"` + BindPasswordLabel string `json:"bindPasswordLabel,omitempty" yaml:"bindPasswordLabel,omitempty"` ForwardUsername bool `json:"forwardUsername,omitempty" yaml:"forwardUsername,omitempty"` ForwardUsernameHeader string `json:"forwardUsernameHeader,omitempty" yaml:"forwardUsernameHeader,omitempty"` ForwardAuthorization bool `json:"forwardAuthorization,omitempty" yaml:"forwardAuthorization,omitempty"` @@ -77,7 +81,8 @@ func CreateConfig() *Config { CacheCookieName: "ldapAuth_session_token", CacheCookiePath: "", CacheCookieSecure: false, - CacheKey: "super-secret-key", + CacheKey: defaultCacheKey, + CacheKeyLabel: "LDAP_AUTH_CACHE_KEY", StartTLS: false, CertificateAuthority: "", InsecureSkipVerify: false, @@ -86,6 +91,7 @@ func CreateConfig() *Config { BaseDN: "", BindDN: "", BindPassword: "", + BindPasswordLabel: "LDAP_AUTH_BIND_PASSWORD", ForwardUsername: true, ForwardUsernameHeader: "Username", ForwardAuthorization: false, @@ -112,6 +118,19 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h LoggerINFO.Printf("Starting %s Middleware...", name) + if config.BindDN != "" && config.BindPassword == "" { + config.BindPassword = getSecret(config.BindPasswordLabel) + } + + // if CacheKey is the default value we try to set it from secret + if config.CacheKey == defaultCacheKey { + cacheKey := getSecret(config.CacheKeyLabel) + // we could not retrieve the secret, so we keep the default value + if cacheKey != "" { + config.CacheKey = cacheKey + } + } + LogConfigParams(config) // Create new session with CacheKey and CacheTimeout. @@ -544,3 +563,19 @@ func LogConfigParams(config *Config) { LoggerDEBUG.Printf(fmt.Sprint(typeOfS.Field(i).Name, " => '", v.Field(i).Interface(), "'")) } } + +// retrieve a secret value from environment variable or secret on the FS +func getSecret(label string) string { + secret := os.Getenv(strings.ToUpper(label)) + + if secret != "" { + return secret + } + + b, err := os.ReadFile(fmt.Sprintf("/run/secrets/%s", strings.ToLower(label))) + if err != nil { + LoggerERROR.Printf("could not load secret %s: %s", label, err) + return "" + } + return strings.TrimSpace(string(b)) +} diff --git a/readme.md b/readme.md index a886831..0aa2e66 100644 --- a/readme.md +++ b/readme.md @@ -161,6 +161,23 @@ Needs `traefik` >= [`v2.8.5`](https://github.com/traefik/traefik/releases/tag/v2 _Optional, Default: `super-secret-key`_ The key used to encrypt session cookie information. You `must` use a strong value here. +You can also use a secret or a environment variable, see `cacheKeyLabel`. + + +#### `cacheKeyLabel` + +_Optional, Default: `"LDAP_AUTH_CACHE_KEY"`_ + +Only used when `cacheKey` is not set. +This allow the user to choose the name or the environment variable or the file name. +To be consistent with other traefik plugins, the environment variable should be upper case, and file name lower case. + +Example: +cacheKeyLabel=my_cache_key_label +The environment variable `MY_CACHE_KEY_LABEL` or a file containing the password should be mounted to `/run/secrets/my_cache_key_label`. +Typically, with docker you can use a secret named `my_cache_key_label`. + +The environment variable will be used if both options are set. ##### `startTLS` _Optional, Default: `false`_ @@ -239,6 +256,21 @@ The domain name to bind to in order to authenticate to the LDAP server when runn _Optional, Default: `""`_ The password corresponding to the `bindDN` specified when running in [`Search Mode`](#search-mode), is used in order to authenticate to the LDAP server. +You can also use a secret or a environment variable, see `bindPasswordLabel`. + +##### `bindPasswordLabel` +_Optional, Default: `"LDAP_AUTH_BIND_PASSWORD"`_ + +Only used when `bindDN` is not empty, and `bindPassword` is not set. +This allow the user to choose the name or the environment variable or the file name. +To be consistent with other traefik plugins, the environment variable should be upper case, and file name lower case. + +Example: +bindPasswordLabel=my_bind_password_label +The environment variable `MY_BIND_PASSWORD_LABEL` or a file containing the password should be mounted to `/run/secrets/my_bind_password_label`. +Typically, with docker you can use a secret named `my_bind_password_label`. + +The environment variable will be used if both options are set. ##### `forwardUsername`