env variable file support (#391)
This commit is contained in:
		
							parent
							
								
									b55543f424
								
							
						
					
					
						commit
						3024d36d76
					
				
							
								
								
									
										11
									
								
								README.md
								
								
								
								
							
							
						
						
									
										11
									
								
								README.md
								
								
								
								
							|  | @ -37,13 +37,16 @@ docker-compose up | ||||||
| ## Environment Variables | ## Environment Variables | ||||||
| 
 | 
 | ||||||
| | Variable                    | Description                                                                                                                                                                 | Default                            | | | Variable                    | Description                                                                                                                                                                 | Default                            | | ||||||
| |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| | |-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| | ||||||
| | `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                                                                                              | N/A                                | | ||||||
|  | | `SESSION_SECRET_FILE`       | Optional filepath for the secret key used to encrypt the session cookies. Leave `SESSION_SECRET` blank to take effect                                                       | 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                                                                  | `admin`                            | | ||||||
|  | | `WGUI_PASSWORD_FILE`        | Optional filepath for the user login password. Will be hashed automatically. Used for db initialization only. Leave `WGUI_PASSWORD` blank to take effect                    | N/A                                | | ||||||
| | `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                                                         | N/A                                | | ||||||
|  | | `WGUI_PASSWORD_HASH_FILE`   | Optional filepath for the user login password hash. (alternative to `WGUI_PASSWORD_FILE`). Used for db initialization only. Leave `WGUI_PASSWORD_HASH` blank to take effect | 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_DNS`                  | The default DNS servers (comma-separated-list) used in the global settings                                                                                                  | `1.1.1.1`                          | | | `WGUI_DNS`                  | The default DNS servers (comma-separated-list) used in the global settings                                                                                                  | `1.1.1.1`                          | | ||||||
|  | @ -57,12 +60,14 @@ docker-compose up | ||||||
| | `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                                                                                                                                                        | N/A                                | | ||||||
|  | | `SENDGRID_API_KEY_FILE`     | Optional filepath for the SendGrid api key. Leave `SENDGRID_API_KEY` blank to take effect                                                                                   | 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                                                                                                                                                      | N/A                                | | ||||||
|  | | `SMTP_PASSWORD_FILE`        | Optional filepath for the SMTP user password. Leave `SMTP_PASSWORD` blank to take effect                                                                                    | 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`                         | | ||||||
| 
 | 
 | ||||||
| ### Defaults for server configuration | ### Defaults for server configuration | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								main.go
								
								
								
								
							
							
						
						
									
										38
									
								
								main.go
								
								
								
								
							|  | @ -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,16 +71,41 @@ 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.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(&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(&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") | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		smtpPasswordLookup  = util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword) | ||||||
|  | 		sengridApiKeyLookup = util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey) | ||||||
|  | 		sessionSecretLookup = util.LookupEnvOrString("SESSION_SECRET", flagSessionSecret) | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	// check empty smtpPassword env var
 | ||||||
|  | 	if smtpPasswordLookup != "" { | ||||||
|  | 		flag.StringVar(&flagSmtpPassword, "smtp-password", smtpPasswordLookup, "SMTP Password") | ||||||
|  | 	} else { | ||||||
|  | 		flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrFile("SMTP_PASSWORD_FILE", flagSmtpPassword), "SMTP Password File") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// check empty sengridApiKey env var
 | ||||||
|  | 	if sengridApiKeyLookup != "" { | ||||||
|  | 		flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", sengridApiKeyLookup, "Your sendgrid api key.") | ||||||
|  | 	} else { | ||||||
|  | 		flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrFile("SENDGRID_API_KEY_FILE", flagSendgridApiKey), "File containing your sendgrid api key.") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// check empty sessionSecret env var
 | ||||||
|  | 	if sessionSecretLookup != "" { | ||||||
|  | 		flag.StringVar(&flagSessionSecret, "session-secret", sessionSecretLookup, "The key used to encrypt session cookies.") | ||||||
|  | 	} else { | ||||||
|  | 		flag.StringVar(&flagSessionSecret, "session-secret", util.LookupEnvOrFile("SESSION_SECRET_FILE", flagSessionSecret), "File containing the key used to encrypt session cookies.") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| 
 | 
 | ||||||
| 	// update runtime config
 | 	// update runtime config
 | ||||||
|  |  | ||||||
|  | @ -127,14 +127,21 @@ func (o *JsonDB) Init() error { | ||||||
| 		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.LookupEnvOrString(util.PasswordHashEnvVar, "") | ||||||
|  | 		if user.PasswordHash == "" { | ||||||
|  | 			user.PasswordHash = util.LookupEnvOrFile(util.PasswordHashFileEnvVar, "") | ||||||
| 			if user.PasswordHash == "" { | 			if user.PasswordHash == "" { | ||||||
| 				plaintext := util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) | 				plaintext := util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) | ||||||
|  | 				if plaintext == util.DefaultPassword { | ||||||
|  | 					plaintext = util.LookupEnvOrFile(util.PasswordFileEnvVar, util.DefaultPassword) | ||||||
|  | 				} | ||||||
| 				hash, err := util.HashPassword(plaintext) | 				hash, err := util.HashPassword(plaintext) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					return err | 					return err | ||||||
| 				} | 				} | ||||||
| 				user.PasswordHash = hash | 				user.PasswordHash = hash | ||||||
| 			} | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		o.conn.Write("users", user.Username, user) | 		o.conn.Write("users", user.Username, user) | ||||||
| 		os.Chmod(path.Join(path.Join(o.dbPath, "users"), user.Username+".json"), 0600) | 		os.Chmod(path.Join(path.Join(o.dbPath, "users"), user.Username+".json"), 0600) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -35,7 +35,9 @@ const ( | ||||||
| 	DefaultConfigFilePath                  = "/etc/wireguard/wg0.conf" | 	DefaultConfigFilePath                  = "/etc/wireguard/wg0.conf" | ||||||
| 	UsernameEnvVar                         = "WGUI_USERNAME" | 	UsernameEnvVar                         = "WGUI_USERNAME" | ||||||
| 	PasswordEnvVar                         = "WGUI_PASSWORD" | 	PasswordEnvVar                         = "WGUI_PASSWORD" | ||||||
|  | 	PasswordFileEnvVar                     = "WGUI_PASSWORD_FILE" | ||||||
| 	PasswordHashEnvVar                     = "WGUI_PASSWORD_HASH" | 	PasswordHashEnvVar                     = "WGUI_PASSWORD_HASH" | ||||||
|  | 	PasswordHashFileEnvVar                 = "WGUI_PASSWORD_HASH_FILE" | ||||||
| 	FaviconFilePathEnvVar                  = "WGUI_FAVICON_FILE_PATH" | 	FaviconFilePathEnvVar                  = "WGUI_FAVICON_FILE_PATH" | ||||||
| 	EndpointAddressEnvVar                  = "WGUI_ENDPOINT_ADDRESS" | 	EndpointAddressEnvVar                  = "WGUI_ENDPOINT_ADDRESS" | ||||||
| 	DNSEnvVar                              = "WGUI_DNS" | 	DNSEnvVar                              = "WGUI_DNS" | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								util/util.go
								
								
								
								
							
							
						
						
									
										20
									
								
								util/util.go
								
								
								
								
							|  | @ -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" | ||||||
|  | @ -19,6 +18,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" | ||||||
|  | @ -466,6 +468,20 @@ func LookupEnvOrStrings(key string, defaultVal []string) []string { | ||||||
| 	return defaultVal | 	return defaultVal | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func LookupEnvOrFile(key string, defaultVal string) string { | ||||||
|  | 	if val, ok := os.LookupEnv(key); ok { | ||||||
|  | 		if file, err := os.Open(val); err == nil { | ||||||
|  | 			var content string | ||||||
|  | 			scanner := bufio.NewScanner(file) | ||||||
|  | 			for scanner.Scan() { | ||||||
|  | 				content += scanner.Text() | ||||||
|  | 			} | ||||||
|  | 			return content | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	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 { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue