Browse Source

automated ext client egress range addition and ext client dns from network

worker-9 4 years ago
parent
commit
c2a9007b8c

+ 20 - 7
controllers/extClientHttpController.go

@@ -9,6 +9,7 @@ import (
 	"net/http"
 	"strconv"
 	"time"
+
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
@@ -91,7 +92,7 @@ func getAllExtClients(w http.ResponseWriter, r *http.Request) {
 	err := errors.New("Networks Error")
 	if networksSlice[0] == ALL_NETWORK_ACCESS {
 		clients, err = functions.GetAllExtClients()
-		if err != nil && !database.IsEmptyRecord(err){
+		if err != nil && !database.IsEmptyRecord(err) {
 			returnErrorResponse(w, r, formatError(err, "internal"))
 			return
 		}
@@ -159,14 +160,14 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
 
 	gwnode, err := functions.GetNodeByMacAddress(client.Network, client.IngressGatewayID)
 	if err != nil {
-		functions.PrintUserLog(r.Header.Get("user"),"Could not retrieve Ingress Gateway Node " + client.IngressGatewayID,1)
+		functions.PrintUserLog(r.Header.Get("user"), "Could not retrieve Ingress Gateway Node "+client.IngressGatewayID, 1)
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
 
 	network, err := functions.GetParentNetwork(client.Network)
 	if err != nil {
-		functions.PrintUserLog(r.Header.Get("user"),"Could not retrieve Ingress Gateway Network " + client.Network,1)
+		functions.PrintUserLog(r.Header.Get("user"), "Could not retrieve Ingress Gateway Network "+client.Network, 1)
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
@@ -175,6 +176,16 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
 	}
 	gwendpoint := gwnode.Endpoint + ":" + strconv.Itoa(int(gwnode.ListenPort))
+	newAllowedIPs := network.AddressRange
+	if egressGatewayRanges, err := client.GetEgressRangesOnNetwork(); err == nil {
+		for _, egressGatewayRange := range egressGatewayRanges {
+			newAllowedIPs += "," + egressGatewayRange
+		}
+	}
+	defaultDNS := ""
+	if network.DefaultExtClientDNS != "" {
+		defaultDNS = "DNS = " + network.DefaultExtClientDNS
+	}
 	config := fmt.Sprintf(`[Interface]
 Address = %s
 PrivateKey = %s
@@ -184,13 +195,15 @@ PublicKey = %s
 AllowedIPs = %s
 Endpoint = %s
 %s
+%s
 
 `, client.Address+"/32",
 		client.PrivateKey,
 		gwnode.PublicKey,
-		network.AddressRange,
+		newAllowedIPs,
 		gwendpoint,
-		keepalive)
+		keepalive,
+		defaultDNS)
 
 	if params["type"] == "qr" {
 		bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
@@ -219,7 +232,7 @@ Endpoint = %s
 		}
 		return
 	}
-	functions.PrintUserLog(r.Header.Get("user"),"retrieved ext client config",2)
+	functions.PrintUserLog(r.Header.Get("user"), "retrieved ext client config", 2)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(client)
 }
@@ -263,6 +276,7 @@ func CreateExtClient(extclient models.ExtClient) error {
 	err = SetNetworkNodesLastModified(extclient.Network)
 	return err
 }
+
 /**
  * To create a extclient
  * Must have valid key and be unique
@@ -289,7 +303,6 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
-
 	err = json.NewDecoder(r.Body).Decode(&extclient)
 	if err != nil && !errors.Is(err, io.EOF) {
 		returnErrorResponse(w, r, formatError(err, "internal"))

+ 13 - 0
docs/external-clients.rst

@@ -57,3 +57,16 @@ Example config file:
 .. literalinclude:: ./examplecode/myclient.conf
 
 Your client should now be able to access the network! A client can be invalidated at any time by simply deleting it from the UI.
+
+Configuring DNS for Ext Clients (OPTIONAL)
+============================================
+
+If you wish to have a DNS field on your ext clients conf, simply edit the network field as shown below to 1.1.1.1 or 8.8.8.8 for example.
+If you do not want DNS on your ext client conf files, simply leave it blank.
+
+.. image:: images/exclient5.png
+   :width: 80%
+   :alt: Gateway
+   :align: center
+
+Important to note, your client automatically adds egress gateway ranges (if any on the same network) to it's allowed IPs.

BIN
docs/images/extclient5.png


+ 44 - 9
models/extclient.go

@@ -1,13 +1,48 @@
 package models
 
+import (
+	"encoding/json"
+
+	"github.com/gravitl/netmaker/database"
+)
+
 type ExtClient struct {
-	ClientID       string             `json:"clientid" bson:"clientid"`
-	Description       string             `json:"description" bson:"description"`
-	PrivateKey     string             `json:"privatekey" bson:"privatekey"`
-	PublicKey      string             `json:"publickey" bson:"publickey"`
-	Network        string             `json:"network" bson:"network"`
-	Address        string             `json:"address" bson:"address"`
-	LastModified   int64              `json:"lastmodified" bson:"lastmodified"`
-	IngressGatewayID string             `json:"ingressgatewayid" bson:"ingressgatewayid"`
-	IngressGatewayEndpoint string             `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
+	ClientID               string `json:"clientid" bson:"clientid"`
+	Description            string `json:"description" bson:"description"`
+	PrivateKey             string `json:"privatekey" bson:"privatekey"`
+	PublicKey              string `json:"publickey" bson:"publickey"`
+	Network                string `json:"network" bson:"network"`
+	Address                string `json:"address" bson:"address"`
+	IngressGatewayID       string `json:"ingressgatewayid" bson:"ingressgatewayid"`
+	IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
+	LastModified           int64  `json:"lastmodified" bson:"lastmodified"`
+}
+
+/**
+ * Get the egress gateway ips of a given ExtClient struct
+ * returns as []string
+ */
+func (client *ExtClient) GetEgressRangesOnNetwork() ([]string, error) {
+
+	var result []string
+	nodesData, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	if err != nil {
+		return []string{}, err
+	}
+	for _, nodeData := range nodesData {
+		var currentNode Node
+		if err = json.Unmarshal([]byte(nodeData), &currentNode); err != nil {
+			continue
+		}
+		if currentNode.Network != client.Network {
+			continue
+		}
+		if currentNode.IsEgressGateway == "yes" { // add the egress gateway range(s) to the result
+			if len(currentNode.EgressGatewayRanges) > 0 {
+				result = append(result, currentNode.EgressGatewayRanges...)
+			}
+		}
+	}
+
+	return result, nil
 }

+ 3 - 1
models/network.go

@@ -7,9 +7,10 @@ import (
 	"reflect"
 	"strings"
 	"time"
-	"github.com/gravitl/netmaker/servercfg"
+
 	"github.com/go-playground/validator/v10"
 	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/servercfg"
 )
 
 //Network Struct
@@ -39,6 +40,7 @@ type Network struct {
 	LocalRange             string      `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
 	DefaultCheckInInterval int32       `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
 	DefaultUDPHolePunch    string      `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
+	DefaultExtClientDNS    string      `json:"defaultextclientdns" bson:"defaultextclientdns"`
 }
 
 type SaveData struct { // put sensitive fields here

BIN
netclient/netclient32


BIN
netmaker32


+ 5 - 5
test/nodecreate.sh

@@ -1,9 +1,9 @@
 #!/bin/bash
 
-PUBKEY="DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
-IPADDR="69.173.21.202"
-MACADDRESS="59:2a:9c:d4:e2:49"
-ACCESSKEY="6Cc1m3x0B0LQhHWF"
+PUBKEY="DM5qhLAE20EG9BbfBEger+Ac9D2NDOwCtY1rbYDLf34="
+IPADDR="70.173.21.212"
+MACADDRESS="59:23:9c:f2:e4:49"
+ACCESSKEY="Gsl6FKOjWi2qPGXy"
 PASSWORD="ppppppp"
 
 generate_post_json ()
@@ -15,7 +15,7 @@ generate_post_json ()
   "macaddress": "$MACADDRESS",
   "password": "$PASSWORD",
   "localaddress": "172.123.123.3",
-  "accesskey": "zKfzHn9W6uL5KuIg"
+  "accesskey": "$ACCESSKEY"
 }
 EOF
 }