Add environment variables for configuration (#189)
This commit is contained in:
		
							parent
							
								
									87b08a8f7c
								
							
						
					
					
						commit
						569eaaee37
					
				
							
								
								
									
										35
									
								
								README.md
								
								
								
								
							
							
						
						
									
										35
									
								
								README.md
								
								
								
								
							|  | @ -30,8 +30,41 @@ wireguard interface stats. See the `cap_add` and `network_mode` options on the d | ||||||
| 
 | 
 | ||||||
| ### Environment Variables | ### Environment Variables | ||||||
| 
 | 
 | ||||||
|  | | Variable                    | Description                                                                                         | | ||||||
|  | |-----------------------------|-----------------------------------------------------------------------------------------------------| | ||||||
|  | | `SESSION_SECRET`            | Used to encrypt the session cookies. Set this to a random value.                                    | | ||||||
|  | | `WGUI_USERNAME`             | The username for the login page. (default `admin`)                                                  | | ||||||
|  | | `WGUI_PASSWORD`             | The password for the user on the login page. (default `admin`)                                      | | ||||||
|  | | `WGUI_ENDPOINT_ADDRESS`     | The default endpoint address used in global settings. (default is your public IP address)           | | ||||||
|  | | `WGUI_DNS`                  | The default DNS servers (comma-separated-list) used in the global settings. (default `1.1.1.1`)     | | ||||||
|  | | `WGUI_MTU`                  | The default MTU used in global settings. (default `1450`)                                           | | ||||||
|  | | `WGUI_PERSISTENT_KEEPALIVE` | The default persistent keepalive for WireGuard in global settings. (default `15`)                   | | ||||||
|  | | `WGUI_FORWARD_MARK`         | The default WireGuard forward mark. (default `0xca6c`)                                              | | ||||||
|  | | `WGUI_CONFIG_FILE_PATH`     | The default WireGuard config file path used in global settings. (default `/etc/wireguard/wg0.conf`) | | ||||||
| 
 | 
 | ||||||
| Set the `SESSION_SECRET` environment variable to a random value. | #### Defaults for server configuration | ||||||
|  | 
 | ||||||
|  | These environment variables are used to control the default server settings used when initializing the database. | ||||||
|  | 
 | ||||||
|  | | Variable                          | Description                                                                                                              | | ||||||
|  | |-----------------------------------|--------------------------------------------------------------------------------------------------------------------------| | ||||||
|  | | `WGUI_SERVER_INTERFACE_ADDRESSES` | The default interface addresses (comma-separated-list) for the WireGuard server configuration. (default `10.252.1.0/24`) | | ||||||
|  | | `WGUI_SERVER_LISTEN_PORT`         | The default server listen port. (default `51820`)                                                                        | | ||||||
|  | | `WGUI_SERVER_POST_UP_SCRIPT`      | The default server post-up script.                                                                                       | | ||||||
|  | | `WGUI_SERVER_POST_DOWN_SCRIPT`    | The default server post-down script.                                                                                     | | ||||||
|  | 
 | ||||||
|  | #### Defaults for new clients | ||||||
|  | 
 | ||||||
|  | These environment variables are used to set the defaults used in `New Client` dialog. | ||||||
|  | 
 | ||||||
|  | | Variable                                    | Description                                                                                                      | | ||||||
|  | |---------------------------------------------|------------------------------------------------------------------------------------------------------------------| | ||||||
|  | | `WGUI_DEFAULT_CLIENT_ALLOWED_IPS`           | Comma-separated-list of CIDRs for the `Allowed IPs` field. (default `0.0.0.0/0`)                                 | | ||||||
|  | | `WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS`     | Comma-separated-list of CIDRs for the `Extra Allowed IPs` field. (default empty)                                 | | ||||||
|  | | `WGUI_DEFAULT_CLIENT_USE_SERVER_DNS`        | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] (default `true`) | | ||||||
|  | | `WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION` | Boolean value [`0`, `f`, `F`, `false`, `False`, `FALSE`, `1`, `t`, `T`, `true`, `True`, `TRUE`] (default `true`) | | ||||||
|  | 
 | ||||||
