Merge pull request #255 from gravitl/feature-0.7.3-automate-egress-extclient

Added egress gateway ranges automatically on ext clients and ability to add DNS from network to ext client.
This commit is contained in:
dcarns 2021-08-25 09:56:30 -04:00 committed by GitHub
commit 8c20bf13a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 22 deletions

View file

@ -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"))

View file

@ -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 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -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
}

View file

@ -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 Executable file

Binary file not shown.

BIN
netmaker32 Executable file

Binary file not shown.

View file

@ -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
}