From 4d2a85f8795701ecb7e976a20961ed100bb6769a Mon Sep 17 00:00:00 2001 From: afeiszli Date: Thu, 20 Jan 2022 17:50:42 -0500 Subject: [PATCH 1/7] adding telemetry --- config/config.go | 1 + controllers/server_util.go | 7 ++ database/database.go | 29 +++++++ go.mod | 2 + go.sum | 5 ++ logic/nodes.go | 2 + main.go | 7 ++ models/node.go | 22 +++++ models/structs.go | 6 ++ servercfg/serverconf.go | 13 +++ serverctl/telemetry.go | 170 +++++++++++++++++++++++++++++++++++++ 11 files changed, 264 insertions(+) create mode 100644 serverctl/telemetry.go diff --git a/config/config.go b/config/config.go index fc1bcbf2..9160cc9f 100644 --- a/config/config.go +++ b/config/config.go @@ -70,6 +70,7 @@ type ServerConfig struct { DisplayKeys string `yaml:"displaykeys"` AzureTenant string `yaml:"azuretenant"` RCE string `yaml:"rce"` + Telemetry string `yaml:"telemetry"` } // SQLConfig - Generic SQL Config diff --git a/controllers/server_util.go b/controllers/server_util.go index c3e56e1d..84cd4566 100644 --- a/controllers/server_util.go +++ b/controllers/server_util.go @@ -4,9 +4,16 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/servercfg" + "github.com/gravitl/netmaker/serverctl" ) func runServerPeerUpdate(network string, shouldPeerUpdate bool) error { + if servercfg.Telemetry() == "on" { + err := serverctl.TelemetryCheckpoint() + if err != nil { + logger.Log(1, "failed to send telemetry:", err.Error()) + } + } if servercfg.IsClientMode() != "on" { return nil } diff --git a/database/database.go b/database/database.go index c70ba111..689ae2f0 100644 --- a/database/database.go +++ b/database/database.go @@ -3,9 +3,12 @@ package database import ( "encoding/json" "errors" + "strings" "time" + "github.com/google/uuid" "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/servercfg" ) @@ -36,6 +39,12 @@ const PEERS_TABLE_NAME = "peers" // SERVERCONF_TABLE_NAME const SERVERCONF_TABLE_NAME = "serverconf" +// SERVER_UUID_TABLE_NAME +const SERVER_UUID_TABLE_NAME = "serveruuid" + +// SERVER_UUID_RECORD_KEY +const SERVER_UUID_RECORD_KEY = "serveruuid" + // DATABASE_FILENAME - database file name const DATABASE_FILENAME = "netmaker.db" @@ -118,6 +127,7 @@ func createTables() { createTable(INT_CLIENTS_TABLE_NAME) createTable(PEERS_TABLE_NAME) createTable(SERVERCONF_TABLE_NAME) + createTable(SERVER_UUID_TABLE_NAME) createTable(GENERATED_TABLE_NAME) } @@ -184,6 +194,25 @@ func FetchRecords(tableName string) (map[string]string, error) { return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName) } +// FetchRecords - fetches all records in given table +func InitializeUUID() error { + records, err := FetchRecords(SERVER_UUID_TABLE_NAME) + if err != nil { + if !strings.Contains("could not find any records", err.Error()) { + return err + } + } else if len(records) > 0 { + return nil + } + telemetry := models.Telemetry{UUID: uuid.NewString()} + telJSON, err := json.Marshal(telemetry) + if err != nil { + return err + } + err = Insert(SERVER_UUID_RECORD_KEY, string(telJSON), SERVER_UUID_TABLE_NAME) + return err +} + // CloseDB - closes a database gracefully func CloseDB() { getCurrentDB()[CLOSE_DB].(func())() diff --git a/go.mod b/go.mod index 70f37dc5..b63dd3cc 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,9 @@ require ( github.com/mdlayher/genetlink v1.0.0 // indirect github.com/mdlayher/netlink v1.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect google.golang.org/appengine v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 1843eb9d..98d74829 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 h1:Y2hUrkfuM0on62KZOci/VLijlkdF/yeWU262BQgvcjE= +github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sAs9tGai3VldabTV0eWejt/O4/OOD7azP8GaikqU= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -156,9 +158,12 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E= github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g= +github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/logic/nodes.go b/logic/nodes.go index 073eeb20..4a286274 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -411,6 +411,8 @@ func SetNodeDefaults(node *models.Node) { node.SetDefaultMTU() node.SetDefaultIsRelayed() node.SetDefaultIsRelay() + node.SetDefaultIsDocker() + node.SetDefaultIsK8S() node.KeyUpdateTimeStamp = time.Now().Unix() } diff --git a/main.go b/main.go index 4e3b71ca..a939d0c5 100644 --- a/main.go +++ b/main.go @@ -41,6 +41,13 @@ func initialize() { // Client Mode Prereq Check } logger.Log(0, "database successfully connected") + if err = database.InitializeUUID(); err != nil { + logger.FatalLog("Failed to set UUID: ", err.Error()) + } + err = serverctl.TelemetryCheckpoint() + if err != nil { + logger.Log(1, "Failed to send telemetry: ", err.Error()) + } var authProvider = auth.InitializeAuthProvider() if authProvider != "" { logger.Log(0, "OAuth provider,", authProvider+",", "initialized") diff --git a/models/node.go b/models/node.go index 16f65afd..3cd629b2 100644 --- a/models/node.go +++ b/models/node.go @@ -54,6 +54,8 @@ type Node struct { IsRelayed string `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` IsPending string `json:"ispending" bson:"ispending" yaml:"ispending"` IsRelay string `json:"isrelay" bson:"isrelay" yaml:"isrelay" validate:"checkyesorno"` + IsDocker string `json:"isdocker" bson:"isdocker" yaml:"isdocker" validate:"checkyesorno"` + IsK8S string `json:"isk8s" bson:"isk8s" yaml:"isk8s" validate:"checkyesorno"` IsEgressGateway string `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway"` IsIngressGateway string `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway"` EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` @@ -122,6 +124,20 @@ func (node *Node) SetDefaultIsRelay() { } } +// Node.SetDefaultIsDocker - set default isdocker +func (node *Node) SetDefaultIsDocker() { + if node.IsDocker == "" { + node.IsDocker = "no" + } +} + +// Node.SetDefaultIsK8S - set default isk8s +func (node *Node) SetDefaultIsK8S() { + if node.IsK8S == "" { + node.IsK8S = "no" + } +} + // Node.SetDefaultEgressGateway - sets default egress gateway status func (node *Node) SetDefaultEgressGateway() { if node.IsEgressGateway == "" { @@ -381,6 +397,12 @@ func (newNode *Node) Fill(currentNode *Node) { if newNode.IsRelayed == "" { newNode.IsRelayed = currentNode.IsRelayed } + if newNode.IsDocker == "" { + newNode.IsDocker = currentNode.IsDocker + } + if newNode.IsK8S == "" { + newNode.IsK8S = currentNode.IsK8S + } if newNode.Version == "" { newNode.Version = currentNode.Version } diff --git a/models/structs.go b/models/structs.go index 16b2ae77..21720325 100644 --- a/models/structs.go +++ b/models/structs.go @@ -163,3 +163,9 @@ type ServerUpdateData struct { UpdatePeers bool `json:"updatepeers" bson:"updatepeers"` Node Node `json:"servernode" bson:"servernode"` } + +// ServerUUID - contains UUID of the server +type Telemetry struct { + UUID string `json:"uuid" bson:"uuid"` + LastSend int64 `json:"lastsend" bson:"lastsend"` +} diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index 224d1862..d0c52fe3 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -85,6 +85,7 @@ func GetServerConfig() config.ServerConfig { } else { cfg.RCE = "off" } + cfg.Telemetry = Telemetry() return cfg } @@ -319,6 +320,18 @@ func IsClientMode() string { return isclient } +// IsClientMode - checks if it should run in client mode +func Telemetry() string { + telemetry := "on" + if os.Getenv("TELEMETRY") == "off" { + telemetry = "off" + } + if config.Config.Server.Telemetry == "off" { + telemetry = "off" + } + return telemetry +} + // IsDNSMode - should it run with DNS func IsDNSMode() bool { isdns := true diff --git a/serverctl/telemetry.go b/serverctl/telemetry.go new file mode 100644 index 00000000..ec77e868 --- /dev/null +++ b/serverctl/telemetry.go @@ -0,0 +1,170 @@ +package serverctl + +import ( + "encoding/json" + "time" + + "github.com/gravitl/netmaker/database" + "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/logic" + "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/servercfg" + "github.com/posthog/posthog-go" +) + +const POSTHOG_PUB_KEY = "phc_1vEXhPOA1P7HP5jP2dVU9xDTUqXHAelmtravyZ1vvES" +const POSTHOG_ENDPOINT = "https://app.posthog.com" +const TELEMETRY_HOURS_BETWEEN_SEND = 24 + +// TelemetryCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog +func TelemetryCheckpoint() error { + + // if telemetry is turned off, return without doing anything + if servercfg.Telemetry() == "off" { + return nil + } + // get the telemetry record in the DB, which contains a timestamp + telRecord, err := fetchTelemetryRecord() + if err != nil { + return err + } + // sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(TELEMETRY_HOURS_BETWEEN_SEND)) + // can set to 2 minutes for testing + sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2) + enoughTimeElapsed := time.Now().After(sendtime) + + // if more than 24 hours has elapsed, send telemetry to posthog + if enoughTimeElapsed { + err = sendTelemetry(telRecord.UUID) + if err != nil { + logger.Log(1, err.Error()) + } + } + return nil +} + +// sendTelemetry - gathers telemetry data and sends to posthog +func sendTelemetry(serverUUID string) error { + // get telemetry data + d, err := fetchTelemetryData() + if err != nil { + return err + } + client, err := posthog.NewWithConfig(POSTHOG_PUB_KEY, posthog.Config{Endpoint: POSTHOG_ENDPOINT}) + if err != nil { + return err + } + defer client.Close() + + // send to posthog + err = client.Enqueue(posthog.Capture{ + DistinctId: serverUUID, + Event: "daily checkin", + Properties: posthog.NewProperties(). + Set("nodes", d.Nodes). + Set("non-server nodes", d.Count.NonServer). + Set("extclients", d.ExtClients). + Set("users", d.Users). + Set("networks", d.Networks). + Set("linux", d.Count.Linux). + Set("darwin", d.Count.MacOS). + Set("windows", d.Count.Windows). + Set("freebsd", d.Count.FreeBSD). + Set("docker", d.Count.Docker). + Set("k8s", d.Count.K8S). + Set("version", d.Version), + }) + if err != nil { + return err + } + //set telemetry timestamp for server, restarts 24 hour cycle + return setTelemetryTimestamp(serverUUID) +} + +// fetchTelemetry - fetches telemetry data: count of various object types in DB +func fetchTelemetryData() (TelemetryData, error) { + var data TelemetryData + extData, _ := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME) + data.ExtClients = len(extData) + userData, _ := database.FetchRecords(database.USERS_TABLE_NAME) + data.Users = len(userData) + netData, _ := database.FetchRecords(database.NETWORKS_TABLE_NAME) + data.Networks = len(netData) + data.Version = servercfg.GetVersion() + nodes, err := logic.GetAllNodes() + if err == nil { + data.Nodes = len(nodes) + data.Count = getClientCount(nodes) + } + return data, err +} + +// setTelemetryTimestamp - Give the entry in the DB a new timestamp +func setTelemetryTimestamp(uuid string) error { + lastsend := time.Now().Unix() + var serverTelData = models.Telemetry{ + UUID: uuid, + LastSend: lastsend, + } + jsonObj, err := json.Marshal(serverTelData) + if err != nil { + return err + } + err = database.Insert(database.SERVER_UUID_RECORD_KEY, string(jsonObj), database.SERVER_UUID_TABLE_NAME) + return err +} + +// getClientCount - returns counts of nodes with various OS types and conditions +func getClientCount(nodes []models.Node) ClientCount { + var count ClientCount + for _, node := range nodes { + switch node.OS { + case "macos": + count.MacOS += 1 + case "windows": + count.Windows += 1 + case "linux": + count.Linux += 1 + case "freebsd": + count.FreeBSD += 1 + } + if !(node.IsServer == "yes") { + count.NonServer += 1 + } + } + return count +} + +// fetchTelemetryRecord - get the existing UUID and Timestamp from the DB +func fetchTelemetryRecord() (models.Telemetry, error) { + var rawData string + var telObj models.Telemetry + var err error + rawData, err = database.FetchRecord(database.SERVER_UUID_TABLE_NAME, database.SERVER_UUID_RECORD_KEY) + if err != nil { + return telObj, err + } + err = json.Unmarshal([]byte(rawData), &telObj) + return telObj, err +} + +// TelemetryData - What data to send to posthog +type TelemetryData struct { + Nodes int + ExtClients int + Users int + Count ClientCount + Networks int + Version string +} + +// ClientCount - What types of netclients we're tallying +type ClientCount struct { + MacOS int + Windows int + Linux int + FreeBSD int + K8S int + Docker int + NonServer int +} From 2f12ded90600b237f7562518fd8b319e0a741846 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Thu, 20 Jan 2022 17:52:49 -0500 Subject: [PATCH 2/7] adding telemetry --- models/structs.go | 2 +- servercfg/serverconf.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/models/structs.go b/models/structs.go index 21720325..3e772bc3 100644 --- a/models/structs.go +++ b/models/structs.go @@ -164,7 +164,7 @@ type ServerUpdateData struct { Node Node `json:"servernode" bson:"servernode"` } -// ServerUUID - contains UUID of the server +// Telemetry - contains UUID of the server and timestamp of last send to posthog type Telemetry struct { UUID string `json:"uuid" bson:"uuid"` LastSend int64 `json:"lastsend" bson:"lastsend"` diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index d0c52fe3..08c90a1c 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -320,7 +320,7 @@ func IsClientMode() string { return isclient } -// IsClientMode - checks if it should run in client mode +// Telemetry - checks if telemetry data should be sent func Telemetry() string { telemetry := "on" if os.Getenv("TELEMETRY") == "off" { From 351a2ac5a8ae299fbe2ffe9ebc619974945ff271 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Fri, 21 Jan 2022 14:16:28 -0500 Subject: [PATCH 3/7] switch time to 24 hour checkins --- database/database.go | 2 +- serverctl/telemetry.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/database/database.go b/database/database.go index 689ae2f0..d1a1279e 100644 --- a/database/database.go +++ b/database/database.go @@ -194,7 +194,7 @@ func FetchRecords(tableName string) (map[string]string, error) { return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName) } -// FetchRecords - fetches all records in given table +// InitializeUUID - create a UUID record for server if none exists func InitializeUUID() error { records, err := FetchRecords(SERVER_UUID_TABLE_NAME) if err != nil { diff --git a/serverctl/telemetry.go b/serverctl/telemetry.go index ec77e868..574a32b9 100644 --- a/serverctl/telemetry.go +++ b/serverctl/telemetry.go @@ -28,9 +28,9 @@ func TelemetryCheckpoint() error { if err != nil { return err } - // sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(TELEMETRY_HOURS_BETWEEN_SEND)) + sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Hour * time.Duration(TELEMETRY_HOURS_BETWEEN_SEND)) // can set to 2 minutes for testing - sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2) + //sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2) enoughTimeElapsed := time.Now().After(sendtime) // if more than 24 hours has elapsed, send telemetry to posthog From 4f3d5dbddc2ca19c883eeb21be760b428946ec70 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Fri, 21 Jan 2022 15:05:54 -0500 Subject: [PATCH 4/7] saving docs --- docs/_build/doctrees/environment.pickle | Bin 102517 -> 103013 bytes .../doctrees/server-installation.doctree | Bin 123403 -> 125417 bytes .../_build/html/_sources/architecture.rst.txt | 6 ++-- .../html/_sources/server-installation.rst.txt | 27 ++++++++++---- docs/_build/html/searchindex.js | 2 +- docs/_build/html/server-installation.html | 33 ++++++++++++------ docs/server-installation.rst | 27 ++++++++++---- 7 files changed, 66 insertions(+), 29 deletions(-) diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index fdf62fb7d29acdf02c124d3e2bca96b47bfdaeea..7bd24483f68cd91d5dec7f84f756d5e79a58aaa3 100644 GIT binary patch literal 103013 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 Oi(iE9qKI!yPyBx;tQPtJ literal 102517 zcmd6Qd6*nmb+4>t_Epkov1PmMwy|W~GhQ&5CB%ay%d(`gEXh{zvuM?H*GzY*H&<0l zGZ+Jo0eeC{5OI?ao>>zD*?7rE0`KKP@(6n{n0?CvVR1;<5=cn$!6SL++;gjLRo&|8 zx>wU9%^y|M_ue}9-19s4+;jJrZ+QKhH5aYHKX0ScD3xmqlVT-!8@WxM6=oGR6;=9Ez}7p7{aTQyFZ_7o&= zrt-5$2>-{#PRr|Y>;n5{Tf1){O`%?!E6=yQVa}WXyJt5=1kCi;Pn)(~E&}BTTiyo8 zbeoJhbHO!hPPtxlS|?iG7QcuK?qs>eD>rsTHc6jRvQ(= zHJyCJa7)O{Kt2cq2FA>VLZw+WF&Y?S{Or57B;s41!NApMBx^1>h zZ=mE>D|xqMRw1`hDo?%&8QEo{((*R5Xs1*^lXvP(yI@wzwNtGnZ=?7uUvIcfKnQAo z%{ZNR%Wegz4f~SF>;VKpGPc>M=bJW=y{hE84d*#iQ}boF)SR6x)T>kTws9Ih6u1MY z?2DQKyp^^B?YaX9%^G&=Q6A+kHXx%Oq5?S<>Xo{kZ`kFkVJ|{NxmGOC*FnA%VH65X zD+ekFN^Z8&gs=N6_4#_f464!cdY_hEFmHM0vq2Q|mHMnvaqESA(QJUk53KbziZGy8 zF&co-qfKv^WJIhn{aJhMwSdr0Zv;u_Tu`D(Oam|m6nMaJrCwmU_z4`-unVQx`T_-* zjyGa9nzQ+W9BH z%AmAR4UV+D^^>-PRn|5g*KQWvCPX9eEyo+KHLFmO@^f_?bc0pjUWaIbA|9pxGFM}@ zgk4O4~~YrtF1Ejg_}mI>|mQ?I>MJ zG&Z>PqOs_Qd;RQZey-}aW+*{l#i-3Ujd{}#7-UG9d9XPQgI@aWv<&)S8x=h7f5*^b zs_Siez^>Qb2PYr!;~snf#QI>1KFrLUP-7R|yiut@HJfX`_{EEP*EVVn)OQBflGn@A zpdh?~s^LKW%!4fi0|6>-E^tzPm=6mtEimGx{iQ>c%P7|dvj(CEVT0Z`-MQQ?Ij1~N zUze^ZT}f$&isqcrthjl*4!CiFY%_{QV6Mg#2&{|^HK}AefYhV()fgtI){D)Gna6Sm z5tq79A3=5MZmsT`dE1-=#j6#}ywflWW^0LO%8U#dM8^*tX)MlTL*nEecaibJaNSsf z`pfEYAZ`GgbIoNjF471C#j+}0R=S+@W7M~x`B||23~NSz_>^fj@@EXY29gSx8F!kE z22>75#GK%nZGmz#AV4Rp)p`v~kcpKJ;u*mKs9AZlQ3iY9%aa9xCWnGHGC^Sz2Q@H1 zS1}-OF5D4r(*WG6Q3gx3wgKA9s>4tX8cz@qYkgZYGpHhC6b4%5w_XoI3`7i7jamb= z+F^Fs*Y#T2ZIlbA7F$a!(Fp&YFVEMol{i7)ZjJ^6kn^BJ_^R9l!pYfpw6KF{@3Fy+`J!z=$jnQ>Y)Dx)HYu>18&91LrpKwE&4%& z7*qi5vRx+-c+oJ_H082p)cj;@TuOYe{MOdg+rnmu$V@-2uD}@cRFz$qad1XY1A-^o3X(rfD7DFu& zFi(#d54_%H?NqIP#wSSmI|b%_lzu>8^|7y- zsbs+f3$rFun6#Q5I3!Rl1fNJ4!)L;EuovWS(pW ztXmT;I&0dvbsS?KKv`|q_Z`!GMy_k5Vd!U+(CdOK&MfZ`3z-Ag5*<7WEbT4bMm+B; z-A>6k3&>U>QY>$j5dceS8_|df$_v`!e6vvmj~SXr=09M*rRSEON0ccUw2dIⅆW+ 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 IH)kjRKkmn(K>z>% diff --git a/docs/_build/doctrees/server-installation.doctree b/docs/_build/doctrees/server-installation.doctree index 5b952659eece6a33c3aa286e967aea18bc906309..8461da319b3b12a6e7f851facca14b7203fe3697 100644 GIT binary patch delta 9320 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 bWL9tlCP;AuH0LiwDjF&~gd#g~1PcBK_YP6a delta 7442 zcmbVRdwfk-_Rrdhd(S~0H?JG=a6LjE4GDsvA~iaVG#AzBs5ZC=$(7th9*pUjBo!nT zk+_LH`fF24WarSLHZe01k(XX;g^MLJs-?u}ebIJD|BOJN8b1Y>=mV8HPnXRC}l3nDOSM-aA zEH=j+%ebPF++SFySmKI`%kqmHwu1P9O?k$gro8Z}(m3}2W$gU!+Wb+g9xt+p03~G) zSQh14N^)lx6&B`-5Oa$P3W^rxJLXx+@^UTKdHIgtNGK)cvoU0;XgF729#nx4a~-x> z1-X_fQyvv&C6>iS(c-GU=l{tvZku0B~5X8UGBI_|8Ibk zue?b6On>M0HY=O&?}RV=vqFF8z)K@pzCT~k2EClMm&|ODzw^Z}C-nbH>iYPU&k{)_ zSmu@I&&j7`QDJh8VLjNQS@Db~$9{v>*IIUF+}TBVIN6^JA-F zh?@0{?Dz3;o@IT8buU>^kY6Tho?BL4tdD)2=gZDo**BA?SNwU#dPol1h)u}z&5O!Q z%!|&t!jl=qI2YY$gFQ~$%>uSxFM#6<)zm6<%kvWK9R>+zkH53(p#(#_fbxdW>JELl zr5pIcPUnnUntFlad?9<{jalCdwX<$&Y^VR4r9GStKMnE5(9TaDfmrCyZyym*DsKnE z6(@9$alUptNmT=6Xk&mxAL@rq7y2K?nEZ`5)m`}oA`)U#*s zOn_<_hd~k`y)%H}h6vynz+c)7{kWAuIy}Ye8H|J+evrXj$dv{xCje{M<(5!>Qlfz; zczZX9)Qj+B>@@=rp!f}lSUKs8L{2aOQy4gMDY$_P{7N30&tQ6N^` zL*;vu$``cDvwR)eUlr&N>H*UFAOOiW)CeE~?$T44))fZBX}+o}3|CH*-Wi!RxAX5Q+-{JdTp^3AWYMr0RG!>bQ07}Vi-(ypkf(KrL8>uO4z?PI z7JE50$ zh*y=eeYG6{Q0B)b2RdO)jI;Q|Fdmo!kwz6=>3BEG4}vLNW{^6bDf*-3Gx?V5>cIF^rHZT5<~f7FbIV zKQ>Y+ZT)HQah(NOT|BW zBUidT!yrewOj%yKQw=!JJ05^&%`qGlVAn(zuZksO?Fg95es<5IUm9d$cTpNtM+BJe zm4@i;HWJ>KPDa8?*4xxs1p~9k^JSx840g7Tf|{6=`?#R<179^->{Wvv>B{RzLnK_I z%8bLxoDafT!f%X*cJ)!=M7)|{qFFTFtv_Q7WUAAsf2!X9OX|ll4b#q#fjT z;e5LlqK%ol%1JBCFjnY|Q4`@g$RJ8xoCx`9J^8IO(OIDun=V3Cb3O_7t1pn!^Lp^* z=&aTx3B_NZ47=HuJF#h@RBK3s4ln%jW00i2O+NPMfi%xR_1g3)(Cn)oBCP{@qz3e( znPizJ{2Gp`r>Or^y??FVkCUf(DhvTKH#EVT{^Nrr+rRzV-yLPMiKD3}NhN z6L&rZCzui}s@cb62$sY0vrv|Y!BpPyB&70VPs4bjDp#YSIS|VtQ9WL~(w65y37{Lf z96gT!zc%p=ry!JP&VXNfBV0#g@$L-BP%(mU*$Mi9_uXB5q#k))Q4L1BCs*#9O->d5e{I4Bf)&b0T{sB z7DH0RRqV&}o>4q>p7*W>^MSvGq3k+h@1yDzxE4$s$077`MKAUWY?N`11j~IiWC`pC zb!3P@8)+XALQBL)?&)MyK)g8%74AwWi&s@ZGEDMBkxeL$qLWNF6c2~UWF`w(=K1&Z zH=nPp6zAY#Pk)8v?_>0rf49G1RYAIEaaQwiP`&<7uh(&^mt0HsRl_=UFZKUL??0*c<65$P86DG+xy# zCfDEw$n;FY#%miO1!j9DF@usgho(=tB{B8BNl4YSP&tS%G{RD)nm{~DAkMpis9gg# zPY~<)zt_Nn@IRg)IDxo`rcO5y4fh2hRSASgf}@0>4b2X_Avhor^ti`ZO4T$iio^51@T2sG)Kabr9Jo(uDKA1g)8bx)EXJ;e z(q8nHgcT|Yu>U29^(MesB7k{4^j4z6BmsKzvFjlv$c!!5_+Qbg*29y);=<^l`0ou+ z04dzGMVu4g5$8lEc(7_CJOOe1!bVta&JgBz9~I;HbDJO4Y8uUh<6+>Tv1xg9!Q!Mi_6?*3L187HI zfjUqtN$d9_FY#4uxQ>ttdCO)PFV?9Gn;}+dBn>Afn`pR!3ajy1U&HId3nal7 zzH7Jt0k!uBWlv$CI5_mS!?RDH)oRliN~#(x8}!&|}6mz@#7Uxh7j z0j=a%D15_f;FH-P`D(5xF>i6lH>(| zu|xKU$(`xY4u}R86;4Fx@;dy1#fEpDmF;3di{AxX&BKJ3yW>XjFL#NLXkm?URbW_d zfe>%Jc+DH)MD#dCe+;9i1Wm-2i-vw$um+!lGK-XExfu{ z4UZ|$kmX`>ztGdYs*TzM--A+1N-JFM4c*ZFLT$m@(APJ(xzo&=7i}${WjFFazAI|p z5{}0QMc?(CdE{Qf_GZe};4eM!NgsfjuiOjAn1vR`1Pz0iS87YP%z!$-lFsa2#^K~W43U=#;8eFClO zYU*000~jc~%=9^)d|d2`Vn@Ovx$c>gNk!84@Cg{>4KIPg0e0~9r(nAG)ELDBPJ@$)HF48vc#c7LZQ$Rb)prnnfs2zeewEwo zxWtMEF1xn!I-|o@n43SR6tC*-mqaA{c{A_xPbjZggP-lm;+ojrh)?w>KwJ>oZ{xci z__Pg0E_Td9QHx?Z3V8`2zx)4z*8zV+QHa8h;v|YsP`roYT@=f4;a`d(0!5gqLda40 zI0A*-DdgrbPb@O_IVjq&;}VKA@d;obhT<@a11OG(bDjMNieX}7wGTlNie@GhGf+H@ zA`8VMD9&Q`XHayA<^=ms_;Re6bM^;Ol%gm`F&}mEP;5i-zbHOMaa@STmc)=u!21GXf_#!pz^e&j0^Si26Yxu%n1G*}!~{I`6BF=!OiaL& z5;5T+e3DGSy@!bKBR(M!670h}nSi?*F#$IqVgfEQk_lpxZoL546noDIykRTlEf?Wa zRvLldqWyfuwH_~SgJk~ECFnKOAymY)_WF6_R{1PjU2s{6%~2|TtSg*Rm|I$En` guide to enable SSL for your environment. +Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you may want to optionally install a database (sqlite is embedded, rqlite or postgres are supported) and CoreDNS (also optional). Once this is enabled and configured for a domain, you can continue with the below. The recommended server runs Ubuntu 20.04. -rqlite Setup ----------------- +Database Setup (optional) +-------------------------- + +You can run the netmaker binary standalone and it will run an embedded sqlite server. Data goes in the data/ directory. Optionally, you can run PostgreSQL or rqlite. Instructions for rqlite are below. + 1. Install rqlite on your server: https://github.com/rqlite/rqlite 2. Run rqlite: rqlited -node-id 1 ~/node.1 +If using rqlite or postgres, you must change the DATABASE environment/config variable and enter connection details. + Server Setup ------------- 1. **Run the install script:** @@ -271,8 +274,18 @@ The following uses Nginx as an http server. You may alternatively use Apache or sudo sh -c 'BACKEND_URL=http://:PORT /usr/share/nginx/html/generate_config_js.sh >/usr/share/nginx/html/config.js' sudo systemctl start nginx -CoreDNS Setup ----------------- +CoreDNS Setup (optional) +---------------------------- + +CoreDNS is only required if you want private DNS features. Once installed, you must set the CoreDNS variables in the env settings of the server. + +See https://coredns.io/manual/toc/#installation + +Proxy / Load Balancer +------------------------ + +You will need to proxy connections to your UI and Server. By default the ports are 8081, 8082, and 50051 (grpc). This proxy should handle SSL certificates. We recommend Caddy or Nginx (you can follow the Nginx guide in these docs). The proxy must be able to handle gRPC connections. + .. _KubeInstall: diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js index da8fa32d..5779273a 100644 --- a/docs/_build/html/searchindex.js +++ b/docs/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["about","api","architecture","client-installation","conduct","egress-gateway","external-clients","getting-started","index","install","license","oauth","quick-start","relay-server","server-installation","support","troubleshoot","ui-reference","upgrades","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["about.rst","api.rst","architecture.rst","client-installation.rst","conduct.rst","egress-gateway.rst","external-clients.rst","getting-started.rst","index.rst","install.rst","license.rst","oauth.rst","quick-start.rst","relay-server.rst","server-installation.rst","support.rst","troubleshoot.rst","ui-reference.rst","upgrades.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,3,5,6,7,8,14,16,18],"04":[12,14],"06":1,"0afehuytvin":3,"0g":3,"1":[1,3,4,6,8,10,16,17],"10":[1,2,3,5,6,7,14],"100":[1,7],"101":3,"1024":17,"11":[3,5,6,7,14],"12":[5,7,13],"127":14,"128":5,"1280":17,"13":5,"14":5,"1420":17,"147":3,"15":[3,5],"16":[1,2,5],"160":5,"168":[3,5],"169":5,"170":[3,5],"172":[1,5],"173":5,"174":5,"176":5,"182":3,"192":[3,5],"193":5,"194":5,"196":5,"1gb":12,"1node":17,"2":[1,3,8,16,17],"20":[3,6,7,12,14],"200":[1,5],"203":3,"208":5,"22":3,"236":6,"24":[2,3,6,7],"245":14,"247":6,"25":7,"251":3,"254":7,"2a":3,"2cpu":12,"2gb":12,"3":[3,5,6,8],"30":[7,12,14,17],"31":1,"32":[3,5,6],"34":3,"3rd":17,"4":[3,4,5,8,18],"4001":14,"4002":14,"41":3,"443":[12,14],"4b":3,"4gb":12,"5":[5,6,11,14,17],"50051":[2,3,7,14],"51821":[3,7,12],"51822":6,"51830":12,"518xx":12,"53":[3,12,14],"5432":14,"5c":3,"5qktbtgsvb45y3qyrmwft":3,"6":5,"60":6,"64":5,"6400":1,"68":3,"69":14,"6c":3,"7":[3,5,6,16],"70":1,"75":14,"77":3,"78":3,"7b":3,"8":[2,3,5,6,11,14,16],"80":14,"8081":[1,2,3,14],"8082":14,"8c":1,"9":[5,12,14,18],"90":1,"91":3,"98":7,"99":7,"abstract":2,"break":[3,7],"case":[1,2,3,6,7,8,9,12,14,16,17,18,19],"class":14,"default":[1,2,3,6,7,11,12,13,14,16,17],"do":[0,1,2,3,4,5,6,7,12,13,14,16,17],"final":[5,16],"function":[1,3,7,13,14,15,16],"import":[2,5,6,7],"long":[0,7,15],"new":[2,3,5,7,17,18],"public":[2,3,4,5,6,7,10,12,13,14,17],"return":[2,5,7],"short":3,"static":[2,5,12,14,16,17],"super":17,"switch":[14,17],"true":[2,3,14],"try":[3,5,15,16],"var":[1,14],"while":[2,5,15],A:[2,3,5,6,7,8,12,14,16,17],And:14,As:[0,2,3,5,11,12,15,16,18],At:[0,2,3,5,12,13],Be:[12,14],Being:4,But:[7,14],By:[0,1,6,11,12,14,17],For:[2,3,5,6,7,8,9,11,12,13,14,16,17],If:[0,1,2,3,6,7,11,12,13,14,15,16,17,19],In:[0,1,2,3,4,5,7,11,12,13,14,16,18],Is:[7,16,17],It:[0,2,3,6,7,14,15,16,17,19],No:15,Not:[2,17],On:[2,3,14,17],Or:12,Such:5,That:2,The:[0,1,2,3,4,5,6,7,12,14,17],Then:[6,7,13,16],There:[0,1,3,7,14,15,16],These:[2,3,5,7,14,17],To:[2,3,6,7,12,13,14,18],Will:3,With:[2,14,17],a6:3,aa3bvg0rnitirxdx:1,abil:[15,16],abl:[1,2,5,6,14],abou:7,about:[2,3,7,12,14,16,17],abov:[2,3,7,13,14],absent:3,abus:4,accept:[3,4,6],access:[0,2,3,6,7,8,11,12,14,15,16,17,19],access_token_valu:14,accesskei:[1,3],accomplish:15,account:[4,16],acess:5,achiev:[1,2,14,15,16],across:[0,3,17],act:[2,4,5,6,17],action:[1,3,4],activ:16,actual:2,ad:[2,7,8,11,14,17,18],adapt:[4,14],add:[0,1,2,3,6,7,14,17,18],addit:[2,3,5,7,14,16,17],addition:[11,12],addnetwork:1,addr:[3,14],address:[2,3,4,5,6,7,13,14,16,17],addressipv6:3,addressrang:1,adequ:14,adm:1,admin:[0,1,2,3,7,11,14,16,17],administr:3,adopt:2,adv:14,advanc:[1,4,7,9,12],advfirewal:3,affect:17,after:[2,3,5,6,7,11,13,17],ag:4,again:12,against:3,agent:[0,2,3,7,8,14,16],agent_backend:14,agentbackend:14,aggreg:2,alex:3,algo:15,align:4,aliv:17,all:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17],allow:[1,2,3,5,6,7,12,13,14,16,17,19],allowedip:[3,6,17],allowedorigin:14,almost:[7,17],along:16,alongsid:14,alreadi:[2,3,7,14],also:[0,1,2,7,11,12,14,16,17],altern:[2,14],although:16,alwai:[5,7,14,17],am:16,an:[0,2,3,4,7,8,11,12,14,16,17,19],android:[2,16,17],ani:[0,2,3,4,6,7,11,12,13,14,16,17,18],annot:[8,17],anoth:[2,5,16],answer:16,anymor:16,anyth:[2,17],anywher:12,aorijqalrik3ajflaqrdajhkr:1,apach:[2,14],api:[2,3,7,11,12,14],api_port:14,apiaddress:3,apihost:14,apiport:14,apiserv:3,app:[6,14,15,16,17],appear:[4,7,17],appli:[4,14],applic:[1,14],appoint:4,appropri:[2,4,6,7,14,17,18],approv:[1,3,7,15,17],aprov:16,apt:12,ar:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18],arbitrari:[0,14,17],arch:[2,7],architectur:[8,14],argument:3,arm:[3,7],around:[12,17],arrai:2,artifact:10,ask:[3,16],asset:14,assign:17,assum:[2,6,12,14,16,17],attach:6,attack:4,attempt:[2,17],attent:4,attribut:8,auth:[11,14],auth_provid:11,authent:[2,3,7],author:1,autofil:17,autom:[0,18],automat:[3,6,14,17],avail:[3,4,8,9,10,17],avoid:[14,17],aw:[0,12,15],awai:2,await:2,azur:11,azure_ten:11,b5:1,back:[2,6,14],backend:14,backend_url:14,background:2,ban:4,bare:[2,8],base64:7,base:[2,3,5,11,12,14,17,18],basedomain:14,bash:[2,3,16],basi:2,basic:19,bcrypt:14,bearer:1,becaus:[0,2,14,16,17],becom:[2,14,16,17],been:[2,3,5,12,14,17],befor:[2,12,16],begin:[2,5,12],behavior:4,behind:[2,6,12,13,16],being:[2,3,14,16,17],believ:15,bellow:14,belong:17,below:[1,2,6,7,13,14,18],benefit:7,besid:2,best:[4,7,15,17],better:[2,17],between:[0,2,17],bewar:3,beyond:14,bin:14,bin_t:16,binari:[2,3,7,9,14,16,18],bind:[12,14],bit:19,biz:12,blank:[3,6,11],blob:14,block:[8,14,16],bodi:4,both:[2,4,5,12,14,15,17],bottleneck:13,bottom:7,bound:12,brief:7,brought:17,brows:[5,15],bsherman:14,build:2,built:2,busi:[12,16],button:[13,16,17],c:[12,14],caddi:14,caddyfil:12,call:[0,2,3,8,14],callabl:3,callback:11,can:[0,1,2,3,5,6,7,10,11,13,14,15,16,17,18,19],candid:5,cang:14,cannot:[3,6,7,12,17],cap_add:14,car:15,cat:16,caus:[2,12,17],cd:2,center:[0,5,7,17],cento:2,cert:14,certain:[2,17],certif:14,certmanag:14,cgnat:[13,17],chang:[0,1,2,3,5,6,7,13,14,16,17,18],charact:[16,17],chart:14,chcon:16,check:[1,2,3,7,12,14,16,17],checkin:[1,2,3,17,18],choic:[6,13,14],choos:[3,9,13,14],chosen:[2,3],cidr:[7,14,17],circumst:[3,4,7],circumv:13,clarifi:4,classnam:14,clear:15,cli:2,click:[2,5,7,11,13,16,17],client:[0,5,7,11,12,14,16],client_id:11,client_max_body_s:14,client_mod:14,client_secret:11,clientmod:14,clone:2,close:18,cloud:[0,12,19],cluster:[14,19],cluster_mgmt:14,clusterip:14,clusterissu:14,code:[2,3,6,10,14,16,17],com:[3,4,7,11,12,14,15,16,18],combin:[5,14,17],come:[2,5,14],comfort:12,comm:3,comma:17,command:[2,3,7,12,14,16,17],comment:[4,14],commit:4,common:[2,5,8,12],commonli:16,commun:[2,3,4,7,8,14,15,16,17],compar:15,compat:[5,6,8,17],compil:[2,3],complaint:4,complet:[2,16],complex:2,complic:2,compon:[8,14,17],compos:[7,8,16,18],comput:[0,2,3],concept:8,concurr:12,conf:[6,14],confidenti:4,config:[1,2,6,17,18],configur:[0,1,2,7,12,16,17],confirm:[17,18],conflict:[14,17],connect:[0,2,3,6,7,13,14,16,17,19],consensu:[2,16],consequ:14,consid:[4,7],consider:2,consist:[2,14],consol:7,construct:4,consult:[14,16],consum:[3,14],contact:[4,8,12,14],contain:[2,7,12,14,17],container_nam:14,content:1,context:14,continu:[14,16],contrast:2,contribut:4,contributor:4,control:[2,7,14],convert:[3,16,17],copi:[7,14],core:[0,8],coredn:[3,8,12],coredns_addr:14,coredns_address:14,coredns_ip:12,corednsaddr:3,corefil:14,coreo:2,corpor:[14,15,16],correct:[4,12,18],correctli:[2,14,17],cors_allowed_origin:14,could:[0,4,7,16,17],countri:5,cours:5,coven:4,cover:8,cp:14,cpu:[12,16],creat:[0,1,2,3,4,5,6,8,12,13,14,16],createadmin:1,creategatewai:1,creation:[0,7,13,17],credenti:14,credit:16,critic:[4,14],cron:2,cross:19,cryptocurr:0,curl:[7,14],current:[2,3,14,16,17],custom:[2,8,12,14],customiz:14,cycl:[1,2],d9:1,d:[1,2,12,14,17,18],daemon:2,dashboard:[8,11,12,14],data:[0,2,5,7,14,16,17],databas:[14,16],datastor:14,date:1,datetim:17,db:[2,8,14],dc:12,ddflzqn:6,debian:2,debug:14,decod:[2,3,7],deem:4,defin:[4,7,17],delet:[1,6,7,14,16,17],deletegatewai:1,deni:16,depend:[2,3,8,16,17,18],depends_on:14,deploi:[2,3,5,8,12,14,16],deploy:[2,14],depreci:[14,17],derogatori:4,design:[2,3,6,13,14,16],desktop:[2,3,6,17],detail:[1,2,3,4,7,8,14],determin:[4,5,17],dev:[12,14],devic:[0,2,3,8,16,17],diagram:2,differ:[0,2,4,5,7,14,15],difficult:17,digitalocean:12,dir:3,direct:13,directli:[0,1,2,6,12,13,14,16],directori:14,disabl:[2,4,17],disable_remote_ip_check:14,disableremoteipcheck:14,disconnect:16,discord:[15,16],discuss:[14,18],displai:[2,14,17],display_kei:14,displaynam:1,distibut:2,distribut:[2,7,14,17],distributionshav:2,dn:[2,8,16,19],dns_mode:[14,16],dnsconfig:14,dnsmode:14,dnson:3,dnsstublisten:14,doc:[7,11,12,14,17],docker:[2,7,8,9,11,16,18],document:[0,2,3,7,14,15],doe:[2,3,6,8,14,16,17],doesn:16,domain:[11,12,14,16],don:[2,3,7,19],done:16,dont:[7,16],doubl:13,down:[0,5,7,11,13,14,16,17,18],download:[3,6,7,14,16,17,18],dual:[3,7,16,17,19],dualstack:17,due:[13,16],duplic:3,dure:[3,17],dynam:[0,2,8,17],e:[2,3,4,5,7,12,14,16,18],each:[0,2,3,7,8,11,14,16,17],easi:[2,14,17],easier:2,easiest:2,easili:[0,5,7,14],echo:12,edit:[4,6,8,13,14,16],effect:[7,17],effici:[2,5],egress:[3,6,15],either:[2,6,13,18],ejf6yy51m:6,electron:4,elev:[11,14],elimin:2,els:17,email:[12,15],empathi:4,empti:14,enabl:[2,5,7,12,14,17],encod:7,encompass:[0,5],encount:2,encrypt:[0,2,3,5,16],end:[2,12,14,16,17],endpoint:[1,2,3,6,7,17],enforc:8,enough:14,enpoint:17,ensur:[13,14,15,18],enter:[7,13,17],enterpris:[12,14],entir:7,entireti:2,entri:[14,16,17],env:[1,14],environ:[0,1,2,4,11,14,16,17],equal:14,equival:14,error:17,essenti:13,establish:6,etc:[3,7,12,14,16,18],eth0:[1,17],eth2:5,ethnic:4,evalu:15,even:[0,2],event:4,everi:[2,3,7,17],everyon:4,everyth:[2,5,14,17],evolv:2,ex:[3,7,12,14],exampl:[2,3,4,5,6,8,11,12,17],except:[7,11,14,17],execut:14,exist:[0,2,7,14,17],expect:[4,5,8,14,17,18],experi:[3,4,9,16],expir:17,explain:2,explicit:4,explicitli:14,exploit:14,expos:2,express:4,expressvpn:15,ext:[5,8,16],extend:14,extens:2,extern:[3,5,14,17],f1:1,f8:3,f:[3,14,16],face:[4,5],fact:0,fail:[2,7,11],fair:4,fairli:[2,16],faith:4,fallback:17,fals:[3,14],familiar:[0,2,15,16],faq:8,fast:[2,8,14],faster:[0,2,3,17],fcontext:16,featur:[12,14,17],fedora:2,few:[3,7,15,17],field:[5,6,7,8,13,14,17,18],figur:19,file:[2,6,17,18],filenam:1,fill:17,filter:17,find:[2,14,17,18,19],fine:0,firewal:[3,7,8,13,14,16],first:[2,3,5,7,8,11,14,16,17,19],fit:[12,19],flag:3,flat:0,flexibl:0,flow:2,focus:4,folder:[2,14,18],follow:[2,3,4,5,7,11,12,14,16],forc:14,form:[3,7,17],format:[11,14],forum:16,forward:[3,5,6],foster:4,found:[0,2,10,11,14],free:[4,17],freebsd:2,freeli:10,frequent:[5,16,17],friend:16,from:[0,1,2,3,4,5,6,7,9,12,13,14,16,17,19],front:[2,14],frontend_url:11,full:[0,2,14],fulli:[0,2],further:4,furthermor:14,futur:[7,12,18],g:[3,7,12,14],gatewai:[1,2,3,8,15,16,17,19],gb:16,gcp:12,gender:4,gener:[1,2,3,6,9,11,12,14,15,17],generate_config_j:14,get:[1,3,5,12,14,16,17,18],gg:15,github:[2,3,8,11,12,14,15,16,18],githubusercont:[3,7,12,14,16],give:[2,7,8,14,15,16],given:[0,2,5,7,16,17],global:[3,5],go:[2,3,5,8,13,14,16,17],goe:[0,14,17],golang:2,good:[4,5,6,7,13,15,16,17,19],googl:[11,14],grab:3,gracefulli:4,grade:14,grant:17,gravitl:[3,4,7,12,14,15,16,18],group:12,grpc:[2,3,7,12],grpc_port:14,grpc_ssl:14,grpcaddress:3,grpchost:14,grpcport:14,grpcserver:3,guid:[0,2,7,9,12,14,16],guidanc:8,guidelin:[14,15],h:[1,3],ha:[0,2,3,5,7,11,12,13,14,16,17,19],hand:8,handl:[0,2,12,14,17],handshak:[16,17],harass:4,hard:[13,16,17],harder:16,hardwar:[3,16,17],harm:4,hasadmin:1,hash:14,have:[0,2,3,4,5,6,7,11,12,13,14,16,17],haven:16,head:12,header:[1,2,14],health:17,heart:3,heavi:2,helm3:14,helm:14,help:[1,2,3,7,8,14,15,17,18],here:[2,4,7,10,12,14,15,17,19],hesit:15,high:[2,8,14,16],highli:[3,8,9],hit:16,hold:[0,2,3],holder:16,hole:[3,7,16,17],holepunch:3,home:[0,2,3,5,17],hook:[2,6],host:[2,3,12,14,15,17],host_ip:14,hostnam:17,hous:1,how:[2,3,5,8,14,16,17],howev:[1,2,3,5,12,14,16],html:14,http:[1,3,7,8,11,12,15,16,18],http_port:14,hub:[0,2,13,17],hundr:12,i:[3,12,14,16],id:[1,3,11,14,17],ideal:14,ident:4,identifi:3,ignor:[3,5,17],imag:[14,18],imageri:4,impact:[2,15],implement:[2,5],importantli:7,imposs:13,inappropri:4,inbound:[3,12],incid:4,includ:[2,4,6,8,14],inclus:4,incompat:18,incorrect:[3,14,16],increas:[2,17],independ:6,indic:[11,17],individu:[4,14,17],industri:2,info:[2,4,12,14,15],inform:[2,3,4,7,8,12,17],ingress:[2,3,5,16,17],ingressroutetcp:14,initi:[3,11],ins:2,insert:[5,12,14,16],insid:[8,14,17],instal:[0,2,6,7,16],instanc:[1,2,3,4,5,7,12,14,17],instead:[0,3,5,6,7,12,14,16,17],instruct:[11,14],insult:4,intact:3,integr:[8,14],intend:3,inter:17,interact:[0,2,3],interest:[4,16],interfac:[1,3,5,6,7,12,14,17],interfer:[12,16],intern:[5,14],internet:[0,2,5,15],intro:19,introduc:16,introduct:8,invalid:[6,7,17],investig:4,invis:[2,17],io:[11,12,14,16,17],iot:[0,2],ip:[2,3,5,6,7,12,13,14,17,18],ipaddress:17,ipforward:[3,17],iphon:2,ipsec:2,iptabl:[3,5,17],ipv4:[3,7,14,16,17],ipv6:[3,7,16,17,19],ipv6address:17,isdualstack:3,isingressgatewai:3,isloc:[3,17],isstat:3,issu:[2,3,4,8,12,13,14,17],issuer:14,issuernam:14,iter:17,its:[0,2,3,4,5,6,7,14,17],itself:[2,3,5,7,14],job:2,join:[2,3,7,14,16,17],journalctl:[3,14,16],jq:1,js:14,json:[1,14],just:[0,2,3,6,7,12,14,15,16,17],jwt:[1,3],k3:19,k8:14,k:[3,7],keep:[1,5,17],keepal:[3,17],kei:[2,3,8,11,12,14,16,17],kept:17,kernel:[0,2],keynam:1,keyupd:1,kill:16,know:[5,14,16,19],known:[2,12,17],kube:14,kubectl:14,kubernet:[0,5,9,17,19],lan:3,languag:4,laptop1:1,laptop:[6,17],larg:[2,17],last:[1,17,18],lastmodifi:1,latenc:2,later:2,latest:[2,3,6,14],launch:2,launchd:[2,3],launchdaemon:2,layer:0,layout:2,lb:14,le:14,leadership:4,least:[0,16],leav:[3,6,7,14,16,17,18],left:[7,11,14,16],length:[3,16,17],less:[2,7],let:[0,5,15,19],letsencrypt:14,level:[2,4,8,14,17],librari:2,light:14,lightweight:2,like:[0,2,3,7,14,17],limit:[3,8,14,16,17],line:[2,17],link:[8,11,12,14],linod:12,linux:[2,3,5,7,8,17],linuxserv:14,list:[0,2,3,5,13,14],listen:14,listenport:1,littl:[2,15],ln:14,load:2,local:[2,3,5,7,14,17],localaddress:[1,3],localhost:[1,14],localrang:3,locat:[0,2,3,5,14,17],log:[11,12,14,16],logic:6,login:[7,11],longer:17,look:[14,15,17],lookup:2,lose:17,lot:[2,3,16],lower:[16,17],lxc:14,m:[3,6,16],mac:[2,3,7,17],macaddress:[1,3],machin:[0,2,3,5,6,7,8,12,13,16,17,18],made:[0,2,16,17],mai:[1,2,3,4,7,11,12,13,14,16,17,18],mail:4,main:14,maintain:[4,14,15,17],make:[0,2,4,5,6,8,9,12,13,14,15,16,17],man:6,manag:[0,2,6,8,14,19],mani:[0,2,12,14,15,17,19],manual:[2,3,7,14,16,17,18],map:14,master:[3,7,12,14,16],master_kei:14,masterkei:[1,14],match:[3,14],maximum:14,md:[1,14],mean:[2,3,5,6,7,14,17],meant:14,measur:13,media:4,medium:9,meet:14,member:4,memori:16,mesh:[0,6,16,17,19],meshclient:1,metal:[2,8],method:[1,2,3,5,6,7,9],mgmt:1,microk8:[14,19],microsoft:11,middl:6,might:[0,2,13,14],min:12,minim:14,minimum:16,minor:18,mint:2,minu:14,minut:[12,14,16,17],mismatch:18,miss:[2,18],mix:3,mode:[2,7,8],model:[0,2],modif:14,modifi:[1,2,3,7,12,14,15,17],moment:17,mongo:14,mongodb:14,more:[0,1,2,6,7,8,12,14,15,17],most:[1,2,3,5,9,12,14,15,16,17],mostli:[2,3],mount:14,move:[7,12,18],mtu:[16,17],much:[0,2],mullvad:15,mullvadvpn:15,multipl:[0,7,14,16,17],must:[1,2,3,5,6,7,11,14,16,17,18],mv:18,my:[1,3,16,18],mydomain:11,mykei:[1,7],mynet:7,myserv:7,mysit:12,myvers:18,n:[2,3,7,12,14,16],name:[1,2,3,5,6,7,14,16,17],nameserv:[2,3,14],namespac:14,nat:[6,8,13,16,17],nation:4,nativ:2,navig:[11,12,16],nebula:[0,15],necessari:[2,3,4,14,17],need:[0,1,2,3,5,12,14,15,16,17,18],neg:15,neighborhood:0,neither:2,net:3,net_admin:14,netclient:[0,5,6,8,17],netclient_accesskei:3,netclient_accesstoken:3,netclient_address:3,netclient_addressipv6:3,netclient_api_serv:3,netclient_daemon:3,netclient_dn:3,netclient_endpoint:3,netclient_grpc_serv:3,netclient_interfac:3,netclient_ipforward:3,netclient_is_dualstack:3,netclient_is_loc:3,netclient_keepal:3,netclient_localaddress:3,netclient_localrang:3,netclient_macaddress:3,netclient_nam:3,netclient_network:3,netclient_o:3,netclient_password:3,netclient_port:3,netclient_postdown:3,netclient_postup:3,netclient_privatekei:3,netclient_publickei:3,netclient_roam:3,netclient_udp_holepunch:3,netconfig:[3,16,18],netid:1,netmak:[1,3,5,6,10,13,16,17,19],netmaker_base_domain:[12,14],netmaker_env:14,netsh:3,network:[0,5,6,8,11,12,13,14,15,16,18,19],network_mod:14,newli:18,next:[3,5,7,11],nextcloud:19,nf:14,nginx:[2,8,16],nip:12,nm:[3,14,17],node:[3,5,6,8,13,14,16],nodn:14,non:[2,3,7,9,14,17],none:0,noonewillguessthi:1,nopass:14,nordvpn:15,normal:14,notabl:14,note:[1,5,6,8,11,12,14,16,17],noteabl:7,notifi:2,now:[0,6,7,12,13,14,15,16,18],ns:14,number:[2,7,12,14,17],o:[12,14],oauth2:11,oauth_provid:11,object:14,oblig:4,obscur:17,obtain:[1,3],od:3,off:[2,3,7,14,16,17],offens:4,offer:11,offic:[0,5,19],offici:[1,4,16],offlin:4,often:[2,15,17],old:18,omit:14,onc:[5,6,7,11,14],one:[2,3,5,6,7,12,14,16,17],onli:[1,2,3,5,6,7,11,14,16,17,18],onlin:4,onto:17,open:[2,4,7,8,15,17],openvpn:[2,15],openwrt:[2,8,16],oper:[2,3,13,14,17],operatingsystem:3,opinion:12,oppos:[2,14],option:[2,3,8,11,14,17],oracl:12,order:[5,11,14,16],org:14,orient:4,origin:[11,14],os:[3,17],osi:15,other:[0,2,3,4,6,7,13,17],otherwis:[0,3,4,16,17],our:[8,14,16],out:[0,2,7,12,14,15,16,17,19],outlin:[2,14],output:[3,7,16],outsid:[8,14],over:[0,2,5,13,14,17],overlai:[0,8],overlap:[5,7],overrid:[3,14],overridden:[2,14],overview:[2,19],overwhelm:19,own:[2,12,14],p2p:17,p:[3,7,12,14],packag:[3,16],packet:17,page:[2,11,17],pair:[2,14],pane:7,panic:18,part:[2,3,14],parti:[16,17],partial:2,particip:4,particular:[2,3],pass:[2,3,14],password:[1,3,7,14,17],past:5,path:[1,14,15,17],peer:[2,3,6,7,13,16,17,19],pend:[1,7,17],peopl:[5,15,17],per:12,perform:[1,2,3,7,14],period:2,perm:14,perman:[4,14],permiss:[4,8,12,14,16],permit:7,persist:17,persistentkeepal:[3,6],person:4,perspect:[0,2],phone:[3,6],physic:4,pick:[2,7],pictur:2,ping:[7,16,17],pivpn:15,place:[3,12,13,14,18],plaintext:3,plan:[12,14,15,16],platform:[2,8],pleas:[3,8,12,14,15,16],pledg:8,plu:[3,12],poc:[9,12],pod:17,point:[2,5,12],polici:4,polit:4,popul:[14,17],port:[2,3,7,12,14,16,17],posgr:14,posit:4,possibl:[2,12],post:[1,2,3,4,14,17],postchang:3,postdown:[3,14,17],postgr:14,postgresql:[2,14],postgress:14,postup:[3,14,17],powershel:3,practic:2,pre:14,preced:2,precend:14,prefer:[12,14,16],prepar:8,prereqisit:7,prerequisit:[2,5,7,8,14],present:18,prevent:[3,17],previou:2,primari:[3,14,16,17],prior:14,privaci:15,privat:[2,4,5,7,8,14,15,17,19],privatekei:[3,6],privileg:14,privkei:3,probabl:[0,15],problem:[3,16],procedur:14,process:[3,7,8,14,18],prod:14,product:[12,14],profession:4,project:[1,4,14,15],proof:0,proper:14,properli:[3,16],properti:3,proto:12,protocol:[3,14],provid:[0,2,3,8,12,14,17],proxi:[8,11,12],proxy_pass:14,proxy_pass_request_head:14,proxy_set_head:14,pubkei:3,publickei:[1,3,6],publicli:[12,13],publish:[4,10],pull:[2,3,6,14,17,18],punch:[3,7,16,17],purchas:16,pure:17,push:[3,6],put:[1,17],q9cog7c9qjnoxygvri:3,qr:[6,16,17],quarantin:3,question:16,quick:[7,8,9,14,16,17],quickli:[12,16],quickstart:16,r:16,race:[4,15],raft:[2,14,16],ram:12,random:[14,17],randomli:17,rang:[3,5,6,7,12,14,17],rangestr:1,rare:17,raspian:2,rather:[11,14,17],raw:[3,7,12,14,16],rce:[14,17],re:[0,3,7,15,16],reach:[0,2,3,5,6,7,13,14,15,16,17],reachabl:[2,3,6,7,8,13,14,17],reactj:2,read:14,readm:[12,14],reallysecret:1,reason:[2,4,7,13,14,17],reboot:16,receiv:[1,2],recent:[2,3,16,17],recommend:[1,3,6,9,12,16],reconfigur:[2,3,16],record:[7,12,16],redirect:11,redund:14,refer:[2,7,16],regard:[2,4],regardless:4,regist:[2,3],registr:3,regularli:[15,17],reject:4,rejoin:18,rel:[2,5,18],relai:[2,3,6,16],relat:14,releas:[2,3,14,16,18],relev:17,reli:[0,3],reliabl:17,religion:4,remain:17,remot:[0,3,14],remoteip:3,remov:[1,2,4,7,14,16,17],removenetwork:1,renam:[3,16,18],repeat:7,repercuss:4,replac:[3,14],replace_master_kei:12,replica:14,replicacount:14,repo:[2,14],report:[2,4],repositori:[2,10],repres:4,represent:4,request:[1,2,14],requir:[1,2,3,7,16],resolv:[2,3,14],resolvectl:[3,14,17],resourc:[6,8,9],respect:[2,4],respons:[2,8],rest:[12,14],rest_backend:14,restart:[11,14,16],restbackend:14,restorecon:16,restrict:[13,14],result:4,retriev:[0,1,2,3,7],revers:[8,12],revert:3,review:4,rf:7,rhel:2,right:[0,4,17],risk:16,rkxlgk2mg:6,rm:7,rncjjbsaa3hzuhrk5hpyxm:3,roam:[3,17],rogu:16,root:[3,12,14,16,18],rout:[0,2,5,11,12,13,14,17],route53:12,router:[2,5,16],rpumvsbpgq:6,rqlite:16,rule:[3,5,12],run:[0,1,2,3,5,6,7,12,14,15,16,17,18],runtim:14,rv:16,rwo:14,rwx:14,s:[0,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],sai:5,said:2,same:[0,3,6,7,14,16,17],sampl:0,save:[7,12,18],saveconfig:17,sbilli:[3,16],scan:[6,17],scenario:[5,7,13,17],schedul:14,scope:8,screen:[7,11],screenshot:[8,17],script:[2,3,7,12,14,16],search:17,second:[5,7,17],secret:[1,3,7,11],secretkei:14,section:[3,14,17],secur:[0,1,2,3,5,8,12,16,17,19],sed:[12,14],see:[1,2,3,7,8,12,14,15,16,17],seem:7,select:[6,7,13,16,17],selector:14,self:[14,15],selinux:16,semanag:16,send:[2,3,14,17],sens:[2,9,15],sensibl:[0,2,7,17],sent:17,separ:[2,4,17,19],seper:16,serv:[2,14],server:[0,3,5,6,7,10,11,12,17],server_api_conn_str:14,server_api_host:14,server_grpc_conn_str:14,server_grpc_host:14,server_host:14,server_http_host:[11,14],server_nam:14,server_public_ip:12,servic:[2,3,5,6,12,14,17,19],set:[1,2,3,4,5,8,12,16,17,19],setup:[0,2,5,8,12],sever:[2,14],sexual:4,sf:14,sfl:[7,14],sh:[3,7,14,16],share:[14,16],shell:[3,16],should:[0,1,2,3,5,6,7,12,13,14,16,17],show:[3,4,14,16,17],shown:[6,17],shut:5,side:10,sign:[2,3,7,11,14,16],signific:2,signup:[2,3,16,17],similar:[0,7,14,15,17],simpl:[2,3,5,7,8,11,14,16],simplest:[2,3],simpli:[2,3,5,6,7,13,14,16],simplifi:[13,14],simultan:0,sinc:17,singl:[1,2,5,16,17],sit:17,site:[0,2,8,14,16,19],situat:[2,16,17],size:4,skip:14,skynet:1,slow:[0,13],slower:14,small:[2,7,9],smartgui:1,so:[0,2,3,5,6,7,12,14,16,17],social:4,sole:17,solut:2,solv:[2,17],some:[1,2,3,5,7,13,14,16,17],someth:[6,7,14,17],sometim:13,somewher:7,soon:16,sort:0,sourc:[2,3,8,10],space:[4,17],spec:16,special:[2,3,7,14],specif:[2,3,4,5,7,8,14,17],specifi:[3,5,11,13,14,17],speed:[0,2],split:3,spoke:[0,2,13,17],spread:0,sql:[2,14],sql_conn:14,sql_db:14,sql_host:14,sql_pass:14,sql_port:14,sql_user:14,sqlconn:14,sqldata:14,sqlite:[14,16],src:12,ssh:[7,12,18],ssl:14,sspl:10,stabl:5,stack:[3,7,16,17,19],stai:[3,17],stake:0,standard:[2,5,8,14,17],start:[14,16,19],startup:1,state:7,statement:8,statu:[3,14,16,17],step:[2,3,7,14,18],still:[0,14,18],stock:15,stop:14,storag:[12,14],storageclassnam:14,store:[2,14,17],straight:5,straightforward:18,string:[7,14],stuck:16,stun:[7,16],su:7,subdomain:[12,14],submit:7,subnet:[2,5,17],subscript:[12,16],subsequ:2,subspac:15,subspacecloud:15,substanti:0,success:[2,11],successfulli:11,sudo:[3,7,11,12,14,16],support:[2,12,14,16],sure:[12,15,16,17],surfshark:15,suse:2,swag:14,symbol:11,system:[7,8,12,17],system_u:16,systemctl:[3,14,16],systemd:[3,7,14,16],t:[2,3,7,16,19],tab:[7,16],tack:17,tail:3,tailscal:[0,15],take:[0,1,2,4,7,11,14,16,17],talk:[0,2],tcp:12,team:4,technic:[0,8,15],technolog:2,ted:17,tell:[0,2,3,13,14,16],templat:14,temporari:[4,17],temporarili:4,tenant:11,term:15,terrain:15,test:[7,9],than:[2,7,11,14,17],thei:[0,2,4,7,8,14,15,16,17],them:[2,7,14,15,16],themselv:[2,16],therefor:16,thi:[0,1,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],thing:[0,2,3,16],think:[5,15,19],third:16,thmpvlcykonxi:3,those:[0,2,3,5,6],thousand:0,threaten:4,three:[7,14],through:[2,13,14,17],ticket:15,time:[1,2,3,6,7,13,14,16,17,19],timer:2,timestamp:[2,17],tl:14,token:[3,7,14,16],too:[16,17],tool:[0,3,5],top:[2,16],topic:19,topolog:2,toward:4,tr:12,track:17,traffic:[0,2,5,6,13,14,16,17],trailofbit:15,transact:2,translat:17,travers:17,treat:[2,3,17],trial:[9,12],tricki:2,troll:4,troubleshooot:12,troubleshoot:[1,3,7,12],tune:17,tunnel:[0,2],tunnelbear:15,turn:[2,3,7,13,14,16,17],tutori:8,two:[0,1,2,3,5,7,14,16],type:[1,14],typi:17,typic:[0,2,5,6,7,13,14,16,17],u:[3,14,16],ua2zjt8wn7ga:6,ubuntu:[2,12,14],udp:[3,7,12,14,16,17],udpholepunch:3,ufw:12,ui:[1,3,5,6,18],unabl:[7,16],unaccept:4,unaccess:17,uncom:14,uncordon:1,under:[3,7,10,14,16],underlai:[0,19],underscores_in_head:14,unedit:17,unexpectedli:5,unfamiliar:7,uninstal:[8,16],uniqu:[3,12,17],unix:[2,3,17],unless:[3,14],unmanag:2,unnecessari:[3,7],unregist:3,unregistr:3,unset:[3,14],unsur:[6,7,13],until:[3,7,14,16,17],unwelcom:4,unzip:14,up:[0,2,3,5,7,8,12,14,16,17,18,19],updat:[1,2,7,12,14,16,17],upgrad:[2,16],upon:[2,3],upstream_app:14,upstream_port:14,upstream_proto:14,urandom:12,uri:11,url:[11,14],us:[1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,19],usag:[3,8,14,19],user:[2,3,7,8,9,14,16],usernam:[1,7,14,17],userspac:14,usr:14,usual:[3,5,7,17],util:3,v0:[2,11,14,16],v:16,valid:[2,14,17],valu:[1,2,3,7,12,16,17],variabl:[2,3,11,16],variou:[3,8,14],ve:16,vehicl:15,verbos:14,veri:[0,2,3,5,7,17],verifi:2,version:[2,3,4,10,12,14,16,18],vi:18,via:[1,2,3,4,5,6,7,8,11,12,14,16,17,19],viabil:15,video:8,view:[7,14,16],viewpoint:4,vim:[3,14],virtual:[0,3,6,8,12,15,17,19],visibl:[7,14],visit:[14,15],vist:18,vm3ow4thatogiwnsla3thsl3894th:7,vm:[0,2,8,12],vne197vmradjodkb1zsuja:3,volum:[7,14,16],vpc:[0,5,15,17],vpn:[2,16,17,19],vs:18,vulner:[14,17],vx:18,wa:[2,11,14,17],wai:[14,15,16,17],wan:7,want:[0,2,3,6,7,11,12,14,15,16,17],warn:[14,17],we:[0,1,2,4,9,12,14,15,16],web:[5,14,15],webserv:2,websit:2,weight:14,welcom:4,well:[2,3,7,8,14,16,17],were:[14,16],wg:[3,14,16,17],wgaddress6:3,wgaddress:3,wget:[3,12,14,16,18],what:[2,4,5,6,8,16],whatev:[3,7,14,17],when:[2,3,4,7,13,14,16,17],where:[2,5,6,7,8,14,17,19],wherev:0,whether:[0,3,17],which:[0,2,3,4,5,6,7,10,11,12,13,14,15,16,17],who:4,why:[2,3,16],wide:[2,14],wider:2,wifi:17,wiki:4,wildcard:[12,14],window:[2,7,8],wipe:16,wireguard:[0,3,5,6,7,8,12,15,16,17],wish:[3,5,6,11,14,17],within:[2,3,4,17],without:[1,2,3,4,7,8,16,17],work:[2,3,5,8,13,14,15,16,17],worker:[5,14],workstat:[3,7],world:[0,2],worri:7,wors:2,would:[0,3,5,6,7,14,15,17],write:[2,14],written:8,wrong:16,ws2:3,www:14,x86:3,x:[1,2,5,7,12,18],y:12,yaml:[1,14],ydazgedrpuxmmrqul35wfjmhvrzr1rq0u:6,ye:[3,15,16,17],yet:16,yml:[12,14,16,18],you:[0,1,2,3,5,6,7,9,11,12,13,14,16,17,18,19],your:[0,1,2,3,5,6,7,8,12,13,14,15,16,18,19],your_db_password:14,your_email:12,your_pass:1,your_password:1,your_secret_kei:1,yournetwork:18,yourwildcard:14,z0:12,za:12,zero:11,zeroti:0,zip:14,zrb9vfhk8a:15},titles:["About","API Reference","Architecture","Advanced Client Installation","Code of Conduct","Egress Gateway","Ingress + External Clients","Getting Started","Welcome to the Netmaker Documentation","Install","License","Integrating OAuth","Quick Install","Relay Servers","Advanced Server Installation","Support","Troubleshooting","UI Reference","Upgrades","External Guides"],titleterms:{"0":12,"1":[5,12,14],"2":[5,12,14],"3":[12,14],"4":[12,14],"case":[0,5],"do":15,Is:15,No:14,about:[0,8],access:[1,5],ad:[3,6],advanc:[3,8,14],an:[5,6,15],ani:15,annot:14,api:[1,8],architectur:2,attribut:4,authent:1,avail:14,balanc:14,bare:14,busi:15,caddi:12,call:1,cli:3,client:[2,3,6,8,17,18],code:[4,8],common:16,compat:[2,3,14],compon:2,compos:[12,14],concept:2,conduct:[4,8],config:[3,14],configur:[3,5,6,8,11,13,14],consider:14,contact:15,core:2,coredn:[2,14,16],creat:[7,17],curl:1,daemon:3,daemonset:14,dashboard:17,databas:2,depend:12,deploi:7,descript:[7,14],detail:17,disabl:14,dn:[3,6,12,14,17],docker:[12,14],document:[1,8],doe:0,edit:17,egress:[5,8,17],enforc:4,enterpris:15,exampl:[1,14],exit:15,ext:[6,17],extern:[2,6,8,19],faq:15,featur:15,file:[1,3,14],firewal:12,format:1,gatewai:[5,6],get:[7,8],grpc:14,guid:[8,19],have:15,highli:14,how:0,http:14,ingress:[6,8,14],instal:[3,8,9,12,14],integr:11,introduct:[3,5,6,11,12,13,18],issu:16,kei:[1,7],kernel:14,kubernet:[8,14],licens:[8,10,15],like:15,limit:2,linux:14,list:17,load:14,log:3,make:3,manag:[1,3,7],mesh:2,metal:14,mode:[3,14],nat:5,netclient:[2,3,7,14,16,18],netmak:[0,2,7,8,11,12,14,15,18],network:[1,2,3,7,17],nginx:14,node:[1,2,7,15,17],nordnpn:15,note:3,oauth:[8,11],offer:15,open:12,openwrt:3,option:6,other:14,our:4,permiss:11,pledg:4,postgr:2,prepar:12,prerequisit:[3,12],privat:3,process:2,provid:11,proxi:14,quick:12,recommend:14,refer:[1,3,8,14,17],relai:[8,13,17],remot:5,remov:3,requir:14,respons:4,revers:14,rqlite:[2,14],scope:4,secur:14,server:[1,2,8,13,14,16,18],set:[7,14],setup:[7,14],sqlite:2,sspl:15,standard:4,start:[7,8,12],support:[8,15],system:[2,3,14],systemd:2,technic:2,test:14,traefik:14,troubleshoot:[8,16],tutori:19,ui:[2,8,14,16,17],uninstal:[3,7],updat:3,upgrad:[8,18],us:[0,5],usag:1,user:[1,11,17],valu:14,variabl:14,video:19,view:3,vm:14,vpn:[5,15],welcom:8,what:0,why:15,window:3,wireguard:[2,14],without:14,work:0,written:19,you:15,your:11}}) \ No newline at end of file +Search.setIndex({docnames:["about","api","architecture","client-installation","conduct","egress-gateway","external-clients","getting-started","index","install","license","oauth","quick-start","relay-server","server-installation","support","troubleshoot","ui-reference","upgrades","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["about.rst","api.rst","architecture.rst","client-installation.rst","conduct.rst","egress-gateway.rst","external-clients.rst","getting-started.rst","index.rst","install.rst","license.rst","oauth.rst","quick-start.rst","relay-server.rst","server-installation.rst","support.rst","troubleshoot.rst","ui-reference.rst","upgrades.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,3,5,6,7,8,14,16,18],"04":[12,14],"06":1,"0afehuytvin":3,"0g":3,"1":[1,3,4,6,8,10,16,17],"10":[1,2,3,5,6,7,14],"100":[1,7],"101":3,"1024":17,"11":[3,5,6,7,14],"12":[5,7,13],"127":14,"128":5,"1280":17,"13":5,"14":5,"1420":17,"147":3,"15":[3,5],"16":[1,2,5],"160":5,"168":[3,5],"169":5,"170":[3,5],"172":[1,5],"173":5,"174":5,"176":5,"182":3,"192":[3,5],"193":5,"194":5,"196":5,"1gb":12,"1node":17,"2":[1,3,8,16,17],"20":[3,6,7,12,14],"200":[1,5],"203":3,"208":5,"22":3,"236":6,"24":[2,3,6,7],"245":14,"247":6,"25":7,"251":3,"254":7,"2a":3,"2cpu":12,"2gb":12,"3":[3,5,6,8],"30":[7,12,14,17],"31":1,"32":[3,5,6],"34":3,"3rd":17,"4":[3,4,5,8,18],"4001":14,"4002":14,"41":3,"443":[12,14],"4b":3,"4gb":12,"5":[5,6,11,14,17],"50051":[2,3,7,14],"51821":[3,7,12],"51822":6,"51830":12,"518xx":12,"53":[3,12,14],"5432":14,"5c":3,"5qktbtgsvb45y3qyrmwft":3,"6":5,"60":6,"64":5,"6400":1,"68":3,"69":14,"6c":3,"7":[3,5,6,16],"70":1,"75":14,"77":3,"78":3,"7b":3,"8":[2,3,5,6,11,14,16],"80":14,"8081":[1,2,3,14],"8082":14,"8c":1,"9":[5,12,14,18],"90":1,"91":3,"98":7,"99":7,"abstract":2,"break":[3,7],"case":[1,2,3,6,7,8,9,12,14,16,17,18,19],"class":14,"default":[1,2,3,6,7,11,12,13,14,16,17],"do":[0,1,2,3,4,5,6,7,12,13,14,16,17],"final":[5,16],"function":[1,3,7,13,14,15,16],"import":[2,5,6,7],"long":[0,7,15],"new":[2,3,5,7,17,18],"public":[2,3,4,5,6,7,10,12,13,14,17],"return":[2,5,7],"short":3,"static":[2,5,12,14,16,17],"super":17,"switch":[14,17],"true":[2,3,14],"try":[3,5,15,16],"var":[1,14],"while":[2,5,15],A:[2,3,5,6,7,8,12,14,16,17],And:14,As:[0,2,3,5,11,12,15,16,18],At:[0,2,3,5,12,13],Be:[12,14],Being:4,But:[7,14],By:[0,1,6,11,12,14,17],For:[2,3,5,6,7,8,9,11,12,13,14,16,17],If:[0,1,2,3,6,7,11,12,13,14,15,16,17,19],In:[0,1,2,3,4,5,7,11,12,13,14,16,18],Is:[7,16,17],It:[0,2,3,6,7,14,15,16,17,19],No:15,Not:[2,17],On:[2,3,14,17],Or:12,Such:5,That:2,The:[0,1,2,3,4,5,6,7,12,14,17],Then:[6,7,13,16],There:[0,1,3,7,14,15,16],These:[2,3,5,7,14,17],To:[2,3,6,7,12,13,14,18],Will:3,With:[2,14,17],a6:3,aa3bvg0rnitirxdx:1,abil:[15,16],abl:[1,2,5,6,14],abou:7,about:[2,3,7,12,14,16,17],abov:[2,3,7,13,14],absent:3,abus:4,accept:[3,4,6],access:[0,2,3,6,7,8,11,12,14,15,16,17,19],access_token_valu:14,accesskei:[1,3],accomplish:15,account:[4,16],acess:5,achiev:[1,2,14,15,16],across:[0,3,17],act:[2,4,5,6,17],action:[1,3,4],activ:16,actual:2,ad:[2,7,8,11,14,17,18],adapt:[4,14],add:[0,1,2,3,6,7,14,17,18],addit:[2,3,5,7,14,16,17],addition:[11,12],addnetwork:1,addr:[3,14],address:[2,3,4,5,6,7,13,14,16,17],addressipv6:3,addressrang:1,adequ:14,adm:1,admin:[0,1,2,3,7,11,14,16,17],administr:3,adopt:2,adv:14,advanc:[1,4,7,9,12],advfirewal:3,affect:17,after:[2,3,5,6,7,11,13,17],ag:4,again:12,against:3,agent:[0,2,3,7,8,14,16],agent_backend:14,agentbackend:14,aggreg:2,alex:3,algo:15,align:4,aliv:17,all:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17],allow:[1,2,3,5,6,7,12,13,14,16,17,19],allowedip:[3,6,17],allowedorigin:14,almost:[7,17],along:16,alongsid:14,alreadi:[2,3,7,14],also:[0,1,2,7,11,12,14,16,17],altern:[2,14],although:16,alwai:[5,7,14,17],am:16,an:[0,2,3,4,7,8,11,12,14,16,17,19],android:[2,16,17],ani:[0,2,3,4,6,7,11,12,13,14,16,17,18],annot:[8,17],anoth:[2,5,16],answer:16,anymor:16,anyth:[2,17],anywher:12,aorijqalrik3ajflaqrdajhkr:1,apach:[2,14],api:[2,3,7,11,12,14],api_port:14,apiaddress:3,apihost:14,apiport:14,apiserv:3,app:[6,14,15,16,17],appear:[4,7,17],appli:[4,14],applic:[1,14],appoint:4,appropri:[2,4,6,7,14,17,18],approv:[1,3,7,15,17],aprov:16,apt:12,ar:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18],arbitrari:[0,14,17],arch:[2,7],architectur:[8,14],argument:3,arm:[3,7],around:[12,17],arrai:2,artifact:10,ask:[3,16],asset:14,assign:17,assum:[2,6,12,14,16,17],attach:6,attack:4,attempt:[2,17],attent:4,attribut:8,auth:[11,14],auth_provid:11,authent:[2,3,7],author:1,autofil:17,autom:[0,18],automat:[3,6,14,17],avail:[3,4,8,9,10,17],avoid:[14,17],aw:[0,12,15],awai:2,await:2,azur:11,azure_ten:11,b5:1,back:[2,6,14],backend:14,backend_url:14,background:2,ban:4,bare:[2,8],base64:7,base:[2,3,5,11,12,14,17,18],basedomain:14,bash:[2,3,16],basi:2,basic:19,bcrypt:14,bearer:1,becaus:[0,2,14,16,17],becom:[2,14,16,17],been:[2,3,5,12,14,17],befor:[2,12,16],begin:[2,5,12],behavior:4,behind:[2,6,12,13,16],being:[2,3,14,16,17],believ:15,bellow:14,belong:17,below:[1,2,6,7,13,14,18],benefit:7,besid:2,best:[4,7,15,17],better:[2,17],between:[0,2,17],bewar:3,beyond:14,bin:14,bin_t:16,binari:[2,3,7,9,14,16,18],bind:[12,14],bit:19,biz:12,blank:[3,6,11],blob:14,block:[8,14,16],bodi:4,both:[2,4,5,12,14,15,17],bottleneck:13,bottom:7,bound:12,brief:7,brought:17,brows:[5,15],bsherman:14,build:2,built:2,busi:[12,16],button:[13,16,17],c:[12,14],caddi:14,caddyfil:12,call:[0,2,3,8,14],callabl:3,callback:11,can:[0,1,2,3,5,6,7,10,11,13,14,15,16,17,18,19],candid:5,cang:14,cannot:[3,6,7,12,17],cap_add:14,car:15,cat:16,caus:[2,12,17],cd:2,center:[0,5,7,17],cento:2,cert:14,certain:[2,17],certif:14,certmanag:14,cgnat:[13,17],chang:[0,1,2,3,5,6,7,13,14,16,17,18],charact:[16,17],chart:14,chcon:16,check:[1,2,3,7,12,14,16,17],checkin:[1,2,3,17,18],choic:[6,13,14],choos:[3,9,13,14],chosen:[2,3],cidr:[7,14,17],circumst:[3,4,7],circumv:13,clarifi:4,classnam:14,clear:15,cli:2,click:[2,5,7,11,13,16,17],client:[0,5,7,11,12,14,16],client_id:11,client_max_body_s:14,client_mod:14,client_secret:11,clientmod:14,clone:2,close:18,cloud:[0,12,19],cluster:[14,19],cluster_mgmt:14,clusterip:14,clusterissu:14,code:[2,3,6,10,14,16,17],com:[3,4,7,11,12,14,15,16,18],combin:[5,14,17],come:[2,5,14],comfort:12,comm:3,comma:17,command:[2,3,7,12,14,16,17],comment:[4,14],commit:4,common:[2,5,8,12],commonli:16,commun:[2,3,4,7,8,14,15,16,17],compar:15,compat:[5,6,8,17],compil:[2,3],complaint:4,complet:[2,16],complex:2,complic:2,compon:[8,14,17],compos:[7,8,16,18],comput:[0,2,3],concept:8,concurr:12,conf:[6,14],confidenti:4,config:[1,2,6,17,18],configur:[0,1,2,7,12,16,17],confirm:[17,18],conflict:[14,17],connect:[0,2,3,6,7,13,14,16,17,19],consensu:[2,16],consequ:14,consid:[4,7],consider:2,consist:[2,14],consol:7,construct:4,consult:[14,16],consum:[3,14],contact:[4,8,12,14],contain:[2,7,12,14,17],container_nam:14,content:1,context:14,continu:[14,16],contrast:2,contribut:4,contributor:4,control:[2,7,14],convert:[3,16,17],copi:[7,14],core:[0,8],coredn:[3,8,12],coredns_addr:14,coredns_address:14,coredns_ip:12,corednsaddr:3,corefil:14,coreo:2,corpor:[14,15,16],correct:[4,12,18],correctli:[2,14,17],cors_allowed_origin:14,could:[0,4,7,16,17],countri:5,cours:5,coven:4,cover:8,cp:14,cpu:[12,16],creat:[0,1,2,3,4,5,6,8,12,13,14,16],createadmin:1,creategatewai:1,creation:[0,7,13,17],credenti:14,credit:16,critic:[4,14],cron:2,cross:19,cryptocurr:0,curl:[7,14],current:[2,3,14,16,17],custom:[2,8,12,14],customiz:14,cycl:[1,2],d9:1,d:[1,2,12,14,17,18],daemon:2,dashboard:[8,11,12,14],data:[0,2,5,7,14,16,17],databas:16,datastor:14,date:1,datetim:17,db:[2,8,14],dc:12,ddflzqn:6,debian:2,debug:14,decod:[2,3,7],deem:4,defin:[4,7,17],delet:[1,6,7,14,16,17],deletegatewai:1,deni:16,depend:[2,3,8,16,17,18],depends_on:14,deploi:[2,3,5,8,12,14,16],deploy:[2,14],depreci:[14,17],derogatori:4,design:[2,3,6,13,14,16],desktop:[2,3,6,17],detail:[1,2,3,4,7,8,14],determin:[4,5,17],dev:[12,14],devic:[0,2,3,8,16,17],diagram:2,differ:[0,2,4,5,7,14,15],difficult:17,digitalocean:12,dir:3,direct:13,directli:[0,1,2,6,12,13,14,16],directori:14,disabl:[2,4,17],disable_remote_ip_check:14,disableremoteipcheck:14,disconnect:16,discord:[15,16],discuss:[14,18],displai:[2,14,17],display_kei:14,displaynam:1,distibut:2,distribut:[2,7,14,17],distributionshav:2,dn:[2,8,16,19],dns_mode:[14,16],dnsconfig:14,dnsmode:14,dnson:3,dnsstublisten:14,doc:[7,11,12,14,17],docker:[2,7,8,9,11,16,18],document:[0,2,3,7,14,15],doe:[2,3,6,8,14,16,17],doesn:16,domain:[11,12,14,16],don:[2,3,7,19],done:16,dont:[7,16],doubl:13,down:[0,5,7,11,13,14,16,17,18],download:[3,6,7,14,16,17,18],dual:[3,7,16,17,19],dualstack:17,due:[13,16],duplic:3,dure:[3,17],dynam:[0,2,8,17],e:[2,3,4,5,7,12,14,16,18],each:[0,2,3,7,8,11,14,16,17],easi:[2,14,17],easier:2,easiest:2,easili:[0,5,7,14],echo:12,edit:[4,6,8,13,14,16],effect:[7,17],effici:[2,5],egress:[3,6,15],either:[2,6,13,18],ejf6yy51m:6,electron:4,elev:[11,14],elimin:2,els:17,email:[12,15],embed:14,empathi:4,empti:14,enabl:[2,5,7,12,14,17],encod:7,encompass:[0,5],encount:2,encrypt:[0,2,3,5,16],end:[2,12,14,16,17],endpoint:[1,2,3,6,7,17],enforc:8,enough:14,enpoint:17,ensur:[13,14,15,18],enter:[7,13,14,17],enterpris:[12,14],entir:7,entireti:2,entri:[14,16,17],env:[1,14],environ:[0,1,2,4,11,14,16,17],equal:14,equival:14,error:17,essenti:13,establish:6,etc:[3,7,12,14,16,18],eth0:[1,17],eth2:5,ethnic:4,evalu:15,even:[0,2],event:4,everi:[2,3,7,17],everyon:4,everyth:[2,5,14,17],evolv:2,ex:[3,7,12,14],exampl:[2,3,4,5,6,8,11,12,17],except:[7,11,14,17],execut:14,exist:[0,2,7,14,17],expect:[4,5,8,14,17,18],experi:[3,4,9,16],expir:17,explain:2,explicit:4,explicitli:14,exploit:14,expos:2,express:4,expressvpn:15,ext:[5,8,16],extend:14,extens:2,extern:[3,5,14,17],f1:1,f8:3,f:[3,14,16],face:[4,5],fact:0,fail:[2,7,11],fair:4,fairli:[2,16],faith:4,fallback:17,fals:[3,14],familiar:[0,2,15,16],faq:8,fast:[2,8,14],faster:[0,2,3,17],fcontext:16,featur:[12,14,17],fedora:2,few:[3,7,15,17],field:[5,6,7,8,13,14,17,18],figur:19,file:[2,6,17,18],filenam:1,fill:17,filter:17,find:[2,14,17,18,19],fine:0,firewal:[3,7,8,13,14,16],first:[2,3,5,7,8,11,14,16,17,19],fit:[12,19],flag:3,flat:0,flexibl:0,flow:2,focus:4,folder:[2,14,18],follow:[2,3,4,5,7,11,12,14,16],forc:14,form:[3,7,17],format:[11,14],forum:16,forward:[3,5,6],foster:4,found:[0,2,10,11,14],free:[4,17],freebsd:2,freeli:10,frequent:[5,16,17],friend:16,from:[0,1,2,3,4,5,6,7,9,12,13,14,16,17,19],front:[2,14],frontend_url:11,full:[0,2,14],fulli:[0,2],further:4,furthermor:14,futur:[7,12,18],g:[3,7,12,14],gatewai:[1,2,3,8,15,16,17,19],gb:16,gcp:12,gender:4,gener:[1,2,3,6,9,11,12,14,15,17],generate_config_j:14,get:[1,3,5,12,14,16,17,18],gg:15,github:[2,3,8,11,12,14,15,16,18],githubusercont:[3,7,12,14,16],give:[2,7,8,14,15,16],given:[0,2,5,7,16,17],global:[3,5],go:[2,3,5,8,13,14,16,17],goe:[0,14,17],golang:2,good:[4,5,6,7,13,15,16,17,19],googl:[11,14],grab:3,gracefulli:4,grade:14,grant:17,gravitl:[3,4,7,12,14,15,16,18],group:12,grpc:[2,3,7,12],grpc_port:14,grpc_ssl:14,grpcaddress:3,grpchost:14,grpcport:14,grpcserver:3,guid:[0,2,7,9,12,14,16],guidanc:8,guidelin:[14,15],h:[1,3],ha:[0,2,3,5,7,11,12,13,14,16,17,19],hand:8,handl:[0,2,12,14,17],handshak:[16,17],harass:4,hard:[13,16,17],harder:16,hardwar:[3,16,17],harm:4,hasadmin:1,hash:14,have:[0,2,3,4,5,6,7,11,12,13,14,16,17],haven:16,head:12,header:[1,2,14],health:17,heart:3,heavi:2,helm3:14,helm:14,help:[1,2,3,7,8,14,15,17,18],here:[2,4,7,10,12,14,15,17,19],hesit:15,high:[2,8,14,16],highli:[3,8,9],hit:16,hold:[0,2,3],holder:16,hole:[3,7,16,17],holepunch:3,home:[0,2,3,5,17],hook:[2,6],host:[2,3,12,14,15,17],host_ip:14,hostnam:17,hous:1,how:[2,3,5,8,14,16,17],howev:[1,2,3,5,12,14,16],html:14,http:[1,3,7,8,11,12,15,16,18],http_port:14,hub:[0,2,13,17],hundr:12,i:[3,12,14,16],id:[1,3,11,14,17],ideal:14,ident:4,identifi:3,ignor:[3,5,17],imag:[14,18],imageri:4,impact:[2,15],implement:[2,5],importantli:7,imposs:13,inappropri:4,inbound:[3,12],incid:4,includ:[2,4,6,8,14],inclus:4,incompat:18,incorrect:[3,14,16],increas:[2,17],independ:6,indic:[11,17],individu:[4,14,17],industri:2,info:[2,4,12,14,15],inform:[2,3,4,7,8,12,17],ingress:[2,3,5,16,17],ingressroutetcp:14,initi:[3,11],ins:2,insert:[5,12,14,16],insid:[8,14,17],instal:[0,2,6,7,16],instanc:[1,2,3,4,5,7,12,14,17],instead:[0,3,5,6,7,12,14,16,17],instruct:[11,14],insult:4,intact:3,integr:[8,14],intend:3,inter:17,interact:[0,2,3],interest:[4,16],interfac:[1,3,5,6,7,12,14,17],interfer:[12,16],intern:[5,14],internet:[0,2,5,15],intro:19,introduc:16,introduct:8,invalid:[6,7,17],investig:4,invis:[2,17],io:[11,12,14,16,17],iot:[0,2],ip:[2,3,5,6,7,12,13,14,17,18],ipaddress:17,ipforward:[3,17],iphon:2,ipsec:2,iptabl:[3,5,17],ipv4:[3,7,14,16,17],ipv6:[3,7,16,17,19],ipv6address:17,isdualstack:3,isingressgatewai:3,isloc:[3,17],isstat:3,issu:[2,3,4,8,12,13,14,17],issuer:14,issuernam:14,iter:17,its:[0,2,3,4,5,6,7,14,17],itself:[2,3,5,7,14],job:2,join:[2,3,7,14,16,17],journalctl:[3,14,16],jq:1,js:14,json:[1,14],just:[0,2,3,6,7,12,14,15,16,17],jwt:[1,3],k3:19,k8:14,k:[3,7],keep:[1,5,17],keepal:[3,17],kei:[2,3,8,11,12,14,16,17],kept:17,kernel:[0,2],keynam:1,keyupd:1,kill:16,know:[5,14,16,19],known:[2,12,17],kube:14,kubectl:14,kubernet:[0,5,9,17,19],lan:3,languag:4,laptop1:1,laptop:[6,17],larg:[2,17],last:[1,17,18],lastmodifi:1,latenc:2,later:2,latest:[2,3,6,14],launch:2,launchd:[2,3],launchdaemon:2,layer:0,layout:2,lb:14,le:14,leadership:4,least:[0,16],leav:[3,6,7,14,16,17,18],left:[7,11,14,16],length:[3,16,17],less:[2,7],let:[0,5,15,19],letsencrypt:14,level:[2,4,8,14,17],librari:2,light:14,lightweight:2,like:[0,2,3,7,14,17],limit:[3,8,14,16,17],line:[2,17],link:[8,11,12,14],linod:12,linux:[2,3,5,7,8,17],linuxserv:14,list:[0,2,3,5,13,14],listen:14,listenport:1,littl:[2,15],ln:14,load:2,local:[2,3,5,7,14,17],localaddress:[1,3],localhost:[1,14],localrang:3,locat:[0,2,3,5,14,17],log:[11,12,14,16],logic:6,login:[7,11],longer:17,look:[14,15,17],lookup:2,lose:17,lot:[2,3,16],lower:[16,17],lxc:14,m:[3,6,16],mac:[2,3,7,17],macaddress:[1,3],machin:[0,2,3,5,6,7,8,12,13,16,17,18],made:[0,2,16,17],mai:[1,2,3,4,7,11,12,13,14,16,17,18],mail:4,main:14,maintain:[4,14,15,17],make:[0,2,4,5,6,8,9,12,13,14,15,16,17],man:6,manag:[0,2,6,8,14,19],mani:[0,2,12,14,15,17,19],manual:[2,3,7,14,16,17,18],map:14,master:[3,7,12,14,16],master_kei:14,masterkei:[1,14],match:[3,14],maximum:14,md:[1,14],mean:[2,3,5,6,7,14,17],meant:14,measur:13,media:4,medium:9,meet:14,member:4,memori:16,mesh:[0,6,16,17,19],meshclient:1,metal:[2,8],method:[1,2,3,5,6,7,9],mgmt:1,microk8:[14,19],microsoft:11,middl:6,might:[0,2,13,14],min:12,minim:14,minimum:16,minor:18,mint:2,minu:14,minut:[12,14,16,17],mismatch:18,miss:[2,18],mix:3,mode:[2,7,8],model:[0,2],modif:14,modifi:[1,2,3,7,12,14,15,17],moment:17,mongo:14,mongodb:[],more:[0,1,2,6,7,8,12,14,15,17],most:[1,2,3,5,9,12,14,15,16,17],mostli:[2,3],mount:14,move:[7,12,18],mtu:[16,17],much:[0,2],mullvad:15,mullvadvpn:15,multipl:[0,7,14,16,17],must:[1,2,3,5,6,7,11,14,16,17,18],mv:18,my:[1,3,16,18],mydomain:11,mykei:[1,7],mynet:7,myserv:7,mysit:12,myvers:18,n:[2,3,7,12,14,16],name:[1,2,3,5,6,7,14,16,17],nameserv:[2,3,14],namespac:14,nat:[6,8,13,16,17],nation:4,nativ:2,navig:[11,12,16],nebula:[0,15],necessari:[2,3,4,14,17],need:[0,1,2,3,5,12,14,15,16,17,18],neg:15,neighborhood:0,neither:2,net:3,net_admin:14,netclient:[0,5,6,8,17],netclient_accesskei:3,netclient_accesstoken:3,netclient_address:3,netclient_addressipv6:3,netclient_api_serv:3,netclient_daemon:3,netclient_dn:3,netclient_endpoint:3,netclient_grpc_serv:3,netclient_interfac:3,netclient_ipforward:3,netclient_is_dualstack:3,netclient_is_loc:3,netclient_keepal:3,netclient_localaddress:3,netclient_localrang:3,netclient_macaddress:3,netclient_nam:3,netclient_network:3,netclient_o:3,netclient_password:3,netclient_port:3,netclient_postdown:3,netclient_postup:3,netclient_privatekei:3,netclient_publickei:3,netclient_roam:3,netclient_udp_holepunch:3,netconfig:[3,16,18],netid:1,netmak:[1,3,5,6,10,13,16,17,19],netmaker_base_domain:[12,14],netmaker_env:14,netsh:3,network:[0,5,6,8,11,12,13,14,15,16,18,19],network_mod:14,newli:18,next:[3,5,7,11],nextcloud:19,nf:14,nginx:[2,8,16],nip:12,nm:[3,14,17],node:[3,5,6,8,13,14,16],nodn:14,non:[2,3,7,9,14,17],none:0,noonewillguessthi:1,nopass:14,nordvpn:15,normal:14,notabl:14,note:[1,5,6,8,11,12,14,16,17],noteabl:7,notifi:2,now:[0,6,7,12,13,14,15,16,18],ns:14,number:[2,7,12,14,17],o:[12,14],oauth2:11,oauth_provid:11,object:14,oblig:4,obscur:17,obtain:[1,3],od:3,off:[2,3,7,14,16,17],offens:4,offer:11,offic:[0,5,19],offici:[1,4,16],offlin:4,often:[2,15,17],old:18,omit:14,onc:[5,6,7,11,14],one:[2,3,5,6,7,12,14,16,17],onli:[1,2,3,5,6,7,11,14,16,17,18],onlin:4,onto:17,open:[2,4,7,8,15,17],openvpn:[2,15],openwrt:[2,8,16],oper:[2,3,13,14,17],operatingsystem:3,opinion:12,oppos:[2,14],option:[2,3,8,11,17],oracl:12,order:[5,11,14,16],org:14,orient:4,origin:[11,14],os:[3,17],osi:15,other:[0,2,3,4,6,7,13,17],otherwis:[0,3,4,16,17],our:[8,14,16],out:[0,2,7,12,14,15,16,17,19],outlin:[2,14],output:[3,7,16],outsid:[8,14],over:[0,2,5,13,14,17],overlai:[0,8],overlap:[5,7],overrid:[3,14],overridden:[2,14],overview:[2,19],overwhelm:19,own:[2,12,14],p2p:17,p:[3,7,12,14],packag:[3,16],packet:17,page:[2,11,17],pair:[2,14],pane:7,panic:18,part:[2,3,14],parti:[16,17],partial:2,particip:4,particular:[2,3],pass:[2,3,14],password:[1,3,7,14,17],past:5,path:[1,14,15,17],peer:[2,3,6,7,13,16,17,19],pend:[1,7,17],peopl:[5,15,17],per:12,perform:[1,2,3,7,14],period:2,perm:14,perman:[4,14],permiss:[4,8,12,14,16],permit:7,persist:17,persistentkeepal:[3,6],person:4,perspect:[0,2],phone:[3,6],physic:4,pick:[2,7],pictur:2,ping:[7,16,17],pivpn:15,place:[3,12,13,14,18],plaintext:3,plan:[12,14,15,16],platform:[2,8],pleas:[3,8,12,14,15,16],pledg:8,plu:[3,12],poc:[9,12],pod:17,point:[2,5,12],polici:4,polit:4,popul:[14,17],port:[2,3,7,12,14,16,17],posgr:14,posit:4,possibl:[2,12],post:[1,2,3,4,14,17],postchang:3,postdown:[3,14,17],postgr:14,postgresql:[2,14],postgress:14,postup:[3,14,17],powershel:3,practic:2,pre:14,preced:2,precend:14,prefer:[12,14,16],prepar:8,prereqisit:7,prerequisit:[2,5,7,8,14],present:18,prevent:[3,17],previou:2,primari:[3,14,16,17],prior:14,privaci:15,privat:[2,4,5,7,8,14,15,17,19],privatekei:[3,6],privileg:14,privkei:3,probabl:[0,15],problem:[3,16],procedur:14,process:[3,7,8,14,18],prod:14,product:[12,14],profession:4,project:[1,4,14,15],proof:0,proper:14,properli:[3,16],properti:3,proto:12,protocol:[3,14],provid:[0,2,3,8,12,14,17],proxi:[8,11,12],proxy_pass:14,proxy_pass_request_head:14,proxy_set_head:14,pubkei:3,publickei:[1,3,6],publicli:[12,13],publish:[4,10],pull:[2,3,6,14,17,18],punch:[3,7,16,17],purchas:16,pure:17,push:[3,6],put:[1,17],q9cog7c9qjnoxygvri:3,qr:[6,16,17],quarantin:3,question:16,quick:[7,8,9,14,16,17],quickli:[12,16],quickstart:16,r:16,race:[4,15],raft:[2,14,16],ram:12,random:[14,17],randomli:17,rang:[3,5,6,7,12,14,17],rangestr:1,rare:17,raspian:2,rather:[11,14,17],raw:[3,7,12,14,16],rce:[14,17],re:[0,3,7,15,16],reach:[0,2,3,5,6,7,13,14,15,16,17],reachabl:[2,3,6,7,8,13,14,17],reactj:2,read:14,readm:[12,14],reallysecret:1,reason:[2,4,7,13,14,17],reboot:16,receiv:[1,2],recent:[2,3,16,17],recommend:[1,3,6,9,12,16],reconfigur:[2,3,16],record:[7,12,16],redirect:11,redund:14,refer:[2,7,16],regard:[2,4],regardless:4,regist:[2,3],registr:3,regularli:[15,17],reject:4,rejoin:18,rel:[2,5,18],relai:[2,3,6,16],relat:14,releas:[2,3,14,16,18],relev:17,reli:[0,3],reliabl:17,religion:4,remain:17,remot:[0,3,14],remoteip:3,remov:[1,2,4,7,14,16,17],removenetwork:1,renam:[3,16,18],repeat:7,repercuss:4,replac:[3,14],replace_master_kei:12,replica:14,replicacount:14,repo:[2,14],report:[2,4],repositori:[2,10],repres:4,represent:4,request:[1,2,14],requir:[1,2,3,7,16],resolv:[2,3,14],resolvectl:[3,14,17],resourc:[6,8,9],respect:[2,4],respons:[2,8],rest:[12,14],rest_backend:14,restart:[11,14,16],restbackend:14,restorecon:16,restrict:[13,14],result:4,retriev:[0,1,2,3,7],revers:[8,12],revert:3,review:4,rf:7,rhel:2,right:[0,4,17],risk:16,rkxlgk2mg:6,rm:7,rncjjbsaa3hzuhrk5hpyxm:3,roam:[3,17],rogu:16,root:[3,12,14,16,18],rout:[0,2,5,11,12,13,14,17],route53:12,router:[2,5,16],rpumvsbpgq:6,rqlite:16,rule:[3,5,12],run:[0,1,2,3,5,6,7,12,14,15,16,17,18],runtim:14,rv:16,rwo:14,rwx:14,s:[0,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],sai:5,said:2,same:[0,3,6,7,14,16,17],sampl:0,save:[7,12,18],saveconfig:17,sbilli:[3,16],scan:[6,17],scenario:[5,7,13,17],schedul:14,scope:8,screen:[7,11],screenshot:[8,17],script:[2,3,7,12,14,16],search:17,second:[5,7,17],secret:[1,3,7,11],secretkei:14,section:[3,14,17],secur:[0,1,2,3,5,8,12,16,17,19],sed:[12,14],see:[1,2,3,7,8,12,14,15,16,17],seem:7,select:[6,7,13,16,17],selector:14,self:[14,15],selinux:16,semanag:16,send:[2,3,14,17],sens:[2,9,15],sensibl:[0,2,7,17],sent:17,separ:[2,4,17,19],seper:16,serv:[2,14],server:[0,3,5,6,7,10,11,12,17],server_api_conn_str:14,server_api_host:14,server_grpc_conn_str:14,server_grpc_host:14,server_host:14,server_http_host:[11,14],server_nam:14,server_public_ip:12,servic:[2,3,5,6,12,14,17,19],set:[1,2,3,4,5,8,12,16,17,19],setup:[0,2,5,8,12],sever:[2,14],sexual:4,sf:14,sfl:[7,14],sh:[3,7,14,16],share:[14,16],shell:[3,16],should:[0,1,2,3,5,6,7,12,13,14,16,17],show:[3,4,14,16,17],shown:[6,17],shut:5,side:10,sign:[2,3,7,11,14,16],signific:2,signup:[2,3,16,17],similar:[0,7,14,15,17],simpl:[2,3,5,7,8,11,14,16],simplest:[2,3],simpli:[2,3,5,6,7,13,14,16],simplifi:[13,14],simultan:0,sinc:17,singl:[1,2,5,16,17],sit:17,site:[0,2,8,14,16,19],situat:[2,16,17],size:4,skip:14,skynet:1,slow:[0,13],slower:14,small:[2,7,9],smartgui:1,so:[0,2,3,5,6,7,12,14,16,17],social:4,sole:17,solut:2,solv:[2,17],some:[1,2,3,5,7,13,14,16,17],someth:[6,7,14,17],sometim:13,somewher:7,soon:16,sort:0,sourc:[2,3,8,10],space:[4,17],spec:16,special:[2,3,7,14],specif:[2,3,4,5,7,8,14,17],specifi:[3,5,11,13,14,17],speed:[0,2],split:3,spoke:[0,2,13,17],spread:0,sql:[2,14],sql_conn:14,sql_db:14,sql_host:14,sql_pass:14,sql_port:14,sql_user:14,sqlconn:14,sqldata:14,sqlite:[14,16],src:12,ssh:[7,12,18],ssl:14,sspl:10,stabl:5,stack:[3,7,16,17,19],stai:[3,17],stake:0,standalon:14,standard:[2,5,8,14,17],start:[14,16,19],startup:1,state:7,statement:8,statu:[3,14,16,17],step:[2,3,7,14,18],still:[0,14,18],stock:15,stop:14,storag:[12,14],storageclassnam:14,store:[2,14,17],straight:5,straightforward:18,string:[7,14],stuck:16,stun:[7,16],su:7,subdomain:[12,14],submit:7,subnet:[2,5,17],subscript:[12,16],subsequ:2,subspac:15,subspacecloud:15,substanti:0,success:[2,11],successfulli:11,sudo:[3,7,11,12,14,16],support:[2,12,14,16],sure:[12,15,16,17],surfshark:15,suse:2,swag:14,symbol:11,system:[7,8,12,17],system_u:16,systemctl:[3,14,16],systemd:[3,7,14,16],t:[2,3,7,16,19],tab:[7,16],tack:17,tail:3,tailscal:[0,15],take:[0,1,2,4,7,11,14,16,17],talk:[0,2],tcp:12,team:4,technic:[0,8,15],technolog:2,ted:17,tell:[0,2,3,13,14,16],templat:14,temporari:[4,17],temporarili:4,tenant:11,term:15,terrain:15,test:[7,9],than:[2,7,11,14,17],thei:[0,2,4,7,8,14,15,16,17],them:[2,7,14,15,16],themselv:[2,16],therefor:16,thi:[0,1,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],thing:[0,2,3,16],think:[5,15,19],third:16,thmpvlcykonxi:3,those:[0,2,3,5,6],thousand:0,threaten:4,three:[7,14],through:[2,13,14,17],ticket:15,time:[1,2,3,6,7,13,14,16,17,19],timer:2,timestamp:[2,17],tl:14,toc:14,token:[3,7,14,16],too:[16,17],tool:[0,3,5],top:[2,16],topic:19,topolog:2,toward:4,tr:12,track:17,traffic:[0,2,5,6,13,14,16,17],trailofbit:15,transact:2,translat:17,travers:17,treat:[2,3,17],trial:[9,12],tricki:2,troll:4,troubleshooot:12,troubleshoot:[1,3,7,12],tune:17,tunnel:[0,2],tunnelbear:15,turn:[2,3,7,13,14,16,17],tutori:8,two:[0,1,2,3,5,7,14,16],type:[1,14],typi:17,typic:[0,2,5,6,7,13,14,16,17],u:[3,14,16],ua2zjt8wn7ga:6,ubuntu:[2,12,14],udp:[3,7,12,14,16,17],udpholepunch:3,ufw:12,ui:[1,3,5,6,18],unabl:[7,16],unaccept:4,unaccess:17,uncom:14,uncordon:1,under:[3,7,10,14,16],underlai:[0,19],underscores_in_head:14,unedit:17,unexpectedli:5,unfamiliar:7,uninstal:[8,16],uniqu:[3,12,17],unix:[2,3,17],unless:[3,14],unmanag:2,unnecessari:[3,7],unregist:3,unregistr:3,unset:[3,14],unsur:[6,7,13],until:[3,7,14,16,17],unwelcom:4,unzip:14,up:[0,2,3,5,7,8,12,14,16,17,18,19],updat:[1,2,7,12,14,16,17],upgrad:[2,16],upon:[2,3],upstream_app:14,upstream_port:14,upstream_proto:14,urandom:12,uri:11,url:[11,14],us:[1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,19],usag:[3,8,14,19],user:[2,3,7,8,9,14,16],usernam:[1,7,14,17],userspac:14,usr:14,usual:[3,5,7,17],util:3,v0:[2,11,14,16],v:16,valid:[2,14,17],valu:[1,2,3,7,12,16,17],variabl:[2,3,11,16],variou:[3,8,14],ve:16,vehicl:15,verbos:14,veri:[0,2,3,5,7,17],verifi:2,version:[2,3,4,10,12,14,16,18],vi:18,via:[1,2,3,4,5,6,7,8,11,12,14,16,17,19],viabil:15,video:8,view:[7,14,16],viewpoint:4,vim:[3,14],virtual:[0,3,6,8,12,15,17,19],visibl:[7,14],visit:[14,15],vist:18,vm3ow4thatogiwnsla3thsl3894th:7,vm:[0,2,8,12],vne197vmradjodkb1zsuja:3,volum:[7,14,16],vpc:[0,5,15,17],vpn:[2,16,17,19],vs:18,vulner:[14,17],vx:18,wa:[2,11,14,17],wai:[14,15,16,17],wan:7,want:[0,2,3,6,7,11,12,14,15,16,17],warn:[14,17],we:[0,1,2,4,9,12,14,15,16],web:[5,14,15],webserv:2,websit:2,weight:14,welcom:4,well:[2,3,7,8,14,16,17],were:[14,16],wg:[3,14,16,17],wgaddress6:3,wgaddress:3,wget:[3,12,14,16,18],what:[2,4,5,6,8,16],whatev:[3,7,14,17],when:[2,3,4,7,13,14,16,17],where:[2,5,6,7,8,14,17,19],wherev:0,whether:[0,3,17],which:[0,2,3,4,5,6,7,10,11,12,13,14,15,16,17],who:4,why:[2,3,16],wide:[2,14],wider:2,wifi:17,wiki:4,wildcard:[12,14],window:[2,7,8],wipe:16,wireguard:[0,3,5,6,7,8,12,15,16,17],wish:[3,5,6,11,14,17],within:[2,3,4,17],without:[1,2,3,4,7,8,16,17],work:[2,3,5,8,13,14,15,16,17],worker:[5,14],workstat:[3,7],world:[0,2],worri:7,wors:2,would:[0,3,5,6,7,14,15,17],write:[2,14],written:8,wrong:16,ws2:3,www:14,x86:3,x:[1,2,5,7,12,18],y:12,yaml:[1,14],ydazgedrpuxmmrqul35wfjmhvrzr1rq0u:6,ye:[3,15,16,17],yet:16,yml:[12,14,16,18],you:[0,1,2,3,5,6,7,9,11,12,13,14,16,17,18,19],your:[0,1,2,3,5,6,7,8,12,13,14,15,16,18,19],your_db_password:14,your_email:12,your_pass:1,your_password:1,your_secret_kei:1,yournetwork:18,yourwildcard:14,z0:12,za:12,zero:11,zeroti:0,zip:14,zrb9vfhk8a:15},titles:["About","API Reference","Architecture","Advanced Client Installation","Code of Conduct","Egress Gateway","Ingress + External Clients","Getting Started","Welcome to the Netmaker Documentation","Install","License","Integrating OAuth","Quick Install","Relay Servers","Advanced Server Installation","Support","Troubleshooting","UI Reference","Upgrades","External Guides"],titleterms:{"0":12,"1":[5,12,14],"2":[5,12,14],"3":[12,14],"4":[12,14],"case":[0,5],"do":15,Is:15,No:14,about:[0,8],access:[1,5],ad:[3,6],advanc:[3,8,14],an:[5,6,15],ani:15,annot:14,api:[1,8],architectur:2,attribut:4,authent:1,avail:14,balanc:14,bare:14,busi:15,caddi:12,call:1,cli:3,client:[2,3,6,8,17,18],code:[4,8],common:16,compat:[2,3,14],compon:2,compos:[12,14],concept:2,conduct:[4,8],config:[3,14],configur:[3,5,6,8,11,13,14],consider:14,contact:15,core:2,coredn:[2,14,16],creat:[7,17],curl:1,daemon:3,daemonset:14,dashboard:17,databas:[2,14],depend:12,deploi:7,descript:[7,14],detail:17,disabl:14,dn:[3,6,12,14,17],docker:[12,14],document:[1,8],doe:0,edit:17,egress:[5,8,17],enforc:4,enterpris:15,exampl:[1,14],exit:15,ext:[6,17],extern:[2,6,8,19],faq:15,featur:15,file:[1,3,14],firewal:12,format:1,gatewai:[5,6],get:[7,8],grpc:14,guid:[8,19],have:15,highli:14,how:0,http:14,ingress:[6,8,14],instal:[3,8,9,12,14],integr:11,introduct:[3,5,6,11,12,13,18],issu:16,kei:[1,7],kernel:14,kubernet:[8,14],licens:[8,10,15],like:15,limit:2,linux:14,list:17,load:14,log:3,make:3,manag:[1,3,7],mesh:2,metal:14,mode:[3,14],nat:5,netclient:[2,3,7,14,16,18],netmak:[0,2,7,8,11,12,14,15,18],network:[1,2,3,7,17],nginx:14,node:[1,2,7,15,17],nordnpn:15,note:3,oauth:[8,11],offer:15,open:12,openwrt:3,option:[6,14],other:14,our:4,permiss:11,pledg:4,postgr:2,prepar:12,prerequisit:[3,12],privat:3,process:2,provid:11,proxi:14,quick:12,recommend:14,refer:[1,3,8,14,17],relai:[8,13,17],remot:5,remov:3,requir:14,respons:4,revers:14,rqlite:[2,14],scope:4,secur:14,server:[1,2,8,13,14,16,18],set:[7,14],setup:[7,14],sqlite:2,sspl:15,standard:4,start:[7,8,12],support:[8,15],system:[2,3,14],systemd:2,technic:2,test:14,traefik:14,troubleshoot:[8,16],tutori:19,ui:[2,8,14,16,17],uninstal:[3,7],updat:3,upgrad:[8,18],us:[0,5],usag:1,user:[1,11,17],valu:14,variabl:14,video:19,view:3,vm:14,vpn:[5,15],welcom:8,what:0,why:15,window:3,wireguard:[2,14],without:14,work:0,written:19,you:15,your:11}}) \ No newline at end of file diff --git a/docs/_build/html/server-installation.html b/docs/_build/html/server-installation.html index ffd70be8..e2dccaa2 100644 --- a/docs/_build/html/server-installation.html +++ b/docs/_build/html/server-installation.html @@ -309,13 +309,15 @@
  • Linux Install without Docker
  • @@ -351,7 +353,7 @@
    • 1. Load Balancer Setup
    • -
    • 2. RQLite Setup +
    • 2. RQLite Setup
    • 3. Netmaker Setup
    • @@ -541,13 +543,15 @@
    • Linux Install without Docker
    • @@ -583,7 +587,7 @@
      • 1. Load Balancer Setup
      • -
      • 2. RQLite Setup +
      • 2. RQLite Setup
      • 3. Netmaker Setup
      • @@ -842,15 +846,16 @@ docker-compose up -d`

        Linux Install without Docker

        -

        Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you need to install MongoDB and CoreDNS (optional).

        -

        To start, we recommend following the Nginx instructions in the Quick Install guide to enable SSL for your environment.

        +

        Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you may want to optionally install a database (sqlite is embedded, rqlite or postgres are supported) and CoreDNS (also optional).

        Once this is enabled and configured for a domain, you can continue with the below. The recommended server runs Ubuntu 20.04.

        -

        rqlite Setup

        +

        Database Setup (optional)

        +

        You can run the netmaker binary standalone and it will run an embedded sqlite server. Data goes in the data/ directory. Optionally, you can run PostgreSQL or rqlite. Instructions for rqlite are below.

        1. Install rqlite on your server: https://github.com/rqlite/rqlite

        2. Run rqlite: rqlited -node-id 1 ~/node.1

        +

        If using rqlite or postgres, you must change the DATABASE environment/config variable and enter connection details.

        Server Setup

        @@ -883,7 +888,13 @@ docker-compose up -d` -

        CoreDNS Setup

        +

        CoreDNS Setup (optional)

        +

        CoreDNS is only required if you want private DNS features. Once installed, you must set the CoreDNS variables in the env settings of the server.

        +

        See https://coredns.io/manual/toc/#installation

        + + +

        Proxy / Load Balancer

        +

        You will need to proxy connections to your UI and Server. By default the ports are 8081, 8082, and 50051 (grpc). This proxy should handle SSL certificates. We recommend Caddy or Nginx (you can follow the Nginx guide in these docs). The proxy must be able to handle gRPC connections.

        @@ -1091,7 +1102,7 @@ This install has some notable exceptions:

        Your load balancer of choice will send requests to the Netmaker servers. Setup is similar to the various guides we have created for Nginx, Caddy, and Traefik. SSL certificates must also be configured and handled by the LB.

        -

        2. RQLite Setup

        +

        2. RQLite Setup

        RQLite is the included distributed datastore for an HA Netmaker installation. If you have a different corporate database you wish to integrate, Netmaker is easily extended to other DB’s. If this is a requirement, please contact us.

        Assuming you use Rqlite, you must run it on each Netmaker server VM, or alongside that VM as a container. Setup a config.json for database credentials (password supports BCRYPT HASHING) and mount in working directory of rqlite and specify with -auth config.json :

        [{
        diff --git a/docs/server-installation.rst b/docs/server-installation.rst
        index 72d1f06d..62b35ded 100644
        --- a/docs/server-installation.rst
        +++ b/docs/server-installation.rst
        @@ -230,18 +230,21 @@ This template is equivalent but omits CoreDNS.
         Linux Install without Docker
         =============================
         
        -Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you need to install MongoDB and CoreDNS (optional). 
        -
        -To start, we recommend following the Nginx instructions in the :doc:`Quick Install <./quick-start>` guide to enable SSL for your environment.
        +Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you may want to optionally install a database (sqlite is embedded, rqlite or postgres are supported) and CoreDNS (also optional). 
         
         Once this is enabled and configured for a domain, you can continue with the below. The recommended server runs Ubuntu 20.04.
         
        -rqlite Setup
        -----------------
        +Database Setup (optional)
        +--------------------------
        +
        +You can run the netmaker binary standalone and it will run an embedded sqlite server. Data goes in the data/ directory. Optionally, you can run PostgreSQL or rqlite. Instructions for rqlite are below.
        +
         1. Install rqlite on your server: https://github.com/rqlite/rqlite
         
         2. Run rqlite: rqlited -node-id 1 ~/node.1
         
        +If using rqlite or postgres, you must change the DATABASE environment/config variable and enter connection details.
        +
         Server Setup
         -------------
         1. **Run the install script:** 
        @@ -271,8 +274,18 @@ The following uses Nginx as an http server. You may alternatively use Apache or
           sudo sh -c 'BACKEND_URL=http://:PORT /usr/share/nginx/html/generate_config_js.sh >/usr/share/nginx/html/config.js'
           sudo systemctl start nginx
         
        -CoreDNS Setup
        -----------------
        +CoreDNS Setup (optional)
        +----------------------------
        +
        +CoreDNS is only required if you want private DNS features. Once installed, you must set the CoreDNS variables in the env settings of the server.
        +
        +See https://coredns.io/manual/toc/#installation
        +
        +Proxy / Load Balancer
        +------------------------
        +
        +You will need to proxy connections to your UI and Server. By default the ports are 8081, 8082, and 50051 (grpc). This proxy should handle SSL certificates. We recommend Caddy or Nginx (you can follow the Nginx guide in these docs). The proxy must be able to handle gRPC connections.
        +
         
         .. _KubeInstall:
         
        
        From e3e239ab84033654b01672a497bdc0324db001fd Mon Sep 17 00:00:00 2001
        From: afeiszli 
        Date: Sat, 22 Jan 2022 10:12:33 -0500
        Subject: [PATCH 5/7] adding code review changes
        
        ---
         database/database.go   |  7 ++++---
         main.go                |  3 ---
         serverctl/telemetry.go | 34 ++++++++++++++++++++--------------
         3 files changed, 24 insertions(+), 20 deletions(-)
        
        diff --git a/database/database.go b/database/database.go
        index d1a1279e..633e691b 100644
        --- a/database/database.go
        +++ b/database/database.go
        @@ -114,7 +114,8 @@ func InitializeDatabase() error {
         		time.Sleep(2 * time.Second)
         	}
         	createTables()
        -	return nil
        +	err := initializeUUID()
        +	return err
         }
         
         func createTables() {
        @@ -194,8 +195,8 @@ func FetchRecords(tableName string) (map[string]string, error) {
         	return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName)
         }
         
        -// InitializeUUID - create a UUID record for server if none exists
        -func InitializeUUID() error {
        +// initializeUUID - create a UUID record for server if none exists
        +func initializeUUID() error {
         	records, err := FetchRecords(SERVER_UUID_TABLE_NAME)
         	if err != nil {
         		if !strings.Contains("could not find any records", err.Error()) {
        diff --git a/main.go b/main.go
        index a939d0c5..eba2c60f 100644
        --- a/main.go
        +++ b/main.go
        @@ -41,9 +41,6 @@ func initialize() { // Client Mode Prereq Check
         	}
         	logger.Log(0, "database successfully connected")
         
        -	if err = database.InitializeUUID(); err != nil {
        -		logger.FatalLog("Failed to set UUID: ", err.Error())
        -	}
         	err = serverctl.TelemetryCheckpoint()
         	if err != nil {
         		logger.Log(1, "Failed to send telemetry: ", err.Error())
        diff --git a/serverctl/telemetry.go b/serverctl/telemetry.go
        index 574a32b9..77e50560 100644
        --- a/serverctl/telemetry.go
        +++ b/serverctl/telemetry.go
        @@ -32,7 +32,6 @@ func TelemetryCheckpoint() error {
         	// can set to 2 minutes for testing
         	//sendtime := time.Unix(telRecord.LastSend, 0).Add(time.Minute * 2)
         	enoughTimeElapsed := time.Now().After(sendtime)
        -
         	// if more than 24 hours has elapsed, send telemetry to posthog
         	if enoughTimeElapsed {
         		err = sendTelemetry(telRecord.UUID)
        @@ -82,14 +81,12 @@ func sendTelemetry(serverUUID string) error {
         }
         
         // fetchTelemetry - fetches telemetry data: count of various object types in DB
        -func fetchTelemetryData() (TelemetryData, error) {
        -	var data TelemetryData
        -	extData, _ := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
        -	data.ExtClients = len(extData)
        -	userData, _ := database.FetchRecords(database.USERS_TABLE_NAME)
        -	data.Users = len(userData)
        -	netData, _ := database.FetchRecords(database.NETWORKS_TABLE_NAME)
        -	data.Networks = len(netData)
        +func fetchTelemetryData() (telemetryData, error) {
        +	var data telemetryData
        +
        +	data.ExtClients = getDBLength(database.EXT_CLIENT_TABLE_NAME)
        +	data.Users = getDBLength(database.USERS_TABLE_NAME)
        +	data.Networks = getDBLength(database.NETWORKS_TABLE_NAME)
         	data.Version = servercfg.GetVersion()
         	nodes, err := logic.GetAllNodes()
         	if err == nil {
        @@ -115,8 +112,8 @@ func setTelemetryTimestamp(uuid string) error {
         }
         
         // getClientCount - returns counts of nodes with various OS types and conditions
        -func getClientCount(nodes []models.Node) ClientCount {
        -	var count ClientCount
        +func getClientCount(nodes []models.Node) clientCount {
        +	var count clientCount
         	for _, node := range nodes {
         		switch node.OS {
         		case "macos":
        @@ -148,18 +145,27 @@ func fetchTelemetryRecord() (models.Telemetry, error) {
         	return telObj, err
         }
         
        +// getDBLength - get length of DB to get count of objects
        +func getDBLength(dbname string) int {
        +	data, err := database.FetchRecords(dbname)
        +	if err != nil {
        +		return 0
        +	}
        +	return len(data)
        +}
        +
         // TelemetryData - What data to send to posthog
        -type TelemetryData struct {
        +type telemetryData struct {
         	Nodes      int
         	ExtClients int
         	Users      int
        -	Count      ClientCount
        +	Count      clientCount
         	Networks   int
         	Version    string
         }
         
         // ClientCount - What types of netclients we're tallying
        -type ClientCount struct {
        +type clientCount struct {
         	MacOS     int
         	Windows   int
         	Linux     int
        
        From 0d74e561dc1122476afe4618ba7d3c994e8df0c7 Mon Sep 17 00:00:00 2001
        From: afeiszli 
        Date: Sat, 22 Jan 2022 12:31:32 -0500
        Subject: [PATCH 6/7] updating docs to fix bugs and include telemetry
        
        ---
         ...ddy.yml => docker-compose.hostnetwork.yml} |   0
         compose/docker-compose.nocaddy.yml            |  64 ++++++++++
         compose/docker-compose.reference.yml          |   2 +
         compose/docker-compose.yml                    |  27 +++--
         docs/_build/doctrees/api.doctree              | Bin 49503 -> 38307 bytes
         docs/_build/doctrees/architecture.doctree     | Bin 54445 -> 57073 bytes
         .../doctrees/client-installation.doctree      | Bin 47998 -> 52176 bytes
         docs/_build/doctrees/environment.pickle       | Bin 103013 -> 105908 bytes
         .../doctrees/server-installation.doctree      | Bin 125417 -> 143421 bytes
         docs/_build/doctrees/support.doctree          | Bin 10265 -> 16140 bytes
         docs/_build/doctrees/troubleshoot.doctree     | Bin 43953 -> 48467 bytes
         docs/_build/html/_sources/api.rst.txt         | 110 ++++++++++--------
         .../_build/html/_sources/architecture.rst.txt |  12 +-
         .../html/_sources/client-installation.rst.txt |  23 ++++
         .../html/_sources/server-installation.rst.txt |  33 +++++-
         docs/_build/html/_sources/support.rst.txt     |  27 +++++
         .../_build/html/_sources/troubleshoot.rst.txt |   7 ++
         docs/_build/html/api.html                     |  87 +++++++++-----
         docs/_build/html/architecture.html            |  13 ++-
         docs/_build/html/client-installation.html     |  41 ++++++-
         docs/_build/html/index.html                   |   1 +
         docs/_build/html/searchindex.js               |   2 +-
         docs/_build/html/server-installation.html     |  31 +++++
         docs/_build/html/support.html                 |  34 ++++++
         docs/_build/html/troubleshoot.html            |   6 +-
         docs/api.rst                                  | 110 ++++++++++--------
         docs/architecture.rst                         |  12 +-
         docs/client-installation.rst                  |  23 ++++
         docs/server-installation.rst                  |  33 +++++-
         docs/support.rst                              |  27 +++++
         docs/troubleshoot.rst                         |   7 ++
         31 files changed, 590 insertions(+), 142 deletions(-)
         rename compose/{docker-compose.caddy.yml => docker-compose.hostnetwork.yml} (100%)
         create mode 100644 compose/docker-compose.nocaddy.yml
        
        diff --git a/compose/docker-compose.caddy.yml b/compose/docker-compose.hostnetwork.yml
        similarity index 100%
        rename from compose/docker-compose.caddy.yml
        rename to compose/docker-compose.hostnetwork.yml
        diff --git a/compose/docker-compose.nocaddy.yml b/compose/docker-compose.nocaddy.yml
        new file mode 100644
        index 00000000..62886587
        --- /dev/null
        +++ b/compose/docker-compose.nocaddy.yml
        @@ -0,0 +1,64 @@
        +version: "3.4"
        +
        +services:
        +  netmaker:
        +    container_name: netmaker
        +    image: gravitl/netmaker:v0.9.4
        +    volumes:
        +      - dnsconfig:/root/config/dnsconfig
        +      - /usr/bin/wg:/usr/bin/wg
        +      - sqldata:/root/data
        +    cap_add: 
        +      - NET_ADMIN
        +    restart: always
        +    privileged: true
        +    environment:
        +      SERVER_HOST: "SERVER_PUBLIC_IP"
        +      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
        +      SERVER_GRPC_CONN_STRING: "grpc.NETMAKER_BASE_DOMAIN:443"
        +      COREDNS_ADDR: "SERVER_PUBLIC_IP"
        +      GRPC_SSL: "on"
        +      DNS_MODE: "on"
        +      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN"
        +      SERVER_GRPC_HOST: "grpc.NETMAKER_BASE_DOMAIN"
        +      API_PORT: "8081"
        +      GRPC_PORT: "50051"
        +      CLIENT_MODE: "on"
        +      MASTER_KEY: "REPLACE_MASTER_KEY"
        +      SERVER_GRPC_WIREGUARD: "off"
        +      CORS_ALLOWED_ORIGIN: "*"
        +      DISPLAY_KEYS: "on"
        +      DATABASE: "sqlite"
        +      NODE_ID: "netmaker-server-1"
        +    ports:
        +      - "51821-51830:51821-51830/udp"
        +      - "8081:8081"
        +      - "50051:50051"
        +  netmaker-ui:
        +    container_name: netmaker-ui
        +    depends_on:
        +      - netmaker
        +    image: gravitl/netmaker-ui:v0.9.3
        +    links:
        +      - "netmaker:api"
        +    ports:
        +      - "8082:80"
        +    environment:
        +      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN"
        +    restart: always
        +  coredns:
        +    depends_on:
        +      - netmaker 
        +    image: coredns/coredns
        +    command: -conf /root/dnsconfig/Corefile
        +    container_name: coredns
        +    restart: always
        +    ports:
        +      - "COREDNS_IP:53:53/udp"
        +      - "COREDNS_IP:53:53/tcp"
        +    volumes:
        +      - dnsconfig:/root/dnsconfig
        +volumes:
        +  sqldata: {}
        +  dnsconfig: {}
        +
        diff --git a/compose/docker-compose.reference.yml b/compose/docker-compose.reference.yml
        index 92d76fe1..8637546f 100644
        --- a/compose/docker-compose.reference.yml
        +++ b/compose/docker-compose.reference.yml
        @@ -38,6 +38,8 @@ services:
               SERVER_API_CONN_STRING: "" # Changes the api connection string. IP:PORT format. By default is empty and uses SERVER_HOST:API_PORT
               SERVER_GRPC_CONN_STRING: "" # Changes the grpc connection string. IP:PORT format. By default is empty and uses SERVER_HOST:GRPC_PORT
               RCE: "off" # Enables setting PostUp and PostDown (arbitrary commands) on nodes from the server. Off by default.
        +      NODE_ID: "" # Sets the name/id of the nodes that the server creates. Necessary for HA configurations to identify between servers (for instance, netmaker-1, netmaker-2, etc). For non-HA deployments, is not necessary.
        +      TELEMETRY: "on" # Whether or not to send telemetry data to help improve Netmaker. Switch to "off" to opt out of sending telemetry.
           netmaker-ui: # The Netmaker UI Component
             container_name: netmaker-ui
             depends_on:
        diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml
        index 413f0af3..e8124158 100644
        --- a/compose/docker-compose.yml
        +++ b/compose/docker-compose.yml
        @@ -5,18 +5,12 @@ services:
             container_name: netmaker
             image: gravitl/netmaker:v0.9.4
             volumes:
        -      - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
        -      - /run/systemd/system:/run/systemd/system
        -      - /etc/systemd/system:/etc/systemd/system
        -      - /sys/fs/cgroup:/sys/fs/cgroup
        -      - /usr/bin/wg:/usr/bin/wg
               - dnsconfig:/root/config/dnsconfig
        +      - /usr/bin/wg:/usr/bin/wg
               - sqldata:/root/data
             cap_add: 
               - NET_ADMIN
        -      - SYS_ADMIN
             restart: always
        -    network_mode: host
             privileged: true
             environment:
               SERVER_HOST: "SERVER_PUBLIC_IP"
        @@ -33,9 +27,13 @@ services:
               MASTER_KEY: "REPLACE_MASTER_KEY"
               SERVER_GRPC_WIREGUARD: "off"
               CORS_ALLOWED_ORIGIN: "*"
        -      DATABASE: "sqlite"
               DISPLAY_KEYS: "on"
        +      DATABASE: "sqlite"
               NODE_ID: "netmaker-server-1"
        +    ports:
        +      - "51821-51830:51821-51830/udp"
        +      - "8081:8081"
        +      - "50051:50051"
           netmaker-ui:
             container_name: netmaker-ui
             depends_on:
        @@ -60,6 +58,19 @@ services:
               - "COREDNS_IP:53:53/tcp"
             volumes:
               - dnsconfig:/root/dnsconfig
        +  caddy:
        +    image: caddy:latest
        +    container_name: caddy
        +    restart: unless-stopped
        +    network_mode: host # Wants ports 80 and 443!
        +    volumes:
        +      - /root/Caddyfile:/etc/caddy/Caddyfile
        +      # - $PWD/site:/srv # you could also serve a static site in site folder
        +      - caddy_data:/data
        +      - caddy_conf:/config
         volumes:
        +  caddy_data: {}
        +  caddy_conf: {}
           sqldata: {}
           dnsconfig: {}
        +
        diff --git a/docs/_build/doctrees/api.doctree b/docs/_build/doctrees/api.doctree
        index c8cec0f392173e6a0563fd0f3546b3959275b8d6..37aca2acb2db110df90c8233130e1f81c61332ae 100644
        GIT binary patch
        delta 5937
        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
        
        literal 49503
        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
        95#E!Kag;b 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 diff --git a/docs/_build/doctrees/client-installation.doctree b/docs/_build/doctrees/client-installation.doctree index 57a4e1aa1b1cfb8e7abf452fec3906feeb673870..a0137a9428ae9a2487a0d7a7df121f18a83c1e73 100644 GIT binary patch delta 7445 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 diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index 7bd24483f68cd91d5dec7f84f756d5e79a58aaa3..51bbe2d4f985721fbbf47ff4d82caeebadd1ee24 100644 GIT binary patch literal 105908 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 Oi(iE9qKI!yPyBx;tQPtJ diff --git a/docs/_build/doctrees/server-installation.doctree b/docs/_build/doctrees/server-installation.doctree index 8461da319b3b12a6e7f851facca14b7203fe3697..f491b4ef927e3a5ca7d4c2cd1c2364c6b2e30c88 100644 GIT binary patch delta 24229 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 T8a|zZ;1GuOY9D3$DJb|Kr4m*8 delta 10719 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 diff --git a/docs/_build/html/_sources/api.rst.txt b/docs/_build/html/_sources/api.rst.txt index f219890d..c3e59488 100644 --- a/docs/_build/html/_sources/api.rst.txt +++ b/docs/_build/html/_sources/api.rst.txt @@ -17,8 +17,11 @@ API calls must be authenticated via a header of the format `-H "Authorization: Format of Calls for Curl ======================== -Requests take the format of `curl -H "Authorization: Bearer " -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint` +Requests take the format of +.. code-block:: + + curl -H "Authorization: Bearer " -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint API Documentation ================= @@ -41,18 +44,21 @@ Networks API Networks API Call Examples -------------------------- - -**Get All Networks:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq` -**Create Network:** `curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks` +.. code-block:: -**Get Network:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq` + Get All Networks: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq -**Update Network:** `curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet` + Create Network: curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks -**Delete Network:** `curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet` + Get Network: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq + + Update Network: curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet + + Delete Network: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet + + Cycle PublicKeys on all Nodes: curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate -**Cycle PublicKeys on all Nodes:** `curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate` Access Keys API --------------- @@ -66,13 +72,15 @@ Access Keys API Access Keys API Call Examples ----------------------------- - -**Get All Keys:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq` - -**Create Key:** `curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys` - -**Delete Key:** `curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey` - + +.. code-block:: + + Get All Keys: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq + + Create Key: curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys + + Delete Key: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey + Nodes API --------- @@ -104,29 +112,31 @@ Nodes API Nodes API Call Examples ----------------------- - -**Get All Nodes:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq` - -**Get Network Nodes:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq` - -**Create Node:** `curl -d '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet` - -**Get Node:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq` - -**Update Node:** `curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9` - -**Delete Node:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9` - -**Create a Gateway:** `curl -d '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway` - -**Delete a Gateway:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway` - -**Approve a Pending Node:** `curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve` - -**Get Last Modified Date (Last Modified Node in Network):** `curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified` -**Authenticate:** `curl -d '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate` - +.. code-block:: + + Get All Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq + + Get Network Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq + + Create Node: curl -d '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet + + Get Node: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq + + Update Node: curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9 + + Delete Node: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9 + + Create a Gateway: curl -d '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway + + Delete a Gateway: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway + + Approve a Pending Node: curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve + + Get Last Modified Date (Last Modified Node in Network): curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified + + Authenticate: curl -d '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate + Users API ----------------------- @@ -148,19 +158,21 @@ Users API Users API Calls Examples ------------------------ - -**Get User:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq` -**Update User:** `curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}` - -**Delete User:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}` - -**Check for Admin User:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin` - -**Create Admin User:** `curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin` - -**Authenticate:** `curl -d '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate` - +.. code-block:: + + Get User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq + + Update User: curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username} + + Delete User: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username} + + Check for Admin User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin + + Create Admin User: curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin + + Authenticate: curl -d '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate + Server Management API --------------------- diff --git a/docs/_build/html/_sources/architecture.rst.txt b/docs/_build/html/_sources/architecture.rst.txt index 3bca05d7..5b097785 100644 --- a/docs/_build/html/_sources/architecture.rst.txt +++ b/docs/_build/html/_sources/architecture.rst.txt @@ -47,7 +47,7 @@ Netmaker Netmaker is a platform built off of WireGuard which enables users to create mesh networks between their devices. Netmaker can create both full and partial mesh networks depending on the use case. -When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. +When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. There is also almost always a proxy server / LB, which is typically Caddy. From an end user perspective, they typically interact with the Netmaker UI, or even just run the install script for the netclient on their devices. The other components run in the background invisibly. @@ -85,6 +85,7 @@ These modes include client mode and dns mode. Either of these can be disabled bu The Netmaker server interacts with either sqlite (default), postgres, or rqlite, a distributed version of sqlite, as its database. This DB holds information about nodes, networks, users, and other important data. This data is configuration data. For the most part, Netmaker serves configuration data to Nodes, telling them how they should configure themselves. The Netclient is the agent that actually does that configuration. +The components of the server are usually proxied via Caddy, or an alternative like Nginx and Traefik. The proxy handles SSL certificates to secure traffic, and routes to the UI, API, and gRPC server. Netclient ---------------- @@ -124,6 +125,15 @@ CoreDNS Netmaker allows users to provide and manage Private DNS for their nodes. This requires a nameserver, and CoreDNS is the chosen nameserver. CoreDNS is lightweight and extensible. CoreDNS loads dns settings from a simple file, managed by Netmaker, and serves out DNS info for managed nodes. DNS can be tricky, and DNS management is currently only supported on a small set of devices, specifically those running systemd-resolved. However, the Netmaker CoreDNS instance can be added manually as a nameserver to other devices. DNS mode can also be turned off. +Caddy +------- + +Caddy is the default proxy for Netmaker if you set it up via Quick Start. Caddy is an extremely simple and docker-friendly proxy, which can be compared to Nginx, Traefik, or HAProxy. We use Caddy by default because of the ease of management, and integration with gRPC. A typical setup for Nginx might take dozens of lines of code, and we need to request and manage SSL certificates separately. + +Caddy handles all these things automatically in very few lines of code. You can see our default "Caddyfile" here, which is fed to the container and has all the configuration necessary to configure the proxy for our app: + +https://github.com/gravitl/netmaker/blob/master/docker/Caddyfile + External Client ---------------- diff --git a/docs/_build/html/_sources/client-installation.rst.txt b/docs/_build/html/_sources/client-installation.rst.txt index 60a0c4ae..4edf3a85 100644 --- a/docs/_build/html/_sources/client-installation.rst.txt +++ b/docs/_build/html/_sources/client-installation.rst.txt @@ -30,6 +30,29 @@ Windows will by default have firewall rules that prevent inbound connections. If If you want to allow all peers access, but do not want to configure firewall rules for all peers, you can configure access for one peer, and set it as a Relay Server. +Running the install script +---------------------------- + +Some file locations have issues running the install script, such as running from the root C:/ folder. Users have noted the following locations work well for running the install powershell script: + +- `C:/Program Files/wireguard` +- `C:/Windows/System32` + +Running netclient commands +---------------------------- + +If running the netclient manually ("netclient join", "netclient checkin", "netclient pull") it should be run from outside of the installed directory, which will be either: + +- `C:/Program Files/netclient` +- `C:/ProgramData/netclient` + +It is better to call it from a different directory. + +High CPU Utilization +-------------------------- + +With some versions of WireGuard on Windows, high CPU utilization has been found with the netclient. This is typically due to interaction with the WireGuard GUI component (app). If you're experiencing high CPU utilization, close the WireGuard app. WireGuard will still be running, but the CPU usage should go back down to normal. + Notes on OpenWRT =========================== diff --git a/docs/_build/html/_sources/server-installation.rst.txt b/docs/_build/html/_sources/server-installation.rst.txt index 62b35ded..e7056591 100644 --- a/docs/_build/html/_sources/server-installation.rst.txt +++ b/docs/_build/html/_sources/server-installation.rst.txt @@ -143,9 +143,26 @@ RCE: **Description:** The server enables you to set PostUp and PostDown commands for nodes, which is standard for WireGuard with wg-quick, but is also **Remote Code Execution**, which is a critical vulnerability if the server is exploited. Because of this, it's turned off by default, but if turned on, PostUp and PostDown become editable. +SERVER_GRPC_WIREGUARD + **Depreciated:** no longer in use + +DISPLAY_KEYS + **Default:** "on" + + **Description:** If "on", will allow you to always show the key values of "access keys". This could be considered a vulnerability, so if turned "off", will only display key values once, and it is up to the users to store the key values locally. + +NODE_ID + **Default:** + + **Description:** This setting is used for HA configurations of the server, to identify between different servers. Nodes are given ID's like netmaker-1, netmaker-2, and netmaker-3. If the server is not HA, there is no reason to set this field. + +TELEMETRY + **Default:** "on" + + **Description:** If "on", the server will send anonymous telemetry data once daily, which is used to improve the product. Data sent includes counts (integer values) for the number of nodes, types of nodes, users, and networks. It also sends the version of the server. Config File Reference ----------------------- +----------------------- A config file may be placed under config/environments/.yml. To read this file at runtime, provide the environment variable NETMAKER_ENV at runtime. For instance, dev.yml paired with ENV=dev. Netmaker will load the specified Config file. This allows you to store and manage configurations for different environments. Below is a reference Config File you may use. .. literalinclude:: ../config/environments/dev.yaml @@ -159,6 +176,20 @@ All environment variables and options are enabled in this file. It is the equiva .. literalinclude:: ../compose/docker-compose.reference.yml :language: YAML +Available docker-compose files +--------------------------------- + +The default options for docker-compose can be found here: https://github.com/gravitl/netmaker/tree/master/compose + +The following is a brief description of each: + +- `docker-compose.contained.yml `_ - This is the default docker-compose, used in the quick start and deployment script in the README on GitHub. It deploys Netmaker with all options included (Caddy and CoreDNS) and has "self-contained" netclients, meaning they do not affect host networking. +- `docker-compose.coredns.yml `_ - This is a simple compose used to spin up a standalone CoreDNS server. Can be useful if, for instance, you are unning Netmaker on baremetal but need CoreDNS. +- `docker-compose.hostnetwork.yml `_ - This is similar to the docker-compose.contained.yml but with a key difference: it has advanced permissions and mounts host volumes to control networking on the host level. +- `docker-compose.nocaddy.yml `_ -= This is the same as docker-compose.contained.yml but without Caddy, in case you need to use a different proxy like Nginx, Traefik, or HAProxy. +- `docker-compose.nodns.yml `_ - This is the same as docker-compose.contained.yml but without CoreDNS, in which case you will not have the Private DNS feature. +- `docker-compose.reference.yml `_ - This is the same as docker-compose.contained.yml but with all variable options on display and annotated (it's what we show right above this section). Use this to determine which variables you should add or change in your configuration. +- `docker-compose.yml `_ - This is a renamed docker-compose.contained.yml. It is meant only to act as a placeholder for what we consider the "primary" docker-compose that users should work with. DNS Mode Setup ==================================== diff --git a/docs/_build/html/_sources/support.rst.txt b/docs/_build/html/_sources/support.rst.txt index 2054aac6..206f46fc 100644 --- a/docs/_build/html/_sources/support.rst.txt +++ b/docs/_build/html/_sources/support.rst.txt @@ -39,6 +39,33 @@ We believe the SSPL lets most people run the project the way they want, for both If you believe the SSPL will negatively impact your ability to use the project, please do not hesitate to reach out. +Telemetry +============== + +As of v0.10.0, Netmaker collects "opt-out" telemetry data. To opt out, simply set "TELEMETRY=off" in your docker-compose file. + +Please consider participating in telemetry, as it helps us focus on the features and bug fixes which are most useful to users. Netmaker is a broad platform, and without this data, it is difficult to know where the team should spend its limited resources. + +The following is the full list of telemetry data we collect. Besides "Server Version" all data is simply an integer count: + +- Randomized server ID +- Count of nodes +- Count of "non-server" nodes +- Count of external clients +- Count of networks +- Count of users +- Count of linux nodes +- Count of freebsd nodes +- Count of macos nodes +- Count of windows nodes +- Count of docker nodes +- Count of k8s nodes +- Server version + +We use `PostHog `_, an open source and trusted framework for telemetry data. + +To look at exactly we collect telemetry, you can view the source code under serverctl/telemetry.go: https://github.com/gravitl/netmaker/blob/master/serverctl/telemetry.go + Contact =========== If you need help, try the discord or open a GitHub ticket. diff --git a/docs/_build/html/_sources/troubleshoot.rst.txt b/docs/_build/html/_sources/troubleshoot.rst.txt index c1a1c0c5..6acc9fb7 100644 --- a/docs/_build/html/_sources/troubleshoot.rst.txt +++ b/docs/_build/html/_sources/troubleshoot.rst.txt @@ -29,6 +29,13 @@ Common Issues Server ------- +**How do I use a private address from the Netmaker Server? How do I contact nodes using their private addresses from the server?** + Default nodes appear in each network with the "netmaker" name. These nodes are created by, and attached to, the server. The server is contained in docker, meaning these clients are also contained in docker. Their networking stack is also contained in docker. The "netmaker" nodes are meant to function as network utilities. They assist with UDP Hole Punching and can run Relays, Egress, and Ingress. However, they are meant to stay contained in the server. They do not touch the host networking stack. + + If you want to give the physical server / VM a private IP in the netmaker network, you must deploy an **additional** node using the standard netclient. The only note here is that the server consumes ports 51821-51831, so you will need to give it a port outside this range, e.x. `./netclient join --port 51835`. + + One a netclient is deployed to the underlying server/VM, you will be able to use the private address to reach other nodes from the host, or to reach the server over the private network. + **I upgraded from 0.7 to 0.8 and now I dont have any data in my server!** In 0.8, sqlite becomes the default database. If you were running with rqlite, you must set the DATABASE environment variable to rqlite in order to continue using rqlite. diff --git a/docs/_build/html/api.html b/docs/_build/html/api.html index 48a44639..74204243 100644 --- a/docs/_build/html/api.html +++ b/docs/_build/html/api.html @@ -489,7 +489,10 @@

        Format of Calls for Curl

        -

        Requests take the format of curl -H “Authorization: Bearer <YOUR_SECRET_KEY>” -H ‘Content-Type: application/json’ localhost:8081/api/path/to/endpoint

        +

        Requests take the format of

        +
        curl -H "Authorization: Bearer <YOUR_SECRET_KEY>" -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint
        +
        +

        API Documentation

        @@ -504,12 +507,19 @@

        Networks API Call Examples

        -

        Get All Networks: curl -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks | jq

        -

        Create Network: curl -d ‘{“addressrange”:”10.70.0.0/16”,”netid”:”skynet”}’ -H “Authorization: Bearer YOUR_SECRET_KEY” -H ‘Content-Type: application/json’ localhost:8081/api/networks

        -

        Get Network: curl -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks/skynet | jq

        -

        Update Network: curl -X PUT -d ‘{“displayname”:”my-house”}’ -H “Authorization: Bearer YOUR_SECRET_KEY” -H ‘Content-Type: application/json’ localhost:8081/api/networks/skynet

        -

        Delete Network: curl -X DELETE -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks/skynet

        -

        Cycle PublicKeys on all Nodes: curl -X POST -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks/skynet/keyupdate

        +
        Get All Networks: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq
        +
        +Create Network: curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks
        +
        +Get Network: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq
        +
        +Update Network: curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet
        +
        +Delete Network: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet
        +
        +Cycle PublicKeys on all Nodes: curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate
        +
        +

        Access Keys API

        @@ -519,9 +529,13 @@

        Access Keys API Call Examples

        -

        Get All Keys: curl -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks/skynet/keys | jq

        -

        Create Key: curl -d ‘{“uses”:10,”name”:”mykey”}’ -H “Authorization: Bearer YOUR_SECRET_KEY” -H ‘Content-Type: application/json’ localhost:8081/api/networks/skynet/keys

        -

        Delete Key: curl -X DELETE -H “Authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/networks/skynet/keys/mykey

        +
        Get All Keys: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq
        +
        +Create Key: curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys
        +
        +Delete Key: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey
        +
        +

        Nodes API

        @@ -540,17 +554,29 @@

        Nodes API Call Examples

        -

        Get All Nodes: curl -H “Authorization: Bearer YOUR_SECRET_KEY” http://localhost:8081/api/nodes | jq

        -

        Get Network Nodes: curl -H “Authorization: Bearer YOUR_SECRET_KEY” http://localhost:8081/api/nodes/skynet | jq

        -

        Create Node: curl -d ‘{ “endpoint”: 100.200.100.200, “publickey”: aorijqalrik3ajflaqrdajhkr,”macaddress”: “8c:90:b5:06:f1:d9”,”password”: “reallysecret”,”localaddress”: “172.16.16.1”,”accesskey”: “aA3bVG0rnItIRXDx”,”listenport”: 6400}’ -H ‘Content-Type: application/json’ -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/skynet

        -

        Get Node: curl -H “Authorization: Bearer YOUR_SECRET_KEY” http://localhost:8081/api/nodes/skynet/{macaddress} | jq

        -

        Update Node: curl -X PUT -d ‘{“name”:”laptop1”}’ -H ‘Content-Type: application/json’ -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9

        -

        Delete Node: curl -X DELETE -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9

        -

        Create a Gateway: curl -d ‘{ “rangestring”: “172.31.0.0/16”, “interface”: “eth0”}’ -H ‘Content-Type: application/json’ -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway

        -

        Delete a Gateway: curl -X DELETE -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway

        -

        Approve a Pending Node: curl -X POST -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve

        -

        Get Last Modified Date (Last Modified Node in Network): curl -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/nodes/adm/skynet/lastmodified

        -

        Authenticate: curl -d ‘{“macaddress”: “8c:90:b5:06:f1:d9”, “password”: “YOUR_PASSWORD”}’ -H ‘Content-Type: application/json’ localhost:8081/api/nodes/adm/skynet/authenticate

        +
        Get All Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq
        +
        +Get Network Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq
        +
        +Create Node: curl  -d  '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet
        +
        +Get Node: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq
        +
        +Update Node: curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9
        +
        +Delete Node: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9
        +
        +Create a Gateway: curl  -d  '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway
        +
        +Delete a Gateway: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway
        +
        +Approve a Pending Node: curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve
        +
        +Get Last Modified Date (Last Modified Node in Network): curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified
        +
        +Authenticate: curl -d  '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate
        +
        +

        Users API

        @@ -564,12 +590,19 @@

        Users API Calls Examples

        -

        Get User: curl -H “Authorization: Bearer YOUR_SECRET_KEY” http://localhost:8081/api/users/{username} | jq

        -

        Update User: curl -X PUT -d ‘{“password”:”noonewillguessthis”}’ -H ‘Content-Type: application/json’ -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/users/{username}

        -

        Delete User: curl -X DELETE -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/users/{username}

        -

        Check for Admin User: curl -H “Authorization: Bearer YOUR_SECRET_KEY” http://localhost:8081/api/users/adm/hasadmin

        -

        Create Admin User: curl -d ‘{ “username”: “smartguy”, “password”: “YOUR_PASS”}’ -H ‘Content-Type: application/json’ -H “authorization: Bearer YOUR_SECRET_KEY” localhost:8081/api/users/adm/createadmin

        -

        Authenticate: curl -d ‘{“username”: “smartguy”, “password”: “YOUR_PASS”}’ -H ‘Content-Type: application/json’ localhost:8081/api/nodes/adm/skynet/authenticate

        +
        Get User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq
        +
        +Update User: curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}
        +
        +Delete User: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}
        +
        +Check for Admin User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin
        +
        +Create Admin User: curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin
        +
        +Authenticate: curl -d  '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate
        +
        +

        Server Management API

        diff --git a/docs/_build/html/architecture.html b/docs/_build/html/architecture.html index f4d01965..0cb5c658 100644 --- a/docs/_build/html/architecture.html +++ b/docs/_build/html/architecture.html @@ -253,6 +253,8 @@
      • CoreDNS
      • +
      • Caddy +
      • External Client
      @@ -473,6 +475,8 @@
    • CoreDNS
    • +
    • Caddy +
    • External Client
    @@ -518,7 +522,7 @@

    Netmaker

    Netmaker is a platform built off of WireGuard which enables users to create mesh networks between their devices. Netmaker can create both full and partial mesh networks depending on the use case.

    -

    When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver.

    +

    When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. There is also almost always a proxy server / LB, which is typically Caddy.

    From an end user perspective, they typically interact with the Netmaker UI, or even just run the install script for the netclient on their devices. The other components run in the background invisibly.

    Netmaker does a lot of work to set configurations for you, so that you don’t have to. This includes things like WireGuard ports, endpoints, public IPs, keys, and peers. Netmaker works to abstract away as much of the network management as possible, so that you can just click to create a network, and click to add a machine to a network. That said, every machine (node) is different, and may require special configuration. That is why, while Netmaker sets practical default settings, everything within Netmaker is fully configurable.

    @@ -543,6 +547,7 @@

    Most server settings are configurable via a config file, or by environment variables (which take precedence). If the server finds neither of these, it sets sensible defaults, including things like the server’s reachable IP, ports, and which “modes” to run in.

    These modes include client mode and dns mode. Either of these can be disabled but are enabled by default. Client mode allows you to treat the Netmaker host machine (operating system) as a network Node, installing the netclient and controlling the host network. DNS mode has the server write config settings for CoreDNS, a separate component and nameserver, which picks up the config settings to manage node DNS.

    The Netmaker server interacts with either sqlite (default), postgres, or rqlite, a distributed version of sqlite, as its database. This DB holds information about nodes, networks, users, and other important data. This data is configuration data. For the most part, Netmaker serves configuration data to Nodes, telling them how they should configure themselves. The Netclient is the agent that actually does that configuration.

    +

    The components of the server are usually proxied via Caddy, or an alternative like Nginx and Traefik. The proxy handles SSL certificates to secure traffic, and routes to the UI, API, and gRPC server.

    Netclient

    @@ -569,6 +574,12 @@

    Netmaker allows users to provide and manage Private DNS for their nodes. This requires a nameserver, and CoreDNS is the chosen nameserver. CoreDNS is lightweight and extensible. CoreDNS loads dns settings from a simple file, managed by Netmaker, and serves out DNS info for managed nodes. DNS can be tricky, and DNS management is currently only supported on a small set of devices, specifically those running systemd-resolved. However, the Netmaker CoreDNS instance can be added manually as a nameserver to other devices. DNS mode can also be turned off.

    +

    Caddy

    +

    Caddy is the default proxy for Netmaker if you set it up via Quick Start. Caddy is an extremely simple and docker-friendly proxy, which can be compared to Nginx, Traefik, or HAProxy. We use Caddy by default because of the ease of management, and integration with gRPC. A typical setup for Nginx might take dozens of lines of code, and we need to request and manage SSL certificates separately.

    +

    Caddy handles all these things automatically in very few lines of code. You can see our default “Caddyfile” here, which is fed to the container and has all the configuration necessary to configure the proxy for our app:

    +

    https://github.com/gravitl/netmaker/blob/master/docker/Caddyfile

    + +

    External Client

    The external client is simply a manually configured WireGuard connection to your network, which Netmaker helps to manage.

    Most machines can run WireGuard. It is fairly simple to set up a WireGuard connection to a single endpoint. It is setting up mesh networks and other topologies like site-to-site which becomes complicated.

    diff --git a/docs/_build/html/client-installation.html b/docs/_build/html/client-installation.html index c209fc0f..b9a6a500 100644 --- a/docs/_build/html/client-installation.html +++ b/docs/_build/html/client-installation.html @@ -292,7 +292,15 @@
    • Introduction to Netclient
    • -
    • Notes on Windows +
    • Notes on Windows
    • Notes on OpenWRT
    • @@ -474,7 +482,15 @@
      • Introduction to Netclient
      • -
      • Notes on Windows +
      • Notes on Windows
      • Notes on OpenWRT
      • @@ -542,6 +558,27 @@

        netsh advfirewall firewall add rule name="Allow from <peer private addr>" dir=in action=allow protocol=ANY remoteip=<peer private addr>

        If you want to allow all peers access, but do not want to configure firewall rules for all peers, you can configure access for one peer, and set it as a Relay Server.

        +

        Running the install script

        +

        Some file locations have issues running the install script, such as running from the root C:/ folder. Users have noted the following locations work well for running the install powershell script:

        +
          +
        • C:/Program Files/wireguard

        • +
        • C:/Windows/System32

        • +
        + + +

        Running netclient commands

        +

        If running the netclient manually (“netclient join”, “netclient checkin”, “netclient pull”) it should be run from outside of the installed directory, which will be either:

        +
          +
        • C:/Program Files/netclient

        • +
        • C:/ProgramData/netclient

        • +
        +

        It is better to call it from a different directory.

        + + +

        High CPU Utilization

        +

        With some versions of WireGuard on Windows, high CPU utilization has been found with the netclient. This is typically due to interaction with the WireGuard GUI component (app). If you’re experiencing high CPU utilization, close the WireGuard app. WireGuard will still be running, but the CPU usage should go back down to normal.

        + +

        Notes on OpenWRT

        Deploying on OpenWRT depends a lot on the version of OpenWRT and the hardware being used. If the primary installer does not work, there are two things you can try:

        diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html index 4e77524e..8ffcdbd5 100644 --- a/docs/_build/html/index.html +++ b/docs/_build/html/index.html @@ -629,6 +629,7 @@
        • Support
        • diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js index 5779273a..e50fe563 100644 --- a/docs/_build/html/searchindex.js +++ b/docs/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["about","api","architecture","client-installation","conduct","egress-gateway","external-clients","getting-started","index","install","license","oauth","quick-start","relay-server","server-installation","support","troubleshoot","ui-reference","upgrades","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["about.rst","api.rst","architecture.rst","client-installation.rst","conduct.rst","egress-gateway.rst","external-clients.rst","getting-started.rst","index.rst","install.rst","license.rst","oauth.rst","quick-start.rst","relay-server.rst","server-installation.rst","support.rst","troubleshoot.rst","ui-reference.rst","upgrades.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,3,5,6,7,8,14,16,18],"04":[12,14],"06":1,"0afehuytvin":3,"0g":3,"1":[1,3,4,6,8,10,16,17],"10":[1,2,3,5,6,7,14],"100":[1,7],"101":3,"1024":17,"11":[3,5,6,7,14],"12":[5,7,13],"127":14,"128":5,"1280":17,"13":5,"14":5,"1420":17,"147":3,"15":[3,5],"16":[1,2,5],"160":5,"168":[3,5],"169":5,"170":[3,5],"172":[1,5],"173":5,"174":5,"176":5,"182":3,"192":[3,5],"193":5,"194":5,"196":5,"1gb":12,"1node":17,"2":[1,3,8,16,17],"20":[3,6,7,12,14],"200":[1,5],"203":3,"208":5,"22":3,"236":6,"24":[2,3,6,7],"245":14,"247":6,"25":7,"251":3,"254":7,"2a":3,"2cpu":12,"2gb":12,"3":[3,5,6,8],"30":[7,12,14,17],"31":1,"32":[3,5,6],"34":3,"3rd":17,"4":[3,4,5,8,18],"4001":14,"4002":14,"41":3,"443":[12,14],"4b":3,"4gb":12,"5":[5,6,11,14,17],"50051":[2,3,7,14],"51821":[3,7,12],"51822":6,"51830":12,"518xx":12,"53":[3,12,14],"5432":14,"5c":3,"5qktbtgsvb45y3qyrmwft":3,"6":5,"60":6,"64":5,"6400":1,"68":3,"69":14,"6c":3,"7":[3,5,6,16],"70":1,"75":14,"77":3,"78":3,"7b":3,"8":[2,3,5,6,11,14,16],"80":14,"8081":[1,2,3,14],"8082":14,"8c":1,"9":[5,12,14,18],"90":1,"91":3,"98":7,"99":7,"abstract":2,"break":[3,7],"case":[1,2,3,6,7,8,9,12,14,16,17,18,19],"class":14,"default":[1,2,3,6,7,11,12,13,14,16,17],"do":[0,1,2,3,4,5,6,7,12,13,14,16,17],"final":[5,16],"function":[1,3,7,13,14,15,16],"import":[2,5,6,7],"long":[0,7,15],"new":[2,3,5,7,17,18],"public":[2,3,4,5,6,7,10,12,13,14,17],"return":[2,5,7],"short":3,"static":[2,5,12,14,16,17],"super":17,"switch":[14,17],"true":[2,3,14],"try":[3,5,15,16],"var":[1,14],"while":[2,5,15],A:[2,3,5,6,7,8,12,14,16,17],And:14,As:[0,2,3,5,11,12,15,16,18],At:[0,2,3,5,12,13],Be:[12,14],Being:4,But:[7,14],By:[0,1,6,11,12,14,17],For:[2,3,5,6,7,8,9,11,12,13,14,16,17],If:[0,1,2,3,6,7,11,12,13,14,15,16,17,19],In:[0,1,2,3,4,5,7,11,12,13,14,16,18],Is:[7,16,17],It:[0,2,3,6,7,14,15,16,17,19],No:15,Not:[2,17],On:[2,3,14,17],Or:12,Such:5,That:2,The:[0,1,2,3,4,5,6,7,12,14,17],Then:[6,7,13,16],There:[0,1,3,7,14,15,16],These:[2,3,5,7,14,17],To:[2,3,6,7,12,13,14,18],Will:3,With:[2,14,17],a6:3,aa3bvg0rnitirxdx:1,abil:[15,16],abl:[1,2,5,6,14],abou:7,about:[2,3,7,12,14,16,17],abov:[2,3,7,13,14],absent:3,abus:4,accept:[3,4,6],access:[0,2,3,6,7,8,11,12,14,15,16,17,19],access_token_valu:14,accesskei:[1,3],accomplish:15,account:[4,16],acess:5,achiev:[1,2,14,15,16],across:[0,3,17],act:[2,4,5,6,17],action:[1,3,4],activ:16,actual:2,ad:[2,7,8,11,14,17,18],adapt:[4,14],add:[0,1,2,3,6,7,14,17,18],addit:[2,3,5,7,14,16,17],addition:[11,12],addnetwork:1,addr:[3,14],address:[2,3,4,5,6,7,13,14,16,17],addressipv6:3,addressrang:1,adequ:14,adm:1,admin:[0,1,2,3,7,11,14,16,17],administr:3,adopt:2,adv:14,advanc:[1,4,7,9,12],advfirewal:3,affect:17,after:[2,3,5,6,7,11,13,17],ag:4,again:12,against:3,agent:[0,2,3,7,8,14,16],agent_backend:14,agentbackend:14,aggreg:2,alex:3,algo:15,align:4,aliv:17,all:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17],allow:[1,2,3,5,6,7,12,13,14,16,17,19],allowedip:[3,6,17],allowedorigin:14,almost:[7,17],along:16,alongsid:14,alreadi:[2,3,7,14],also:[0,1,2,7,11,12,14,16,17],altern:[2,14],although:16,alwai:[5,7,14,17],am:16,an:[0,2,3,4,7,8,11,12,14,16,17,19],android:[2,16,17],ani:[0,2,3,4,6,7,11,12,13,14,16,17,18],annot:[8,17],anoth:[2,5,16],answer:16,anymor:16,anyth:[2,17],anywher:12,aorijqalrik3ajflaqrdajhkr:1,apach:[2,14],api:[2,3,7,11,12,14],api_port:14,apiaddress:3,apihost:14,apiport:14,apiserv:3,app:[6,14,15,16,17],appear:[4,7,17],appli:[4,14],applic:[1,14],appoint:4,appropri:[2,4,6,7,14,17,18],approv:[1,3,7,15,17],aprov:16,apt:12,ar:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18],arbitrari:[0,14,17],arch:[2,7],architectur:[8,14],argument:3,arm:[3,7],around:[12,17],arrai:2,artifact:10,ask:[3,16],asset:14,assign:17,assum:[2,6,12,14,16,17],attach:6,attack:4,attempt:[2,17],attent:4,attribut:8,auth:[11,14],auth_provid:11,authent:[2,3,7],author:1,autofil:17,autom:[0,18],automat:[3,6,14,17],avail:[3,4,8,9,10,17],avoid:[14,17],aw:[0,12,15],awai:2,await:2,azur:11,azure_ten:11,b5:1,back:[2,6,14],backend:14,backend_url:14,background:2,ban:4,bare:[2,8],base64:7,base:[2,3,5,11,12,14,17,18],basedomain:14,bash:[2,3,16],basi:2,basic:19,bcrypt:14,bearer:1,becaus:[0,2,14,16,17],becom:[2,14,16,17],been:[2,3,5,12,14,17],befor:[2,12,16],begin:[2,5,12],behavior:4,behind:[2,6,12,13,16],being:[2,3,14,16,17],believ:15,bellow:14,belong:17,below:[1,2,6,7,13,14,18],benefit:7,besid:2,best:[4,7,15,17],better:[2,17],between:[0,2,17],bewar:3,beyond:14,bin:14,bin_t:16,binari:[2,3,7,9,14,16,18],bind:[12,14],bit:19,biz:12,blank:[3,6,11],blob:14,block:[8,14,16],bodi:4,both:[2,4,5,12,14,15,17],bottleneck:13,bottom:7,bound:12,brief:7,brought:17,brows:[5,15],bsherman:14,build:2,built:2,busi:[12,16],button:[13,16,17],c:[12,14],caddi:14,caddyfil:12,call:[0,2,3,8,14],callabl:3,callback:11,can:[0,1,2,3,5,6,7,10,11,13,14,15,16,17,18,19],candid:5,cang:14,cannot:[3,6,7,12,17],cap_add:14,car:15,cat:16,caus:[2,12,17],cd:2,center:[0,5,7,17],cento:2,cert:14,certain:[2,17],certif:14,certmanag:14,cgnat:[13,17],chang:[0,1,2,3,5,6,7,13,14,16,17,18],charact:[16,17],chart:14,chcon:16,check:[1,2,3,7,12,14,16,17],checkin:[1,2,3,17,18],choic:[6,13,14],choos:[3,9,13,14],chosen:[2,3],cidr:[7,14,17],circumst:[3,4,7],circumv:13,clarifi:4,classnam:14,clear:15,cli:2,click:[2,5,7,11,13,16,17],client:[0,5,7,11,12,14,16],client_id:11,client_max_body_s:14,client_mod:14,client_secret:11,clientmod:14,clone:2,close:18,cloud:[0,12,19],cluster:[14,19],cluster_mgmt:14,clusterip:14,clusterissu:14,code:[2,3,6,10,14,16,17],com:[3,4,7,11,12,14,15,16,18],combin:[5,14,17],come:[2,5,14],comfort:12,comm:3,comma:17,command:[2,3,7,12,14,16,17],comment:[4,14],commit:4,common:[2,5,8,12],commonli:16,commun:[2,3,4,7,8,14,15,16,17],compar:15,compat:[5,6,8,17],compil:[2,3],complaint:4,complet:[2,16],complex:2,complic:2,compon:[8,14,17],compos:[7,8,16,18],comput:[0,2,3],concept:8,concurr:12,conf:[6,14],confidenti:4,config:[1,2,6,17,18],configur:[0,1,2,7,12,16,17],confirm:[17,18],conflict:[14,17],connect:[0,2,3,6,7,13,14,16,17,19],consensu:[2,16],consequ:14,consid:[4,7],consider:2,consist:[2,14],consol:7,construct:4,consult:[14,16],consum:[3,14],contact:[4,8,12,14],contain:[2,7,12,14,17],container_nam:14,content:1,context:14,continu:[14,16],contrast:2,contribut:4,contributor:4,control:[2,7,14],convert:[3,16,17],copi:[7,14],core:[0,8],coredn:[3,8,12],coredns_addr:14,coredns_address:14,coredns_ip:12,corednsaddr:3,corefil:14,coreo:2,corpor:[14,15,16],correct:[4,12,18],correctli:[2,14,17],cors_allowed_origin:14,could:[0,4,7,16,17],countri:5,cours:5,coven:4,cover:8,cp:14,cpu:[12,16],creat:[0,1,2,3,4,5,6,8,12,13,14,16],createadmin:1,creategatewai:1,creation:[0,7,13,17],credenti:14,credit:16,critic:[4,14],cron:2,cross:19,cryptocurr:0,curl:[7,14],current:[2,3,14,16,17],custom:[2,8,12,14],customiz:14,cycl:[1,2],d9:1,d:[1,2,12,14,17,18],daemon:2,dashboard:[8,11,12,14],data:[0,2,5,7,14,16,17],databas:16,datastor:14,date:1,datetim:17,db:[2,8,14],dc:12,ddflzqn:6,debian:2,debug:14,decod:[2,3,7],deem:4,defin:[4,7,17],delet:[1,6,7,14,16,17],deletegatewai:1,deni:16,depend:[2,3,8,16,17,18],depends_on:14,deploi:[2,3,5,8,12,14,16],deploy:[2,14],depreci:[14,17],derogatori:4,design:[2,3,6,13,14,16],desktop:[2,3,6,17],detail:[1,2,3,4,7,8,14],determin:[4,5,17],dev:[12,14],devic:[0,2,3,8,16,17],diagram:2,differ:[0,2,4,5,7,14,15],difficult:17,digitalocean:12,dir:3,direct:13,directli:[0,1,2,6,12,13,14,16],directori:14,disabl:[2,4,17],disable_remote_ip_check:14,disableremoteipcheck:14,disconnect:16,discord:[15,16],discuss:[14,18],displai:[2,14,17],display_kei:14,displaynam:1,distibut:2,distribut:[2,7,14,17],distributionshav:2,dn:[2,8,16,19],dns_mode:[14,16],dnsconfig:14,dnsmode:14,dnson:3,dnsstublisten:14,doc:[7,11,12,14,17],docker:[2,7,8,9,11,16,18],document:[0,2,3,7,14,15],doe:[2,3,6,8,14,16,17],doesn:16,domain:[11,12,14,16],don:[2,3,7,19],done:16,dont:[7,16],doubl:13,down:[0,5,7,11,13,14,16,17,18],download:[3,6,7,14,16,17,18],dual:[3,7,16,17,19],dualstack:17,due:[13,16],duplic:3,dure:[3,17],dynam:[0,2,8,17],e:[2,3,4,5,7,12,14,16,18],each:[0,2,3,7,8,11,14,16,17],easi:[2,14,17],easier:2,easiest:2,easili:[0,5,7,14],echo:12,edit:[4,6,8,13,14,16],effect:[7,17],effici:[2,5],egress:[3,6,15],either:[2,6,13,18],ejf6yy51m:6,electron:4,elev:[11,14],elimin:2,els:17,email:[12,15],embed:14,empathi:4,empti:14,enabl:[2,5,7,12,14,17],encod:7,encompass:[0,5],encount:2,encrypt:[0,2,3,5,16],end:[2,12,14,16,17],endpoint:[1,2,3,6,7,17],enforc:8,enough:14,enpoint:17,ensur:[13,14,15,18],enter:[7,13,14,17],enterpris:[12,14],entir:7,entireti:2,entri:[14,16,17],env:[1,14],environ:[0,1,2,4,11,14,16,17],equal:14,equival:14,error:17,essenti:13,establish:6,etc:[3,7,12,14,16,18],eth0:[1,17],eth2:5,ethnic:4,evalu:15,even:[0,2],event:4,everi:[2,3,7,17],everyon:4,everyth:[2,5,14,17],evolv:2,ex:[3,7,12,14],exampl:[2,3,4,5,6,8,11,12,17],except:[7,11,14,17],execut:14,exist:[0,2,7,14,17],expect:[4,5,8,14,17,18],experi:[3,4,9,16],expir:17,explain:2,explicit:4,explicitli:14,exploit:14,expos:2,express:4,expressvpn:15,ext:[5,8,16],extend:14,extens:2,extern:[3,5,14,17],f1:1,f8:3,f:[3,14,16],face:[4,5],fact:0,fail:[2,7,11],fair:4,fairli:[2,16],faith:4,fallback:17,fals:[3,14],familiar:[0,2,15,16],faq:8,fast:[2,8,14],faster:[0,2,3,17],fcontext:16,featur:[12,14,17],fedora:2,few:[3,7,15,17],field:[5,6,7,8,13,14,17,18],figur:19,file:[2,6,17,18],filenam:1,fill:17,filter:17,find:[2,14,17,18,19],fine:0,firewal:[3,7,8,13,14,16],first:[2,3,5,7,8,11,14,16,17,19],fit:[12,19],flag:3,flat:0,flexibl:0,flow:2,focus:4,folder:[2,14,18],follow:[2,3,4,5,7,11,12,14,16],forc:14,form:[3,7,17],format:[11,14],forum:16,forward:[3,5,6],foster:4,found:[0,2,10,11,14],free:[4,17],freebsd:2,freeli:10,frequent:[5,16,17],friend:16,from:[0,1,2,3,4,5,6,7,9,12,13,14,16,17,19],front:[2,14],frontend_url:11,full:[0,2,14],fulli:[0,2],further:4,furthermor:14,futur:[7,12,18],g:[3,7,12,14],gatewai:[1,2,3,8,15,16,17,19],gb:16,gcp:12,gender:4,gener:[1,2,3,6,9,11,12,14,15,17],generate_config_j:14,get:[1,3,5,12,14,16,17,18],gg:15,github:[2,3,8,11,12,14,15,16,18],githubusercont:[3,7,12,14,16],give:[2,7,8,14,15,16],given:[0,2,5,7,16,17],global:[3,5],go:[2,3,5,8,13,14,16,17],goe:[0,14,17],golang:2,good:[4,5,6,7,13,15,16,17,19],googl:[11,14],grab:3,gracefulli:4,grade:14,grant:17,gravitl:[3,4,7,12,14,15,16,18],group:12,grpc:[2,3,7,12],grpc_port:14,grpc_ssl:14,grpcaddress:3,grpchost:14,grpcport:14,grpcserver:3,guid:[0,2,7,9,12,14,16],guidanc:8,guidelin:[14,15],h:[1,3],ha:[0,2,3,5,7,11,12,13,14,16,17,19],hand:8,handl:[0,2,12,14,17],handshak:[16,17],harass:4,hard:[13,16,17],harder:16,hardwar:[3,16,17],harm:4,hasadmin:1,hash:14,have:[0,2,3,4,5,6,7,11,12,13,14,16,17],haven:16,head:12,header:[1,2,14],health:17,heart:3,heavi:2,helm3:14,helm:14,help:[1,2,3,7,8,14,15,17,18],here:[2,4,7,10,12,14,15,17,19],hesit:15,high:[2,8,14,16],highli:[3,8,9],hit:16,hold:[0,2,3],holder:16,hole:[3,7,16,17],holepunch:3,home:[0,2,3,5,17],hook:[2,6],host:[2,3,12,14,15,17],host_ip:14,hostnam:17,hous:1,how:[2,3,5,8,14,16,17],howev:[1,2,3,5,12,14,16],html:14,http:[1,3,7,8,11,12,15,16,18],http_port:14,hub:[0,2,13,17],hundr:12,i:[3,12,14,16],id:[1,3,11,14,17],ideal:14,ident:4,identifi:3,ignor:[3,5,17],imag:[14,18],imageri:4,impact:[2,15],implement:[2,5],importantli:7,imposs:13,inappropri:4,inbound:[3,12],incid:4,includ:[2,4,6,8,14],inclus:4,incompat:18,incorrect:[3,14,16],increas:[2,17],independ:6,indic:[11,17],individu:[4,14,17],industri:2,info:[2,4,12,14,15],inform:[2,3,4,7,8,12,17],ingress:[2,3,5,16,17],ingressroutetcp:14,initi:[3,11],ins:2,insert:[5,12,14,16],insid:[8,14,17],instal:[0,2,6,7,16],instanc:[1,2,3,4,5,7,12,14,17],instead:[0,3,5,6,7,12,14,16,17],instruct:[11,14],insult:4,intact:3,integr:[8,14],intend:3,inter:17,interact:[0,2,3],interest:[4,16],interfac:[1,3,5,6,7,12,14,17],interfer:[12,16],intern:[5,14],internet:[0,2,5,15],intro:19,introduc:16,introduct:8,invalid:[6,7,17],investig:4,invis:[2,17],io:[11,12,14,16,17],iot:[0,2],ip:[2,3,5,6,7,12,13,14,17,18],ipaddress:17,ipforward:[3,17],iphon:2,ipsec:2,iptabl:[3,5,17],ipv4:[3,7,14,16,17],ipv6:[3,7,16,17,19],ipv6address:17,isdualstack:3,isingressgatewai:3,isloc:[3,17],isstat:3,issu:[2,3,4,8,12,13,14,17],issuer:14,issuernam:14,iter:17,its:[0,2,3,4,5,6,7,14,17],itself:[2,3,5,7,14],job:2,join:[2,3,7,14,16,17],journalctl:[3,14,16],jq:1,js:14,json:[1,14],just:[0,2,3,6,7,12,14,15,16,17],jwt:[1,3],k3:19,k8:14,k:[3,7],keep:[1,5,17],keepal:[3,17],kei:[2,3,8,11,12,14,16,17],kept:17,kernel:[0,2],keynam:1,keyupd:1,kill:16,know:[5,14,16,19],known:[2,12,17],kube:14,kubectl:14,kubernet:[0,5,9,17,19],lan:3,languag:4,laptop1:1,laptop:[6,17],larg:[2,17],last:[1,17,18],lastmodifi:1,latenc:2,later:2,latest:[2,3,6,14],launch:2,launchd:[2,3],launchdaemon:2,layer:0,layout:2,lb:14,le:14,leadership:4,least:[0,16],leav:[3,6,7,14,16,17,18],left:[7,11,14,16],length:[3,16,17],less:[2,7],let:[0,5,15,19],letsencrypt:14,level:[2,4,8,14,17],librari:2,light:14,lightweight:2,like:[0,2,3,7,14,17],limit:[3,8,14,16,17],line:[2,17],link:[8,11,12,14],linod:12,linux:[2,3,5,7,8,17],linuxserv:14,list:[0,2,3,5,13,14],listen:14,listenport:1,littl:[2,15],ln:14,load:2,local:[2,3,5,7,14,17],localaddress:[1,3],localhost:[1,14],localrang:3,locat:[0,2,3,5,14,17],log:[11,12,14,16],logic:6,login:[7,11],longer:17,look:[14,15,17],lookup:2,lose:17,lot:[2,3,16],lower:[16,17],lxc:14,m:[3,6,16],mac:[2,3,7,17],macaddress:[1,3],machin:[0,2,3,5,6,7,8,12,13,16,17,18],made:[0,2,16,17],mai:[1,2,3,4,7,11,12,13,14,16,17,18],mail:4,main:14,maintain:[4,14,15,17],make:[0,2,4,5,6,8,9,12,13,14,15,16,17],man:6,manag:[0,2,6,8,14,19],mani:[0,2,12,14,15,17,19],manual:[2,3,7,14,16,17,18],map:14,master:[3,7,12,14,16],master_kei:14,masterkei:[1,14],match:[3,14],maximum:14,md:[1,14],mean:[2,3,5,6,7,14,17],meant:14,measur:13,media:4,medium:9,meet:14,member:4,memori:16,mesh:[0,6,16,17,19],meshclient:1,metal:[2,8],method:[1,2,3,5,6,7,9],mgmt:1,microk8:[14,19],microsoft:11,middl:6,might:[0,2,13,14],min:12,minim:14,minimum:16,minor:18,mint:2,minu:14,minut:[12,14,16,17],mismatch:18,miss:[2,18],mix:3,mode:[2,7,8],model:[0,2],modif:14,modifi:[1,2,3,7,12,14,15,17],moment:17,mongo:14,mongodb:[],more:[0,1,2,6,7,8,12,14,15,17],most:[1,2,3,5,9,12,14,15,16,17],mostli:[2,3],mount:14,move:[7,12,18],mtu:[16,17],much:[0,2],mullvad:15,mullvadvpn:15,multipl:[0,7,14,16,17],must:[1,2,3,5,6,7,11,14,16,17,18],mv:18,my:[1,3,16,18],mydomain:11,mykei:[1,7],mynet:7,myserv:7,mysit:12,myvers:18,n:[2,3,7,12,14,16],name:[1,2,3,5,6,7,14,16,17],nameserv:[2,3,14],namespac:14,nat:[6,8,13,16,17],nation:4,nativ:2,navig:[11,12,16],nebula:[0,15],necessari:[2,3,4,14,17],need:[0,1,2,3,5,12,14,15,16,17,18],neg:15,neighborhood:0,neither:2,net:3,net_admin:14,netclient:[0,5,6,8,17],netclient_accesskei:3,netclient_accesstoken:3,netclient_address:3,netclient_addressipv6:3,netclient_api_serv:3,netclient_daemon:3,netclient_dn:3,netclient_endpoint:3,netclient_grpc_serv:3,netclient_interfac:3,netclient_ipforward:3,netclient_is_dualstack:3,netclient_is_loc:3,netclient_keepal:3,netclient_localaddress:3,netclient_localrang:3,netclient_macaddress:3,netclient_nam:3,netclient_network:3,netclient_o:3,netclient_password:3,netclient_port:3,netclient_postdown:3,netclient_postup:3,netclient_privatekei:3,netclient_publickei:3,netclient_roam:3,netclient_udp_holepunch:3,netconfig:[3,16,18],netid:1,netmak:[1,3,5,6,10,13,16,17,19],netmaker_base_domain:[12,14],netmaker_env:14,netsh:3,network:[0,5,6,8,11,12,13,14,15,16,18,19],network_mod:14,newli:18,next:[3,5,7,11],nextcloud:19,nf:14,nginx:[2,8,16],nip:12,nm:[3,14,17],node:[3,5,6,8,13,14,16],nodn:14,non:[2,3,7,9,14,17],none:0,noonewillguessthi:1,nopass:14,nordvpn:15,normal:14,notabl:14,note:[1,5,6,8,11,12,14,16,17],noteabl:7,notifi:2,now:[0,6,7,12,13,14,15,16,18],ns:14,number:[2,7,12,14,17],o:[12,14],oauth2:11,oauth_provid:11,object:14,oblig:4,obscur:17,obtain:[1,3],od:3,off:[2,3,7,14,16,17],offens:4,offer:11,offic:[0,5,19],offici:[1,4,16],offlin:4,often:[2,15,17],old:18,omit:14,onc:[5,6,7,11,14],one:[2,3,5,6,7,12,14,16,17],onli:[1,2,3,5,6,7,11,14,16,17,18],onlin:4,onto:17,open:[2,4,7,8,15,17],openvpn:[2,15],openwrt:[2,8,16],oper:[2,3,13,14,17],operatingsystem:3,opinion:12,oppos:[2,14],option:[2,3,8,11,17],oracl:12,order:[5,11,14,16],org:14,orient:4,origin:[11,14],os:[3,17],osi:15,other:[0,2,3,4,6,7,13,17],otherwis:[0,3,4,16,17],our:[8,14,16],out:[0,2,7,12,14,15,16,17,19],outlin:[2,14],output:[3,7,16],outsid:[8,14],over:[0,2,5,13,14,17],overlai:[0,8],overlap:[5,7],overrid:[3,14],overridden:[2,14],overview:[2,19],overwhelm:19,own:[2,12,14],p2p:17,p:[3,7,12,14],packag:[3,16],packet:17,page:[2,11,17],pair:[2,14],pane:7,panic:18,part:[2,3,14],parti:[16,17],partial:2,particip:4,particular:[2,3],pass:[2,3,14],password:[1,3,7,14,17],past:5,path:[1,14,15,17],peer:[2,3,6,7,13,16,17,19],pend:[1,7,17],peopl:[5,15,17],per:12,perform:[1,2,3,7,14],period:2,perm:14,perman:[4,14],permiss:[4,8,12,14,16],permit:7,persist:17,persistentkeepal:[3,6],person:4,perspect:[0,2],phone:[3,6],physic:4,pick:[2,7],pictur:2,ping:[7,16,17],pivpn:15,place:[3,12,13,14,18],plaintext:3,plan:[12,14,15,16],platform:[2,8],pleas:[3,8,12,14,15,16],pledg:8,plu:[3,12],poc:[9,12],pod:17,point:[2,5,12],polici:4,polit:4,popul:[14,17],port:[2,3,7,12,14,16,17],posgr:14,posit:4,possibl:[2,12],post:[1,2,3,4,14,17],postchang:3,postdown:[3,14,17],postgr:14,postgresql:[2,14],postgress:14,postup:[3,14,17],powershel:3,practic:2,pre:14,preced:2,precend:14,prefer:[12,14,16],prepar:8,prereqisit:7,prerequisit:[2,5,7,8,14],present:18,prevent:[3,17],previou:2,primari:[3,14,16,17],prior:14,privaci:15,privat:[2,4,5,7,8,14,15,17,19],privatekei:[3,6],privileg:14,privkei:3,probabl:[0,15],problem:[3,16],procedur:14,process:[3,7,8,14,18],prod:14,product:[12,14],profession:4,project:[1,4,14,15],proof:0,proper:14,properli:[3,16],properti:3,proto:12,protocol:[3,14],provid:[0,2,3,8,12,14,17],proxi:[8,11,12],proxy_pass:14,proxy_pass_request_head:14,proxy_set_head:14,pubkei:3,publickei:[1,3,6],publicli:[12,13],publish:[4,10],pull:[2,3,6,14,17,18],punch:[3,7,16,17],purchas:16,pure:17,push:[3,6],put:[1,17],q9cog7c9qjnoxygvri:3,qr:[6,16,17],quarantin:3,question:16,quick:[7,8,9,14,16,17],quickli:[12,16],quickstart:16,r:16,race:[4,15],raft:[2,14,16],ram:12,random:[14,17],randomli:17,rang:[3,5,6,7,12,14,17],rangestr:1,rare:17,raspian:2,rather:[11,14,17],raw:[3,7,12,14,16],rce:[14,17],re:[0,3,7,15,16],reach:[0,2,3,5,6,7,13,14,15,16,17],reachabl:[2,3,6,7,8,13,14,17],reactj:2,read:14,readm:[12,14],reallysecret:1,reason:[2,4,7,13,14,17],reboot:16,receiv:[1,2],recent:[2,3,16,17],recommend:[1,3,6,9,12,16],reconfigur:[2,3,16],record:[7,12,16],redirect:11,redund:14,refer:[2,7,16],regard:[2,4],regardless:4,regist:[2,3],registr:3,regularli:[15,17],reject:4,rejoin:18,rel:[2,5,18],relai:[2,3,6,16],relat:14,releas:[2,3,14,16,18],relev:17,reli:[0,3],reliabl:17,religion:4,remain:17,remot:[0,3,14],remoteip:3,remov:[1,2,4,7,14,16,17],removenetwork:1,renam:[3,16,18],repeat:7,repercuss:4,replac:[3,14],replace_master_kei:12,replica:14,replicacount:14,repo:[2,14],report:[2,4],repositori:[2,10],repres:4,represent:4,request:[1,2,14],requir:[1,2,3,7,16],resolv:[2,3,14],resolvectl:[3,14,17],resourc:[6,8,9],respect:[2,4],respons:[2,8],rest:[12,14],rest_backend:14,restart:[11,14,16],restbackend:14,restorecon:16,restrict:[13,14],result:4,retriev:[0,1,2,3,7],revers:[8,12],revert:3,review:4,rf:7,rhel:2,right:[0,4,17],risk:16,rkxlgk2mg:6,rm:7,rncjjbsaa3hzuhrk5hpyxm:3,roam:[3,17],rogu:16,root:[3,12,14,16,18],rout:[0,2,5,11,12,13,14,17],route53:12,router:[2,5,16],rpumvsbpgq:6,rqlite:16,rule:[3,5,12],run:[0,1,2,3,5,6,7,12,14,15,16,17,18],runtim:14,rv:16,rwo:14,rwx:14,s:[0,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],sai:5,said:2,same:[0,3,6,7,14,16,17],sampl:0,save:[7,12,18],saveconfig:17,sbilli:[3,16],scan:[6,17],scenario:[5,7,13,17],schedul:14,scope:8,screen:[7,11],screenshot:[8,17],script:[2,3,7,12,14,16],search:17,second:[5,7,17],secret:[1,3,7,11],secretkei:14,section:[3,14,17],secur:[0,1,2,3,5,8,12,16,17,19],sed:[12,14],see:[1,2,3,7,8,12,14,15,16,17],seem:7,select:[6,7,13,16,17],selector:14,self:[14,15],selinux:16,semanag:16,send:[2,3,14,17],sens:[2,9,15],sensibl:[0,2,7,17],sent:17,separ:[2,4,17,19],seper:16,serv:[2,14],server:[0,3,5,6,7,10,11,12,17],server_api_conn_str:14,server_api_host:14,server_grpc_conn_str:14,server_grpc_host:14,server_host:14,server_http_host:[11,14],server_nam:14,server_public_ip:12,servic:[2,3,5,6,12,14,17,19],set:[1,2,3,4,5,8,12,16,17,19],setup:[0,2,5,8,12],sever:[2,14],sexual:4,sf:14,sfl:[7,14],sh:[3,7,14,16],share:[14,16],shell:[3,16],should:[0,1,2,3,5,6,7,12,13,14,16,17],show:[3,4,14,16,17],shown:[6,17],shut:5,side:10,sign:[2,3,7,11,14,16],signific:2,signup:[2,3,16,17],similar:[0,7,14,15,17],simpl:[2,3,5,7,8,11,14,16],simplest:[2,3],simpli:[2,3,5,6,7,13,14,16],simplifi:[13,14],simultan:0,sinc:17,singl:[1,2,5,16,17],sit:17,site:[0,2,8,14,16,19],situat:[2,16,17],size:4,skip:14,skynet:1,slow:[0,13],slower:14,small:[2,7,9],smartgui:1,so:[0,2,3,5,6,7,12,14,16,17],social:4,sole:17,solut:2,solv:[2,17],some:[1,2,3,5,7,13,14,16,17],someth:[6,7,14,17],sometim:13,somewher:7,soon:16,sort:0,sourc:[2,3,8,10],space:[4,17],spec:16,special:[2,3,7,14],specif:[2,3,4,5,7,8,14,17],specifi:[3,5,11,13,14,17],speed:[0,2],split:3,spoke:[0,2,13,17],spread:0,sql:[2,14],sql_conn:14,sql_db:14,sql_host:14,sql_pass:14,sql_port:14,sql_user:14,sqlconn:14,sqldata:14,sqlite:[14,16],src:12,ssh:[7,12,18],ssl:14,sspl:10,stabl:5,stack:[3,7,16,17,19],stai:[3,17],stake:0,standalon:14,standard:[2,5,8,14,17],start:[14,16,19],startup:1,state:7,statement:8,statu:[3,14,16,17],step:[2,3,7,14,18],still:[0,14,18],stock:15,stop:14,storag:[12,14],storageclassnam:14,store:[2,14,17],straight:5,straightforward:18,string:[7,14],stuck:16,stun:[7,16],su:7,subdomain:[12,14],submit:7,subnet:[2,5,17],subscript:[12,16],subsequ:2,subspac:15,subspacecloud:15,substanti:0,success:[2,11],successfulli:11,sudo:[3,7,11,12,14,16],support:[2,12,14,16],sure:[12,15,16,17],surfshark:15,suse:2,swag:14,symbol:11,system:[7,8,12,17],system_u:16,systemctl:[3,14,16],systemd:[3,7,14,16],t:[2,3,7,16,19],tab:[7,16],tack:17,tail:3,tailscal:[0,15],take:[0,1,2,4,7,11,14,16,17],talk:[0,2],tcp:12,team:4,technic:[0,8,15],technolog:2,ted:17,tell:[0,2,3,13,14,16],templat:14,temporari:[4,17],temporarili:4,tenant:11,term:15,terrain:15,test:[7,9],than:[2,7,11,14,17],thei:[0,2,4,7,8,14,15,16,17],them:[2,7,14,15,16],themselv:[2,16],therefor:16,thi:[0,1,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],thing:[0,2,3,16],think:[5,15,19],third:16,thmpvlcykonxi:3,those:[0,2,3,5,6],thousand:0,threaten:4,three:[7,14],through:[2,13,14,17],ticket:15,time:[1,2,3,6,7,13,14,16,17,19],timer:2,timestamp:[2,17],tl:14,toc:14,token:[3,7,14,16],too:[16,17],tool:[0,3,5],top:[2,16],topic:19,topolog:2,toward:4,tr:12,track:17,traffic:[0,2,5,6,13,14,16,17],trailofbit:15,transact:2,translat:17,travers:17,treat:[2,3,17],trial:[9,12],tricki:2,troll:4,troubleshooot:12,troubleshoot:[1,3,7,12],tune:17,tunnel:[0,2],tunnelbear:15,turn:[2,3,7,13,14,16,17],tutori:8,two:[0,1,2,3,5,7,14,16],type:[1,14],typi:17,typic:[0,2,5,6,7,13,14,16,17],u:[3,14,16],ua2zjt8wn7ga:6,ubuntu:[2,12,14],udp:[3,7,12,14,16,17],udpholepunch:3,ufw:12,ui:[1,3,5,6,18],unabl:[7,16],unaccept:4,unaccess:17,uncom:14,uncordon:1,under:[3,7,10,14,16],underlai:[0,19],underscores_in_head:14,unedit:17,unexpectedli:5,unfamiliar:7,uninstal:[8,16],uniqu:[3,12,17],unix:[2,3,17],unless:[3,14],unmanag:2,unnecessari:[3,7],unregist:3,unregistr:3,unset:[3,14],unsur:[6,7,13],until:[3,7,14,16,17],unwelcom:4,unzip:14,up:[0,2,3,5,7,8,12,14,16,17,18,19],updat:[1,2,7,12,14,16,17],upgrad:[2,16],upon:[2,3],upstream_app:14,upstream_port:14,upstream_proto:14,urandom:12,uri:11,url:[11,14],us:[1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,19],usag:[3,8,14,19],user:[2,3,7,8,9,14,16],usernam:[1,7,14,17],userspac:14,usr:14,usual:[3,5,7,17],util:3,v0:[2,11,14,16],v:16,valid:[2,14,17],valu:[1,2,3,7,12,16,17],variabl:[2,3,11,16],variou:[3,8,14],ve:16,vehicl:15,verbos:14,veri:[0,2,3,5,7,17],verifi:2,version:[2,3,4,10,12,14,16,18],vi:18,via:[1,2,3,4,5,6,7,8,11,12,14,16,17,19],viabil:15,video:8,view:[7,14,16],viewpoint:4,vim:[3,14],virtual:[0,3,6,8,12,15,17,19],visibl:[7,14],visit:[14,15],vist:18,vm3ow4thatogiwnsla3thsl3894th:7,vm:[0,2,8,12],vne197vmradjodkb1zsuja:3,volum:[7,14,16],vpc:[0,5,15,17],vpn:[2,16,17,19],vs:18,vulner:[14,17],vx:18,wa:[2,11,14,17],wai:[14,15,16,17],wan:7,want:[0,2,3,6,7,11,12,14,15,16,17],warn:[14,17],we:[0,1,2,4,9,12,14,15,16],web:[5,14,15],webserv:2,websit:2,weight:14,welcom:4,well:[2,3,7,8,14,16,17],were:[14,16],wg:[3,14,16,17],wgaddress6:3,wgaddress:3,wget:[3,12,14,16,18],what:[2,4,5,6,8,16],whatev:[3,7,14,17],when:[2,3,4,7,13,14,16,17],where:[2,5,6,7,8,14,17,19],wherev:0,whether:[0,3,17],which:[0,2,3,4,5,6,7,10,11,12,13,14,15,16,17],who:4,why:[2,3,16],wide:[2,14],wider:2,wifi:17,wiki:4,wildcard:[12,14],window:[2,7,8],wipe:16,wireguard:[0,3,5,6,7,8,12,15,16,17],wish:[3,5,6,11,14,17],within:[2,3,4,17],without:[1,2,3,4,7,8,16,17],work:[2,3,5,8,13,14,15,16,17],worker:[5,14],workstat:[3,7],world:[0,2],worri:7,wors:2,would:[0,3,5,6,7,14,15,17],write:[2,14],written:8,wrong:16,ws2:3,www:14,x86:3,x:[1,2,5,7,12,18],y:12,yaml:[1,14],ydazgedrpuxmmrqul35wfjmhvrzr1rq0u:6,ye:[3,15,16,17],yet:16,yml:[12,14,16,18],you:[0,1,2,3,5,6,7,9,11,12,13,14,16,17,18,19],your:[0,1,2,3,5,6,7,8,12,13,14,15,16,18,19],your_db_password:14,your_email:12,your_pass:1,your_password:1,your_secret_kei:1,yournetwork:18,yourwildcard:14,z0:12,za:12,zero:11,zeroti:0,zip:14,zrb9vfhk8a:15},titles:["About","API Reference","Architecture","Advanced Client Installation","Code of Conduct","Egress Gateway","Ingress + External Clients","Getting Started","Welcome to the Netmaker Documentation","Install","License","Integrating OAuth","Quick Install","Relay Servers","Advanced Server Installation","Support","Troubleshooting","UI Reference","Upgrades","External Guides"],titleterms:{"0":12,"1":[5,12,14],"2":[5,12,14],"3":[12,14],"4":[12,14],"case":[0,5],"do":15,Is:15,No:14,about:[0,8],access:[1,5],ad:[3,6],advanc:[3,8,14],an:[5,6,15],ani:15,annot:14,api:[1,8],architectur:2,attribut:4,authent:1,avail:14,balanc:14,bare:14,busi:15,caddi:12,call:1,cli:3,client:[2,3,6,8,17,18],code:[4,8],common:16,compat:[2,3,14],compon:2,compos:[12,14],concept:2,conduct:[4,8],config:[3,14],configur:[3,5,6,8,11,13,14],consider:14,contact:15,core:2,coredn:[2,14,16],creat:[7,17],curl:1,daemon:3,daemonset:14,dashboard:17,databas:[2,14],depend:12,deploi:7,descript:[7,14],detail:17,disabl:14,dn:[3,6,12,14,17],docker:[12,14],document:[1,8],doe:0,edit:17,egress:[5,8,17],enforc:4,enterpris:15,exampl:[1,14],exit:15,ext:[6,17],extern:[2,6,8,19],faq:15,featur:15,file:[1,3,14],firewal:12,format:1,gatewai:[5,6],get:[7,8],grpc:14,guid:[8,19],have:15,highli:14,how:0,http:14,ingress:[6,8,14],instal:[3,8,9,12,14],integr:11,introduct:[3,5,6,11,12,13,18],issu:16,kei:[1,7],kernel:14,kubernet:[8,14],licens:[8,10,15],like:15,limit:2,linux:14,list:17,load:14,log:3,make:3,manag:[1,3,7],mesh:2,metal:14,mode:[3,14],nat:5,netclient:[2,3,7,14,16,18],netmak:[0,2,7,8,11,12,14,15,18],network:[1,2,3,7,17],nginx:14,node:[1,2,7,15,17],nordnpn:15,note:3,oauth:[8,11],offer:15,open:12,openwrt:3,option:[6,14],other:14,our:4,permiss:11,pledg:4,postgr:2,prepar:12,prerequisit:[3,12],privat:3,process:2,provid:11,proxi:14,quick:12,recommend:14,refer:[1,3,8,14,17],relai:[8,13,17],remot:5,remov:3,requir:14,respons:4,revers:14,rqlite:[2,14],scope:4,secur:14,server:[1,2,8,13,14,16,18],set:[7,14],setup:[7,14],sqlite:2,sspl:15,standard:4,start:[7,8,12],support:[8,15],system:[2,3,14],systemd:2,technic:2,test:14,traefik:14,troubleshoot:[8,16],tutori:19,ui:[2,8,14,16,17],uninstal:[3,7],updat:3,upgrad:[8,18],us:[0,5],usag:1,user:[1,11,17],valu:14,variabl:14,video:19,view:3,vm:14,vpn:[5,15],welcom:8,what:0,why:15,window:3,wireguard:[2,14],without:14,work:0,written:19,you:15,your:11}}) \ No newline at end of file +Search.setIndex({docnames:["about","api","architecture","client-installation","conduct","egress-gateway","external-clients","getting-started","index","install","license","oauth","quick-start","relay-server","server-installation","support","troubleshoot","ui-reference","upgrades","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["about.rst","api.rst","architecture.rst","client-installation.rst","conduct.rst","egress-gateway.rst","external-clients.rst","getting-started.rst","index.rst","install.rst","license.rst","oauth.rst","quick-start.rst","relay-server.rst","server-installation.rst","support.rst","troubleshoot.rst","ui-reference.rst","upgrades.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"0":[1,2,3,5,6,7,8,14,15,16,18],"04":[12,14],"06":1,"0afehuytvin":3,"0g":3,"1":[1,3,4,6,8,10,16,17],"10":[1,2,3,5,6,7,14,15],"100":[1,7],"101":3,"1024":17,"11":[3,5,6,7,14],"12":[5,7,13],"127":14,"128":5,"1280":17,"13":5,"14":5,"1420":17,"147":3,"15":[3,5],"16":[1,2,5],"160":5,"168":[3,5],"169":5,"170":[3,5],"172":[1,5],"173":5,"174":5,"176":5,"182":3,"192":[3,5],"193":5,"194":5,"196":5,"1gb":12,"1node":17,"2":[1,3,8,16,17],"20":[3,6,7,12,14],"200":[1,5],"203":3,"208":5,"22":3,"236":6,"24":[2,3,6,7],"245":14,"247":6,"25":7,"251":3,"254":7,"2a":3,"2cpu":12,"2gb":12,"3":[3,5,6,8],"30":[7,12,14,17],"31":1,"32":[3,5,6],"34":3,"3rd":17,"4":[3,4,5,8,18],"4001":14,"4002":14,"41":3,"443":[12,14],"4b":3,"4gb":12,"5":[5,6,11,14,17],"50051":[2,3,7,14],"51821":[3,7,12,16],"51822":6,"51830":12,"51831":16,"51835":16,"518xx":12,"53":[3,12,14],"5432":14,"5c":3,"5qktbtgsvb45y3qyrmwft":3,"6":5,"60":6,"64":5,"6400":1,"68":3,"69":14,"6c":3,"7":[3,5,6,16],"70":1,"75":14,"77":3,"78":3,"7b":3,"8":[2,3,5,6,11,14,16],"80":14,"8081":[1,2,3,14],"8082":14,"8c":1,"9":[5,12,14,18],"90":1,"91":3,"98":7,"99":7,"abstract":2,"break":[3,7],"case":[1,2,3,6,7,8,9,12,14,16,17,18,19],"class":14,"default":[1,2,3,6,7,11,12,13,14,16,17],"do":[0,1,2,3,4,5,6,7,12,13,14,16,17],"final":[5,16],"function":[1,3,7,13,14,15,16],"import":[2,5,6,7],"long":[0,7,15],"new":[2,3,5,7,17,18],"public":[2,3,4,5,6,7,10,12,13,14,17],"return":[2,5,7],"short":3,"static":[2,5,12,14,16,17],"super":17,"switch":[14,17],"true":[2,3,14],"try":[3,5,15,16],"var":[1,14],"while":[2,5,15],A:[2,3,5,6,7,8,12,14,16,17],And:14,As:[0,2,3,5,11,12,15,16,18],At:[0,2,3,5,12,13],Be:[12,14],Being:4,But:[7,14],By:[0,1,6,11,12,14,17],For:[2,3,5,6,7,8,9,11,12,13,14,16,17],If:[0,1,2,3,6,7,11,12,13,14,15,16,17,19],In:[0,1,2,3,4,5,7,11,12,13,14,16,18],Is:[7,16,17],It:[0,2,3,6,7,14,15,16,17,19],No:15,Not:[2,17],On:[2,3,14,17],One:16,Or:12,Such:5,That:2,The:[0,1,2,3,4,5,6,7,12,14,15,16,17],Their:16,Then:[6,7,13,16],There:[0,1,2,3,7,14,15,16],These:[2,3,5,7,14,16,17],To:[2,3,6,7,12,13,14,15,18],Will:3,With:[2,3,14,17],_:[],a6:3,aa3bvg0rnitirxdx:1,abil:[15,16],abl:[1,2,5,6,14,16],abou:7,about:[2,3,7,12,14,16,17],abov:[2,3,7,13,14],absent:3,abus:4,accept:[3,4,6],access:[0,2,3,6,7,8,11,12,14,15,16,17,19],access_token_valu:14,accesskei:[1,3],accomplish:15,account:[4,16],acess:5,achiev:[1,2,14,15,16],across:[0,3,17],act:[2,4,5,6,14,17],action:[1,3,4],activ:16,actual:2,ad:[2,7,8,11,14,17,18],adapt:[4,14],add:[0,1,2,3,6,7,14,17,18],addit:[2,3,5,7,14,16,17],addition:[11,12],addnetwork:1,addr:[3,14],address:[2,3,4,5,6,7,13,14,16,17],addressipv6:3,addressrang:1,adequ:14,adm:1,admin:[0,1,2,3,7,11,14,16,17],administr:3,adopt:2,adv:14,advanc:[1,4,7,9,12],advfirewal:3,affect:[14,17],after:[2,3,5,6,7,11,13,17],ag:4,again:12,against:3,agent:[0,2,3,7,8,14,16],agent_backend:14,agentbackend:14,aggreg:2,alex:3,algo:15,align:4,aliv:17,all:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17],allow:[1,2,3,5,6,7,12,13,14,16,17,19],allowedip:[3,6,17],allowedorigin:14,almost:[2,7,17],along:16,alongsid:14,alreadi:[2,3,7,14],also:[0,1,2,7,11,12,14,16,17],altern:[2,14],although:16,alwai:[2,5,7,14,17],am:16,an:[0,2,3,4,7,8,11,12,14,16,17,19],android:[2,16,17],ani:[0,2,3,4,6,7,11,12,13,14,16,17,18],annot:[8,17],anonym:14,anoth:[2,5,16],answer:16,anymor:16,anyth:[2,17],anywher:12,aorijqalrik3ajflaqrdajhkr:1,apach:[2,14],api:[2,3,7,11,12,14],api_port:14,apiaddress:3,apihost:14,apiport:14,apiserv:3,app:[2,3,6,14,15,16,17],appear:[4,7,16,17],appli:[4,14],applic:[1,14],appoint:4,appropri:[2,4,6,7,14,17,18],approv:[1,3,7,15,17],aprov:16,apt:12,ar:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18],arbitrari:[0,14,17],arch:[2,7],architectur:[8,14],argument:3,arm:[3,7],around:[12,17],arrai:2,artifact:10,ask:[3,16],asset:14,assign:17,assist:16,assum:[2,6,12,14,16,17],attach:[6,16],attack:4,attempt:[2,17],attent:4,attribut:8,auth:[11,14],auth_provid:11,authent:[2,3,7],author:1,autofil:17,autom:[0,18],automat:[2,3,6,14,17],avail:[3,4,8,9,10,17],avoid:[14,17],aw:[0,12,15],awai:2,await:2,azur:11,azure_ten:11,b5:1,back:[2,3,6,14],backend:14,backend_url:14,background:2,ban:4,bare:[2,8],baremet:14,base64:7,base:[2,3,5,11,12,14,17,18],basedomain:14,bash:[2,3,16],basi:2,basic:19,bcrypt:14,bearer:1,becaus:[0,2,14,16,17],becom:[2,14,16,17],been:[2,3,5,12,14,17],befor:[2,12,16],begin:[2,5,12],behavior:4,behind:[2,6,12,13,16],being:[2,3,14,16,17],believ:15,bellow:14,belong:17,below:[1,2,6,7,13,14,18],benefit:7,besid:[2,15],best:[4,7,15,17],better:[2,3,17],between:[0,2,14,17],bewar:3,beyond:14,bin:14,bin_t:16,binari:[2,3,7,9,14,16,18],bind:[12,14],bit:19,biz:12,blank:[3,6,11],blob:[2,14,15],block:[8,14,16],bodi:4,both:[2,4,5,12,14,15,17],bottleneck:13,bottom:7,bound:12,brief:[7,14],broad:15,brought:17,brows:[5,15],bsherman:14,bug:15,build:2,built:2,busi:[12,16],button:[13,16,17],c:[3,12,14],caddi:14,caddyfil:[2,12],call:[0,2,3,8,14],callabl:3,callback:11,can:[0,1,2,3,5,6,7,10,11,13,14,15,16,17,18,19],candid:5,cang:14,cannot:[3,6,7,12,17],cap_add:14,car:15,cat:16,caus:[2,12,17],cd:2,center:[0,5,7,17],cento:2,cert:14,certain:[2,17],certif:[2,14],certmanag:14,cgnat:[13,17],chang:[0,1,2,3,5,6,7,13,14,16,17,18],charact:[16,17],chart:14,chcon:16,check:[1,2,3,7,12,14,16,17],checkin:[1,2,3,17,18],choic:[6,13,14],choos:[3,9,13,14],chosen:[2,3],cidr:[7,14,17],circumst:[3,4,7],circumv:13,clarifi:4,classnam:14,clear:15,cli:2,click:[2,5,7,11,13,16,17],client:[0,5,7,11,12,14,15,16],client_id:11,client_max_body_s:14,client_mod:14,client_secret:11,clientmod:14,clone:2,close:[3,18],cloud:[0,12,19],cluster:[14,19],cluster_mgmt:14,clusterip:14,clusterissu:14,code:[2,3,6,10,14,15,16,17],collect:15,com:[2,3,4,7,11,12,14,15,16,18],combin:[5,14,17],come:[2,5,14],comfort:12,comm:3,comma:17,command:[2,7,12,14,16,17],comment:[4,14],commit:4,common:[2,5,8,12],commonli:16,commun:[2,3,4,7,8,14,15,16,17],compar:[2,15],compat:[5,6,8,17],compil:[2,3],complaint:4,complet:[2,16],complex:2,complic:2,compon:[3,8,14,17],compos:[7,8,15,16,18],comput:[0,2,3],concept:8,concurr:12,conf:[6,14],confidenti:4,config:[1,2,6,17,18],configur:[0,1,2,7,12,16,17],confirm:[17,18],conflict:[14,17],connect:[0,2,3,6,7,13,14,16,17,19],consensu:[2,16],consequ:14,consid:[4,7,14,15],consider:2,consist:[2,14],consol:7,construct:4,consult:[14,16],consum:[3,14,16],contact:[4,8,12,14,16],contain:[2,7,12,14,16,17],container_nam:14,content:1,context:14,continu:[14,16],contrast:2,contribut:4,contributor:4,control:[2,7,14],convert:[3,16,17],copi:[7,14],core:[0,8],coredn:[3,8,12],coredns_addr:14,coredns_address:14,coredns_ip:12,corednsaddr:3,corefil:14,coreo:2,corpor:[14,15,16],correct:[4,12,18],correctli:[2,14,17],cors_allowed_origin:14,could:[0,4,7,14,16,17],count:[14,15],countri:5,cours:5,coven:4,cover:8,cp:14,cpu:[12,16],creat:[0,1,2,3,4,5,6,8,12,13,14,16],createadmin:1,creategatewai:1,creation:[0,7,13,17],credenti:14,credit:16,critic:[4,14],cron:2,cross:19,cryptocurr:0,curl:[7,14],current:[2,3,14,16,17],custom:[2,8,12,14],customiz:14,cycl:[1,2],d9:1,d:[1,2,12,14,17,18],daemon:2,daili:14,dashboard:[8,11,12,14],data:[0,2,5,7,14,15,16,17],databas:16,datastor:14,date:1,datetim:17,db:[2,8,14],dc:12,ddflzqn:6,debian:2,debug:14,decod:[2,3,7],deem:4,defin:[4,7,17],delet:[1,6,7,14,16,17],deletegatewai:1,deni:16,depend:[2,3,8,16,17,18],depends_on:14,deploi:[2,3,5,8,12,14,16],deploy:[2,14],depreci:[14,17],derogatori:4,design:[2,3,6,13,14,16],desktop:[2,3,6,17],detail:[1,2,3,4,7,8,14],determin:[4,5,14,17],dev:[12,14],devic:[0,2,3,8,16,17],diagram:2,differ:[0,2,3,4,5,7,14,15],difficult:[15,17],digitalocean:12,dir:3,direct:13,directli:[0,1,2,6,12,13,14,16],directori:[3,14],disabl:[2,4,17],disable_remote_ip_check:14,disableremoteipcheck:14,disconnect:16,discord:[15,16],discuss:[14,18],displai:[2,14,17],display_kei:14,displaynam:1,distibut:2,distribut:[2,7,14,17],distributionshav:2,dn:[2,8,16,19],dns_mode:[14,16],dnsconfig:14,dnsmode:14,dnson:3,dnsstublisten:14,doc:[7,11,12,14,17],docker:[2,7,8,9,11,15,16,18],document:[0,2,3,7,14,15],doe:[2,3,6,8,14,16,17],doesn:16,domain:[11,12,14,16],don:[2,3,7,19],done:16,dont:[7,16],doubl:13,down:[0,3,5,7,11,13,14,16,17,18],download:[3,6,7,14,16,17,18],dozen:2,dual:[3,7,16,17,19],dualstack:17,due:[3,13,16],duplic:3,dure:[3,17],dynam:[0,2,8,17],e:[2,3,4,5,7,12,14,16,18],each:[0,2,3,7,8,11,14,16,17],eas:2,easi:[2,14,17],easier:2,easiest:2,easili:[0,5,7,14],echo:12,edit:[4,6,8,13,14,16],effect:[7,17],effici:[2,5],egress:[3,6,15,16],either:[2,3,6,13,18],ejf6yy51m:6,electron:4,elev:[11,14],elimin:2,els:17,email:[12,15],embed:14,empathi:4,empti:14,enabl:[2,5,7,12,14,17],encod:7,encompass:[0,5],encount:2,encrypt:[0,2,3,5,16],end:[2,12,14,16,17],endpoint:[1,2,3,6,7,17],enforc:8,enough:14,enpoint:17,ensur:[13,14,15,18],enter:[7,13,14,17],enterpris:[12,14],entir:7,entireti:2,entri:[14,16,17],env:[1,14],environ:[0,1,2,4,11,14,16,17],equal:14,equival:14,error:17,essenti:13,establish:6,etc:[3,7,12,14,16,18],eth0:[1,17],eth2:5,ethnic:4,evalu:15,even:[0,2],event:4,everi:[2,3,7,17],everyon:4,everyth:[2,5,14,17],evolv:2,ex:[3,7,12,14],exactli:15,exampl:[2,3,4,5,6,8,11,12,17],except:[7,11,14,17],execut:14,exist:[0,2,7,14,17],expect:[4,5,8,14,17,18],experi:[3,4,9,16],experienc:3,expir:17,explain:2,explicit:4,explicitli:14,exploit:14,expos:2,express:4,expressvpn:15,ext:[5,8,16],extend:14,extens:2,extern:[3,5,14,15,17],extrem:2,f1:1,f8:3,f:[3,14,16],face:[4,5],fact:0,fail:[2,7,11],fair:4,fairli:[2,16],faith:4,fallback:17,fals:[3,14],familiar:[0,2,15,16],faq:8,fast:[2,8,14],faster:[0,2,3,17],fcontext:16,featur:[12,14,17],fed:2,fedora:2,few:[2,3,7,15,17],field:[5,6,7,8,13,14,17,18],figur:19,file:[2,6,15,17,18],filenam:1,fill:17,filter:17,find:[2,14,17,18,19],fine:0,firewal:[3,7,8,13,14,16],first:[2,3,5,7,8,11,14,16,17,19],fit:[12,19],fix:15,flag:3,flat:0,flexibl:0,flow:2,focu:15,focus:4,folder:[2,3,14,18],follow:[2,3,4,5,7,11,12,14,15,16],forc:14,form:[3,7,17],format:[11,14],forum:16,forward:[3,5,6],foster:4,found:[0,2,3,10,11,14],framework:15,free:[4,17],freebsd:[2,15],freeli:10,frequent:[5,16,17],friend:16,friendli:2,from:[0,1,2,3,4,5,6,7,9,12,13,14,16,17,19],front:[2,14],frontend_url:11,full:[0,2,14,15],fulli:[0,2],further:4,furthermor:14,futur:[7,12,18],g:[3,7,12,14],gatewai:[1,2,3,8,15,16,17,19],gb:16,gcp:12,gender:4,gener:[1,2,3,6,9,11,12,14,15,17],generate_config_j:14,get:[1,3,5,12,14,16,17,18],gg:15,github:[2,3,8,11,12,14,15,16,18],githubusercont:[3,7,12,14,16],give:[2,7,8,14,15,16],given:[0,2,5,7,14,16,17],global:[3,5],go:[2,3,5,8,13,14,15,16,17],goe:[0,14,17],golang:2,good:[4,5,6,7,13,15,16,17,19],googl:[11,14],grab:3,gracefulli:4,grade:14,grant:17,gravitl:[2,3,4,7,12,14,15,16,18],group:12,grpc:[2,3,7,12],grpc_port:14,grpc_ssl:14,grpcaddress:3,grpchost:14,grpcport:14,grpcserver:3,gui:3,guid:[0,2,7,9,12,14,16],guidanc:8,guidelin:[14,15],h:[1,3],ha:[0,2,3,5,7,11,12,13,14,16,17,19],hand:8,handl:[0,2,12,14,17],handshak:[16,17],haproxi:[2,14],harass:4,hard:[13,16,17],harder:16,hardwar:[3,16,17],harm:4,hasadmin:1,hash:14,have:[0,2,3,4,5,6,7,11,12,13,14,16,17],haven:16,head:12,header:[1,2,14],health:17,heart:3,heavi:2,helm3:14,helm:14,help:[1,2,3,7,8,14,15,17,18],here:[2,4,7,10,12,14,15,16,17,19],hesit:15,high:[2,8,14,16],highli:[3,8,9],hit:16,hold:[0,2,3],holder:16,hole:[3,7,16,17],holepunch:3,home:[0,2,3,5,17],hook:[2,6],host:[2,3,12,14,15,16,17],host_ip:14,hostnam:17,hostnetwork:14,hous:1,how:[2,3,5,8,14,16,17],howev:[1,2,3,5,12,14,16],html:14,http:[1,2,3,7,8,11,12,15,16,18],http_port:14,hub:[0,2,13,17],hundr:12,i:[3,12,14,16],id:[1,3,11,14,15,17],ideal:14,ident:4,identifi:[3,14],ignor:[3,5,17],imag:[14,18],imageri:4,impact:[2,15],implement:[2,5],importantli:7,imposs:13,improv:14,inappropri:4,inbound:[3,12],incid:4,includ:[2,4,6,8,14],inclus:4,incompat:18,incorrect:[3,14,16],increas:[2,17],independ:6,indic:[11,17],individu:[4,14,17],industri:2,info:[2,4,12,14,15],inform:[2,3,4,7,8,12,17],ingress:[2,3,5,16,17],ingressroutetcp:14,initi:[3,11],ins:2,insert:[5,12,14,16],insid:[8,14,17],instal:[0,2,6,7,16],instanc:[1,2,3,4,5,7,12,14,17],instead:[0,3,5,6,7,12,14,16,17],instruct:[11,14],insult:4,intact:3,integ:[14,15],integr:[2,8,14],intend:3,inter:17,interact:[0,2,3],interest:[4,16],interfac:[1,3,5,6,7,12,14,17],interfer:[12,16],intern:[5,14],internet:[0,2,5,15],intro:19,introduc:16,introduct:8,invalid:[6,7,17],investig:4,invis:[2,17],io:[11,12,14,16,17],iot:[0,2],ip:[2,3,5,6,7,12,13,14,16,17,18],ipaddress:17,ipforward:[3,17],iphon:2,ipsec:2,iptabl:[3,5,17],ipv4:[3,7,14,16,17],ipv6:[3,7,16,17,19],ipv6address:17,isdualstack:3,isingressgatewai:3,isloc:[3,17],isstat:3,issu:[2,3,4,8,12,13,14,17],issuer:14,issuernam:14,iter:17,its:[0,2,3,4,5,6,7,14,15,17],itself:[2,3,5,7,14],job:2,join:[2,3,7,14,16,17],journalctl:[3,14,16],jq:1,js:14,json:[1,14],just:[0,2,3,6,7,12,14,15,16,17],jwt:[1,3],k3:19,k8:[14,15],k:[3,7],keep:[1,5,17],keepal:[3,17],kei:[2,3,8,11,12,14,16,17],kept:17,kernel:[0,2],keynam:1,keyupd:1,kill:16,know:[5,14,15,16,19],known:[2,12,17],kube:14,kubectl:14,kubernet:[0,5,9,17,19],lan:3,languag:4,laptop1:1,laptop:[6,17],larg:[2,17],last:[1,17,18],lastmodifi:1,latenc:2,later:2,latest:[2,3,6,14],launch:2,launchd:[2,3],launchdaemon:2,layer:0,layout:2,lb:[2,14],le:14,leadership:4,least:[0,16],leav:[3,6,7,14,16,17,18],left:[7,11,14,16],length:[3,16,17],less:[2,7],let:[0,5,15,19],letsencrypt:14,level:[2,4,8,14,17],librari:2,light:14,lightweight:2,like:[0,2,3,7,14,17],limit:[3,8,14,15,16,17],line:[2,17],link:[8,11,12,14],linod:12,linux:[2,3,5,7,8,15,17],linuxserv:14,list:[0,2,3,5,13,14,15],listen:14,listenport:1,littl:[2,15],ln:14,load:2,local:[2,3,5,7,14,17],localaddress:[1,3],localhost:[1,14],localrang:3,locat:[0,2,3,5,14,17],log:[11,12,14,16],logic:6,login:[7,11],longer:[14,17],look:[14,15,17],lookup:2,lose:17,lot:[2,3,16],lower:[16,17],lxc:14,m:[3,6,16],mac:[2,3,7,14,17],macaddress:[1,3],machin:[0,2,3,5,6,7,8,12,13,16,17,18],maco:15,made:[0,2,16,17],mai:[1,2,3,4,7,11,12,13,14,16,17,18],mail:4,main:14,maintain:[4,14,15,17],make:[0,2,4,5,6,8,9,12,13,14,15,16,17],man:6,manag:[0,2,6,8,14,19],mani:[0,2,12,14,15,17,19],manual:[2,3,7,14,16,17,18],map:14,master:[2,3,7,12,14,15,16],master_kei:14,masterkei:[1,14],match:[3,14],maximum:14,md:[1,14],mean:[2,3,5,6,7,14,16,17],meant:[14,16],measur:13,media:4,medium:9,meet:14,member:4,memori:16,mesh:[0,6,16,17,19],meshclient:1,metal:[2,8],method:[1,2,3,5,6,7,9],mgmt:1,microk8:[14,19],microsoft:11,middl:6,might:[0,2,13,14],min:12,minim:14,minimum:16,minor:18,mint:2,minu:14,minut:[12,14,16,17],mismatch:18,miss:[2,18],mix:3,mode:[2,7,8],model:[0,2],modif:14,modifi:[1,2,3,7,12,14,15,17],moment:17,mongo:14,mongodb:[],more:[0,1,2,6,7,8,12,14,15,17],most:[1,2,3,5,9,12,14,15,16,17],mostli:[2,3],mount:14,move:[7,12,18],mtu:[16,17],much:[0,2],mullvad:15,mullvadvpn:15,multipl:[0,7,14,16,17],must:[1,2,3,5,6,7,11,14,16,17,18],mv:18,my:[1,3,16,18],mydomain:11,mykei:[1,7],mynet:7,myserv:7,mysit:12,myvers:18,n:[2,3,7,12,14,16],name:[1,2,3,5,6,7,14,16,17],nameserv:[2,3,14],namespac:14,nat:[6,8,13,16,17],nation:4,nativ:2,navig:[11,12,16],nebula:[0,15],necessari:[2,3,4,14,17],need:[0,1,2,3,5,12,14,15,16,17,18],neg:15,neighborhood:0,neither:2,net:3,net_admin:14,netclient:[0,5,6,8,17],netclient_accesskei:3,netclient_accesstoken:3,netclient_address:3,netclient_addressipv6:3,netclient_api_serv:3,netclient_daemon:3,netclient_dn:3,netclient_endpoint:3,netclient_grpc_serv:3,netclient_interfac:3,netclient_ipforward:3,netclient_is_dualstack:3,netclient_is_loc:3,netclient_keepal:3,netclient_localaddress:3,netclient_localrang:3,netclient_macaddress:3,netclient_nam:3,netclient_network:3,netclient_o:3,netclient_password:3,netclient_port:3,netclient_postdown:3,netclient_postup:3,netclient_privatekei:3,netclient_publickei:3,netclient_roam:3,netclient_udp_holepunch:3,netconfig:[3,16,18],netid:1,netmak:[1,3,5,6,10,13,16,17,19],netmaker_base_domain:[12,14],netmaker_env:14,netsh:3,network:[0,5,6,8,11,12,13,14,15,16,18,19],network_mod:14,newli:18,next:[3,5,7,11],nextcloud:19,nf:14,nginx:[2,8,16],nip:12,nm:[3,14,17],nocaddi:14,node:[3,5,6,8,13,14,16],node_id:14,nodn:14,non:[2,3,7,9,14,15,17],none:0,noonewillguessthi:1,nopass:14,nordvpn:15,normal:[3,14],notabl:14,note:[1,5,6,8,11,12,14,16,17],noteabl:7,notifi:2,now:[0,6,7,12,13,14,15,16,18],ns:14,number:[2,7,12,14,17],o:[12,14],oauth2:11,oauth_provid:11,object:14,oblig:4,obscur:17,obtain:[1,3],od:3,off:[2,3,7,14,15,16,17],offens:4,offer:11,offic:[0,5,19],offici:[1,4,16],offlin:4,often:[2,15,17],old:18,omit:14,onc:[5,6,7,11,14],one:[2,3,5,6,7,12,14,16,17],onli:[1,2,3,5,6,7,11,14,16,17,18],onlin:4,onto:17,open:[2,4,7,8,15,17],openvpn:[2,15],openwrt:[2,8,16],oper:[2,3,13,14,17],operatingsystem:3,opinion:12,oppos:[2,14],opt:[14,15],option:[2,3,8,11,17],oracl:12,order:[5,11,14,16],org:14,orient:4,origin:[11,14],os:[3,17],osi:15,other:[0,2,3,4,6,7,13,16,17],otherwis:[0,3,4,16,17],our:[2,8,14,16],out:[0,2,7,12,14,15,16,17,19],outlin:[2,14],output:[3,7,16],outsid:[3,8,14,16],over:[0,2,5,13,14,16,17],overlai:[0,8],overlap:[5,7],overrid:[3,14],overridden:[2,14],overview:[2,19],overwhelm:19,own:[2,12,14],p2p:17,p:[3,7,12,14],packag:[3,16],packet:17,page:[2,11,17],pair:[2,14],pane:7,panic:18,part:[2,3,14],parti:[16,17],partial:2,particip:[4,15],particular:[2,3],pass:[2,3,14],password:[1,3,7,14,17],past:5,path:[1,14,15,17],peer:[2,3,6,7,13,16,17,19],pend:[1,7,17],peopl:[5,15,17],per:12,perform:[1,2,3,7,14],period:2,perm:14,perman:[4,14],permiss:[4,8,12,14,16],permit:7,persist:17,persistentkeepal:[3,6],person:4,perspect:[0,2],phone:[3,6],physic:[4,16],pick:[2,7],pictur:2,ping:[7,16,17],pivpn:15,place:[3,12,13,14,18],placehold:14,plaintext:3,plan:[12,14,15,16],platform:[2,8,15],pleas:[3,8,12,14,15,16],pledg:8,plu:[3,12],poc:[9,12],pod:17,point:[2,5,12],polici:4,polit:4,popul:[14,17],port:[2,3,7,12,14,16,17],posgr:14,posit:4,possibl:[2,12],post:[1,2,3,4,14,17],postchang:3,postdown:[3,14,17],postgr:14,postgresql:[2,14],postgress:14,posthog:15,postup:[3,14,17],powershel:3,practic:2,pre:14,preced:2,precend:14,prefer:[12,14,16],prepar:8,prereqisit:7,prerequisit:[2,5,7,8,14],present:18,prevent:[3,17],previou:2,primari:[3,14,16,17],prior:14,privaci:15,privat:[2,4,5,7,8,14,15,16,17,19],privatekei:[3,6],privileg:14,privkei:3,probabl:[0,15],problem:[3,16],procedur:14,process:[3,7,8,14,18],prod:14,product:[12,14],profession:4,program:3,programdata:3,project:[1,4,14,15],proof:0,proper:14,properli:[3,16],properti:3,proto:12,protocol:[3,14],provid:[0,2,3,8,12,14,17],proxi:[2,8,11,12],proxy_pass:14,proxy_pass_request_head:14,proxy_set_head:14,pubkei:3,publickei:[1,3,6],publicli:[12,13],publish:[4,10],pull:[2,3,6,14,17,18],punch:[3,7,16,17],purchas:16,pure:17,push:[3,6],put:[1,17],q9cog7c9qjnoxygvri:3,qr:[6,16,17],quarantin:3,question:16,quick:[2,7,8,9,14,16,17],quickli:[12,16],quickstart:16,r:16,race:[4,15],raft:[2,14,16],ram:12,random:[14,15,17],randomli:17,rang:[3,5,6,7,12,14,16,17],rangestr:1,rare:17,raspian:2,rather:[11,14,17],raw:[3,7,12,14,16],rce:[14,17],re:[0,3,7,15,16],reach:[0,2,3,5,6,7,13,14,15,16,17],reachabl:[2,3,6,7,8,13,14,17],reactj:2,read:14,readm:[12,14],reallysecret:1,reason:[2,4,7,13,14,17],reboot:16,receiv:[1,2],recent:[2,3,16,17],recommend:[1,3,6,9,12,16],reconfigur:[2,3,16],record:[7,12,16],redirect:11,redund:14,refer:[2,7,16],regard:[2,4],regardless:4,regist:[2,3],registr:3,regularli:[15,17],reject:4,rejoin:18,rel:[2,5,18],relai:[2,3,6,16],relat:14,releas:[2,3,14,16,18],relev:17,reli:[0,3],reliabl:17,religion:4,remain:17,remot:[0,3,14],remoteip:3,remov:[1,2,4,7,14,16,17],removenetwork:1,renam:[3,14,16,18],repeat:7,repercuss:4,replac:[3,14],replace_master_kei:12,replica:14,replicacount:14,repo:[2,14],report:[2,4],repositori:[2,10],repres:4,represent:4,request:[1,2,14],requir:[1,2,3,7,16],resolv:[2,3,14],resolvectl:[3,14,17],resourc:[6,8,9,15],respect:[2,4],respons:[2,8],rest:[12,14],rest_backend:14,restart:[11,14,16],restbackend:14,restorecon:16,restrict:[13,14],result:4,retriev:[0,1,2,3,7],revers:[8,12],revert:3,review:4,rf:7,rhel:2,right:[0,4,14,17],risk:16,rkxlgk2mg:6,rm:7,rncjjbsaa3hzuhrk5hpyxm:3,roam:[3,17],rogu:16,root:[3,12,14,16,18],rout:[0,2,5,11,12,13,14,17],route53:12,router:[2,5,16],rpumvsbpgq:6,rqlite:16,rule:[3,5,12],run:[0,1,2,5,6,7,12,14,15,16,17,18],runtim:14,rv:16,rwo:14,rwx:14,s:[0,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],sai:5,said:2,same:[0,3,6,7,14,16,17],sampl:0,save:[7,12,18],saveconfig:17,sbilli:[3,16],scan:[6,17],scenario:[5,7,13,17],schedul:14,scope:8,screen:[7,11],screenshot:[8,17],script:[2,7,12,14,16],search:17,second:[5,7,17],secret:[1,3,7,11],secretkei:14,section:[3,14,17],secur:[0,1,2,3,5,8,12,16,17,19],sed:[12,14],see:[1,2,3,7,8,12,14,15,16,17],seem:7,select:[6,7,13,16,17],selector:14,self:[14,15],selinux:16,semanag:16,send:[2,3,14,17],sens:[2,9,15],sensibl:[0,2,7,17],sent:[14,17],separ:[2,4,17,19],seper:16,serv:[2,14],server:[0,3,5,6,7,10,11,12,15,17],server_api_conn_str:14,server_api_host:14,server_grpc_conn_str:14,server_grpc_host:14,server_grpc_wireguard:14,server_host:14,server_http_host:[11,14],server_nam:14,server_public_ip:12,serverctl:15,servic:[2,3,5,6,12,14,17,19],set:[1,2,3,4,5,8,12,15,16,17,19],setup:[0,2,5,8,12],sever:[2,14],sexual:4,sf:14,sfl:[7,14],sh:[3,7,14,16],share:[14,16],shell:[3,16],should:[0,1,2,3,5,6,7,12,13,14,15,16,17],show:[3,4,14,16,17],shown:[6,17],shut:5,side:10,sign:[2,3,7,11,14,16],signific:2,signup:[2,3,16,17],similar:[0,7,14,15,17],simpl:[2,3,5,7,8,11,14,16],simplest:[2,3],simpli:[2,3,5,6,7,13,14,15,16],simplifi:[13,14],simultan:0,sinc:17,singl:[1,2,5,16,17],sit:17,site:[0,2,8,14,16,19],situat:[2,16,17],size:4,skip:14,skynet:1,slow:[0,13],slower:14,small:[2,7,9],smartgui:1,so:[0,2,3,5,6,7,12,14,16,17],social:4,sole:17,solut:2,solv:[2,17],some:[1,2,3,5,7,13,14,16,17],someth:[6,7,14,17],sometim:13,somewher:7,soon:16,sort:0,sourc:[2,3,8,10,15],space:[4,17],spec:16,special:[2,3,7,14],specif:[2,3,4,5,7,8,14,17],specifi:[3,5,11,13,14,17],speed:[0,2],spend:15,spin:14,split:3,spoke:[0,2,13,17],spread:0,sql:[2,14],sql_conn:14,sql_db:14,sql_host:14,sql_pass:14,sql_port:14,sql_user:14,sqlconn:14,sqldata:14,sqlite:[14,16],src:12,ssh:[7,12,18],ssl:[2,14],sspl:10,stabl:5,stack:[3,7,16,17,19],stai:[3,16,17],stake:0,standalon:14,standard:[2,5,8,14,16,17],start:[2,14,16,19],startup:1,state:7,statement:8,statu:[3,14,16,17],step:[2,3,7,14,18],still:[0,3,14,18],stock:15,stop:14,storag:[12,14],storageclassnam:14,store:[2,14,17],straight:5,straightforward:18,string:[7,14],stuck:16,stun:[7,16],su:7,subdomain:[12,14],submit:7,subnet:[2,5,17],subscript:[12,16],subsequ:2,subspac:15,subspacecloud:15,substanti:0,success:[2,11],successfulli:11,sudo:[3,7,11,12,14,16],support:[2,12,14,16],sure:[12,15,16,17],surfshark:15,suse:2,swag:14,symbol:11,system32:3,system:[7,8,12,17],system_u:16,systemctl:[3,14,16],systemd:[3,7,14,16],t:[2,3,7,16,19],tab:[7,16],tack:17,tail:3,tailscal:[0,15],take:[0,1,2,4,7,11,14,16,17],talk:[0,2],tcp:12,team:[4,15],technic:[0,8,15],technolog:2,ted:17,telemetri:[8,14],tell:[0,2,3,13,14,16],templat:14,temporari:[4,17],temporarili:4,tenant:11,term:15,terrain:15,test:[7,9],than:[2,7,11,14,17],thei:[0,2,4,7,8,14,15,16,17],them:[2,7,14,15,16],themselv:[2,16],therefor:16,thi:[0,1,2,3,4,5,6,7,8,10,12,13,14,15,16,17,18],thing:[0,2,3,16],think:[5,15,19],third:16,thmpvlcykonxi:3,those:[0,2,3,5,6],thousand:0,threaten:4,three:[7,14],through:[2,13,14,17],ticket:15,time:[1,2,3,6,7,13,14,16,17,19],timer:2,timestamp:[2,17],tl:14,toc:14,token:[3,7,14,16],too:[16,17],tool:[0,3,5],top:[2,16],topic:19,topolog:2,touch:16,toward:4,tr:12,track:17,traefik:2,traffic:[0,2,5,6,13,14,16,17],trailofbit:15,transact:2,translat:17,travers:17,treat:[2,3,17],tree:14,trial:[9,12],tricki:2,troll:4,troubleshooot:12,troubleshoot:[1,3,7,12],trust:15,tune:17,tunnel:[0,2],tunnelbear:15,turn:[2,3,7,13,14,16,17],tutori:8,two:[0,1,2,3,5,7,14,16],type:[1,14],typi:17,typic:[0,2,3,5,6,7,13,14,16,17],u:[3,14,16],ua2zjt8wn7ga:6,ubuntu:[2,12,14],udp:[3,7,12,14,16,17],udpholepunch:3,ufw:12,ui:[1,3,5,6,18],un:14,unabl:[7,16],unaccept:4,unaccess:17,uncom:14,uncordon:1,under:[3,7,10,14,15,16],underlai:[0,19],underli:16,underscores_in_head:14,unedit:17,unexpectedli:5,unfamiliar:7,uninstal:[8,16],uniqu:[3,12,17],unix:[2,3,17],unless:[3,14],unmanag:2,unnecessari:[3,7],unregist:3,unregistr:3,unset:[3,14],unsur:[6,7,13],until:[3,7,14,16,17],unwelcom:4,unzip:14,up:[0,2,3,5,7,8,12,14,16,17,18,19],updat:[1,2,7,12,14,16,17],upgrad:[2,16],upon:[2,3],upstream_app:14,upstream_port:14,upstream_proto:14,urandom:12,uri:11,url:[11,14],us:[1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,19],usag:[3,8,14,19],user:[2,3,7,8,9,14,15,16],usernam:[1,7,14,17],userspac:14,usr:14,usual:[2,3,5,7,17],util:16,v0:[2,11,14,15,16],v:16,valid:[2,14,17],valu:[1,2,3,7,12,16,17],variabl:[2,3,11,16],variou:[3,8,14],ve:16,vehicl:15,verbos:14,veri:[0,2,3,5,7,17],verifi:2,version:[2,3,4,10,12,14,15,16,18],vi:18,via:[1,2,3,4,5,6,7,8,11,12,14,16,17,19],viabil:15,video:8,view:[7,14,15,16],viewpoint:4,vim:[3,14],virtual:[0,3,6,8,12,15,17,19],visibl:[7,14],visit:[14,15],vist:18,vm3ow4thatogiwnsla3thsl3894th:7,vm:[0,2,8,12,16],vne197vmradjodkb1zsuja:3,volum:[7,14,16],vpc:[0,5,15,17],vpn:[2,16,17,19],vs:18,vulner:[14,17],vx:18,wa:[2,11,14,17],wai:[14,15,16,17],wan:7,want:[0,2,3,6,7,11,12,14,15,16,17],warn:[14,17],we:[0,1,2,4,9,12,14,15,16],web:[5,14,15],webserv:2,websit:2,weight:14,welcom:4,well:[2,3,7,8,14,16,17],were:[14,16],wg:[3,14,16,17],wgaddress6:3,wgaddress:3,wget:[3,12,14,16,18],what:[2,4,5,6,8,14,16],whatev:[3,7,14,17],when:[2,3,4,7,13,14,16,17],where:[2,5,6,7,8,14,15,17,19],wherev:0,whether:[0,3,14,17],which:[0,2,3,4,5,6,7,10,11,12,13,14,15,16,17],who:4,why:[2,3,16],wide:[2,14],wider:2,wifi:17,wiki:4,wildcard:[12,14],window:[2,7,8,15],wipe:16,wireguard:[0,3,5,6,7,8,12,15,16,17],wish:[3,5,6,11,14,17],within:[2,3,4,17],without:[1,2,3,4,7,8,15,16,17],work:[2,3,5,8,13,14,15,16,17],worker:[5,14],workstat:[3,7],world:[0,2],worri:7,wors:2,would:[0,3,5,6,7,14,15,17],write:[2,14],written:8,wrong:16,ws2:3,www:14,x86:3,x:[1,2,5,7,12,16,18],y:12,yaml:[1,14],ydazgedrpuxmmrqul35wfjmhvrzr1rq0u:6,ye:[3,15,16,17],yet:16,yml:[12,14,16,18],you:[0,1,2,3,5,6,7,9,11,12,13,14,16,17,18,19],your:[0,1,2,3,5,6,7,8,12,13,14,15,16,18,19],your_db_password:14,your_email:12,your_pass:1,your_password:1,your_secret_kei:1,yournetwork:18,yourwildcard:14,z0:12,za:12,zero:11,zeroti:0,zip:14,zrb9vfhk8a:15},titles:["About","API Reference","Architecture","Advanced Client Installation","Code of Conduct","Egress Gateway","Ingress + External Clients","Getting Started","Welcome to the Netmaker Documentation","Install","License","Integrating OAuth","Quick Install","Relay Servers","Advanced Server Installation","Support","Troubleshooting","UI Reference","Upgrades","External Guides"],titleterms:{"0":12,"1":[5,12,14],"2":[5,12,14],"3":[12,14],"4":[12,14],"case":[0,5],"do":15,Is:15,No:14,about:[0,8],access:[1,5],ad:[3,6],advanc:[3,8,14],an:[5,6,15],ani:15,annot:14,api:[1,8],architectur:2,attribut:4,authent:1,avail:14,balanc:14,bare:14,busi:15,caddi:[2,12],call:1,cli:3,client:[2,3,6,8,17,18],code:[4,8],command:3,common:16,compat:[2,3,14],compon:2,compos:[12,14],concept:2,conduct:[4,8],config:[3,14],configur:[3,5,6,8,11,13,14],consider:14,contact:15,core:2,coredn:[2,14,16],cpu:3,creat:[7,17],curl:1,daemon:3,daemonset:14,dashboard:17,databas:[2,14],depend:12,deploi:7,descript:[7,14],detail:17,disabl:14,dn:[3,6,12,14,17],docker:[12,14],document:[1,8],doe:0,edit:17,egress:[5,8,17],enforc:4,enterpris:15,exampl:[1,14],exit:15,ext:[6,17],extern:[2,6,8,19],faq:15,featur:15,file:[1,3,14],firewal:12,format:1,gatewai:[5,6],get:[7,8],grpc:14,guid:[8,19],have:15,high:3,highli:14,how:0,http:14,ingress:[6,8,14],instal:[3,8,9,12,14],integr:11,introduct:[3,5,6,11,12,13,18],issu:16,kei:[1,7],kernel:14,kubernet:[8,14],licens:[8,10,15],like:15,limit:2,linux:14,list:17,load:14,log:3,make:3,manag:[1,3,7],mesh:2,metal:14,mode:[3,14],nat:5,netclient:[2,3,7,14,16,18],netmak:[0,2,7,8,11,12,14,15,18],network:[1,2,3,7,17],nginx:14,node:[1,2,7,15,17],nordnpn:15,note:3,oauth:[8,11],offer:15,open:12,openwrt:3,option:[6,14],other:14,our:4,permiss:11,pledg:4,postgr:2,prepar:12,prerequisit:[3,12],privat:3,process:2,provid:11,proxi:14,quick:12,recommend:14,refer:[1,3,8,14,17],relai:[8,13,17],remot:5,remov:3,requir:14,respons:4,revers:14,rqlite:[2,14],run:3,scope:4,script:3,secur:14,server:[1,2,8,13,14,16,18],set:[7,14],setup:[7,14],sqlite:2,sspl:15,standard:4,start:[7,8,12],support:[8,15],system:[2,3,14],systemd:2,technic:2,telemetri:15,test:14,traefik:14,troubleshoot:[8,16],tutori:19,ui:[2,8,14,16,17],uninstal:[3,7],updat:3,upgrad:[8,18],us:[0,5],usag:1,user:[1,11,17],util:3,valu:14,variabl:14,video:19,view:3,vm:14,vpn:[5,15],welcom:8,what:0,why:15,window:3,wireguard:[2,14],without:14,work:0,written:19,you:15,your:11}}) \ No newline at end of file diff --git a/docs/_build/html/server-installation.html b/docs/_build/html/server-installation.html index e2dccaa2..f8c81e69 100644 --- a/docs/_build/html/server-installation.html +++ b/docs/_build/html/server-installation.html @@ -292,6 +292,8 @@
        • Config File Reference
        • Compose File - Annotated +
        • +
        • Available docker-compose files
        @@ -526,6 +528,8 @@
      • Config File Reference
      • Compose File - Annotated +
      • +
      • Available docker-compose files
      @@ -696,6 +700,17 @@
      RCE:

      Default: “off”

      Description: The server enables you to set PostUp and PostDown commands for nodes, which is standard for WireGuard with wg-quick, but is also Remote Code Execution, which is a critical vulnerability if the server is exploited. Because of this, it’s turned off by default, but if turned on, PostUp and PostDown become editable.

      +
      SERVER_GRPC_WIREGUARD

      Depreciated: no longer in use

      +
      +
      DISPLAY_KEYS

      Default: “on”

      +

      Description: If “on”, will allow you to always show the key values of “access keys”. This could be considered a vulnerability, so if turned “off”, will only display key values once, and it is up to the users to store the key values locally.

      +
      +
      NODE_ID

      Default: <system mac addres>

      +

      Description: This setting is used for HA configurations of the server, to identify between different servers. Nodes are given ID’s like netmaker-1, netmaker-2, and netmaker-3. If the server is not HA, there is no reason to set this field.

      +
      +
      TELEMETRY

      Default: “on”

      +

      Description: If “on”, the server will send anonymous telemetry data once daily, which is used to improve the product. Data sent includes counts (integer values) for the number of nodes, types of nodes, users, and networks. It also sends the version of the server.

      +
      @@ -762,6 +777,8 @@ SERVER_API_CONN_STRING: "" # Changes the api connection string. IP:PORT format. By default is empty and uses SERVER_HOST:API_PORT SERVER_GRPC_CONN_STRING: "" # Changes the grpc connection string. IP:PORT format. By default is empty and uses SERVER_HOST:GRPC_PORT RCE: "off" # Enables setting PostUp and PostDown (arbitrary commands) on nodes from the server. Off by default. + NODE_ID: "" # Sets the name/id of the nodes that the server creates. Necessary for HA configurations to identify between servers (for instance, netmaker-1, netmaker-2, etc). For non-HA deployments, is not necessary. + TELEMETRY: "on" # Whether or not to send telemetry data to help improve Netmaker. Switch to "off" to opt out of sending telemetry. netmaker-ui: # The Netmaker UI Component container_name: netmaker-ui depends_on: @@ -791,6 +808,20 @@ +

      Available docker-compose files

      +

      The default options for docker-compose can be found here: https://github.com/gravitl/netmaker/tree/master/compose

      +

      The following is a brief description of each:

      +
        +
      • docker-compose.contained.yml - This is the default docker-compose, used in the quick start and deployment script in the README on GitHub. It deploys Netmaker with all options included (Caddy and CoreDNS) and has “self-contained” netclients, meaning they do not affect host networking.

      • +
      • docker-compose.coredns.yml - This is a simple compose used to spin up a standalone CoreDNS server. Can be useful if, for instance, you are unning Netmaker on baremetal but need CoreDNS.

      • +
      • docker-compose.hostnetwork.yml - This is similar to the docker-compose.contained.yml but with a key difference: it has advanced permissions and mounts host volumes to control networking on the host level.

      • +
      • docker-compose.nocaddy.yml -= This is the same as docker-compose.contained.yml but without Caddy, in case you need to use a different proxy like Nginx, Traefik, or HAProxy.

      • +
      • docker-compose.nodns.yml - This is the same as docker-compose.contained.yml but without CoreDNS, in which case you will not have the Private DNS feature.

      • +
      • docker-compose.reference.yml - This is the same as docker-compose.contained.yml but with all variable options on display and annotated (it’s what we show right above this section). Use this to determine which variables you should add or change in your configuration.

      • +
      • docker-compose.yml - This is a renamed docker-compose.contained.yml. It is meant only to act as a placeholder for what we consider the “primary” docker-compose that users should work with.

      • +
      + +

      DNS Mode Setup

      If you plan on running the server in DNS Mode, know that a CoreDNS Server will be installed. CoreDNS is a light-weight, fast, and easy-to-configure DNS server. It is recommended to bind CoreDNS to port 53 of the host system, and it will do so by default. The clients will expect the nameserver to be on port 53, and many systems have issues resolving a different port.

      diff --git a/docs/_build/html/support.html b/docs/_build/html/support.html index fb846bbc..c3b40b2b 100644 --- a/docs/_build/html/support.html +++ b/docs/_build/html/support.html @@ -351,6 +351,8 @@
    +
  • Telemetry +
  • Contact
  • @@ -364,6 +366,13 @@ FAQ + +
  • + + + Telemetry + +
  • @@ -416,6 +425,8 @@
  • +
  • Telemetry +
  • Contact
  • @@ -459,6 +470,29 @@ +

    Telemetry

    +

    As of v0.10.0, Netmaker collects “opt-out” telemetry data. To opt out, simply set “TELEMETRY=off” in your docker-compose file.

    +

    Please consider participating in telemetry, as it helps us focus on the features and bug fixes which are most useful to users. Netmaker is a broad platform, and without this data, it is difficult to know where the team should spend its limited resources.

    +

    The following is the full list of telemetry data we collect. Besides “Server Version” all data is simply an integer count:

    +
      +
    • Randomized server ID

    • +
    • Count of nodes

    • +
    • Count of “non-server” nodes

    • +
    • Count of external clients

    • +
    • Count of networks

    • +
    • Count of users

    • +
    • Count of linux nodes

    • +
    • Count of freebsd nodes

    • +
    • Count of macos nodes

    • +
    • Count of windows nodes

    • +
    • Count of docker nodes

    • +
    • Count of k8s nodes

    • +
    • Server version

    • +
    +

    We use PostHog, an open source and trusted framework for telemetry data.

    +

    To look at exactly we collect telemetry, you can view the source code under serverctl/telemetry.go: https://github.com/gravitl/netmaker/blob/master/serverctl/telemetry.go

    + +

    Contact

    If you need help, try the discord or open a GitHub ticket.

    Email: info@gravitl.com

    diff --git a/docs/_build/html/troubleshoot.html b/docs/_build/html/troubleshoot.html index 5808b54c..e7f4a0f4 100644 --- a/docs/_build/html/troubleshoot.html +++ b/docs/_build/html/troubleshoot.html @@ -467,7 +467,11 @@ You can also sign-up for updates at our Server -
    +
    +
    How do I use a private address from the Netmaker Server? How do I contact nodes using their private addresses from the server?

    Default nodes appear in each network with the “netmaker” name. These nodes are created by, and attached to, the server. The server is contained in docker, meaning these clients are also contained in docker. Their networking stack is also contained in docker. The “netmaker” nodes are meant to function as network utilities. They assist with UDP Hole Punching and can run Relays, Egress, and Ingress. However, they are meant to stay contained in the server. They do not touch the host networking stack.

    +

    If you want to give the physical server / VM a private IP in the netmaker network, you must deploy an additional node using the standard netclient. The only note here is that the server consumes ports 51821-51831, so you will need to give it a port outside this range, e.x. ./netclient join <token> –port 51835.

    +

    One a netclient is deployed to the underlying server/VM, you will be able to use the private address to reach other nodes from the host, or to reach the server over the private network.

    +
    I upgraded from 0.7 to 0.8 and now I dont have any data in my server!

    In 0.8, sqlite becomes the default database. If you were running with rqlite, you must set the DATABASE environment variable to rqlite in order to continue using rqlite.

    Can I secure/encrypt all the traffic to my server and UI?

    This can fairly simple to achieve assuming you have access to a domain and are familiar with Nginx. diff --git a/docs/api.rst b/docs/api.rst index f219890d..c3e59488 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -17,8 +17,11 @@ API calls must be authenticated via a header of the format `-H "Authorization: Format of Calls for Curl ======================== -Requests take the format of `curl -H "Authorization: Bearer " -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint` +Requests take the format of +.. code-block:: + + curl -H "Authorization: Bearer " -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint API Documentation ================= @@ -41,18 +44,21 @@ Networks API Networks API Call Examples -------------------------- - -**Get All Networks:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq` -**Create Network:** `curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks` +.. code-block:: -**Get Network:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq` + Get All Networks: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq -**Update Network:** `curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet` + Create Network: curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks -**Delete Network:** `curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet` + Get Network: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq + + Update Network: curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet + + Delete Network: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet + + Cycle PublicKeys on all Nodes: curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate -**Cycle PublicKeys on all Nodes:** `curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate` Access Keys API --------------- @@ -66,13 +72,15 @@ Access Keys API Access Keys API Call Examples ----------------------------- - -**Get All Keys:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq` - -**Create Key:** `curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys` - -**Delete Key:** `curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey` - + +.. code-block:: + + Get All Keys: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq + + Create Key: curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys + + Delete Key: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey + Nodes API --------- @@ -104,29 +112,31 @@ Nodes API Nodes API Call Examples ----------------------- - -**Get All Nodes:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq` - -**Get Network Nodes:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq` - -**Create Node:** `curl -d '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet` - -**Get Node:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq` - -**Update Node:** `curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9` - -**Delete Node:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9` - -**Create a Gateway:** `curl -d '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway` - -**Delete a Gateway:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway` - -**Approve a Pending Node:** `curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve` - -**Get Last Modified Date (Last Modified Node in Network):** `curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified` -**Authenticate:** `curl -d '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate` - +.. code-block:: + + Get All Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq + + Get Network Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq + + Create Node: curl -d '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet + + Get Node: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq + + Update Node: curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9 + + Delete Node: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9 + + Create a Gateway: curl -d '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway + + Delete a Gateway: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway + + Approve a Pending Node: curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve + + Get Last Modified Date (Last Modified Node in Network): curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified + + Authenticate: curl -d '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate + Users API ----------------------- @@ -148,19 +158,21 @@ Users API Users API Calls Examples ------------------------ - -**Get User:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq` -**Update User:** `curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}` - -**Delete User:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}` - -**Check for Admin User:** `curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin` - -**Create Admin User:** `curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin` - -**Authenticate:** `curl -d '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate` - +.. code-block:: + + Get User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq + + Update User: curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username} + + Delete User: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username} + + Check for Admin User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin + + Create Admin User: curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin + + Authenticate: curl -d '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate + Server Management API --------------------- diff --git a/docs/architecture.rst b/docs/architecture.rst index 3bca05d7..5b097785 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -47,7 +47,7 @@ Netmaker Netmaker is a platform built off of WireGuard which enables users to create mesh networks between their devices. Netmaker can create both full and partial mesh networks depending on the use case. -When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. +When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. There is also almost always a proxy server / LB, which is typically Caddy. From an end user perspective, they typically interact with the Netmaker UI, or even just run the install script for the netclient on their devices. The other components run in the background invisibly. @@ -85,6 +85,7 @@ These modes include client mode and dns mode. Either of these can be disabled bu The Netmaker server interacts with either sqlite (default), postgres, or rqlite, a distributed version of sqlite, as its database. This DB holds information about nodes, networks, users, and other important data. This data is configuration data. For the most part, Netmaker serves configuration data to Nodes, telling them how they should configure themselves. The Netclient is the agent that actually does that configuration. +The components of the server are usually proxied via Caddy, or an alternative like Nginx and Traefik. The proxy handles SSL certificates to secure traffic, and routes to the UI, API, and gRPC server. Netclient ---------------- @@ -124,6 +125,15 @@ CoreDNS Netmaker allows users to provide and manage Private DNS for their nodes. This requires a nameserver, and CoreDNS is the chosen nameserver. CoreDNS is lightweight and extensible. CoreDNS loads dns settings from a simple file, managed by Netmaker, and serves out DNS info for managed nodes. DNS can be tricky, and DNS management is currently only supported on a small set of devices, specifically those running systemd-resolved. However, the Netmaker CoreDNS instance can be added manually as a nameserver to other devices. DNS mode can also be turned off. +Caddy +------- + +Caddy is the default proxy for Netmaker if you set it up via Quick Start. Caddy is an extremely simple and docker-friendly proxy, which can be compared to Nginx, Traefik, or HAProxy. We use Caddy by default because of the ease of management, and integration with gRPC. A typical setup for Nginx might take dozens of lines of code, and we need to request and manage SSL certificates separately. + +Caddy handles all these things automatically in very few lines of code. You can see our default "Caddyfile" here, which is fed to the container and has all the configuration necessary to configure the proxy for our app: + +https://github.com/gravitl/netmaker/blob/master/docker/Caddyfile + External Client ---------------- diff --git a/docs/client-installation.rst b/docs/client-installation.rst index 60a0c4ae..4edf3a85 100644 --- a/docs/client-installation.rst +++ b/docs/client-installation.rst @@ -30,6 +30,29 @@ Windows will by default have firewall rules that prevent inbound connections. If If you want to allow all peers access, but do not want to configure firewall rules for all peers, you can configure access for one peer, and set it as a Relay Server. +Running the install script +---------------------------- + +Some file locations have issues running the install script, such as running from the root C:/ folder. Users have noted the following locations work well for running the install powershell script: + +- `C:/Program Files/wireguard` +- `C:/Windows/System32` + +Running netclient commands +---------------------------- + +If running the netclient manually ("netclient join", "netclient checkin", "netclient pull") it should be run from outside of the installed directory, which will be either: + +- `C:/Program Files/netclient` +- `C:/ProgramData/netclient` + +It is better to call it from a different directory. + +High CPU Utilization +-------------------------- + +With some versions of WireGuard on Windows, high CPU utilization has been found with the netclient. This is typically due to interaction with the WireGuard GUI component (app). If you're experiencing high CPU utilization, close the WireGuard app. WireGuard will still be running, but the CPU usage should go back down to normal. + Notes on OpenWRT =========================== diff --git a/docs/server-installation.rst b/docs/server-installation.rst index 62b35ded..e7056591 100644 --- a/docs/server-installation.rst +++ b/docs/server-installation.rst @@ -143,9 +143,26 @@ RCE: **Description:** The server enables you to set PostUp and PostDown commands for nodes, which is standard for WireGuard with wg-quick, but is also **Remote Code Execution**, which is a critical vulnerability if the server is exploited. Because of this, it's turned off by default, but if turned on, PostUp and PostDown become editable. +SERVER_GRPC_WIREGUARD + **Depreciated:** no longer in use + +DISPLAY_KEYS + **Default:** "on" + + **Description:** If "on", will allow you to always show the key values of "access keys". This could be considered a vulnerability, so if turned "off", will only display key values once, and it is up to the users to store the key values locally. + +NODE_ID + **Default:** + + **Description:** This setting is used for HA configurations of the server, to identify between different servers. Nodes are given ID's like netmaker-1, netmaker-2, and netmaker-3. If the server is not HA, there is no reason to set this field. + +TELEMETRY + **Default:** "on" + + **Description:** If "on", the server will send anonymous telemetry data once daily, which is used to improve the product. Data sent includes counts (integer values) for the number of nodes, types of nodes, users, and networks. It also sends the version of the server. Config File Reference ----------------------- +----------------------- A config file may be placed under config/environments/.yml. To read this file at runtime, provide the environment variable NETMAKER_ENV at runtime. For instance, dev.yml paired with ENV=dev. Netmaker will load the specified Config file. This allows you to store and manage configurations for different environments. Below is a reference Config File you may use. .. literalinclude:: ../config/environments/dev.yaml @@ -159,6 +176,20 @@ All environment variables and options are enabled in this file. It is the equiva .. literalinclude:: ../compose/docker-compose.reference.yml :language: YAML +Available docker-compose files +--------------------------------- + +The default options for docker-compose can be found here: https://github.com/gravitl/netmaker/tree/master/compose + +The following is a brief description of each: + +- `docker-compose.contained.yml `_ - This is the default docker-compose, used in the quick start and deployment script in the README on GitHub. It deploys Netmaker with all options included (Caddy and CoreDNS) and has "self-contained" netclients, meaning they do not affect host networking. +- `docker-compose.coredns.yml `_ - This is a simple compose used to spin up a standalone CoreDNS server. Can be useful if, for instance, you are unning Netmaker on baremetal but need CoreDNS. +- `docker-compose.hostnetwork.yml `_ - This is similar to the docker-compose.contained.yml but with a key difference: it has advanced permissions and mounts host volumes to control networking on the host level. +- `docker-compose.nocaddy.yml `_ -= This is the same as docker-compose.contained.yml but without Caddy, in case you need to use a different proxy like Nginx, Traefik, or HAProxy. +- `docker-compose.nodns.yml `_ - This is the same as docker-compose.contained.yml but without CoreDNS, in which case you will not have the Private DNS feature. +- `docker-compose.reference.yml `_ - This is the same as docker-compose.contained.yml but with all variable options on display and annotated (it's what we show right above this section). Use this to determine which variables you should add or change in your configuration. +- `docker-compose.yml `_ - This is a renamed docker-compose.contained.yml. It is meant only to act as a placeholder for what we consider the "primary" docker-compose that users should work with. DNS Mode Setup ==================================== diff --git a/docs/support.rst b/docs/support.rst index 2054aac6..206f46fc 100644 --- a/docs/support.rst +++ b/docs/support.rst @@ -39,6 +39,33 @@ We believe the SSPL lets most people run the project the way they want, for both If you believe the SSPL will negatively impact your ability to use the project, please do not hesitate to reach out. +Telemetry +============== + +As of v0.10.0, Netmaker collects "opt-out" telemetry data. To opt out, simply set "TELEMETRY=off" in your docker-compose file. + +Please consider participating in telemetry, as it helps us focus on the features and bug fixes which are most useful to users. Netmaker is a broad platform, and without this data, it is difficult to know where the team should spend its limited resources. + +The following is the full list of telemetry data we collect. Besides "Server Version" all data is simply an integer count: + +- Randomized server ID +- Count of nodes +- Count of "non-server" nodes +- Count of external clients +- Count of networks +- Count of users +- Count of linux nodes +- Count of freebsd nodes +- Count of macos nodes +- Count of windows nodes +- Count of docker nodes +- Count of k8s nodes +- Server version + +We use `PostHog `_, an open source and trusted framework for telemetry data. + +To look at exactly we collect telemetry, you can view the source code under serverctl/telemetry.go: https://github.com/gravitl/netmaker/blob/master/serverctl/telemetry.go + Contact =========== If you need help, try the discord or open a GitHub ticket. diff --git a/docs/troubleshoot.rst b/docs/troubleshoot.rst index c1a1c0c5..6acc9fb7 100644 --- a/docs/troubleshoot.rst +++ b/docs/troubleshoot.rst @@ -29,6 +29,13 @@ Common Issues Server ------- +**How do I use a private address from the Netmaker Server? How do I contact nodes using their private addresses from the server?** + Default nodes appear in each network with the "netmaker" name. These nodes are created by, and attached to, the server. The server is contained in docker, meaning these clients are also contained in docker. Their networking stack is also contained in docker. The "netmaker" nodes are meant to function as network utilities. They assist with UDP Hole Punching and can run Relays, Egress, and Ingress. However, they are meant to stay contained in the server. They do not touch the host networking stack. + + If you want to give the physical server / VM a private IP in the netmaker network, you must deploy an **additional** node using the standard netclient. The only note here is that the server consumes ports 51821-51831, so you will need to give it a port outside this range, e.x. `./netclient join --port 51835`. + + One a netclient is deployed to the underlying server/VM, you will be able to use the private address to reach other nodes from the host, or to reach the server over the private network. + **I upgraded from 0.7 to 0.8 and now I dont have any data in my server!** In 0.8, sqlite becomes the default database. If you were running with rqlite, you must set the DATABASE environment variable to rqlite in order to continue using rqlite. From aa4baa55037c4ac1e3dea1ee31737584efafe8a1 Mon Sep 17 00:00:00 2001 From: afeiszli Date: Sun, 23 Jan 2022 09:39:48 -0500 Subject: [PATCH 7/7] fixing minor things for code review --- database/database.go | 4 ++-- serverctl/telemetry.go | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/database/database.go b/database/database.go index 633e691b..b2769d1f 100644 --- a/database/database.go +++ b/database/database.go @@ -210,8 +210,8 @@ func initializeUUID() error { if err != nil { return err } - err = Insert(SERVER_UUID_RECORD_KEY, string(telJSON), SERVER_UUID_TABLE_NAME) - return err + + return Insert(SERVER_UUID_RECORD_KEY, string(telJSON), SERVER_UUID_TABLE_NAME) } // CloseDB - closes a database gracefully diff --git a/serverctl/telemetry.go b/serverctl/telemetry.go index 77e50560..fd64492c 100644 --- a/serverctl/telemetry.go +++ b/serverctl/telemetry.go @@ -12,8 +12,13 @@ import ( "github.com/posthog/posthog-go" ) +// POSTHOG_PUB_KEY - Key for sending data to PostHog const POSTHOG_PUB_KEY = "phc_1vEXhPOA1P7HP5jP2dVU9xDTUqXHAelmtravyZ1vvES" + +// POSTHOG_ENDPOINT - Endpoint of PostHog server const POSTHOG_ENDPOINT = "https://app.posthog.com" + +// TELEMETRY_HOURS_BETWEEN_SEND - How long to wait before sending telemetry to server (24 hours) const TELEMETRY_HOURS_BETWEEN_SEND = 24 // TelemetryCheckpoint - Checks if 24 hours has passed since telemetry was last sent. If so, sends telemetry data to posthog @@ -154,7 +159,7 @@ func getDBLength(dbname string) int { return len(data) } -// TelemetryData - What data to send to posthog +// telemetryData - What data to send to posthog type telemetryData struct { Nodes int ExtClients int @@ -164,7 +169,7 @@ type telemetryData struct { Version string } -// ClientCount - What types of netclients we're tallying +// clientCount - What types of netclients we're tallying type clientCount struct { MacOS int Windows int