|  | #### Email configuration | ||||||
| 
 | 
 | ||||||
| To use custom `wg.conf` template set the `WG_CONF_TEMPLATE` environment variable to a path to such file. Make sure `wireguard-ui` will be able to work with it - use [default template](templates/wg.conf) for reference. | To use custom `wg.conf` template set the `WG_CONF_TEMPLATE` environment variable to a path to such file. Make sure `wireguard-ui` will be able to work with it - use [default template](templates/wg.conf) for reference. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | package model | ||||||
|  | 
 | ||||||
|  | // Defaults for creation of new clients used in the templates
 | ||||||
|  | type ClientDefaults struct { | ||||||
|  | 	AllowedIps          []string | ||||||
|  | 	ExtraAllowedIps     []string | ||||||
|  | 	UseServerDNS        bool | ||||||
|  | 	EnableAfterCreation bool | ||||||
|  | } | ||||||
|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io" | 	"io" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"strings" | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 
 | 
 | ||||||
| 	rice "github.com/GeertJohan/go.rice" | 	rice "github.com/GeertJohan/go.rice" | ||||||
|  | @ -12,6 +13,7 @@ import ( | ||||||
| 	"github.com/labstack/echo/v4" | 	"github.com/labstack/echo/v4" | ||||||
| 	"github.com/labstack/echo/v4/middleware" | 	"github.com/labstack/echo/v4/middleware" | ||||||
| 	"github.com/labstack/gommon/log" | 	"github.com/labstack/gommon/log" | ||||||
|  | 	"github.com/ngoduykhanh/wireguard-ui/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // TemplateRegistry is a custom html/template renderer for Echo framework
 | // TemplateRegistry is a custom html/template renderer for Echo framework
 | ||||||
|  | @ -33,6 +35,8 @@ func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c | ||||||
| 		for k, v := range t.extraData { | 		for k, v := range t.extraData { | ||||||
| 			data.(map[string]interface{})[k] = v | 			data.(map[string]interface{})[k] = v | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		data.(map[string]interface{})["client_defaults"] = util.ClientDefaultsFromEnv() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// login page does not need the base layout
 | 	// login page does not need the base layout
 | ||||||
|  | @ -85,13 +89,16 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// create template list
 | 	// create template list
 | ||||||
|  | 	funcs := template.FuncMap{ | ||||||
|  | 		"StringsJoin": strings.Join, | ||||||
|  | 	} | ||||||
| 	templates := make(map[string]*template.Template) | 	templates := make(map[string]*template.Template) | ||||||
| 	templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString)) | 	templates["login.html"] = template.Must(template.New("login").Funcs(funcs).Parse(tmplLoginString)) | ||||||
| 	templates["clients.html"] = template.Must(template.New("clients").Parse(tmplBaseString + tmplClientsString)) | 	templates["clients.html"] = template.Must(template.New("clients").Funcs(funcs).Parse(tmplBaseString + tmplClientsString)) | ||||||
| 	templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString)) | 	templates["server.html"] = template.Must(template.New("server").Funcs(funcs).Parse(tmplBaseString + tmplServerString)) | ||||||
| 	templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString)) | 	templates["global_settings.html"] = template.Must(template.New("global_settings").Funcs(funcs).Parse(tmplBaseString + tmplGlobalSettingsString)) | ||||||
| 	templates["status.html"] = template.Must(template.New("status").Parse(tmplBaseString + tmplStatusString)) | 	templates["status.html"] = template.Must(template.New("status").Funcs(funcs).Parse(tmplBaseString + tmplStatusString)) | ||||||
| 	templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Parse(tmplBaseString + tmplWakeOnLanHostsString)) | 	templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Funcs(funcs).Parse(tmplBaseString + tmplWakeOnLanHostsString)) | ||||||
| 
 | 
 | ||||||
| 	e.Logger.SetLevel(log.DEBUG) | 	e.Logger.SetLevel(log.DEBUG) | ||||||
| 	e.Pre(middleware.RemoveTrailingSlash()) | 	e.Pre(middleware.RemoveTrailingSlash()) | ||||||
|  |  | ||||||
|  | @ -57,8 +57,10 @@ func (o *JsonDB) Init() error { | ||||||
| 	// server's interface
 | 	// server's interface
 | ||||||
| 	if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) { | 	if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) { | ||||||
| 		serverInterface := new(model.ServerInterface) | 		serverInterface := new(model.ServerInterface) | ||||||
| 		serverInterface.Addresses = []string{util.DefaultServerAddress} | 		serverInterface.Addresses = util.LookupEnvOrStrings(util.ServerAddressesEnvVar, []string{util.DefaultServerAddress}) | ||||||
| 		serverInterface.ListenPort = util.DefaultServerPort | 		serverInterface.ListenPort = util.LookupEnvOrInt(util.ServerListenPortEnvVar, util.DefaultServerPort) | ||||||
|  | 		serverInterface.PostUp = util.LookupEnvOrString(util.ServerPostUpScriptEnvVar, "") | ||||||
|  | 		serverInterface.PostDown = util.LookupEnvOrString(util.ServerPostDownScriptEnvVar, "") | ||||||
| 		serverInterface.UpdatedAt = time.Now().UTC() | 		serverInterface.UpdatedAt = time.Now().UTC() | ||||||
| 		o.conn.Write("server", "interfaces", serverInterface) | 		o.conn.Write("server", "interfaces", serverInterface) | ||||||
| 	} | 	} | ||||||
|  | @ -86,12 +88,12 @@ func (o *JsonDB) Init() error { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		globalSetting := new(model.GlobalSetting) | 		globalSetting := new(model.GlobalSetting) | ||||||
| 		globalSetting.EndpointAddress = publicInterface.IPAddress | 		globalSetting.EndpointAddress = util.LookupEnvOrString(util.EndpointAddressEnvVar, publicInterface.IPAddress) | ||||||
| 		globalSetting.DNSServers = []string{util.DefaultDNS} | 		globalSetting.DNSServers = util.LookupEnvOrStrings(util.DNSEnvVar, []string{util.DefaultDNS}) | ||||||
| 		globalSetting.MTU = util.DefaultMTU | 		globalSetting.MTU = util.LookupEnvOrInt(util.MTUEnvVar, util.DefaultMTU) | ||||||
| 		globalSetting.PersistentKeepalive = util.DefaultPersistentKeepalive | 		globalSetting.PersistentKeepalive = util.LookupEnvOrInt(util.PersistentKeepaliveEnvVar, util.DefaultPersistentKeepalive) | ||||||
| 		globalSetting.ForwardMark = util.DefaultForwardMark | 		globalSetting.ForwardMark = util.LookupEnvOrString(util.ForwardMarkEnvVar, util.DefaultForwardMark) | ||||||
| 		globalSetting.ConfigFilePath = util.DefaultConfigFilePath | 		globalSetting.ConfigFilePath = util.LookupEnvOrString(util.ConfigFilePathEnvVar, util.DefaultConfigFilePath) | ||||||
| 		globalSetting.UpdatedAt = time.Now().UTC() | 		globalSetting.UpdatedAt = time.Now().UTC() | ||||||
| 		o.conn.Write("server", "global_settings", globalSetting) | 		o.conn.Write("server", "global_settings", globalSetting) | ||||||
| 	} | 	} | ||||||
|  | @ -99,8 +101,8 @@ func (o *JsonDB) Init() error { | ||||||
| 	// user info
 | 	// user info
 | ||||||
| 	if _, err := os.Stat(userPath); os.IsNotExist(err) { | 	if _, err := os.Stat(userPath); os.IsNotExist(err) { | ||||||
| 		user := new(model.User) | 		user := new(model.User) | ||||||
| 		user.Username = util.GetCredVar(util.UsernameEnvVar, util.DefaultUsername) | 		user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername) | ||||||
| 		user.Password = util.GetCredVar(util.PasswordEnvVar, util.DefaultPassword) | 		user.Password = util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) | ||||||
| 		o.conn.Write("server", "users", user) | 		o.conn.Write("server", "users", user) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -175,7 +175,7 @@ | ||||||
|                                     </i> |                                     </i> | ||||||
|                                 </label> |                                 </label> | ||||||
|                                 <input type="text" data-role="tagsinput" class="form-control" id="client_allowed_ips" |                                 <input type="text" data-role="tagsinput" class="form-control" id="client_allowed_ips" | ||||||
|                                     value="0.0.0.0/0"> |                                     value="{{ StringsJoin .client_defaults.AllowedIps "," }}"> | ||||||
|                             </div> |                             </div> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <label for="client_extra_allowed_ips" class="control-label">Extra Allowed IPs |                                 <label for="client_extra_allowed_ips" class="control-label">Extra Allowed IPs | ||||||
|  | @ -184,11 +184,11 @@ | ||||||
|                                        client. These addresses will be included in 'AllowedIPs' of WG server config"> |                                        client. These addresses will be included in 'AllowedIPs' of WG server config"> | ||||||
|                                     </i> |                                     </i> | ||||||
|                                 </label> |                                 </label> | ||||||
|                                 <input type="text" data-role="tagsinput" class="form-control" id="client_extra_allowed_ips"> |                                 <input type="text" data-role="tagsinput" class="form-control" id="client_extra_allowed_ips" value="{{ StringsJoin .client_defaults.ExtraAllowedIps "," }}"> | ||||||
|                             </div> |                             </div> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <div class="icheck-primary d-inline"> |                                 <div class="icheck-primary d-inline"> | ||||||
|                                     <input type="checkbox" id="use_server_dns" checked> |                                     <input type="checkbox" id="use_server_dns" {{ if .client_defaults.UseServerDNS }}checked{{ end }}> | ||||||
|                                     <label for="use_server_dns"> |                                     <label for="use_server_dns"> | ||||||
|                                         Use server DNS |                                         Use server DNS | ||||||
|                                     </label> |                                     </label> | ||||||
|  | @ -196,7 +196,7 @@ | ||||||
|                             </div> |                             </div> | ||||||
|                             <div class="form-group"> |                             <div class="form-group"> | ||||||
|                                 <div class="icheck-primary d-inline"> |                                 <div class="icheck-primary d-inline"> | ||||||
|                                     <input type="checkbox" id="enabled" checked> |                                     <input type="checkbox" id="enabled" {{ if .client_defaults.EnableAfterCreation }}checked{{ end }}> | ||||||
|                                     <label for="enabled"> |                                     <label for="enabled"> | ||||||
|                                         Enable after creation |                                         Enable after creation | ||||||
|                                     </label> |                                     </label> | ||||||
|  |  | ||||||
|  | @ -23,17 +23,31 @@ var ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	DefaultUsername            = "admin" | 	DefaultUsername                        = "admin" | ||||||
| 	DefaultPassword            = "admin" | 	DefaultPassword                        = "admin" | ||||||
| 	DefaultServerAddress       = "10.252.1.0/24" | 	DefaultServerAddress                   = "10.252.1.0/24" | ||||||
| 	DefaultServerPort          = 51820 | 	DefaultServerPort                      = 51820 | ||||||
| 	DefaultDNS                 = "1.1.1.1" | 	DefaultDNS                             = "1.1.1.1" | ||||||
| 	DefaultMTU                 = 1450 | 	DefaultMTU                             = 1450 | ||||||
| 	DefaultPersistentKeepalive = 15 | 	DefaultPersistentKeepalive             = 15 | ||||||
| 	DefaultForwardMark         = "0xca6c" | 	DefaultForwardMark                     = "0xca6c" | ||||||
| 	DefaultConfigFilePath      = "/etc/wireguard/wg0.conf" | 	DefaultConfigFilePath                  = "/etc/wireguard/wg0.conf" | ||||||
| 	UsernameEnvVar             = "WGUI_USERNAME" | 	UsernameEnvVar                         = "WGUI_USERNAME" | ||||||
| 	PasswordEnvVar             = "WGUI_PASSWORD" | 	PasswordEnvVar                         = "WGUI_PASSWORD" | ||||||
|  | 	EndpointAddressEnvVar                  = "WGUI_ENDPOINT_ADDRESS" | ||||||
|  | 	DNSEnvVar                              = "WGUI_DNS" | ||||||
|  | 	MTUEnvVar                              = "WGUI_MTU" | ||||||
|  | 	PersistentKeepaliveEnvVar              = "WGUI_PERSISTENT_KEEPALIVE" | ||||||
|  | 	ForwardMarkEnvVar                      = "WGUI_FORWARD_MARK" | ||||||
|  | 	ConfigFilePathEnvVar                   = "WGUI_CONFIG_FILE_PATH" | ||||||
|  | 	ServerAddressesEnvVar                  = "WGUI_SERVER_INTERFACE_ADDRESSES" | ||||||
|  | 	ServerListenPortEnvVar                 = "WGUI_SERVER_LISTEN_PORT" | ||||||
|  | 	ServerPostUpScriptEnvVar               = "WGUI_SERVER_POST_UP_SCRIPT" | ||||||
|  | 	ServerPostDownScriptEnvVar             = "WGUI_SERVER_POST_DOWN_SCRIPT" | ||||||
|  | 	DefaultClientAllowedIpsEnvVar          = "WGUI_DEFAULT_CLIENT_ALLOWED_IPS" | ||||||
|  | 	DefaultClientExtraAllowedIpsEnvVar     = "WGUI_DEFAULT_CLIENT_EXTRA_ALLOWED_IPS" | ||||||
|  | 	DefaultClientUseServerDNSEnvVar        = "WGUI_DEFAULT_CLIENT_USE_SERVER_DNS" | ||||||
|  | 	DefaultClientEnableAfterCreationEnvVar = "WGUI_DEFAULT_CLIENT_ENABLE_AFTER_CREATION" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func ParseBasePath(basePath string) string { | func ParseBasePath(basePath string) string { | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								util/util.go
								
								
								
								
							
							
						
						
									
										20
									
								
								util/util.go
								
								
								
								
							|  | @ -77,6 +77,17 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G | ||||||
| 	return strConfig | 	return strConfig | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Read the default values for creating a new client from the environment or use sane defaults
 | ||||||
|  | func ClientDefaultsFromEnv() model.ClientDefaults { | ||||||
|  | 	client_defaults := model.ClientDefaults{} | ||||||
|  | 	client_defaults.AllowedIps = LookupEnvOrStrings(DefaultClientAllowedIpsEnvVar, []string{"0.0.0.0/0"}) | ||||||
|  | 	client_defaults.ExtraAllowedIps = LookupEnvOrStrings(DefaultClientExtraAllowedIpsEnvVar, []string{}) | ||||||
|  | 	client_defaults.UseServerDNS = LookupEnvOrBool(DefaultClientUseServerDNSEnvVar, true) | ||||||
|  | 	client_defaults.EnableAfterCreation = LookupEnvOrBool(DefaultClientEnableAfterCreationEnvVar, true) | ||||||
|  | 
 | ||||||
|  | 	return client_defaults | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // ValidateCIDR to validate a network CIDR
 | // ValidateCIDR to validate a network CIDR
 | ||||||
| func ValidateCIDR(cidr string) bool { | func ValidateCIDR(cidr string) bool { | ||||||
| 	_, _, err := net.ParseCIDR(cidr) | 	_, _, err := net.ParseCIDR(cidr) | ||||||
|  | @ -440,10 +451,9 @@ func LookupEnvOrInt(key string, defaultVal int) int { | ||||||
| 	return defaultVal | 	return defaultVal | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetCredVar reads value from environment variable or returns fallback
 | func LookupEnvOrStrings(key string, defaultVal []string) []string { | ||||||
| func GetCredVar(key, fallback string) string { | 	if val, ok := os.LookupEnv(key); ok { | ||||||
| 	if value, ok := os.LookupEnv(key); ok { | 		return strings.Split(val, ",") | ||||||
| 		return value |  | ||||||
| 	} | 	} | ||||||
| 	return fallback | 	return defaultVal | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue