From 569eaaee375ded9a9285e50461c81ba641b88b1e Mon Sep 17 00:00:00 2001 From: Fin Christensen Date: Tue, 26 Apr 2022 20:35:35 +0200 Subject: [PATCH] Add environment variables for configuration (#189) --- README.md | 35 ++++++++++++++++++++++++++++++++++- model/client_defaults.go | 9 +++++++++ router/router.go | 19 +++++++++++++------ store/jsondb/jsondb.go | 22 ++++++++++++---------- templates/base.html | 8 ++++---- util/config.go | 36 +++++++++++++++++++++++++----------- util/util.go | 20 +++++++++++++++----- 7 files changed, 112 insertions(+), 37 deletions(-) create mode 100644 model/client_defaults.go diff --git a/README.md b/README.md index ee3bb44..c7d0273 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,41 @@ wireguard interface stats. See the `cap_add` and `network_mode` options on the d ### 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. diff --git a/model/client_defaults.go b/model/client_defaults.go new file mode 100644 index 0000000..e73fcfd --- /dev/null +++ b/model/client_defaults.go @@ -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 +} diff --git a/router/router.go b/router/router.go index b3231f7..3369f6b 100644 --- a/router/router.go +++ b/router/router.go @@ -4,6 +4,7 @@ import ( "errors" "io" "reflect" + "strings" "text/template" rice "github.com/GeertJohan/go.rice" @@ -12,6 +13,7 @@ import ( "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/labstack/gommon/log" + "github.com/ngoduykhanh/wireguard-ui/util" ) // 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 { data.(map[string]interface{})[k] = v } + + data.(map[string]interface{})["client_defaults"] = util.ClientDefaultsFromEnv() } // 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 + funcs := template.FuncMap{ + "StringsJoin": strings.Join, + } templates := make(map[string]*template.Template) - templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString)) - templates["clients.html"] = template.Must(template.New("clients").Parse(tmplBaseString + tmplClientsString)) - templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString)) - templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString)) - templates["status.html"] = template.Must(template.New("status").Parse(tmplBaseString + tmplStatusString)) - templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Parse(tmplBaseString + tmplWakeOnLanHostsString)) + templates["login.html"] = template.Must(template.New("login").Funcs(funcs).Parse(tmplLoginString)) + templates["clients.html"] = template.Must(template.New("clients").Funcs(funcs).Parse(tmplBaseString + tmplClientsString)) + templates["server.html"] = template.Must(template.New("server").Funcs(funcs).Parse(tmplBaseString + tmplServerString)) + templates["global_settings.html"] = template.Must(template.New("global_settings").Funcs(funcs).Parse(tmplBaseString + tmplGlobalSettingsString)) + 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").Funcs(funcs).Parse(tmplBaseString + tmplWakeOnLanHostsString)) e.Logger.SetLevel(log.DEBUG) e.Pre(middleware.RemoveTrailingSlash()) diff --git a/store/jsondb/jsondb.go b/store/jsondb/jsondb.go index 643e5e5..755145b 100644 --- a/store/jsondb/jsondb.go +++ b/store/jsondb/jsondb.go @@ -57,8 +57,10 @@ func (o *JsonDB) Init() error { // server's interface if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) { serverInterface := new(model.ServerInterface) - serverInterface.Addresses = []string{util.DefaultServerAddress} - serverInterface.ListenPort = util.DefaultServerPort + serverInterface.Addresses = util.LookupEnvOrStrings(util.ServerAddressesEnvVar, []string{util.DefaultServerAddress}) + 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() o.conn.Write("server", "interfaces", serverInterface) } @@ -86,12 +88,12 @@ func (o *JsonDB) Init() error { } globalSetting := new(model.GlobalSetting) - globalSetting.EndpointAddress = publicInterface.IPAddress - globalSetting.DNSServers = []string{util.DefaultDNS} - globalSetting.MTU = util.DefaultMTU - globalSetting.PersistentKeepalive = util.DefaultPersistentKeepalive - globalSetting.ForwardMark = util.DefaultForwardMark - globalSetting.ConfigFilePath = util.DefaultConfigFilePath + globalSetting.EndpointAddress = util.LookupEnvOrString(util.EndpointAddressEnvVar, publicInterface.IPAddress) + globalSetting.DNSServers = util.LookupEnvOrStrings(util.DNSEnvVar, []string{util.DefaultDNS}) + globalSetting.MTU = util.LookupEnvOrInt(util.MTUEnvVar, util.DefaultMTU) + globalSetting.PersistentKeepalive = util.LookupEnvOrInt(util.PersistentKeepaliveEnvVar, util.DefaultPersistentKeepalive) + globalSetting.ForwardMark = util.LookupEnvOrString(util.ForwardMarkEnvVar, util.DefaultForwardMark) + globalSetting.ConfigFilePath = util.LookupEnvOrString(util.ConfigFilePathEnvVar, util.DefaultConfigFilePath) globalSetting.UpdatedAt = time.Now().UTC() o.conn.Write("server", "global_settings", globalSetting) } @@ -99,8 +101,8 @@ func (o *JsonDB) Init() error { // user info if _, err := os.Stat(userPath); os.IsNotExist(err) { user := new(model.User) - user.Username = util.GetCredVar(util.UsernameEnvVar, util.DefaultUsername) - user.Password = util.GetCredVar(util.PasswordEnvVar, util.DefaultPassword) + user.Username = util.LookupEnvOrString(util.UsernameEnvVar, util.DefaultUsername) + user.Password = util.LookupEnvOrString(util.PasswordEnvVar, util.DefaultPassword) o.conn.Write("server", "users", user) } diff --git a/templates/base.html b/templates/base.html index 5b6319c..f3d7898 100644 --- a/templates/base.html +++ b/templates/base.html @@ -175,7 +175,7 @@ + value="{{ StringsJoin .client_defaults.AllowedIps "," }}">
- +
- + @@ -196,7 +196,7 @@
- + diff --git a/util/config.go b/util/config.go index 934e049..f5967eb 100644 --- a/util/config.go +++ b/util/config.go @@ -23,17 +23,31 @@ var ( ) const ( - DefaultUsername = "admin" - DefaultPassword = "admin" - DefaultServerAddress = "10.252.1.0/24" - DefaultServerPort = 51820 - DefaultDNS = "1.1.1.1" - DefaultMTU = 1450 - DefaultPersistentKeepalive = 15 - DefaultForwardMark = "0xca6c" - DefaultConfigFilePath = "/etc/wireguard/wg0.conf" - UsernameEnvVar = "WGUI_USERNAME" - PasswordEnvVar = "WGUI_PASSWORD" + DefaultUsername = "admin" + DefaultPassword = "admin" + DefaultServerAddress = "10.252.1.0/24" + DefaultServerPort = 51820 + DefaultDNS = "1.1.1.1" + DefaultMTU = 1450 + DefaultPersistentKeepalive = 15 + DefaultForwardMark = "0xca6c" + DefaultConfigFilePath = "/etc/wireguard/wg0.conf" + UsernameEnvVar = "WGUI_USERNAME" + 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 { diff --git a/util/util.go b/util/util.go index a9d8bf7..87ac7c7 100644 --- a/util/util.go +++ b/util/util.go @@ -77,6 +77,17 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G 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 func ValidateCIDR(cidr string) bool { _, _, err := net.ParseCIDR(cidr) @@ -440,10 +451,9 @@ func LookupEnvOrInt(key string, defaultVal int) int { return defaultVal } -// GetCredVar reads value from environment variable or returns fallback -func GetCredVar(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value +func LookupEnvOrStrings(key string, defaultVal []string) []string { + if val, ok := os.LookupEnv(key); ok { + return strings.Split(val, ",") } - return fallback + return defaultVal }