Added support for file env vars and docker secrets

This commit is contained in:
Cameron Wichman 2023-06-14 03:44:31 -07:00
parent b9e5ddf194
commit 3e2fc5b983
4 changed files with 45 additions and 16 deletions

View file

@ -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 | | `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 | | `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_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` | 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 | N/A | | `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_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_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 | | `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 | | `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_ADDRESS` | The sender email address | N/A |
| `EMAIL_FROM_NAME` | The sender name | `WireGuard UI` | | `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_HOSTNAME` | The SMTP IP address or hostname | `127.0.0.1` |
| `SMTP_PORT` | The SMTP port | `25` | | `SMTP_PORT` | The SMTP port | `25` |
| `SMTP_USERNAME` | The SMTP username | N/A | | `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_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` | | `SMTP_ENCRYPTION` | the encryption method. Possible values: `NONE`, `SSL`, `SSLTLS`, `TLS`, `STARTTLS` | `STARTTLS` |

13
main.go
View file

@ -4,14 +4,15 @@ import (
"embed" "embed"
"flag" "flag"
"fmt" "fmt"
"github.com/labstack/echo/v4"
"github.com/labstack/gommon/log"
"github.com/ngoduykhanh/wireguard-ui/store"
"io/fs" "io/fs"
"net/http" "net/http"
"os" "os"
"time" "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/emailer"
"github.com/ngoduykhanh/wireguard-ui/handler" "github.com/ngoduykhanh/wireguard-ui/handler"
"github.com/ngoduykhanh/wireguard-ui/router" "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.StringVar(&flagSmtpHostname, "smtp-hostname", util.LookupEnvOrString("SMTP_HOSTNAME", flagSmtpHostname), "SMTP Hostname")
flag.IntVar(&flagSmtpPort, "smtp-port", util.LookupEnvOrInt("SMTP_PORT", flagSmtpPort), "SMTP Port") 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(&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.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(&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(&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(&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(&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(&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.StringVar(&flagBasePath, "base-path", util.LookupEnvOrString("BASE_PATH", flagBasePath), "The base path of the URL")
flag.Parse() flag.Parse()

View file

@ -107,7 +107,7 @@ func (o *JsonDB) Init() error {
globalSetting.UpdatedAt = time.Now().UTC() globalSetting.UpdatedAt = time.Now().UTC()
o.conn.Write("server", "global_settings", globalSetting) o.conn.Write("server", "global_settings", globalSetting)
} }
// hashes // hashes
if _, err := os.Stat(hashesPath); os.IsNotExist(err) { if _, err := os.Stat(hashesPath); os.IsNotExist(err) {
clientServerHashes := new(model.ClientServerHashes) clientServerHashes := new(model.ClientServerHashes)
@ -122,9 +122,9 @@ func (o *JsonDB) Init() error {
user := new(model.User) user := new(model.User)
user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername) user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername)
user.Admin = util.DefaultIsAdmin user.Admin = util.DefaultIsAdmin
user.PasswordHash = util.LookupEnvOrString(util.PasswordHashEnvVar, "") user.PasswordHash = util.LookupEnvOrSecretString(util.PasswordHashEnvVar, "")
if user.PasswordHash == "" { if user.PasswordHash == "" {
plaintext := util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) plaintext := util.LookupEnvOrSecretString(util.PasswordEnvVar, util.DefaultPassword)
hash, err := util.HashPassword(plaintext) hash, err := util.HashPassword(plaintext)
if err != nil { if err != nil {
return err return err

View file

@ -1,11 +1,10 @@
package util package util
import ( import (
"bufio"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/ngoduykhanh/wireguard-ui/store"
"golang.org/x/mod/sumdb/dirhash"
"io" "io"
"io/fs" "io/fs"
"io/ioutil" "io/ioutil"
@ -18,6 +17,9 @@ import (
"text/template" "text/template"
"time" "time"
"github.com/ngoduykhanh/wireguard-ui/store"
"golang.org/x/mod/sumdb/dirhash"
externalip "github.com/glendc/go-external-ip" externalip "github.com/glendc/go-external-ip"
"github.com/labstack/gommon/log" "github.com/labstack/gommon/log"
"github.com/ngoduykhanh/wireguard-ui/model" "github.com/ngoduykhanh/wireguard-ui/model"
@ -465,6 +467,32 @@ func LookupEnvOrStrings(key string, defaultVal []string) []string {
return defaultVal 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) { func StringFromEmbedFile(embed fs.FS, filename string) (string, error) {
file, err := embed.Open(filename) file, err := embed.Open(filename)
if err != nil { if err != nil {