Merge pull request #2484 from gravitl/release-v0.20.5

v0.20.5
This commit is contained in:
Abhishek K 2023-08-01 11:45:44 +05:30 committed by GitHub
commit 16d5b5807a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 260 additions and 884 deletions

View file

@ -31,6 +31,7 @@ body:
label: Version
description: What version are you running?
options:
- v0.20.5
- v0.20.4
- v0.20.3
- v0.20.2

View file

@ -16,7 +16,7 @@
<p align="center">
<a href="https://github.com/gravitl/netmaker/releases">
<img src="https://img.shields.io/badge/Version-0.20.4-informational?style=flat-square" />
<img src="https://img.shields.io/badge/Version-0.20.5-informational?style=flat-square" />
</a>
<a href="https://hub.docker.com/r/gravitl/netmaker/tags">
<img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />

View file

@ -15,9 +15,7 @@ var (
endpoint string
name string
listenPort int
proxyListenPort int
mtu int
proxyEnabled bool
isStatic bool
isDefault bool
)
@ -42,9 +40,7 @@ var hostUpdateCmd = &cobra.Command{
apiHost.EndpointIP = endpoint
apiHost.Name = name
apiHost.ListenPort = listenPort
apiHost.ProxyListenPort = proxyListenPort
apiHost.MTU = mtu
apiHost.ProxyEnabled = proxyEnabled
apiHost.IsStatic = isStatic
apiHost.IsDefault = isDefault
}
@ -57,9 +53,7 @@ func init() {
hostUpdateCmd.Flags().StringVar(&endpoint, "endpoint", "", "Endpoint of the Host")
hostUpdateCmd.Flags().StringVar(&name, "name", "", "Host name")
hostUpdateCmd.Flags().IntVar(&listenPort, "listen_port", 0, "Listen port of the host")
hostUpdateCmd.Flags().IntVar(&proxyListenPort, "proxy_listen_port", 0, "Proxy listen port of the host")
hostUpdateCmd.Flags().IntVar(&mtu, "mtu", 0, "Host MTU size")
hostUpdateCmd.Flags().BoolVar(&proxyEnabled, "proxy", false, "Enable proxy ?")
hostUpdateCmd.Flags().BoolVar(&isStatic, "static", false, "Make Host Static ?")
hostUpdateCmd.Flags().BoolVar(&isDefault, "default", false, "Make Host Default ?")
rootCmd.AddCommand(hostUpdateCmd)

View file

@ -3,7 +3,7 @@ version: "3.4"
services:
netclient:
container_name: netclient
image: 'gravitl/netclient:v0.20.4'
image: 'gravitl/netclient:v0.20.5'
hostname: netmaker-1
network_mode: host
restart: on-failure

View file

@ -32,68 +32,60 @@ type EnvironmentConfig struct {
// ServerConfig - server conf struct
type ServerConfig struct {
CoreDNSAddr string `yaml:"corednsaddr"`
APIConnString string `yaml:"apiconn"`
APIHost string `yaml:"apihost"`
APIPort string `yaml:"apiport"`
Broker string `yam:"broker"`
ServerBrokerEndpoint string `yaml:"serverbrokerendpoint"`
BrokerType string `yaml:"brokertype"`
EmqxRestEndpoint string `yaml:"emqxrestendpoint"`
NetclientAutoUpdate string `yaml:"netclientautoupdate"`
NetclientEndpointDetection string `yaml:"netclientendpointdetection"`
MasterKey string `yaml:"masterkey"`
DNSKey string `yaml:"dnskey"`
AllowedOrigin string `yaml:"allowedorigin"`
NodeID string `yaml:"nodeid"`
RestBackend string `yaml:"restbackend"`
MessageQueueBackend string `yaml:"messagequeuebackend"`
DNSMode string `yaml:"dnsmode"`
DisableRemoteIPCheck string `yaml:"disableremoteipcheck"`
Version string `yaml:"version"`
SQLConn string `yaml:"sqlconn"`
Platform string `yaml:"platform"`
Database string `yaml:"database"`
Verbosity int32 `yaml:"verbosity"`
AuthProvider string `yaml:"authprovider"`
OIDCIssuer string `yaml:"oidcissuer"`
ClientID string `yaml:"clientid"`
ClientSecret string `yaml:"clientsecret"`
FrontendURL string `yaml:"frontendurl"`
DisplayKeys string `yaml:"displaykeys"`
AzureTenant string `yaml:"azuretenant"`
Telemetry string `yaml:"telemetry"`
HostNetwork string `yaml:"hostnetwork"`
Server string `yaml:"server"`
PublicIPService string `yaml:"publicipservice"`
MQPassword string `yaml:"mqpassword"`
MQUserName string `yaml:"mqusername"`
MetricsExporter string `yaml:"metrics_exporter"`
BasicAuth string `yaml:"basic_auth"`
LicenseValue string `yaml:"license_value"`
NetmakerTenantID string `yaml:"netmaker_tenant_id"`
IsEE string `yaml:"is_ee"`
StunPort int `yaml:"stun_port"`
StunList string `yaml:"stun_list"`
Proxy string `yaml:"proxy"`
DefaultProxyMode ProxyMode `yaml:"defaultproxymode"`
TurnServer string `yaml:"turn_server"`
TurnApiServer string `yaml:"turn_api_server"`
TurnPort int `yaml:"turn_port"`
TurnUserName string `yaml:"turn_username"`
TurnPassword string `yaml:"turn_password"`
UseTurn bool `yaml:"use_turn"`
UsersLimit int `yaml:"user_limit"`
ClientsLimit int `yaml:"client_limit"`
NetworksLimit int `yaml:"network_limit"`
HostsLimit int `yaml:"host_limit"`
DeployedByOperator bool `yaml:"deployed_by_operator"`
}
// ProxyMode - default proxy mode for server
type ProxyMode struct {
Set bool
Value bool
CoreDNSAddr string `yaml:"corednsaddr"`
APIConnString string `yaml:"apiconn"`
APIHost string `yaml:"apihost"`
APIPort string `yaml:"apiport"`
Broker string `yam:"broker"`
ServerBrokerEndpoint string `yaml:"serverbrokerendpoint"`
BrokerType string `yaml:"brokertype"`
EmqxRestEndpoint string `yaml:"emqxrestendpoint"`
NetclientAutoUpdate string `yaml:"netclientautoupdate"`
NetclientEndpointDetection string `yaml:"netclientendpointdetection"`
MasterKey string `yaml:"masterkey"`
DNSKey string `yaml:"dnskey"`
AllowedOrigin string `yaml:"allowedorigin"`
NodeID string `yaml:"nodeid"`
RestBackend string `yaml:"restbackend"`
MessageQueueBackend string `yaml:"messagequeuebackend"`
DNSMode string `yaml:"dnsmode"`
DisableRemoteIPCheck string `yaml:"disableremoteipcheck"`
Version string `yaml:"version"`
SQLConn string `yaml:"sqlconn"`
Platform string `yaml:"platform"`
Database string `yaml:"database"`
Verbosity int32 `yaml:"verbosity"`
AuthProvider string `yaml:"authprovider"`
OIDCIssuer string `yaml:"oidcissuer"`
ClientID string `yaml:"clientid"`
ClientSecret string `yaml:"clientsecret"`
FrontendURL string `yaml:"frontendurl"`
DisplayKeys string `yaml:"displaykeys"`
AzureTenant string `yaml:"azuretenant"`
Telemetry string `yaml:"telemetry"`
HostNetwork string `yaml:"hostnetwork"`
Server string `yaml:"server"`
PublicIPService string `yaml:"publicipservice"`
MQPassword string `yaml:"mqpassword"`
MQUserName string `yaml:"mqusername"`
MetricsExporter string `yaml:"metrics_exporter"`
BasicAuth string `yaml:"basic_auth"`
LicenseValue string `yaml:"license_value"`
NetmakerTenantID string `yaml:"netmaker_tenant_id"`
IsEE string `yaml:"is_ee"`
StunPort int `yaml:"stun_port"`
StunList string `yaml:"stun_list"`
TurnServer string `yaml:"turn_server"`
TurnApiServer string `yaml:"turn_api_server"`
TurnPort int `yaml:"turn_port"`
TurnUserName string `yaml:"turn_username"`
TurnPassword string `yaml:"turn_password"`
UseTurn bool `yaml:"use_turn"`
UsersLimit int `yaml:"user_limit"`
ClientsLimit int `yaml:"client_limit"`
NetworksLimit int `yaml:"network_limit"`
HostsLimit int `yaml:"host_limit"`
DeployedByOperator bool `yaml:"deployed_by_operator"`
}
// SQLConfig - Generic SQL Config

View file

@ -10,7 +10,7 @@
//
// Schemes: https
// BasePath: /
// Version: 0.20.4
// Version: 0.20.5
// Host: netmaker.io
//
// Consumes:

View file

@ -348,11 +348,8 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
listenPort := host.ListenPort
if host.ProxyEnabled {
listenPort = host.ProxyListenPort
}
extclient.IngressGatewayEndpoint = host.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
listenPort := logic.GetPeerListenPort(host)
extclient.IngressGatewayEndpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), listenPort)
extclient.Enabled = true
parentNetwork, err := logic.GetNetwork(networkName)
if err == nil { // check if parent network default ACL is enabled (yes) or not (no)
@ -423,6 +420,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
var update models.CustomExtClient
var oldExtClient models.ExtClient
var sendPeerUpdate bool
err := json.NewDecoder(r.Body).Decode(&update)
if err != nil {
logger.Log(0, r.Header.Get("user"), "error decoding request body: ",
@ -478,9 +476,15 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
logger.Log(0, "failed to associate client", update.ClientID, "to user", oldExtClient.OwnerID)
}
}
if len(update.DeniedACLs) != len(oldExtClient.DeniedACLs) {
sendPeerUpdate = true
logic.SetClientACLs(&oldExtClient, update.DeniedACLs)
}
// == END PRO ==
var changedEnabled = (update.Enabled != oldExtClient.Enabled) // indicates there was a change in enablement
if update.Enabled != oldExtClient.Enabled {
sendPeerUpdate = true
}
// extra var need as logic.Update changes oldExtClient
currentClient := oldExtClient
newclient, err := logic.UpdateExtClient(&oldExtClient, &update)
@ -492,7 +496,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
return
}
logger.Log(0, r.Header.Get("user"), "updated ext client", update.ClientID)
if changedEnabled { // need to send a peer update to the ingress node as enablement of one of it's clients has changed
if sendPeerUpdate { // need to send a peer update to the ingress node as enablement of one of it's clients has changed
if ingressNode, err := logic.GetNodeByID(newclient.IngressGatewayID); err == nil {
if err = mq.PublishPeerUpdate(); err != nil {
logger.Log(1, "error setting ext peers on", ingressNode.ID.String(), ":", err.Error())

View file

@ -566,7 +566,7 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
nodeid := params["nodeid"]
netid := params["network"]
node, wasFailover, removedClients, err := logic.DeleteIngressGateway(netid, nodeid)
node, wasFailover, removedClients, err := logic.DeleteIngressGateway(nodeid)
if err != nil {
logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",

View file

@ -7,13 +7,15 @@ import (
"bytes"
"crypto/rand"
"encoding/json"
"errors"
"fmt"
"golang.org/x/exp/slog"
"io"
"net/http"
"os"
"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/netclient/ncutils"
@ -49,19 +51,22 @@ func AddLicenseHooks() {
func ValidateLicense() error {
licenseKeyValue := servercfg.GetLicenseKey()
netmakerTenantID := servercfg.GetNetmakerTenantID()
logger.Log(0, "proceeding with Netmaker license validation...")
if len(licenseKeyValue) == 0 || len(netmakerTenantID) == 0 {
logger.FatalLog0(errValidation.Error())
slog.Info("proceeding with Netmaker license validation...")
if len(licenseKeyValue) == 0 {
failValidation(errors.New("empty license-key (LICENSE_KEY environment variable)"))
}
if len(netmakerTenantID) == 0 {
failValidation(errors.New("empty tenant-id (NETMAKER_TENANT_ID environment variable)"))
}
apiPublicKey, err := getLicensePublicKey(licenseKeyValue)
if err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to get license public key: %w", err))
}
tempPubKey, tempPrivKey, err := FetchApiServerKeys()
if err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to fetch api server keys: %w", err))
}
licenseSecret := LicenseSecret{
@ -71,35 +76,38 @@ func ValidateLicense() error {
secretData, err := json.Marshal(&licenseSecret)
if err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to marshal license secret: %w", err))
}
encryptedData, err := ncutils.BoxEncrypt(secretData, apiPublicKey, tempPrivKey)
if err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to encrypt license secret data: %w", err))
}
validationResponse, err := validateLicenseKey(encryptedData, tempPubKey)
if err != nil || len(validationResponse) == 0 {
logger.FatalLog0(errValidation.Error())
if err != nil {
failValidation(fmt.Errorf("failed to validate license key: %w", err))
}
if len(validationResponse) == 0 {
failValidation(errors.New("empty validation response"))
}
var licenseResponse ValidatedLicense
if err = json.Unmarshal(validationResponse, &licenseResponse); err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to unmarshal validation response: %w", err))
}
respData, err := ncutils.BoxDecrypt(base64decode(licenseResponse.EncryptedLicense), apiPublicKey, tempPrivKey)
if err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to decrypt license: %w", err))
}
license := LicenseKey{}
if err = json.Unmarshal(respData, &license); err != nil {
logger.FatalLog0(errValidation.Error())
failValidation(fmt.Errorf("failed to unmarshal license key: %w", err))
}
logger.Log(0, "License validation succeeded!")
slog.Info("License validation succeeded!")
return nil
}
@ -150,6 +158,11 @@ func FetchApiServerKeys() (pub *[32]byte, priv *[32]byte, err error) {
return pub, priv, nil
}
func failValidation(err error) {
slog.Error(errValidation.Error(), "error", err)
os.Exit(0)
}
func getLicensePublicKey(licensePubKeyEncoded string) (*[32]byte, error) {
decodedPubKey := base64decode(licensePubKeyEncoded)
return ncutils.ConvertBytesToKey(decodedPubKey)
@ -187,11 +200,11 @@ func validateLicenseKey(encryptedData []byte, publicKey *[32]byte) ([]byte, erro
if err != nil {
return nil, err
}
logger.Log(3, "proceeding with cached response, Netmaker API may be down")
slog.Warn("proceeding with cached response, Netmaker API may be down")
} else {
defer validateResponse.Body.Close()
if validateResponse.StatusCode != 200 {
return nil, fmt.Errorf("could not validate license")
return nil, fmt.Errorf("could not validate license, got status code %d", validateResponse.StatusCode)
} // if you received a 200 cache the response locally
body, err = io.ReadAll(validateResponse.Body)

View file

@ -7,11 +7,11 @@ func DenyClientNode(ec *models.ExtClient, clientOrNodeID string) (ok bool) {
if ec == nil || len(clientOrNodeID) == 0 {
return
}
if ec.ACLs == nil {
ec.ACLs = map[string]struct{}{}
if ec.DeniedACLs == nil {
ec.DeniedACLs = map[string]struct{}{}
}
ok = true
ec.ACLs[clientOrNodeID] = struct{}{}
ec.DeniedACLs[clientOrNodeID] = struct{}{}
return
}
@ -20,22 +20,22 @@ func IsClientNodeAllowed(ec *models.ExtClient, clientOrNodeID string) bool {
if ec == nil || len(clientOrNodeID) == 0 {
return false
}
if ec.ACLs == nil {
if ec.DeniedACLs == nil {
return true
}
_, ok := ec.ACLs[clientOrNodeID]
return ok
_, ok := ec.DeniedACLs[clientOrNodeID]
return !ok
}
// RemoveDeniedNodeFromClient - removes a node id from set of denied nodes
func RemoveDeniedNodeFromClient(ec *models.ExtClient, clientOrNodeID string) bool {
if ec.ACLs == nil {
if ec.DeniedACLs == nil {
return true
}
_, ok := ec.ACLs[clientOrNodeID]
_, ok := ec.DeniedACLs[clientOrNodeID]
if !ok {
return false
}
delete(ec.ACLs, clientOrNodeID)
delete(ec.DeniedACLs, clientOrNodeID)
return true
}

6
go.mod
View file

@ -20,7 +20,6 @@ require (
golang.org/x/oauth2 v0.10.0
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c // indirect
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220324164955-056925b7df31
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1
@ -62,14 +61,9 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/hashicorp/go-version v1.6.0
github.com/josharian/native v1.0.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mdlayher/genetlink v1.2.0 // indirect
github.com/mdlayher/netlink v1.6.0 // indirect
github.com/mdlayher/socket v0.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
golang.org/x/sync v0.1.0 // indirect

8
go.sum
View file

@ -43,7 +43,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
@ -58,7 +57,6 @@ github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mO
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
@ -72,13 +70,9 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mdlayher/genetlink v1.2.0 h1:4yrIkRV5Wfk1WfpWTcoOlGmsWgQj3OtQN9ZsbrE+XtU=
github.com/mdlayher/genetlink v1.2.0/go.mod h1:ra5LDov2KrUCZJiAtEvXXZBxGMInICMXIwshlJ+qRxQ=
github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
github.com/mdlayher/socket v0.1.1 h1:q3uOGirUPfAV2MUoaC7BavjQ154J7+JOkTWyiV+intI=
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
@ -164,8 +158,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d/go.mod h1:5yyfuiqVIJ7t+3MqrpTQ+QqRkMWiESiyDvPNvKYCecg=
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
golang.zx2c4.com/wireguard v0.0.0-20220202223031-3b95c81cc178/go.mod h1:TjUWrnD5ATh7bFvmm/ALEJZQ4ivKbETb6pmyj1vUoNI=
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c h1:Okh6a1xpnJslG9Mn84pId1Mn+Q8cvpo4HCeeFWHo0cA=
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c/go.mod h1:enML0deDxY1ux+B6ANGiwtg0yAJi1rctkTpcHNAVPyg=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220324164955-056925b7df31 h1:AgW3hljgTzuRbCB0j+q9tXT0uy6ij7vMjEzSCeMlQY0=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220324164955-056925b7df31/go.mod h1:8P32Ilp1kCpwB4ItaHyvSk4xAtnpQ+8gQVfg5WaO1TU=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=

View file

@ -16,7 +16,7 @@ spec:
hostNetwork: true
containers:
- name: netclient
image: gravitl/netclient:v0.20.4
image: gravitl/netclient:v0.20.5
env:
- name: TOKEN
value: "TOKEN_VALUE"

View file

@ -28,7 +28,7 @@ spec:
# - "<node label value>"
containers:
- name: netclient
image: gravitl/netclient:v0.20.4
image: gravitl/netclient:v0.20.5
env:
- name: TOKEN
value: "TOKEN_VALUE"

View file

@ -15,7 +15,7 @@ spec:
spec:
containers:
- name: netmaker-ui
image: gravitl/netmaker-ui:v0.20.4
image: gravitl/netmaker-ui:v0.20.5
ports:
- containerPort: 443
env:

View file

@ -10,11 +10,17 @@ import (
var (
// DenyClientNodeAccess - function to handle adding a node to an ext client's denied node set
DenyClientNodeAccess = func(ec *models.ExtClient, clientOrNodeID string) bool { return true }
DenyClientNodeAccess = func(ec *models.ExtClient, clientOrNodeID string) bool {
return true
}
// IsClientNodeAllowed - function to check if an ext client's denied node set contains a node ID
IsClientNodeAllowed = func(ec *models.ExtClient, clientOrNodeID string) bool { return true }
IsClientNodeAllowed = func(ec *models.ExtClient, clientOrNodeID string) bool {
return true
}
// AllowClientNodeAccess - function to handle removing a node ID from ext client's denied nodes, thus allowing it
AllowClientNodeAccess = func(ec *models.ExtClient, clientOrNodeID string) bool { return true }
AllowClientNodeAccess = func(ec *models.ExtClient, clientOrNodeID string) bool {
return true
}
)
// SetClientDefaultACLs - set's a client's default ACLs based on network and nodes in network
@ -34,6 +40,8 @@ func SetClientDefaultACLs(ec *models.ExtClient) error {
currNode := networkNodes[i]
if network.DefaultACL == "no" || currNode.DefaultACL == "no" {
DenyClientNodeAccess(ec, currNode.ID.String())
} else {
AllowClientNodeAccess(ec, currNode.ID.String())
}
}
return nil
@ -44,7 +52,7 @@ func SetClientACLs(ec *models.ExtClient, newACLs map[string]struct{}) {
if ec == nil || newACLs == nil || !isEE {
return
}
ec.ACLs = newACLs
ec.DeniedACLs = newACLs
}
// IsClientNodeAllowedByID - checks if a given ext client ID + nodeID are allowed

View file

@ -3,6 +3,7 @@ package logic
import (
"encoding/json"
"fmt"
"reflect"
"sync"
"time"
@ -94,6 +95,9 @@ func GetNetworkExtClients(network string) ([]models.ExtClient, error) {
}
records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
if err != nil {
if database.IsEmptyRecord(err) {
return extclients, nil
}
return extclients, err
}
for _, value := range records {
@ -150,6 +154,9 @@ func GetExtClientByPubKey(publicKey string, network string) (*models.ExtClient,
// CreateExtClient - creates an extclient
func CreateExtClient(extclient *models.ExtClient) error {
// lock because we need unique IPs and having it concurrent makes parallel calls result in same "unique" IPs
addressLock.Lock()
defer addressLock.Unlock()
if len(extclient.PublicKey) == 0 {
privateKey, err := wgtypes.GeneratePrivateKey()
@ -231,6 +238,9 @@ func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) (*mo
if update.ExtraAllowedIPs != nil && StringDifference(old.ExtraAllowedIPs, update.ExtraAllowedIPs) != nil {
new.ExtraAllowedIPs = update.ExtraAllowedIPs
}
if update.DeniedACLs != nil && !reflect.DeepEqual(old.DeniedACLs, update.DeniedACLs) {
new.DeniedACLs = update.DeniedACLs
}
return new, CreateExtClient(new)
}

View file

@ -127,13 +127,13 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
}
// DeleteIngressGateway - deletes an ingress gateway
func DeleteIngressGateway(networkName string, nodeid string) (models.Node, bool, []models.ExtClient, error) {
func DeleteIngressGateway(nodeid string) (models.Node, bool, []models.ExtClient, error) {
removedClients := []models.ExtClient{}
node, err := GetNodeByID(nodeid)
if err != nil {
return models.Node{}, false, removedClients, err
}
clients, err := GetExtClientsByID(nodeid, networkName)
clients, err := GetExtClientsByID(nodeid, node.Network)
if err != nil && !database.IsEmptyRecord(err) {
return models.Node{}, false, removedClients, err
}
@ -141,7 +141,7 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, bool,
removedClients = clients
// delete ext clients belonging to ingress gateway
if err = DeleteGatewayExtClients(node.ID.String(), networkName); err != nil {
if err = DeleteGatewayExtClients(node.ID.String(), node.Network); err != nil {
return models.Node{}, false, removedClients, err
}
logger.Log(3, "deleting ingress gateway")
@ -163,7 +163,7 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, bool,
if err != nil {
return models.Node{}, wasFailover, removedClients, err
}
err = SetNetworkNodesLastModified(networkName)
err = SetNetworkNodesLastModified(node.Network)
return node, wasFailover, removedClients, err
}

View file

@ -30,16 +30,14 @@ func TestMain(m *testing.M) {
func TestCheckPorts(t *testing.T) {
h := models.Host{
ID: uuid.New(),
EndpointIP: net.ParseIP("192.168.1.1"),
ListenPort: 51821,
ProxyListenPort: maxPort,
ID: uuid.New(),
EndpointIP: net.ParseIP("192.168.1.1"),
ListenPort: 51821,
}
testHost := models.Host{
ID: uuid.New(),
EndpointIP: net.ParseIP("192.168.1.1"),
ListenPort: 51830,
ProxyListenPort: 51730,
ID: uuid.New(),
EndpointIP: net.ParseIP("192.168.1.1"),
ListenPort: 51830,
}
//not sure why this initialization is required but without it
// RemoveHost returns database is closed
@ -49,45 +47,17 @@ func TestCheckPorts(t *testing.T) {
t.Run("no change", func(t *testing.T) {
is := is.New(t)
CheckHostPorts(&testHost)
t.Log(testHost.ListenPort, testHost.ProxyListenPort)
t.Log(h.ListenPort, h.ProxyListenPort)
t.Log(testHost.ListenPort)
t.Log(h.ListenPort)
is.Equal(testHost.ListenPort, 51830)
is.Equal(testHost.ProxyListenPort, 51730)
})
t.Run("same listen port", func(t *testing.T) {
is := is.New(t)
testHost.ListenPort = 51821
CheckHostPorts(&testHost)
t.Log(testHost.ListenPort, testHost.ProxyListenPort)
t.Log(h.ListenPort, h.ProxyListenPort)
t.Log(testHost.ListenPort)
t.Log(h.ListenPort)
is.Equal(testHost.ListenPort, 51822)
is.Equal(testHost.ProxyListenPort, 51730)
})
t.Run("same proxy port", func(t *testing.T) {
is := is.New(t)
testHost.ProxyListenPort = 65535
CheckHostPorts(&testHost)
t.Log(testHost.ListenPort, testHost.ProxyListenPort)
t.Log(h.ListenPort, h.ProxyListenPort)
is.Equal(testHost.ListenPort, 51822)
is.Equal(testHost.ProxyListenPort, minPort)
})
t.Run("listenport equals proxy port", func(t *testing.T) {
is := is.New(t)
testHost.ListenPort = maxPort
CheckHostPorts(&testHost)
t.Log(testHost.ListenPort, testHost.ProxyListenPort)
t.Log(h.ListenPort, h.ProxyListenPort)
is.Equal(testHost.ListenPort, minPort)
is.Equal(testHost.ProxyListenPort, minPort+1)
})
t.Run("proxyport equals listenport", func(t *testing.T) {
is := is.New(t)
testHost.ProxyListenPort = 51821
CheckHostPorts(&testHost)
t.Log(testHost.ListenPort, testHost.ProxyListenPort)
t.Log(h.ListenPort, h.ProxyListenPort)
is.Equal(testHost.ListenPort, minPort)
is.Equal(testHost.ProxyListenPort, 51822)
})
}

View file

@ -6,7 +6,6 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"sort"
"strconv"
@ -184,15 +183,6 @@ func CreateHost(h *models.Host) error {
}
h.HostPass = string(hash)
h.AutoUpdate = servercfg.AutoUpdateEnabled()
// if another server has already updated proxyenabled, leave it alone
if !h.ProxyEnabledSet {
log.Println("checking default proxy", servercfg.GetServerConfig().DefaultProxyMode)
if servercfg.GetServerConfig().DefaultProxyMode.Set {
h.ProxyEnabledSet = true
h.ProxyEnabled = servercfg.GetServerConfig().DefaultProxyMode.Value
log.Println("set proxy enabled to ", h.ProxyEnabled)
}
}
checkForZombieHosts(h)
return UpsertHost(h)
}
@ -228,11 +218,6 @@ func UpdateHost(newHost, currentHost *models.Host) {
newHost.ListenPort = currentHost.ListenPort
}
if newHost.ProxyListenPort == 0 {
newHost.ProxyListenPort = currentHost.ProxyListenPort
}
newHost.PublicListenPort = currentHost.PublicListenPort
}
// UpdateHostFromClient - used for updating host on server with update recieved from client
@ -250,18 +235,6 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool)
currHost.WgPublicListenPort = newHost.WgPublicListenPort
sendPeerUpdate = true
}
if newHost.ProxyListenPort != 0 && currHost.ProxyListenPort != newHost.ProxyListenPort {
currHost.ProxyListenPort = newHost.ProxyListenPort
sendPeerUpdate = true
}
if newHost.PublicListenPort != 0 && currHost.PublicListenPort != newHost.PublicListenPort {
currHost.PublicListenPort = newHost.PublicListenPort
sendPeerUpdate = true
}
if currHost.ProxyEnabled != newHost.ProxyEnabled {
currHost.ProxyEnabled = newHost.ProxyEnabled
sendPeerUpdate = true
}
if currHost.EndpointIP.String() != newHost.EndpointIP.String() {
currHost.EndpointIP = newHost.EndpointIP
sendPeerUpdate = true
@ -409,6 +382,15 @@ func DissasociateNodeFromHost(n *models.Node, h *models.Host) error {
} else {
h.Nodes = RemoveStringSlice(h.Nodes, index)
}
go func() {
if servercfg.Is_EE {
if clients, err := GetNetworkExtClients(n.Network); err != nil {
for i := range clients {
AllowClientNodeAccess(&clients[i], n.ID.String())
}
}
}
}()
if err := deleteNodeByID(n); err != nil {
return err
}
@ -514,7 +496,6 @@ func CheckHostPorts(h *models.Host) {
continue
}
portsInUse[host.ListenPort] = true
portsInUse[host.ProxyListenPort] = true
}
// iterate until port is not found or max iteration is reached
for i := 0; portsInUse[h.ListenPort] && i < maxPort-minPort+1; i++ {
@ -523,14 +504,7 @@ func CheckHostPorts(h *models.Host) {
h.ListenPort = minPort
}
}
// allocate h.ListenPort so it is unavailable to h.ProxyListenPort
portsInUse[h.ListenPort] = true
for i := 0; portsInUse[h.ProxyListenPort] && i < maxPort-minPort+1; i++ {
h.ProxyListenPort++
if h.ProxyListenPort > maxPort {
h.ProxyListenPort = minPort
}
}
}
// HostExists - checks if given host already exists

View file

@ -1,90 +0,0 @@
package metrics
import (
"time"
"github.com/gravitl/netmaker/logger"
proxy_metrics "github.com/gravitl/netmaker/metrics"
"github.com/gravitl/netmaker/models"
"golang.zx2c4.com/wireguard/wgctrl"
)
// Collect - collects metrics
func Collect(iface, server, network string, peerMap models.PeerMap, proxy bool) (*models.Metrics, error) {
var metrics models.Metrics
metrics.Connectivity = make(map[string]models.Metric)
var wgclient, err = wgctrl.New()
if err != nil {
fillUnconnectedData(&metrics, peerMap)
return &metrics, err
}
defer wgclient.Close()
device, err := wgclient.Device(iface)
if err != nil {
fillUnconnectedData(&metrics, peerMap)
return &metrics, err
}
// TODO handle freebsd??
for i := range device.Peers {
currPeer := device.Peers[i]
if _, ok := peerMap[currPeer.PublicKey.String()]; !ok {
continue
}
id := peerMap[currPeer.PublicKey.String()].ID
address := peerMap[currPeer.PublicKey.String()].Address
if id == "" || address == "" {
logger.Log(0, "attempted to parse metrics for invalid peer from server", id, address)
continue
}
proxyMetrics := proxy_metrics.GetMetric(server, currPeer.PublicKey.String())
var newMetric = models.Metric{
NodeName: peerMap[currPeer.PublicKey.String()].Name,
}
logger.Log(2, "collecting metrics for peer", address)
newMetric.TotalReceived = int64(proxyMetrics.TrafficRecieved)
newMetric.TotalSent = int64(proxyMetrics.TrafficSent)
newMetric.Latency = int64(proxyMetrics.LastRecordedLatency)
newMetric.Connected = proxyMetrics.NodeConnectionStatus[id]
newMetric.CollectedByProxy = proxy
if newMetric.Connected {
newMetric.Uptime = 1
}
// check device peer to see if WG is working if ping failed
if !newMetric.Connected {
if currPeer.ReceiveBytes > 0 &&
currPeer.TransmitBytes > 0 &&
time.Now().Before(currPeer.LastHandshakeTime.Add(time.Minute<<1)) {
newMetric.Connected = true
newMetric.Uptime = 1
}
}
newMetric.TotalTime = 1
metrics.Connectivity[id] = newMetric
if len(proxyMetrics.NodeConnectionStatus) == 1 {
proxy_metrics.ResetMetricsForPeer(server, currPeer.PublicKey.String())
} else {
proxy_metrics.ResetMetricForNode(server, currPeer.PublicKey.String(), id)
}
}
fillUnconnectedData(&metrics, peerMap)
return &metrics, nil
}
// == used to fill zero value data for non connected peers ==
func fillUnconnectedData(metrics *models.Metrics, peerMap models.PeerMap) {
for r := range peerMap {
id := peerMap[r].ID
if !metrics.Connectivity[id].Connected {
newMetric := models.Metric{
NodeName: peerMap[r].Name,
Uptime: 0,
TotalTime: 1,
Connected: false,
Latency: 999,
PercentUp: 0,
}
metrics.Connectivity[id] = newMetric
}
}
}

View file

@ -7,6 +7,7 @@ import (
"net"
"sort"
"strings"
"sync"
"github.com/c-robinson/iplib"
validator "github.com/go-playground/validator/v10"
@ -147,7 +148,7 @@ func GetNetworkSettings(networkname string) (models.Network, error) {
return network, nil
}
// UniqueAddress - see if address is unique
// UniqueAddress - get a unique ipv4 address
func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
add := net.IP{}
var network models.Network
@ -424,3 +425,5 @@ func SortNetworks(unsortedNetworks []models.Network) {
}
// == Private ==
var addressLock = &sync.Mutex{}

View file

@ -460,6 +460,10 @@ func updateProNodeACLS(node *models.Node) error {
// createNode - creates a node in database
func createNode(node *models.Node) error {
// lock because we need unique IPs and having it concurrent makes parallel calls result in same "unique" IPs
addressLock.Lock()
defer addressLock.Unlock()
host, err := GetHost(node.HostID.String())
if err != nil {
return err

View file

@ -15,69 +15,9 @@ import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
// GetProxyUpdateForHost - gets the proxy update for host
func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error) {
proxyPayload := models.ProxyManagerPayload{
Action: models.ProxyUpdate,
}
peerConfMap := make(map[string]models.PeerConf)
var ingressStatus bool
for _, nodeID := range host.Nodes {
node, err := GetNodeByID(nodeID)
if err != nil {
continue
}
if !node.Connected || node.PendingDelete || node.Action == models.NODE_DELETE {
continue
}
currentPeers, err := GetNetworkNodes(node.Network)
if err != nil {
continue
}
for _, peer := range currentPeers {
if peer.ID == node.ID {
//skip yourself
continue
}
if !peer.Connected || peer.PendingDelete || peer.Action == models.NODE_DELETE {
continue
}
peerHost, err := GetHost(peer.HostID.String())
if err != nil {
continue
}
var currPeerConf models.PeerConf
var found bool
if currPeerConf, found = peerConfMap[peerHost.PublicKey.String()]; !found {
currPeerConf = models.PeerConf{
Proxy: peerHost.ProxyEnabled,
PublicListenPort: int32(GetPeerListenPort(peerHost)),
ProxyListenPort: GetProxyListenPort(peerHost),
NatType: peerHost.NatType,
}
}
peerConfMap[peerHost.PublicKey.String()] = currPeerConf
}
if node.IsIngressGateway {
ingressStatus = true
_, peerConfMap, err = getExtPeersForProxy(&node, peerConfMap)
if err == nil {
} else if !database.IsEmptyRecord(err) {
logger.Log(1, "error retrieving external clients:", err.Error())
}
}
}
proxyPayload.IsIngress = ingressStatus
proxyPayload.PeerMap = peerConfMap
return proxyPayload, nil
}
// GetPeerUpdateForHost - gets the consolidated peer update for the host from all networks
func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.Node, deletedNode *models.Node, deletedClients []models.ExtClient) (models.HostPeerUpdate, error) {
func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.Node,
deletedNode *models.Node, deletedClients []models.ExtClient) (models.HostPeerUpdate, error) {
if host == nil {
return models.HostPeerUpdate{}, errors.New("host is nil")
}
@ -87,13 +27,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
hostPeerUpdate := models.HostPeerUpdate{
Host: *host,
Server: servercfg.GetServer(),
HostPeerIDs: make(models.HostPeerMap, 0),
ServerVersion: servercfg.GetVersion(),
ServerAddrs: []models.ServerAddr{},
IngressInfo: models.IngressInfo{
ExtPeers: make(map[string]models.ExtClientInfo),
FwUpdate: models.FwUpdate{
EgressInfo: make(map[string]models.EgressInfo),
},
EgressInfo: make(map[string]models.EgressInfo),
PeerIDs: make(models.PeerMap, 0),
Peers: []wgtypes.PeerConfig{},
NodePeers: []wgtypes.PeerConfig{},
@ -145,7 +83,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
}
relayPeer.Endpoint = &net.UDPAddr{
IP: relayHost.EndpointIP,
Port: getPeerWgListenPort(relayHost),
Port: GetPeerListenPort(relayHost),
}
if uselocal {
@ -169,10 +107,6 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
}
currentPeers := GetNetworkNodesMemory(allNodes, node.Network)
var nodePeerMap map[string]models.PeerRouteInfo
if node.IsIngressGateway || node.IsEgressGateway {
nodePeerMap = make(map[string]models.PeerRouteInfo)
}
for _, peer := range currentPeers {
peer := peer
if peer.ID.String() == node.ID.String() {
@ -197,41 +131,9 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
EgressRanges: peer.EgressGatewayRanges,
})
}
if node.IsIngressGateway || node.IsEgressGateway {
if peer.IsIngressGateway {
_, extPeerIDAndAddrs, err := getExtPeers(&peer)
if err == nil {
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
extPeerIdAndAddr := extPeerIdAndAddr
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(extPeerIdAndAddr.Address),
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
},
PeerKey: extPeerIdAndAddr.ID,
Allow: true,
ID: extPeerIdAndAddr.ID,
}
}
}
}
if node.IsIngressGateway && peer.IsEgressGateway {
hostPeerUpdate.IngressInfo.EgressRanges = append(hostPeerUpdate.IngressInfo.EgressRanges,
peer.EgressGatewayRanges...)
}
nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(peer.PrimaryAddress()),
Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
},
PeerKey: peerHost.PublicKey.String(),
Allow: true,
ID: peer.ID.String(),
}
}
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || (peer.IsRelayed && peer.RelayedBy != node.ID.String()) {
// if node is relayed and peer is not the relay, set remove to true
if _, ok := hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()]; ok {
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
continue
}
peerConfig.Remove = true
@ -255,7 +157,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
}
peerConfig.Endpoint = &net.UDPAddr{
IP: peerHost.EndpointIP,
Port: getPeerWgListenPort(peerHost),
Port: GetPeerListenPort(peerHost),
}
if uselocal {
@ -271,22 +173,14 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
peerConfig.AllowedIPs = allowedips // only append allowed IPs if valid connection
}
peerProxyPort := GetProxyListenPort(peerHost)
peerPort := GetPeerListenPort(peerHost)
var nodePeer wgtypes.PeerConfig
if _, ok := hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()]; !ok {
hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()] = make(map[string]models.IDandAddr)
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; !ok {
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
ID: peer.ID.String(),
Address: peer.PrimaryAddress(),
Name: peerHost.Name,
Network: peer.Network,
ProxyListenPort: peerProxyPort,
}
hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
Interfaces: peerHost.Interfaces,
ProxyListenPort: peerProxyPort,
Interfaces: peerHost.Interfaces,
ListenPort: peerPort,
}
nodePeer = peerConfig
} else {
@ -294,27 +188,20 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
peerAllowedIPs = append(peerAllowedIPs, peerConfig.AllowedIPs...)
hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].Remove = false
hostPeerUpdate.HostPeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
ID: peer.ID.String(),
Address: peer.PrimaryAddress(),
Name: peerHost.Name,
Network: peer.Network,
ProxyListenPort: GetProxyListenPort(peerHost),
}
hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
Interfaces: peerHost.Interfaces,
ProxyListenPort: peerProxyPort,
Interfaces: peerHost.Interfaces,
ListenPort: peerPort,
}
nodePeer = hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]]
}
if node.Network == network { // add to peers map for metrics
hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{
ID: peer.ID.String(),
Address: peer.PrimaryAddress(),
Name: peerHost.Name,
Network: peer.Network,
ProxyListenPort: peerHost.ProxyListenPort,
ID: peer.ID.String(),
Address: peer.PrimaryAddress(),
Name: peerHost.Name,
Network: peer.Network,
ListenPort: peerHost.ListenPort,
}
hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, nodePeer)
}
@ -322,45 +209,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
var extPeers []wgtypes.PeerConfig
var extPeerIDAndAddrs []models.IDandAddr
if node.IsIngressGateway {
extPeers, extPeerIDAndAddrs, err = getExtPeers(&node)
extPeers, extPeerIDAndAddrs, err = getExtPeers(&node, &node)
if err == nil {
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
extPeerIdAndAddr := extPeerIdAndAddr
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
PeerAddr: net.IPNet{
IP: net.ParseIP(extPeerIdAndAddr.Address),
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
},
PeerKey: extPeerIdAndAddr.ID,
Allow: true,
ID: extPeerIdAndAddr.ID,
}
}
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
extPeerIdAndAddr := extPeerIdAndAddr
hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID] = make(map[string]models.IDandAddr)
hostPeerUpdate.HostPeerIDs[extPeerIdAndAddr.ID][extPeerIdAndAddr.ID] = models.IDandAddr{
ID: extPeerIdAndAddr.ID,
Address: extPeerIdAndAddr.Address,
Name: extPeerIdAndAddr.Name,
Network: node.Network,
}
hostPeerUpdate.IngressInfo.ExtPeers[extPeerIdAndAddr.ID] = models.ExtClientInfo{
Masquerade: true,
IngGwAddr: net.IPNet{
IP: net.ParseIP(node.PrimaryAddress()),
Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
},
Network: node.PrimaryNetworkRange(),
ExtPeerAddr: net.IPNet{
IP: net.ParseIP(extPeerIdAndAddr.Address),
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
},
ExtPeerKey: extPeerIdAndAddr.ID,
Peers: filterNodeMapForClientACLs(extPeerIdAndAddr.ID, node.Network, nodePeerMap),
}
if node.Network == network {
hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID] = extPeerIdAndAddr
hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, extPeers...)
@ -370,15 +223,15 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
logger.Log(1, "error retrieving external clients:", err.Error())
}
}
if node.IsEgressGateway {
hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
if node.IsEgressGateway && node.EgressGatewayRequest.NatEnabled == "yes" && len(node.EgressGatewayRequest.Ranges) > 0 {
hostPeerUpdate.FwUpdate.IsEgressGw = true
hostPeerUpdate.FwUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
EgressID: node.ID.String(),
Network: node.PrimaryNetworkRange(),
EgressGwAddr: net.IPNet{
IP: net.ParseIP(node.PrimaryAddress()),
Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
},
GwPeers: nodePeerMap,
EgressGWCfg: node.EgressGatewayRequest,
}
}
@ -429,41 +282,16 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
return hostPeerUpdate, nil
}
// getPeerWgListenPort - fetches the wg listen port for the host
func getPeerWgListenPort(host *models.Host) int {
peerPort := host.ListenPort
if host.WgPublicListenPort != 0 {
peerPort = host.WgPublicListenPort
}
return peerPort
}
// GetPeerListenPort - given a host, retrieve it's appropriate listening port
func GetPeerListenPort(host *models.Host) int {
peerPort := host.ListenPort
if host.WgPublicListenPort != 0 {
peerPort = host.WgPublicListenPort
}
if host.ProxyEnabled {
if host.PublicListenPort != 0 {
peerPort = host.PublicListenPort
} else if host.ProxyListenPort != 0 {
peerPort = host.ProxyListenPort
}
}
return peerPort
}
// GetProxyListenPort - fetches the proxy listen port
func GetProxyListenPort(host *models.Host) int {
proxyPort := host.ProxyListenPort
if host.PublicListenPort != 0 {
proxyPort = host.PublicListenPort
}
return proxyPort
}
func getExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, error) {
func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, error) {
var peers []wgtypes.PeerConfig
var idsAndAddr []models.IDandAddr
extPeers, err := GetNetworkExtClients(node.Network)
@ -476,6 +304,9 @@ func getExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, e
}
for _, extPeer := range extPeers {
extPeer := extPeer
if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
continue
}
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
if err != nil {
logger.Log(1, "error parsing ext pub key:", err.Error())
@ -520,77 +351,16 @@ func getExtPeers(node *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, e
}
peers = append(peers, peer)
idsAndAddr = append(idsAndAddr, models.IDandAddr{
ID: peer.PublicKey.String(),
Name: extPeer.ClientID,
Address: primaryAddr,
ID: peer.PublicKey.String(),
Name: extPeer.ClientID,
Address: primaryAddr,
IsExtClient: true,
})
}
return peers, idsAndAddr, nil
}
func getExtPeersForProxy(node *models.Node, proxyPeerConf map[string]models.PeerConf) ([]wgtypes.PeerConfig, map[string]models.PeerConf, error) {
var peers []wgtypes.PeerConfig
host, err := GetHost(node.HostID.String())
if err != nil {
logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
}
extPeers, err := GetNetworkExtClients(node.Network)
if err != nil {
return peers, proxyPeerConf, err
}
for _, extPeer := range extPeers {
pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
if err != nil {
logger.Log(1, "error parsing ext pub key:", err.Error())
continue
}
if host.PublicKey.String() == extPeer.PublicKey ||
extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
continue
}
var allowedips []net.IPNet
var peer wgtypes.PeerConfig
if extPeer.Address != "" {
var peeraddr = net.IPNet{
IP: net.ParseIP(extPeer.Address),
Mask: net.CIDRMask(32, 32),
}
if peeraddr.IP != nil && peeraddr.Mask != nil {
allowedips = append(allowedips, peeraddr)
}
}
if extPeer.Address6 != "" {
var addr6 = net.IPNet{
IP: net.ParseIP(extPeer.Address6),
Mask: net.CIDRMask(128, 128),
}
if addr6.IP != nil && addr6.Mask != nil {
allowedips = append(allowedips, addr6)
}
}
peer = wgtypes.PeerConfig{
PublicKey: pubkey,
ReplaceAllowedIPs: true,
AllowedIPs: allowedips,
}
extConf := models.PeerConf{
IsExtClient: true,
Address: net.ParseIP(extPeer.Address),
}
proxyPeerConf[peer.PublicKey.String()] = extConf
peers = append(peers, peer)
}
return peers, proxyPeerConf, nil
}
// GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
var allowedips []net.IPNet
@ -598,7 +368,7 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
// handle ingress gateway peers
if peer.IsIngressGateway {
extPeers, _, err := getExtPeers(peer)
extPeers, _, err := getExtPeers(peer, node)
if err != nil {
logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
}
@ -746,29 +516,3 @@ func getCIDRMaskFromAddr(addr string) net.IPMask {
}
return cidr
}
// accounts for ext client ACLs
func filterNodeMapForClientACLs(publicKey, network string, nodePeerMap map[string]models.PeerRouteInfo) map[string]models.PeerRouteInfo {
if !isEE {
return nodePeerMap
}
if nodePeerMap == nil {
return map[string]models.PeerRouteInfo{}
}
if len(publicKey) == 0 || len(network) == 0 {
return nodePeerMap
}
client, err := GetExtClientByPubKey(publicKey, network)
if err != nil {
return nodePeerMap
}
for k := range nodePeerMap {
currNodePeer := nodePeerMap[k]
if _, ok := client.ACLs[currNodePeer.ID]; ok {
delete(nodePeerMap, k)
}
}
return nodePeerMap
}

