Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add environment variables for configuration #189

Merged
merged 2 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}