Skip to content

Commit

Permalink
Add environment variables for configuration (ngoduykhanh#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
fin-ger authored Apr 26, 2022
1 parent 87b08a8 commit 569eaae
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 38 deletions.
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,41 @@ wireguard interface stats. See the `cap_add` and `network_mode` options on the d

### Environment Variables


Set the `SESSION_SECRET` environment variable to a random value.
| 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`) |

#### 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.

Expand Down
9 changes: 9 additions & 0 deletions model/client_defaults.go
Original file line number Diff line number Diff line change
@@ -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
}
19 changes: 13 additions & 6 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"io"
"reflect"
"strings"
"text/template"

rice "github.com/GeertJohan/go.rice"
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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())
Expand Down
22 changes: 12 additions & 10 deletions store/jsondb/jsondb.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -86,21 +88,21 @@ 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)
}

// 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)
}

Expand Down
8 changes: 4 additions & 4 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ <h4 class="modal-title">New Wireguard Client</h4>
</i>
</label>
<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 class="form-group">
<label for="client_extra_allowed_ips" class="control-label">Extra Allowed IPs
Expand All @@ -184,19 +184,19 @@ <h4 class="modal-title">New Wireguard Client</h4>
client. These addresses will be included in 'AllowedIPs' of WG server config">
</i>
</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 class="form-group">
<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">
Use server DNS
</label>
</div>
</div>
<div class="form-group">
<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">
Enable after creation
</label>
Expand Down
36 changes: 25 additions & 11 deletions util/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
20 changes: 15 additions & 5 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
}

0 comments on commit 569eaae

Please sign in to comment.