View file

@ -29,7 +29,7 @@ import (
"golang.org/x/exp/slog"
)
var version = "v0.20.4"
var version = "v0.20.5"
// Start DB Connection and start API Request Handler
func main() {

View file

@ -1,83 +0,0 @@
package metrics
import (
"sync"
"time"
"github.com/gravitl/netmaker/models"
)
// lock for metrics map
var metricsMapLock = &sync.RWMutex{}
// metrics data map
var metricsPeerMap = make(map[string]map[string]*models.ProxyMetric)
// GetMetricByServer - get metric data of peers by server
func GetMetricByServer(server string) map[string]*models.ProxyMetric {
metricsMapLock.RLock()
defer metricsMapLock.RUnlock()
if _, ok := metricsPeerMap[server]; !ok {
return nil
}
return metricsPeerMap[server]
}
// GetMetric - fetches the metric data for the peer
func GetMetric(server, peerKey string) models.ProxyMetric {
metric := models.ProxyMetric{}
peerMetricMap := GetMetricByServer(server)
metricsMapLock.RLock()
defer metricsMapLock.RUnlock()
if peerMetricMap == nil {
return metric
}
if m, ok := peerMetricMap[peerKey]; ok && m != nil {
metric = *m
}
return metric
}
// UpdateMetric - updates metric data for the peer
func UpdateMetric(server, peerKey string, metric *models.ProxyMetric) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
if metricsPeerMap[server] == nil {
metricsPeerMap[server] = make(map[string]*models.ProxyMetric)
}
metricsPeerMap[server][peerKey] = metric
}
// UpdateMetricByPeer - updates metrics data by peer public key
func UpdateMetricByPeer(peerKey string, metric *models.ProxyMetric, onlyTraffic bool) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
for server, peerKeyMap := range metricsPeerMap {
if peerMetric, ok := peerKeyMap[peerKey]; ok {
peerMetric.TrafficRecieved += metric.TrafficRecieved
peerMetric.TrafficSent += metric.TrafficSent
if !onlyTraffic {
peerMetric.LastRecordedLatency = metric.LastRecordedLatency
}
metricsPeerMap[server][peerKey] = peerMetric
}
}
}
// ResetMetricsForPeer - reset metrics for peer
func ResetMetricsForPeer(server, peerKey string) {
metricsMapLock.Lock()
defer metricsMapLock.Unlock()
delete(metricsPeerMap[server], peerKey)
}
// ResetMetricForNode - resets node level metrics
func ResetMetricForNode(server, peerKey, peerID string) {
metric := GetMetric(server, peerKey)
delete(metric.NodeConnectionStatus, peerID)
UpdateMetric(server, peerKey, &metric)
}
// MetricCollectionInterval - collection interval for metrics
const MetricCollectionInterval = time.Second * 25

View file

@ -16,9 +16,6 @@ type ApiHost struct {
Debug bool `json:"debug"`
IsStatic bool `json:"isstatic"`
ListenPort int `json:"listenport"`
LocalListenPort int `json:"locallistenport"`
ProxyListenPort int `json:"proxy_listen_port"`
PublicListenPort int `json:"public_listen_port" yaml:"public_listen_port"`
WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"`
MTU int `json:"mtu" yaml:"mtu"`
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
@ -28,7 +25,6 @@ type ApiHost struct {
MacAddress string `json:"macaddress"`
InternetGateway string `json:"internetgateway"`
Nodes []string `json:"nodes"`
ProxyEnabled bool `json:"proxy_enabled" yaml:"proxy_enabled"`
IsDefault bool `json:"isdefault" yaml:"isdefault"`
IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
RelayedBy string `json:"relayed_by" bson:"relayed_by" yaml:"relayed_by"`
@ -60,10 +56,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
a.Name = h.Name
a.OS = h.OS
a.Nodes = h.Nodes
a.ProxyEnabled = h.ProxyEnabled
a.PublicListenPort = h.PublicListenPort
a.WgPublicListenPort = h.WgPublicListenPort
a.ProxyListenPort = h.ProxyListenPort
a.PublicKey = h.PublicKey.String()
a.Verbosity = h.Verbosity
a.Version = h.Version
@ -95,8 +88,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
h.IsK8S = currentHost.IsK8S
h.IsStatic = a.IsStatic
h.ListenPort = a.ListenPort
h.ProxyListenPort = a.ProxyListenPort
h.PublicListenPort = currentHost.PublicListenPort
h.MTU = a.MTU
h.MacAddress = currentHost.MacAddress
h.PublicKey = currentHost.PublicKey
@ -106,7 +97,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
h.Nodes = currentHost.Nodes
h.TrafficKeyPublic = currentHost.TrafficKeyPublic
h.OS = currentHost.OS
h.ProxyEnabled = a.ProxyEnabled
h.IsDefault = a.IsDefault
h.NatType = currentHost.NatType
h.TurnEndpoint = currentHost.TurnEndpoint

View file

@ -15,14 +15,15 @@ type ExtClient struct {
LastModified int64 `json:"lastmodified" bson:"lastmodified"`
Enabled bool `json:"enabled" bson:"enabled"`
OwnerID string `json:"ownerid" bson:"ownerid"`
ACLs map[string]struct{} `json:"acls,omitempty" bson:"acls,omitempty"`
DeniedACLs map[string]struct{} `json:"deniednodeacls" bson:"acls,omitempty"`
}
// CustomExtClient - struct for CustomExtClient params
type CustomExtClient struct {
ClientID string `json:"clientid,omitempty"`
PublicKey string `json:"publickey,omitempty"`
DNS string `json:"dns,omitempty"`
ExtraAllowedIPs []string `json:"extraallowedips,omitempty"`
Enabled bool `json:"enabled,omitempty"`
ClientID string `json:"clientid,omitempty"`
PublicKey string `json:"publickey,omitempty"`
DNS string `json:"dns,omitempty"`
ExtraAllowedIPs []string `json:"extraallowedips,omitempty"`
Enabled bool `json:"enabled,omitempty"`
DeniedACLs map[string]struct{} `json:"deniednodeacls" bson:"acls,omitempty"`
}

View file

@ -25,15 +25,11 @@ var OS_Types = struct {
// NAT_Types - the type of NAT in which a HOST currently resides (simplified)
var NAT_Types = struct {
Public string
Symmetric string
Asymmetric string
Double string
Public string
BehindNAT string
}{
Public: "public",
Symmetric: "symmetric",
Asymmetric: "asymmetric",
Double: "double",
Public: "public",
BehindNAT: "behind_nat",
}
// WIREGUARD_INTERFACE name of wireguard interface
@ -54,24 +50,16 @@ type Host struct {
Interface string `json:"interface" yaml:"interface"`
Debug bool `json:"debug" yaml:"debug"`
ListenPort int `json:"listenport" yaml:"listenport"`
PublicListenPort int `json:"public_listen_port" yaml:"public_listen_port"`
WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"`
ProxyListenPort int `json:"proxy_listen_port" yaml:"proxy_listen_port"`
MTU int `json:"mtu" yaml:"mtu"`
PublicKey wgtypes.Key `json:"publickey" yaml:"publickey"`
MacAddress net.HardwareAddr `json:"macaddress" yaml:"macaddress"`
TrafficKeyPublic []byte `json:"traffickeypublic" yaml:"traffickeypublic"`
InternetGateway net.UDPAddr `json:"internetgateway" yaml:"internetgateway"`
Nodes []string `json:"nodes" yaml:"nodes"`
IsRelayed bool `json:"isrelayed" yaml:"isrelayed"`
RelayedBy string `json:"relayed_by" yaml:"relayed_by"`
IsRelay bool `json:"isrelay" yaml:"isrelay"`
RelayedHosts []string `json:"relay_hosts" yaml:"relay_hosts"`
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
DefaultInterface string `json:"defaultinterface" yaml:"defaultinterface"`
EndpointIP net.IP `json:"endpointip" yaml:"endpointip"`
ProxyEnabled bool `json:"proxy_enabled" yaml:"proxy_enabled"`
ProxyEnabledSet bool `json:"proxy_enabled_updated" yaml:"proxy_enabled_updated"`
IsDocker bool `json:"isdocker" yaml:"isdocker"`
IsK8S bool `json:"isk8s" yaml:"isk8s"`
IsStatic bool `json:"isstatic" yaml:"isstatic"`
@ -154,6 +142,7 @@ type Signal struct {
ToHostPubKey string `json:"to_host_pubkey"`
Reply bool `json:"reply"`
Action SignalAction `json:"action"`
TimeStamp int64 `json:"timestamp"`
}
// RegisterMsg - login message struct for hosts to join via SSO login

View file

@ -15,26 +15,26 @@ type Metrics struct {
// Metric - holds a metric for data between nodes
type Metric struct {
NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"`
Uptime int64 `json:"uptime" bson:"uptime" yaml:"uptime"`
TotalTime int64 `json:"totaltime" bson:"totaltime" yaml:"totaltime"`
Latency int64 `json:"latency" bson:"latency" yaml:"latency"`
TotalReceived int64 `json:"totalreceived" bson:"totalreceived" yaml:"totalreceived"`
TotalSent int64 `json:"totalsent" bson:"totalsent" yaml:"totalsent"`
ActualUptime time.Duration `json:"actualuptime" bson:"actualuptime" yaml:"actualuptime"`
PercentUp float64 `json:"percentup" bson:"percentup" yaml:"percentup"`
Connected bool `json:"connected" bson:"connected" yaml:"connected"`
CollectedByProxy bool `json:"collected_by_proxy" bson:"collected_by_proxy" yaml:"collected_by_proxy"`
NodeName string `json:"node_name" bson:"node_name" yaml:"node_name"`
Uptime int64 `json:"uptime" bson:"uptime" yaml:"uptime"`
TotalTime int64 `json:"totaltime" bson:"totaltime" yaml:"totaltime"`
Latency int64 `json:"latency" bson:"latency" yaml:"latency"`
TotalReceived int64 `json:"totalreceived" bson:"totalreceived" yaml:"totalreceived"`
TotalSent int64 `json:"totalsent" bson:"totalsent" yaml:"totalsent"`
ActualUptime time.Duration `json:"actualuptime" bson:"actualuptime" yaml:"actualuptime"`
PercentUp float64 `json:"percentup" bson:"percentup" yaml:"percentup"`
Connected bool `json:"connected" bson:"connected" yaml:"connected"`
}
// IDandAddr - struct to hold ID and primary Address
type IDandAddr struct {
ID string `json:"id" bson:"id" yaml:"id"`
Address string `json:"address" bson:"address" yaml:"address"`
Name string `json:"name" bson:"name" yaml:"name"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
Network string `json:"network" bson:"network" yaml:"network" validate:"network"`
ProxyListenPort int `json:"proxy_listen_port" yaml:"proxy_listen_port"`
ID string `json:"id" bson:"id" yaml:"id"`
Address string `json:"address" bson:"address" yaml:"address"`
Name string `json:"name" bson:"name" yaml:"name"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
Network string `json:"network" bson:"network" yaml:"network" validate:"network"`
ListenPort int `json:"listen_port" yaml:"listen_port"`
IsExtClient bool `json:"is_extclient"`
}
// HostInfoMap - map of host public keys to host networking info
@ -42,16 +42,13 @@ type HostInfoMap map[string]HostNetworkInfo
// HostNetworkInfo - holds info related to host networking (used for client side peer calculations)
type HostNetworkInfo struct {
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
ProxyListenPort int `json:"proxy_listen_port" yaml:"proxy_listen_port"`
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
ListenPort int `json:"listen_port" yaml:"listen_port"`
}
// PeerMap - peer map for ids and addresses in metrics
type PeerMap map[string]IDandAddr
// HostPeerMap - host peer map for ids and addresses
type HostPeerMap map[string]map[string]IDandAddr
// MetricsMap - map for holding multiple metrics in memory
type MetricsMap map[string]Metrics

View file

@ -15,14 +15,11 @@ type HostPeerUpdate struct {
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
NodePeers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
Peers []wgtypes.PeerConfig
HostPeerIDs HostPeerMap `json:"hostpeerids" bson:"hostpeerids" yaml:"hostpeerids"`
ProxyUpdate ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
EgressInfo map[string]EgressInfo `json:"egress_info" bson:"egress_info" yaml:"egress_info"` // map key is node ID
IngressInfo IngressInfo `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
EndpointDetection bool `json:"endpointdetection" yaml:"endpointdetection"`
HostNetworkInfo HostInfoMap `json:"host_network_info,omitempty" bson:"host_network_info,omitempty" yaml:"host_network_info,omitempty"`
EgressRoutes []EgressNetworkRoutes `json:"egress_network_routes"`
FwUpdate FwUpdate `json:"fw_update"`
}
// IngressInfo - struct for ingress info
@ -33,11 +30,10 @@ type IngressInfo struct {
// EgressInfo - struct for egress info
type EgressInfo struct {
EgressID string `json:"egress_id" yaml:"egress_id"`
Network net.IPNet `json:"network" yaml:"network"`
EgressGwAddr net.IPNet `json:"egress_gw_addr" yaml:"egress_gw_addr"`
GwPeers map[string]PeerRouteInfo `json:"gateway_peers" yaml:"gateway_peers"`
EgressGWCfg EgressGatewayRequest `json:"egress_gateway_cfg" yaml:"egress_gateway_cfg"`
EgressID string `json:"egress_id" yaml:"egress_id"`
Network net.IPNet `json:"network" yaml:"network"`
EgressGwAddr net.IPNet `json:"egress_gw_addr" yaml:"egress_gw_addr"`
EgressGWCfg EgressGatewayRequest `json:"egress_gateway_cfg" yaml:"egress_gateway_cfg"`
}
// EgressNetworkRoutes - struct for egress network routes for adding routes to peer's interface
@ -69,3 +65,9 @@ type KeyUpdate struct {
Network string `json:"network" bson:"network"`
Interface string `json:"interface" bson:"interface"`
}
// FwUpdate - struct for firewall updates
type FwUpdate struct {
IsEgressGw bool `json:"is_egress_gw"`
EgressInfo map[string]EgressInfo `json:"egress_info"`
}

View file

@ -358,7 +358,7 @@ func (node *LegacyNode) SetDefaultFailover() {
}
}
// Node.Fill - fills other node data into calling node data if not set on calling node
// Node.Fill - fills other node data into calling node data if not set on calling node (skips DNSOn)
func (newNode *Node) Fill(currentNode *Node, isEE bool) { // TODO add new field for nftables present
newNode.ID = currentNode.ID
newNode.HostID = currentNode.HostID
@ -404,9 +404,6 @@ func (newNode *Node) Fill(currentNode *Node, isEE bool) { // TODO add new field
if newNode.IngressGatewayRange6 == "" {
newNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
}
if newNode.DNSOn != currentNode.DNSOn {
newNode.DNSOn = currentNode.DNSOn
}
if newNode.Action == "" {
newNode.Action = currentNode.Action
}
@ -483,7 +480,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
host.HostPass = ln.Password
host.Name = ln.Name
host.ListenPort = int(ln.ListenPort)
host.ProxyListenPort = int(ln.ProxyListenPort)
host.MTU = int(ln.MTU)
host.PublicKey, _ = wgtypes.ParseKey(ln.PublicKey)
host.MacAddress, _ = net.ParseMAC(ln.MacAddress)
@ -540,7 +536,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
l.Name = h.Name
l.NetworkSettings = *net
l.ListenPort = int32(h.ListenPort)
l.ProxyListenPort = int32(h.ProxyListenPort)
l.PublicKey = h.PublicKey.String()
l.Endpoint = h.EndpointIP.String()
//l.AllowedIPs =
@ -580,7 +575,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
l.InternetGateway = h.InternetGateway.String()
l.Connected = formatBool(n.Connected)
//l.PendingDelete = formatBool(n.PendingDelete)
l.Proxy = h.ProxyEnabled
l.DefaultACL = n.DefaultACL
l.OwnerID = n.OwnerID
//l.Failover = n.Failover

View file

@ -1,68 +0,0 @@
package models
import (
"net"
"time"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
// ProxyAction - type for proxy action
type ProxyAction string
const (
// default proxy port
NmProxyPort = 51722
// PersistentKeepaliveInterval - default keepalive for wg peer
DefaultPersistentKeepaliveInterval = time.Duration(time.Second * 20)
// ProxyUpdate - constant for proxy update action
ProxyUpdate ProxyAction = "PROXY_UPDATE"
// ProxyDeletePeers - constant for proxy delete peers action
ProxyDeletePeers ProxyAction = "PROXY_DELETE"
// ProxyDeleteAllPeers - constant for proxy delete all peers action
ProxyDeleteAllPeers ProxyAction = "PROXY_DELETE_ALL"
// NoProxy - constant for no ProxyAction
NoProxy ProxyAction = "NO_PROXY"
)
// RelayedConf - struct relayed peers config
type RelayedConf struct {
RelayedPeerEndpoint *net.UDPAddr `json:"relayed_peer_endpoint"`
RelayedPeerPubKey string `json:"relayed_peer_pub_key"`
Peers []wgtypes.PeerConfig `json:"relayed_peers"`
}
// PeerConf - struct for peer config in the network
type PeerConf struct {
Proxy bool `json:"proxy"`
PublicListenPort int32 `json:"public_listen_port"`
ProxyListenPort int `json:"proxy_listen_port"`
IsExtClient bool `json:"is_ext_client"`
Address net.IP `json:"address"`
IsRelayed bool `json:"is_relayed"`
RelayedTo *net.UDPAddr `json:"relayed_to"`
NatType string `json:"nat_type"`
}
// ProxyManagerPayload - struct for proxy manager payload
type ProxyManagerPayload struct {
Action ProxyAction `json:"action"`
InterfaceName string `json:"interface_name"`
Server string `json:"server"`
Peers []wgtypes.PeerConfig `json:"peers"`
PeerMap map[string]PeerConf `json:"peer_map"`
IsIngress bool `json:"is_ingress"`
IsRelayed bool `json:"is_relayed"`
RelayedTo *net.UDPAddr `json:"relayed_to"`
IsRelay bool `json:"is_relay"`
RelayedPeerConf map[string]RelayedConf `json:"relayed_conf"`
}
// Metric - struct for metric data
type ProxyMetric struct {
NodeConnectionStatus map[string]bool `json:"node_connection_status"`
LastRecordedLatency uint64 `json:"last_recorded_latency"`
TrafficSent int64 `json:"traffic_sent"` // stored in MB
TrafficRecieved int64 `json:"traffic_recieved"` // stored in MB
}

View file

@ -324,21 +324,18 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) boo
oldMetric := oldMetrics.Connectivity[k]
currMetric.TotalTime += oldMetric.TotalTime
currMetric.Uptime += oldMetric.Uptime // get the total uptime for this connection
if currMetric.CollectedByProxy {
if currMetric.TotalReceived < oldMetric.TotalReceived {
currMetric.TotalReceived += oldMetric.TotalReceived
} else {
currMetric.TotalReceived += int64(math.Abs(float64(currMetric.TotalReceived) - float64(oldMetric.TotalReceived)))
}
if currMetric.TotalSent < oldMetric.TotalSent {
currMetric.TotalSent += oldMetric.TotalSent
} else {
if currMetric.TotalReceived < oldMetric.TotalReceived {
currMetric.TotalReceived += oldMetric.TotalReceived
} else {
currMetric.TotalReceived += int64(math.Abs(float64(currMetric.TotalReceived) - float64(oldMetric.TotalReceived)))
}
if currMetric.TotalSent < oldMetric.TotalSent {
currMetric.TotalSent += oldMetric.TotalSent
} else {
currMetric.TotalSent += int64(math.Abs(float64(currMetric.TotalSent) - float64(oldMetric.TotalSent)))
}
currMetric.TotalSent += int64(math.Abs(float64(currMetric.TotalSent) - float64(oldMetric.TotalSent)))
}
if currMetric.Uptime == 0 || currMetric.TotalTime == 0 {
currMetric.PercentUp = 0
} else {

View file

@ -96,20 +96,6 @@ func PublishSingleHostPeerUpdate(host *models.Host, allNodes []models.Node, dele
if len(peerUpdate.Peers) == 0 { // no peers to send
return nil
}
if host.OS != models.OS_Types.IoT {
proxyUpdate, err := logic.GetProxyUpdateForHost(host)
if err != nil {
return err
}
proxyUpdate.Server = servercfg.GetServer()
if host.ProxyEnabled {
proxyUpdate.Action = models.ProxyUpdate
} else {
proxyUpdate.Action = models.NoProxy
}
peerUpdate.ProxyUpdate = proxyUpdate
}
data, err := json.Marshal(&peerUpdate)
if err != nil {

View file

@ -1,22 +1,22 @@
# Netmaker v0.20.4
# Netmaker v0.20.5
## Whats New
- FreeBSD 13/14 specific binaries
- Whitelabelling capabilities
- Extclient Acls
- Force delete host along with all the associated nodes
## What's Fixed
- Fixes for FreeBSD
- Mac installer installs WireGuard
- ACL rendering on UI
- Updating Endpoint IP from UI
- Deprecated Proxy
- Solved Race condition for multiple nodes joining network at same time
- Node dns toggle
- Simplified Firewall rules for added stability
## known issues
- Expired nodes are not getting cleaned up
- Windows installer does not install WireGuard
- netclient-gui (windows) will display an erroneous error dialog when joining a network (can be ignored)
- netclient-gui will continously display error dialog if netmaker server is offline
- Incorrect metrics against ext clients
- Host ListenPorts set to 0 after migration from 0.17.1 -> 0.20.4
- Host ListenPorts set to 0 after migration from 0.17.1 -> 0.20.5
- Mac IPv6 addresses/route issues
- Docker client can not re-join after complete deletion
- netclient-gui network tab blank after disconnect

View file

@ -46,10 +46,6 @@ SERVER_BROKER_ENDPOINT="ws://mq:1883"
STUN_PORT="3478"
# Logging verbosity level - 1, 2, or 3
VERBOSITY="1"
# If ON, all new clients will enable proxy by default
# If OFF, all new clients will disable proxy by default
# If AUTO, stick with the existing logic for NAT detection
DEFAULT_PROXY_MODE="off"
# Port to access turn server
TURN_PORT="3479"
# Config for using turn, accepts either true/false

View file

@ -310,7 +310,7 @@ save_config() { (
local toCopy=("SERVER_HOST" "MASTER_KEY" "TURN_USERNAME" "TURN_PASSWORD" "MQ_USERNAME" "MQ_PASSWORD"
"INSTALL_TYPE" "NODE_ID" "DNS_MODE" "NETCLIENT_AUTO_UPDATE" "API_PORT"
"CORS_ALLOWED_ORIGIN" "DISPLAY_KEYS" "DATABASE" "SERVER_BROKER_ENDPOINT" "STUN_PORT" "VERBOSITY"
"DEFAULT_PROXY_MODE" "TURN_PORT" "USE_TURN" "DEBUG_MODE" "TURN_API_PORT" "REST_BACKEND"
"TURN_PORT" "USE_TURN" "DEBUG_MODE" "TURN_API_PORT" "REST_BACKEND"
"DISABLE_REMOTE_IP_CHECK" "NETCLIENT_ENDPOINT_DETECTION" "TELEMETRY" "AUTH_PROVIDER" "CLIENT_ID" "CLIENT_SECRET"
"FRONTEND_URL" "AZURE_TENANT" "OIDC_ISSUER" "EXPORTER_API_PORT")
for name in "${toCopy[@]}"; do

View file

@ -1,6 +1,6 @@
#!/bin/bash
LATEST="v0.20.4"
LATEST="v0.20.5"
INSTALL_PATH="/root"
trap restore_old_netmaker_instructions

View file

@ -90,7 +90,6 @@ func GetServerConfig() config.ServerConfig {
if Is_EE {
cfg.IsEE = "yes"
}
cfg.DefaultProxyMode = GetDefaultProxyMode()
return cfg
}
@ -731,17 +730,6 @@ func GetTurnPassword() string {
}
// IsProxyEnabled - is proxy on or off
func IsProxyEnabled() bool {
var enabled = false //default
if os.Getenv("PROXY") != "" {
enabled = os.Getenv("PROXY") == "on"
} else if config.Config.Server.Proxy != "" {
enabled = config.Config.Server.Proxy == "on"
}
return enabled
}
// GetNetworkLimit - fetches free tier limits on users
func GetUserLimit() int {
var userslimit int
@ -794,32 +782,6 @@ func DeployedByOperator() bool {
return config.Config.Server.DeployedByOperator
}
// GetDefaultProxyMode - default proxy mode for a server
func GetDefaultProxyMode() config.ProxyMode {
var (
mode config.ProxyMode
def string
)
if os.Getenv("DEFAULT_PROXY_MODE") != "" {
def = os.Getenv("DEFAULT_PROXY_MODE")
} else if config.Config.Server.DefaultProxyMode.Set {
return config.Config.Server.DefaultProxyMode
}
switch strings.ToUpper(def) {
case "ON":
mode.Set = true
mode.Value = true
case "OFF":
mode.Set = true
mode.Value = false
// AUTO or any other value
default:
mode.Set = false
}
return mode
}
// parseStunList - turn string into slice of StunServers
func parseStunList(stunString string) ([]models.StunServer, error) {
var err error

View file

@ -704,7 +704,7 @@ info:
API calls must be authenticated via a header of the format -H “Authorization: Bearer <YOUR_SECRET_KEY>” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes/<network>/authenticate endpoint, as documented below.
title: Netmaker
version: 0.20.4
version: 0.20.5
paths:
/api/dns:
get: