From 3e2fc5b9834b7298ebae15ed1d041c04bd7baaac Mon Sep 17 00:00:00 2001 From: Cameron Wichman Date: Wed, 14 Jun 2023 03:44:31 -0700 Subject: [PATCH] Added support for file env vars and docker secrets --- README.md | 10 +++++----- main.go | 13 +++++++------ store/jsondb/jsondb.go | 6 +++--- util/util.go | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 6a48efb..1e637ad 100644 --- a/README.md +++ b/README.md @@ -40,10 +40,10 @@ docker-compose up |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| | `BASE_PATH` | Set this variable if you run wireguard-ui under a subpath of your reverse proxy virtual host (e.g. /wireguard)) | N/A | | `BIND_ADDRESS` | The addresses that can access to the web interface and the port | 0.0.0.0:80 | -| `SESSION_SECRET` | The secret key used to encrypt the session cookies. Set this to a random value | N/A | +| `SESSION_SECRET` | The secret key used to encrypt the session cookies. Set this to a random value. Accepts files | N/A | | `WGUI_USERNAME` | The username for the login page. Used for db initialization only | `admin` | -| `WGUI_PASSWORD` | The password for the user on the login page. Will be hashed automatically. Used for db initialization only | `admin` | -| `WGUI_PASSWORD_HASH` | The password hash for the user on the login page. (alternative to `WGUI_PASSWORD`). Used for db initialization only | N/A | +| `WGUI_PASSWORD` | The password for the user on the login page. Will be hashed automatically. Used for db initialization only. Accepts files | `admin` | +| `WGUI_PASSWORD_HASH` | The password hash for the user on the login page. (alternative to `WGUI_PASSWORD`). Used for db initialization only. Accepts files | N/A | | `WGUI_ENDPOINT_ADDRESS` | The default endpoint address used in global settings where clients should connect to | Resolved to your public ip address | | `WGUI_FAVICON_FILE_PATH` | The file path used as website favicon | Embedded WireGuard logo | | `WGUI_ENDPOINT_ADDRESS` | The default endpoint address used in global settings | Resolved to your public ip address | @@ -57,11 +57,11 @@ docker-compose up | `WG_CONF_TEMPLATE` | The custom `wg.conf` config file template. Please refer to our [default template](https://github.com/ngoduykhanh/wireguard-ui/blob/master/templates/wg.conf) | N/A | | `EMAIL_FROM_ADDRESS` | The sender email address | N/A | | `EMAIL_FROM_NAME` | The sender name | `WireGuard UI` | -| `SENDGRID_API_KEY` | The SendGrid api key | N/A | +| `SENDGRID_API_KEY` | The SendGrid api key. Accepts files | N/A | | `SMTP_HOSTNAME` | The SMTP IP address or hostname | `127.0.0.1` | | `SMTP_PORT` | The SMTP port | `25` | | `SMTP_USERNAME` | The SMTP username | N/A | -| `SMTP_PASSWORD` | The SMTP user password | N/A | +| `SMTP_PASSWORD` | The SMTP user password. Accepts files | N/A | | `SMTP_AUTH_TYPE` | The SMTP authentication type. Possible values: `PLAIN`, `LOGIN`, `NONE` | `NONE` | | `SMTP_ENCRYPTION` | the encryption method. Possible values: `NONE`, `SSL`, `SSLTLS`, `TLS`, `STARTTLS` | `STARTTLS` | diff --git a/main.go b/main.go index a6c147f..e6b0f5b 100644 --- a/main.go +++ b/main.go @@ -4,14 +4,15 @@ import ( "embed" "flag" "fmt" - "github.com/labstack/echo/v4" - "github.com/labstack/gommon/log" - "github.com/ngoduykhanh/wireguard-ui/store" "io/fs" "net/http" "os" "time" + "github.com/labstack/echo/v4" + "github.com/labstack/gommon/log" + "github.com/ngoduykhanh/wireguard-ui/store" + "github.com/ngoduykhanh/wireguard-ui/emailer" "github.com/ngoduykhanh/wireguard-ui/handler" "github.com/ngoduykhanh/wireguard-ui/router" @@ -70,14 +71,14 @@ func init() { flag.StringVar(&flagSmtpHostname, "smtp-hostname", util.LookupEnvOrString("SMTP_HOSTNAME", flagSmtpHostname), "SMTP Hostname") flag.IntVar(&flagSmtpPort, "smtp-port", util.LookupEnvOrInt("SMTP_PORT", flagSmtpPort), "SMTP Port") flag.StringVar(&flagSmtpUsername, "smtp-username", util.LookupEnvOrString("SMTP_USERNAME", flagSmtpUsername), "SMTP Username") - flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword), "SMTP Password") + flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrSecretString("SMTP_PASSWORD", flagSmtpPassword), "SMTP Password") flag.BoolVar(&flagSmtpNoTLSCheck, "smtp-no-tls-check", util.LookupEnvOrBool("SMTP_NO_TLS_CHECK", flagSmtpNoTLSCheck), "Disable TLS verification for SMTP. This is potentially dangerous.") flag.StringVar(&flagSmtpEncryption, "smtp-encryption", util.LookupEnvOrString("SMTP_ENCRYPTION", flagSmtpEncryption), "SMTP Encryption : NONE, SSL, SSLTLS, TLS or STARTTLS (by default)") flag.StringVar(&flagSmtpAuthType, "smtp-auth-type", util.LookupEnvOrString("SMTP_AUTH_TYPE", flagSmtpAuthType), "SMTP Auth Type : PLAIN, LOGIN or NONE.") - flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey), "Your sendgrid api key.") + flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrSecretString("SENDGRID_API_KEY", flagSendgridApiKey), "Your sendgrid api key.") flag.StringVar(&flagEmailFrom, "email-from", util.LookupEnvOrString("EMAIL_FROM_ADDRESS", flagEmailFrom), "'From' email address.") flag.StringVar(&flagEmailFromName, "email-from-name", util.LookupEnvOrString("EMAIL_FROM_NAME", flagEmailFromName), "'From' email name.") - flag.StringVar(&flagSessionSecret, "session-secret", util.LookupEnvOrString("SESSION_SECRET", flagSessionSecret), "The key used to encrypt session cookies.") + flag.StringVar(&flagSessionSecret, "session-secret", util.LookupEnvOrSecretString("SESSION_SECRET", flagSessionSecret), "The key used to encrypt session cookies.") flag.StringVar(&flagWgConfTemplate, "wg-conf-template", util.LookupEnvOrString("WG_CONF_TEMPLATE", flagWgConfTemplate), "Path to custom wg.conf template.") flag.StringVar(&flagBasePath, "base-path", util.LookupEnvOrString("BASE_PATH", flagBasePath), "The base path of the URL") flag.Parse() diff --git a/store/jsondb/jsondb.go b/store/jsondb/jsondb.go index cb831ca..9d518f9 100644 --- a/store/jsondb/jsondb.go +++ b/store/jsondb/jsondb.go @@ -107,7 +107,7 @@ func (o *JsonDB) Init() error { globalSetting.UpdatedAt = time.Now().UTC() o.conn.Write("server", "global_settings", globalSetting) } - + // hashes if _, err := os.Stat(hashesPath); os.IsNotExist(err) { clientServerHashes := new(model.ClientServerHashes) @@ -122,9 +122,9 @@ func (o *JsonDB) Init() error { user := new(model.User) user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername) user.Admin = util.DefaultIsAdmin - user.PasswordHash = util.LookupEnvOrString(util.PasswordHashEnvVar, "") + user.PasswordHash = util.LookupEnvOrSecretString(util.PasswordHashEnvVar, "") if user.PasswordHash == "" { - plaintext := util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) + plaintext := util.LookupEnvOrSecretString(util.PasswordEnvVar, util.DefaultPassword) hash, err := util.HashPassword(plaintext) if err != nil { return err diff --git a/util/util.go b/util/util.go index 4d4b9b3..c11ed0d 100644 --- a/util/util.go +++ b/util/util.go @@ -1,11 +1,10 @@ package util import ( + "bufio" "encoding/json" "errors" "fmt" - "github.com/ngoduykhanh/wireguard-ui/store" - "golang.org/x/mod/sumdb/dirhash" "io" "io/fs" "io/ioutil" @@ -18,6 +17,9 @@ import ( "text/template" "time" + "github.com/ngoduykhanh/wireguard-ui/store" + "golang.org/x/mod/sumdb/dirhash" + externalip "github.com/glendc/go-external-ip" "github.com/labstack/gommon/log" "github.com/ngoduykhanh/wireguard-ui/model" @@ -465,6 +467,32 @@ func LookupEnvOrStrings(key string, defaultVal []string) []string { return defaultVal } +func LookupEnvOrSecretString(key string, defaultVal string) string { + blacklist := []string{ + "wg-ui", + "init.sh", + } + if val, ok := os.LookupEnv(key); ok { + // checks if key is blacklisted + for i := 0; i < len(blacklist); i++ { + if val == blacklist[i] { + return val + } + } + // returns file contents if file exists + var content string + if file, err := os.Open(val); err == nil { + scanner := bufio.NewScanner(file) + for scanner.Scan() { + content += scanner.Text() + } + return content + } + return val + } + return defaultVal +} + func StringFromEmbedFile(embed fs.FS, filename string) (string, error) { file, err := embed.Open(filename) if err != nil {