From 5fff577c603c10ac646c002134a41d27fcd6ab20 Mon Sep 17 00:00:00 2001
From: Arminas
Date: Fri, 10 Feb 2023 07:22:24 +0200
Subject: [PATCH] Added client default settings page
Added client default settings page, where you can set Allowed IPs, Extra Allowed IPs, use server dns, enable after creation.
---
handler/routes.go | 60 +++++++++
main.go | 2 +
model/client_defaults.go | 8 +-
router/router.go | 8 +-
store/jsondb/jsondb.go | 19 ++-
store/store.go | 2 +
templates/base.html | 10 +-
templates/client_default_settings.html | 173 +++++++++++++++++++++++++
util/util.go | 18 +++
9 files changed, 293 insertions(+), 7 deletions(-)
create mode 100644 templates/client_default_settings.html
diff --git a/handler/routes.go b/handler/routes.go
index 3ddbb2d..c1c61d9 100644
--- a/handler/routes.go
+++ b/handler/routes.go
@@ -596,6 +596,22 @@ func GlobalSettings(db store.IStore) echo.HandlerFunc {
}
}
+// ClientDefaultSettings handler
+func ClientDefaultSettings(db store.IStore) echo.HandlerFunc {
+ return func(c echo.Context) error {
+
+ clientDefaultSettings, err := db.GetClientDefaultSettings()
+ if err != nil {
+ log.Error("Cannot get client default settings: ", err)
+ }
+
+ return c.Render(http.StatusOK, "client_default_settings.html", map[string]interface{}{
+ "baseData": model.BaseData{Active: "client-default-settings", CurrentUser: currentUser(c)},
+ "clientDefaultSettings": clientDefaultSettings,
+ })
+ }
+}
+
// Status handler
func Status(db store.IStore) echo.HandlerFunc {
type PeerVM struct {
@@ -709,6 +725,50 @@ func GlobalSettingSubmit(db store.IStore) echo.HandlerFunc {
}
}
+// ClientDefaultSettingsSubmit handler to update the client default settings
+func ClientDefaultSettingsSubmit(db store.IStore) echo.HandlerFunc {
+ return func(c echo.Context) error {
+
+ //data := make(map[string]interface{})
+ //err := json.NewDecoder(c.Request().Body).Decode(&data)
+ //if err != nil {
+ // return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Bad post data"})
+ //}
+ //
+ //var clientDefaultSettings model.ClientDefaults
+ //fmt.Println(data["allowed_ips"])
+ //
+ //clientDefaultSettings.AllowedIps = strings.Split(data["allowed_ips"].(string), ",")
+ //clientDefaultSettings.ExtraAllowedIps = strings.Split(data["extra_allowed_ips"].(string), ",")
+ //clientDefaultSettings.EnableAfterCreation = data["enable_after_creation"].(bool)
+ //clientDefaultSettings.UseServerDNS = data["use_server_dns"].(bool)
+
+ var clientDefaultSettings model.ClientDefaults
+ c.Bind(&clientDefaultSettings)
+
+ // validate the input allowed ips list
+ if util.ValidateCIDRList(clientDefaultSettings.AllowedIps, true) == false {
+ log.Warnf("Invalid Allowed IPs list input from user: %v", clientDefaultSettings.AllowedIps)
+ return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Allowed IPs must be in CIDR format"})
+ }
+
+ // validate the input extra allowed ips list
+ if util.ValidateCIDRList(clientDefaultSettings.ExtraAllowedIps, true) == false {
+ log.Warnf("Invalid Extra Allowed IPs list input from user: %v", clientDefaultSettings.ExtraAllowedIps)
+ return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Extra Allowed IPs must be in CIDR format"})
+ }
+
+ // write config to the database
+ if err := db.SaveClientDefaultSettings(clientDefaultSettings); err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Error saving client default settings"})
+ }
+
+ log.Infof("Updated client default settings: %v", clientDefaultSettings)
+
+ return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated client default settings successfully"})
+ }
+}
+
// MachineIPAddresses handler to get local interface ip addresses
func MachineIPAddresses() echo.HandlerFunc {
return func(c echo.Context) error {
diff --git a/main.go b/main.go
index 3f0cd13..edc24fe 100644
--- a/main.go
+++ b/main.go
@@ -158,7 +158,9 @@ func main() {
app.POST(util.BasePath+"/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession, handler.ContentTypeJson)
app.POST(util.BasePath+"/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession, handler.ContentTypeJson)
app.GET(util.BasePath+"/global-settings", handler.GlobalSettings(db), handler.ValidSession)
+ app.GET(util.BasePath+"/client-default-settings", handler.ClientDefaultSettings(db), handler.ValidSession)
app.POST(util.BasePath+"/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession, handler.ContentTypeJson)
+ app.POST(util.BasePath+"/client-default-settings", handler.ClientDefaultSettingsSubmit(db), handler.ValidSession, handler.ContentTypeJson)
app.GET(util.BasePath+"/status", handler.Status(db), handler.ValidSession)
app.GET(util.BasePath+"/api/clients", handler.GetClients(db), handler.ValidSession)
app.GET(util.BasePath+"/api/client/:id", handler.GetClient(db), handler.ValidSession)
diff --git a/model/client_defaults.go b/model/client_defaults.go
index 615ebed..b8cfb72 100644
--- a/model/client_defaults.go
+++ b/model/client_defaults.go
@@ -2,8 +2,8 @@ package model
// ClientDefaults Defaults for creation of new clients used in the templates
type ClientDefaults struct {
- AllowedIps []string
- ExtraAllowedIps []string
- UseServerDNS bool
- EnableAfterCreation bool
+ AllowedIps []string `json:"allowed_ips"`
+ ExtraAllowedIps []string `json:"extra_allowed_ips"`
+ UseServerDNS bool `json:"use_server_dns"`
+ EnableAfterCreation bool `json:"enable_after_creation"`
}
diff --git a/router/router.go b/router/router.go
index 0f9facc..cdb2d22 100644
--- a/router/router.go
+++ b/router/router.go
@@ -36,7 +36,7 @@ func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c
data.(map[string]interface{})[k] = v
}
- data.(map[string]interface{})["client_defaults"] = util.ClientDefaultsFromEnv()
+ data.(map[string]interface{})["client_defaults"] = util.ClientDefaultsFromDatabase()
}
// login page does not need the base layout
@@ -83,6 +83,11 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
log.Fatal(err)
}
+ tmplClientDefaultSettingsString, err := tmplBox.String("client_default_settings.html")
+ if err != nil {
+ log.Fatal(err)
+ }
+
tmplStatusString, err := tmplBox.String("status.html")
if err != nil {
log.Fatal(err)
@@ -103,6 +108,7 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
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["client_default_settings.html"] = template.Must(template.New("client_default_settings").Funcs(funcs).Parse(tmplBaseString + tmplClientDefaultSettingsString))
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))
diff --git a/store/jsondb/jsondb.go b/store/jsondb/jsondb.go
index f39a452..c29464e 100644
--- a/store/jsondb/jsondb.go
+++ b/store/jsondb/jsondb.go
@@ -42,6 +42,7 @@ func (o *JsonDB) Init() error {
var serverInterfacePath string = path.Join(serverPath, "interfaces.json")
var serverKeyPairPath string = path.Join(serverPath, "keypair.json")
var globalSettingPath string = path.Join(serverPath, "global_settings.json")
+ var clientDefaultSettingsPath string = path.Join(serverPath, "client_default_settings.json")
var userPath string = path.Join(serverPath, "users.json")
// create directories if they do not exist
if _, err := os.Stat(clientPath); os.IsNotExist(err) {
@@ -102,6 +103,12 @@ func (o *JsonDB) Init() error {
o.conn.Write("server", "global_settings", globalSetting)
}
+ // client default settings
+ if _, err := os.Stat(clientDefaultSettingsPath); os.IsNotExist(err) {
+ clientDefaultSetting := util.ClientDefaultsFromEnv()
+ o.conn.Write("server", "client_default_settings", clientDefaultSetting)
+ }
+
// user info
if _, err := os.Stat(userPath); os.IsNotExist(err) {
user := new(model.User)
@@ -138,6 +145,12 @@ func (o *JsonDB) GetGlobalSettings() (model.GlobalSetting, error) {
return settings, o.conn.Read("server", "global_settings", &settings)
}
+// GetClientDefaultSettings func to query client default settings from the database
+func (o *JsonDB) GetClientDefaultSettings() (model.ClientDefaults, error) {
+ settings := model.ClientDefaults{}
+ return settings, o.conn.Read("server", "client_default_settings", &settings)
+}
+
// GetServer func to query Server settings from the database
func (o *JsonDB) GetServer() (model.Server, error) {
server := model.Server{}
@@ -213,7 +226,7 @@ func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSetti
server, _ := o.GetServer()
globalSettings, _ := o.GetGlobalSettings()
client := client
- if !qrCodeSettings.IncludeDNS{
+ if !qrCodeSettings.IncludeDNS {
globalSettings.DNSServers = []string{}
}
if !qrCodeSettings.IncludeMTU {
@@ -255,3 +268,7 @@ func (o *JsonDB) SaveServerKeyPair(serverKeyPair model.ServerKeypair) error {
func (o *JsonDB) SaveGlobalSettings(globalSettings model.GlobalSetting) error {
return o.conn.Write("server", "global_settings", globalSettings)
}
+
+func (o *JsonDB) SaveClientDefaultSettings(clientDefaults model.ClientDefaults) error {
+ return o.conn.Write("server", "client_default_settings", clientDefaults)
+}
diff --git a/store/store.go b/store/store.go
index 86d6224..d35fc59 100644
--- a/store/store.go
+++ b/store/store.go
@@ -9,6 +9,7 @@ type IStore interface {
GetUser() (model.User, error)
SaveUser(user model.User) error
GetGlobalSettings() (model.GlobalSetting, error)
+ GetClientDefaultSettings() (model.ClientDefaults, error)
GetServer() (model.Server, error)
GetClients(hasQRCode bool) ([]model.ClientData, error)
GetClientByID(clientID string, qrCode model.QRCodeSettings) (model.ClientData, error)
@@ -17,6 +18,7 @@ type IStore interface {
SaveServerInterface(serverInterface model.ServerInterface) error
SaveServerKeyPair(serverKeyPair model.ServerKeypair) error
SaveGlobalSettings(globalSettings model.GlobalSetting) error
+ SaveClientDefaultSettings(clientDefaults model.ClientDefaults) error
GetWakeOnLanHosts() ([]model.WakeOnLanHost, error)
GetWakeOnLanHost(macAddress string) (*model.WakeOnLanHost, error)
DeleteWakeOnHostLanHost(macAddress string) error
diff --git a/templates/base.html b/templates/base.html
index fd337a7..6f89679 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -124,6 +124,14 @@
+
+
+
+
+ Client Default Settings
+
+
+
@@ -488,7 +496,7 @@
$("#client_public_key").val("");
$("#client_preshared_key").val("");
$("#client_allocated_ips").importTags('');
- $("#client_extra_allowed_ips").importTags('');
+ //$("#client_extra_allowed_ips").importTags('');
updateIPAllocationSuggestion();
});
});
diff --git a/templates/client_default_settings.html b/templates/client_default_settings.html
new file mode 100644
index 0000000..b949f04
--- /dev/null
+++ b/templates/client_default_settings.html
@@ -0,0 +1,173 @@
+{{define "title"}}
+Client Defaults Settings
+{{end}}
+
+{{define "top_css"}}
+{{end}}
+
+{{define "username"}}
+{{ .username }}
+{{end}}
+
+{{define "page_title"}}
+Client Defaults Settings
+{{end}}
+
+{{define "page_content"}}
+
+
+
+
+
+
+
+
+
+
+
+
+ - 1. Endpoint Address
+ - The public IP address of your Wireguard server that the client will connect to. Click on
+ Suggest button to auto detect the public IP address of your server.
+ - 2. DNS Servers
+ - The DNS servers will be set to client config.
+ - 3. MTU
+ - The MTU will be set to server and client config. By default it is
1420
. You might want
+ to adjust the MTU size if your connection (e.g PPPoE, 3G, satellite network, etc) has a low MTU.
+ - Leave blank to omit this setting in the configs.
+ - 4. Persistent Keepalive
+ - By default, WireGuard peers remain silent while they do not need to communicate,
+ so peers located behind a NAT and/or firewall may be unreachable from other peers
+ until they reach out to other peers themselves. Adding
PersistentKeepalive
+ can ensure that the connection remains open.
+ - Leave blank to omit this setting in the Client config.
+ - 5. Forward Mark
+ - Set an
fwmark
on all packets going out of WireGuard's UDP socket. Default value: 0xca6c
+ - 6. Wireguard Config File Path
+ - The path of your Wireguard server config file. Please make sure the parent directory
+ exists and is writable.
+
+
+
+
+
+
+
+
+
+
+{{end}}
+
+{{define "bottom_js"}}
+
+
+{{end}}
diff --git a/util/util.go b/util/util.go
index 40eb357..b1610bd 100644
--- a/util/util.go
+++ b/util/util.go
@@ -93,6 +93,24 @@ func ClientDefaultsFromEnv() model.ClientDefaults {
return clientDefaults
}
+// ClientDefaultsFromDatabase to read the default values for creating a new client from the database
+func ClientDefaultsFromDatabase() model.ClientDefaults {
+ // initialize database directory
+ dir := "./db"
+ db, err := scribble.New(dir, nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // read client default settings
+ clientDefaults := model.ClientDefaults{}
+ if err := db.Read("server", "client_default_settings", &clientDefaults); err != nil {
+ panic(err)
+ }
+
+ return clientDefaults
+}
+
// ValidateCIDR to validate a network CIDR
func ValidateCIDR(cidr string) bool {
_, _, err := net.ParseCIDR(cidr)