mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-04 16:33:49 +08:00
remove local network/range
This commit is contained in:
@@ -35,9 +35,6 @@ var networkCreateCmd = &cobra.Command{
|
|||||||
if udpHolePunch {
|
if udpHolePunch {
|
||||||
network.DefaultUDPHolePunch = "yes"
|
network.DefaultUDPHolePunch = "yes"
|
||||||
}
|
}
|
||||||
if localNetwork {
|
|
||||||
network.IsLocal = "yes"
|
|
||||||
}
|
|
||||||
if defaultACL {
|
if defaultACL {
|
||||||
network.DefaultACL = "yes"
|
network.DefaultACL = "yes"
|
||||||
}
|
}
|
||||||
@@ -62,7 +59,6 @@ func init() {
|
|||||||
networkCreateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network")
|
networkCreateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network")
|
||||||
networkCreateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network")
|
networkCreateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network")
|
||||||
networkCreateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?")
|
networkCreateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?")
|
||||||
networkCreateCmd.Flags().BoolVar(&localNetwork, "local", false, "Is the network local (LAN) ?")
|
|
||||||
networkCreateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?")
|
networkCreateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?")
|
||||||
networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
|
networkCreateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
|
||||||
networkCreateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
|
networkCreateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
|
||||||
|
@@ -6,7 +6,6 @@ var (
|
|||||||
address string
|
address string
|
||||||
address6 string
|
address6 string
|
||||||
udpHolePunch bool
|
udpHolePunch bool
|
||||||
localNetwork bool
|
|
||||||
defaultACL bool
|
defaultACL bool
|
||||||
defaultInterface string
|
defaultInterface string
|
||||||
defaultListenPort int
|
defaultListenPort int
|
||||||
|
@@ -38,9 +38,6 @@ var networkUpdateCmd = &cobra.Command{
|
|||||||
if udpHolePunch {
|
if udpHolePunch {
|
||||||
network.DefaultUDPHolePunch = "yes"
|
network.DefaultUDPHolePunch = "yes"
|
||||||
}
|
}
|
||||||
if localNetwork {
|
|
||||||
network.IsLocal = "yes"
|
|
||||||
}
|
|
||||||
if defaultACL {
|
if defaultACL {
|
||||||
network.DefaultACL = "yes"
|
network.DefaultACL = "yes"
|
||||||
}
|
}
|
||||||
@@ -63,7 +60,6 @@ func init() {
|
|||||||
networkUpdateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network")
|
networkUpdateCmd.Flags().StringVar(&address, "ipv4_addr", "", "IPv4 address of the network")
|
||||||
networkUpdateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network")
|
networkUpdateCmd.Flags().StringVar(&address6, "ipv6_addr", "", "IPv6 address of the network")
|
||||||
networkUpdateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?")
|
networkUpdateCmd.Flags().BoolVar(&udpHolePunch, "udp_hole_punch", false, "Enable UDP Hole Punching ?")
|
||||||
networkUpdateCmd.Flags().BoolVar(&localNetwork, "local", false, "Is the network local (LAN) ?")
|
|
||||||
networkUpdateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?")
|
networkUpdateCmd.Flags().BoolVar(&defaultACL, "default_acl", false, "Enable default Access Control List ?")
|
||||||
networkUpdateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
|
networkUpdateCmd.Flags().StringVar(&defaultInterface, "interface", "", "Name of the network interface")
|
||||||
networkUpdateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
|
networkUpdateCmd.Flags().StringVar(&defaultExtClientDNS, "ext_client_dns", "", "IPv4 address of DNS server to be used by external clients")
|
||||||
|
@@ -10,11 +10,9 @@
|
|||||||
"defaultinterface": "nm-test3",
|
"defaultinterface": "nm-test3",
|
||||||
"accesskeys": [],
|
"accesskeys": [],
|
||||||
"allowmanualsignup": "no",
|
"allowmanualsignup": "no",
|
||||||
"islocal": "no",
|
|
||||||
"isipv4": "yes",
|
"isipv4": "yes",
|
||||||
"isipv6": "no",
|
"isipv6": "no",
|
||||||
"ispointtosite": "no",
|
"ispointtosite": "no",
|
||||||
"localrange": "",
|
|
||||||
"defaultudpholepunch": "yes",
|
"defaultudpholepunch": "yes",
|
||||||
"defaultextclientdns": "",
|
"defaultextclientdns": "",
|
||||||
"defaultmtu": 1280,
|
"defaultmtu": 1280,
|
||||||
|
@@ -18,11 +18,9 @@
|
|||||||
"defaultkeepalive": 20,
|
"defaultkeepalive": 20,
|
||||||
"accesskeys": [],
|
"accesskeys": [],
|
||||||
"allowmanualsignup": "no",
|
"allowmanualsignup": "no",
|
||||||
"islocal": "no",
|
|
||||||
"isipv4": "no",
|
"isipv4": "no",
|
||||||
"isipv6": "yes",
|
"isipv6": "yes",
|
||||||
"ispointtosite": "no",
|
"ispointtosite": "no",
|
||||||
"localrange": "",
|
|
||||||
"defaultudpholepunch": "yes",
|
"defaultudpholepunch": "yes",
|
||||||
"defaultextclientdns": "",
|
"defaultextclientdns": "",
|
||||||
"defaultmtu": 1280,
|
"defaultmtu": 1280,
|
||||||
@@ -82,8 +80,6 @@
|
|||||||
"dnson": "no",
|
"dnson": "no",
|
||||||
"isserver": "yes",
|
"isserver": "yes",
|
||||||
"action": "noop",
|
"action": "noop",
|
||||||
"islocal": "no",
|
|
||||||
"localrange": "",
|
|
||||||
"ipforwarding": "yes",
|
"ipforwarding": "yes",
|
||||||
"os": "linux",
|
"os": "linux",
|
||||||
"mtu": 1280,
|
"mtu": 1280,
|
||||||
|
@@ -32,7 +32,6 @@ type ApiNode struct {
|
|||||||
RelayAddrs []string `json:"relayaddrs"`
|
RelayAddrs []string `json:"relayaddrs"`
|
||||||
FailoverNode string `json:"failovernode"`
|
FailoverNode string `json:"failovernode"`
|
||||||
DNSOn bool `json:"dnson"`
|
DNSOn bool `json:"dnson"`
|
||||||
IsLocal bool `json:"islocal"`
|
|
||||||
Server string `json:"server"`
|
Server string `json:"server"`
|
||||||
InternetGateway string `json:"internetgateway"`
|
InternetGateway string `json:"internetgateway"`
|
||||||
Connected bool `json:"connected"`
|
Connected bool `json:"connected"`
|
||||||
@@ -51,7 +50,6 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
|||||||
convertedNode.Connected = a.Connected
|
convertedNode.Connected = a.Connected
|
||||||
convertedNode.ID, _ = uuid.Parse(a.ID)
|
convertedNode.ID, _ = uuid.Parse(a.ID)
|
||||||
convertedNode.HostID, _ = uuid.Parse(a.HostID)
|
convertedNode.HostID, _ = uuid.Parse(a.HostID)
|
||||||
convertedNode.IsLocal = a.IsLocal
|
|
||||||
convertedNode.IsRelay = a.IsRelay
|
convertedNode.IsRelay = a.IsRelay
|
||||||
convertedNode.IsRelayed = a.IsRelayed
|
convertedNode.IsRelayed = a.IsRelayed
|
||||||
convertedNode.PendingDelete = a.PendingDelete
|
convertedNode.PendingDelete = a.PendingDelete
|
||||||
@@ -150,7 +148,6 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
|
|||||||
apiNode.FailoverNode = ""
|
apiNode.FailoverNode = ""
|
||||||
}
|
}
|
||||||
apiNode.DNSOn = nm.DNSOn
|
apiNode.DNSOn = nm.DNSOn
|
||||||
apiNode.IsLocal = nm.IsLocal
|
|
||||||
apiNode.Server = nm.Server
|
apiNode.Server = nm.Server
|
||||||
apiNode.InternetGateway = nm.InternetGateway.String()
|
apiNode.InternetGateway = nm.InternetGateway.String()
|
||||||
if isEmptyAddr(apiNode.InternetGateway) {
|
if isEmptyAddr(apiNode.InternetGateway) {
|
||||||
|
@@ -21,7 +21,6 @@ type Network struct {
|
|||||||
DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"`
|
DefaultKeepalive int32 `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"`
|
||||||
AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"`
|
AccessKeys []AccessKey `json:"accesskeys" bson:"accesskeys"`
|
||||||
AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"`
|
AllowManualSignUp string `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"`
|
||||||
IsLocal string `json:"islocal" bson:"islocal" validate:"checkyesorno"`
|
|
||||||
IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
|
IsIPv4 string `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
|
||||||
IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
|
IsIPv6 string `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
|
||||||
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
||||||
@@ -51,9 +50,6 @@ func (network *Network) SetDefaults() {
|
|||||||
if network.DefaultUDPHolePunch == "" {
|
if network.DefaultUDPHolePunch == "" {
|
||||||
network.DefaultUDPHolePunch = "no"
|
network.DefaultUDPHolePunch = "no"
|
||||||
}
|
}
|
||||||
if network.IsLocal == "" {
|
|
||||||
network.IsLocal = "no"
|
|
||||||
}
|
|
||||||
if network.DefaultInterface == "" {
|
if network.DefaultInterface == "" {
|
||||||
if len(network.NetID) < 13 {
|
if len(network.NetID) < 13 {
|
||||||
network.DefaultInterface = "nm-" + network.NetID
|
network.DefaultInterface = "nm-" + network.NetID
|
||||||
|
@@ -68,7 +68,6 @@ type CommonNode struct {
|
|||||||
Address6 net.IPNet `json:"address6" yaml:"address6"`
|
Address6 net.IPNet `json:"address6" yaml:"address6"`
|
||||||
Action string `json:"action" yaml:"action"`
|
Action string `json:"action" yaml:"action"`
|
||||||
LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"`
|
LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"`
|
||||||
IsLocal bool `json:"islocal" yaml:"islocal"`
|
|
||||||
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
||||||
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||||
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
||||||
@@ -145,7 +144,6 @@ type LegacyNode struct {
|
|||||||
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
|
DNSOn string `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
|
||||||
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
|
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
|
||||||
Action string `json:"action" bson:"action" yaml:"action"`
|
Action string `json:"action" bson:"action" yaml:"action"`
|
||||||
IsLocal string `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
|
|
||||||
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
|
IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
|
||||||
OS string `json:"os" bson:"os" yaml:"os"`
|
OS string `json:"os" bson:"os" yaml:"os"`
|
||||||
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
|
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
|
||||||
@@ -295,13 +293,6 @@ func (node *LegacyNode) SetIPForwardingDefault() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node.SetIsLocalDefault - set is local default
|
|
||||||
func (node *LegacyNode) SetIsLocalDefault() {
|
|
||||||
if node.IsLocal == "" {
|
|
||||||
node.IsLocal = "no"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node.SetDNSOnDefault - sets dns on default
|
// Node.SetDNSOnDefault - sets dns on default
|
||||||
func (node *LegacyNode) SetDNSOnDefault() {
|
func (node *LegacyNode) SetDNSOnDefault() {
|
||||||
if node.DNSOn == "" {
|
if node.DNSOn == "" {
|
||||||
@@ -408,9 +399,6 @@ func (newNode *Node) Fill(currentNode *Node) { // TODO add new field for nftable
|
|||||||
if newNode.DNSOn != currentNode.DNSOn {
|
if newNode.DNSOn != currentNode.DNSOn {
|
||||||
newNode.DNSOn = currentNode.DNSOn
|
newNode.DNSOn = currentNode.DNSOn
|
||||||
}
|
}
|
||||||
if newNode.IsLocal != currentNode.IsLocal {
|
|
||||||
newNode.IsLocal = currentNode.IsLocal
|
|
||||||
}
|
|
||||||
if newNode.Action == "" {
|
if newNode.Action == "" {
|
||||||
newNode.Action = currentNode.Action
|
newNode.Action = currentNode.Action
|
||||||
}
|
}
|
||||||
@@ -526,7 +514,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.Action = ln.Action
|
node.Action = ln.Action
|
||||||
node.IsLocal = parseBool(ln.IsLocal)
|
|
||||||
node.IsEgressGateway = parseBool(ln.IsEgressGateway)
|
node.IsEgressGateway = parseBool(ln.IsEgressGateway)
|
||||||
node.IsIngressGateway = parseBool(ln.IsIngressGateway)
|
node.IsIngressGateway = parseBool(ln.IsIngressGateway)
|
||||||
node.DNSOn = parseBool(ln.DNSOn)
|
node.DNSOn = parseBool(ln.DNSOn)
|
||||||
@@ -574,7 +561,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
|
|||||||
l.UDPHolePunch = formatBool(true)
|
l.UDPHolePunch = formatBool(true)
|
||||||
l.DNSOn = formatBool(n.DNSOn)
|
l.DNSOn = formatBool(n.DNSOn)
|
||||||
l.Action = n.Action
|
l.Action = n.Action
|
||||||
l.IsLocal = formatBool(n.IsLocal)
|
|
||||||
l.IPForwarding = formatBool(h.IPForwarding)
|
l.IPForwarding = formatBool(h.IPForwarding)
|
||||||
l.OS = h.OS
|
l.OS = h.OS
|
||||||
l.MTU = int32(h.MTU)
|
l.MTU = int32(h.MTU)
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
package global_settings
|
|
||||||
|
|
||||||
// globalsettings - settings that are global in nature. Avoids circular dependencies between config loading and usage.
|
|
||||||
|
|
||||||
// PublicIPServices - the list of user-specified IP services to use to obtain the node's public IP
|
|
||||||
var PublicIPServices map[string]string = make(map[string]string)
|
|
||||||
|
|
||||||
// User - holds a user string for joins when using basic auth
|
|
||||||
var User string
|
|
@@ -2,62 +2,8 @@ package ncutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/models"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IfaceDelta - checks if the new node causes an interface change
|
|
||||||
func IfaceDelta(currentNode *models.LegacyNode, newNode *models.LegacyNode) bool {
|
|
||||||
// single comparison statements
|
|
||||||
if newNode.Endpoint != currentNode.Endpoint ||
|
|
||||||
newNode.PublicKey != currentNode.PublicKey ||
|
|
||||||
newNode.Address != currentNode.Address ||
|
|
||||||
newNode.Address6 != currentNode.Address6 ||
|
|
||||||
newNode.IsEgressGateway != currentNode.IsEgressGateway ||
|
|
||||||
newNode.IsIngressGateway != currentNode.IsIngressGateway ||
|
|
||||||
newNode.IsRelay != currentNode.IsRelay ||
|
|
||||||
newNode.ListenPort != currentNode.ListenPort ||
|
|
||||||
newNode.UDPHolePunch != currentNode.UDPHolePunch ||
|
|
||||||
newNode.MTU != currentNode.MTU ||
|
|
||||||
newNode.IsPending != currentNode.IsPending ||
|
|
||||||
newNode.PersistentKeepalive != currentNode.PersistentKeepalive ||
|
|
||||||
newNode.DNSOn != currentNode.DNSOn ||
|
|
||||||
newNode.Connected != currentNode.Connected ||
|
|
||||||
len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// multi-comparison statements
|
|
||||||
if newNode.IsEgressGateway == "yes" {
|
|
||||||
if len(currentNode.EgressGatewayRanges) != len(newNode.EgressGatewayRanges) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, address := range newNode.EgressGatewayRanges {
|
|
||||||
if !StringSliceContains(currentNode.EgressGatewayRanges, address) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newNode.IsRelay == "yes" {
|
|
||||||
if len(currentNode.RelayAddrs) != len(newNode.RelayAddrs) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, address := range newNode.RelayAddrs {
|
|
||||||
if !StringSliceContains(currentNode.RelayAddrs, address) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, address := range newNode.AllowedIPs {
|
|
||||||
if !StringSliceContains(currentNode.AllowedIPs, address) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSliceContains - sees if a string slice contains a string element
|
// StringSliceContains - sees if a string slice contains a string element
|
||||||
func StringSliceContains(slice []string, item string) bool {
|
func StringSliceContains(slice []string, item string) bool {
|
||||||
for _, s := range slice {
|
for _, s := range slice {
|
||||||
@@ -68,30 +14,6 @@ func StringSliceContains(slice []string, item string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPNetSliceContains - sees if a string slice contains a string element
|
|
||||||
func IPNetSliceContains(slice []net.IPNet, item net.IPNet) bool {
|
|
||||||
for _, s := range slice {
|
|
||||||
if s.String() == item.String() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IfaceExists - return true if you can find the iface
|
|
||||||
func IfaceExists(ifacename string) bool {
|
|
||||||
localnets, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, localnet := range localnets {
|
|
||||||
if ifacename == localnet.Name {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func IpIsPrivate(ipnet net.IP) bool {
|
func IpIsPrivate(ipnet net.IP) bool {
|
||||||
return ipnet.IsPrivate() || ipnet.IsLoopback()
|
return ipnet.IsPrivate() || ipnet.IsLoopback()
|
||||||
}
|
}
|
||||||
|
@@ -4,562 +4,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/c-robinson/iplib"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
"github.com/gravitl/netmaker/models"
|
|
||||||
"github.com/gravitl/netmaker/netclient/global_settings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// Version - version of the netclient
|
|
||||||
Version = "dev"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MAX_NAME_LENGTH - maximum node name length
|
|
||||||
const MAX_NAME_LENGTH = 62
|
|
||||||
|
|
||||||
// NO_DB_RECORD - error message result
|
|
||||||
const NO_DB_RECORD = "no result found"
|
|
||||||
|
|
||||||
// NO_DB_RECORDS - error record result
|
|
||||||
const NO_DB_RECORDS = "could not find any records"
|
|
||||||
|
|
||||||
// LINUX_APP_DATA_PATH - linux path
|
|
||||||
const LINUX_APP_DATA_PATH = "/etc/netclient"
|
|
||||||
|
|
||||||
// MAC_APP_DATA_PATH - mac path
|
|
||||||
const MAC_APP_DATA_PATH = "/Applications/Netclient"
|
|
||||||
|
|
||||||
// WINDOWS_APP_DATA_PATH - windows path
|
|
||||||
const WINDOWS_APP_DATA_PATH = "C:\\Program Files (x86)\\Netclient"
|
|
||||||
|
|
||||||
// WINDOWS_SVC_NAME - service name
|
|
||||||
const WINDOWS_SVC_NAME = "netclient"
|
|
||||||
|
|
||||||
// NETCLIENT_DEFAULT_PORT - default port
|
|
||||||
const NETCLIENT_DEFAULT_PORT = 51821
|
|
||||||
|
|
||||||
// DEFAULT_GC_PERCENT - garbage collection percent
|
// DEFAULT_GC_PERCENT - garbage collection percent
|
||||||
const DEFAULT_GC_PERCENT = 10
|
const DEFAULT_GC_PERCENT = 10
|
||||||
|
|
||||||
// KEY_SIZE = ideal length for keys
|
|
||||||
const KEY_SIZE = 2048
|
|
||||||
|
|
||||||
// SetVersion -- set netclient version for use by other packages
|
|
||||||
func SetVersion(ver string) {
|
|
||||||
Version = ver
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWindows - checks if is windows
|
|
||||||
func IsWindows() bool {
|
|
||||||
return runtime.GOOS == "windows"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMac - checks if is a mac
|
|
||||||
func IsMac() bool {
|
|
||||||
return runtime.GOOS == "darwin"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLinux - checks if is linux
|
|
||||||
func IsLinux() bool {
|
|
||||||
return runtime.GOOS == "linux"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsFreeBSD - checks if is freebsd
|
|
||||||
func IsFreeBSD() bool {
|
|
||||||
return runtime.GOOS == "freebsd"
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasWGQuick - checks if WGQuick command is present
|
|
||||||
func HasWgQuick() bool {
|
|
||||||
cmd, err := exec.LookPath("wg-quick")
|
|
||||||
return err == nil && cmd != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetWireGuard - checks if wg is installed
|
|
||||||
func GetWireGuard() string {
|
|
||||||
userspace := os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION")
|
|
||||||
if userspace != "" && (userspace == "boringtun" || userspace == "wireguard-go") {
|
|
||||||
return userspace
|
|
||||||
}
|
|
||||||
return "wg"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNFTablesPresent - returns true if nftables is present, false otherwise.
|
|
||||||
// Does not consider OS, up to the caller to determine if the OS supports nftables/whether this check is valid.
|
|
||||||
func IsNFTablesPresent() bool {
|
|
||||||
found := false
|
|
||||||
_, err := exec.LookPath("nft")
|
|
||||||
if err == nil {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsIPTablesPresent - returns true if iptables is present, false otherwise
|
|
||||||
// Does not consider OS, up to the caller to determine if the OS supports iptables/whether this check is valid.
|
|
||||||
func IsIPTablesPresent() bool {
|
|
||||||
found := false
|
|
||||||
_, err := exec.LookPath("iptables")
|
|
||||||
if err == nil {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsKernel - checks if running kernel WireGuard
|
|
||||||
func IsKernel() bool {
|
|
||||||
// TODO
|
|
||||||
// Replace && true with some config file value
|
|
||||||
// This value should be something like kernelmode, which should be 'on' by default.
|
|
||||||
return IsLinux() && os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION") == ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEmptyRecord - repeat from database
|
|
||||||
func IsEmptyRecord(err error) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return strings.Contains(err.Error(), NO_DB_RECORD) || strings.Contains(err.Error(), NO_DB_RECORDS)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPublicIP - gets public ip
|
|
||||||
func GetPublicIP(api string) (string, error) {
|
|
||||||
|
|
||||||
iplist := []string{"https://ip.client.gravitl.com", "https://ifconfig.me", "https://api.ipify.org", "https://ipinfo.io/ip"}
|
|
||||||
|
|
||||||
for network, ipService := range global_settings.PublicIPServices {
|
|
||||||
logger.Log(3, "User provided public IP service defined for network", network, "is", ipService)
|
|
||||||
|
|
||||||
// prepend the user-specified service so it's checked first
|
|
||||||
iplist = append([]string{ipService}, iplist...)
|
|
||||||
}
|
|
||||||
if api != "" {
|
|
||||||
api = "https://" + api + "/api/getip"
|
|
||||||
iplist = append([]string{api}, iplist...)
|
|
||||||
}
|
|
||||||
|
|
||||||
endpoint := ""
|
|
||||||
var err error
|
|
||||||
for _, ipserver := range iplist {
|
|
||||||
client := &http.Client{
|
|
||||||
Timeout: time.Second * 10,
|
|
||||||
}
|
|
||||||
var resp *http.Response
|
|
||||||
resp, err = client.Get(ipserver)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
|
||||||
var bodyBytes []byte
|
|
||||||
bodyBytes, err = io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
if resp.Body != nil {
|
|
||||||
_ = resp.Body.Close()
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
_ = resp.Body.Close()
|
|
||||||
endpoint = string(bodyBytes)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil && endpoint == "" {
|
|
||||||
err = errors.New("public address not found")
|
|
||||||
}
|
|
||||||
return endpoint, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMacAddr - get's mac address
|
|
||||||
func GetMacAddr() ([]string, error) {
|
|
||||||
ifas, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var as []string
|
|
||||||
for _, ifa := range ifas {
|
|
||||||
a := ifa.HardwareAddr.String()
|
|
||||||
if a != "" {
|
|
||||||
as = append(as, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return as, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLocalIP - gets local ip of machine
|
|
||||||
func GetLocalIP(localrange string) (string, error) {
|
|
||||||
_, localRange, err := net.ParseCIDR(localrange)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
ifaces, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
var local string
|
|
||||||
found := false
|
|
||||||
for _, i := range ifaces {
|
|
||||||
if i.Flags&net.FlagUp == 0 {
|
|
||||||
continue // interface down
|
|
||||||
}
|
|
||||||
if i.Flags&net.FlagLoopback != 0 {
|
|
||||||
continue // loopback interface
|
|
||||||
}
|
|
||||||
addrs, err := i.Addrs()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
var ip net.IP
|
|
||||||
switch v := addr.(type) {
|
|
||||||
case *net.IPNet:
|
|
||||||
if !found {
|
|
||||||
ip = v.IP
|
|
||||||
local = ip.String()
|
|
||||||
found = localRange.Contains(ip)
|
|
||||||
}
|
|
||||||
case *net.IPAddr:
|
|
||||||
if !found {
|
|
||||||
ip = v.IP
|
|
||||||
local = ip.String()
|
|
||||||
found = localRange.Contains(ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found || local == "" {
|
|
||||||
return "", errors.New("Failed to find local IP in range " + localrange)
|
|
||||||
}
|
|
||||||
return local, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNetworkIPMask - Pulls the netmask out of the network
|
|
||||||
func GetNetworkIPMask(networkstring string) (string, string, error) {
|
|
||||||
ip, ipnet, err := net.ParseCIDR(networkstring)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
ipstring := ip.String()
|
|
||||||
mask := ipnet.Mask
|
|
||||||
maskstring := fmt.Sprintf("%d.%d.%d.%d", mask[0], mask[1], mask[2], mask[3])
|
|
||||||
// maskstring := ipnet.Mask.String()
|
|
||||||
return ipstring, maskstring, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFreePort - gets free port of machine
|
|
||||||
func GetFreePort(rangestart int32) (int32, error) {
|
|
||||||
addr := net.UDPAddr{}
|
|
||||||
if rangestart == 0 {
|
|
||||||
rangestart = NETCLIENT_DEFAULT_PORT
|
|
||||||
}
|
|
||||||
for x := rangestart; x <= 65535; x++ {
|
|
||||||
addr.Port = int(x)
|
|
||||||
conn, err := net.ListenUDP("udp", &addr)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
return rangestart, errors.New("no free ports")
|
|
||||||
}
|
|
||||||
|
|
||||||
// == OS PATH FUNCTIONS ==
|
// == OS PATH FUNCTIONS ==
|
||||||
|
|
||||||
// GetHomeDirWindows - gets home directory in windows
|
|
||||||
func GetHomeDirWindows() string {
|
|
||||||
if IsWindows() {
|
|
||||||
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
|
||||||
if home == "" {
|
|
||||||
home = os.Getenv("USERPROFILE")
|
|
||||||
}
|
|
||||||
return home
|
|
||||||
}
|
|
||||||
return os.Getenv("HOME")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNetclientPath - gets netclient path locally
|
|
||||||
func GetNetclientPath() string {
|
|
||||||
if IsWindows() {
|
|
||||||
return WINDOWS_APP_DATA_PATH
|
|
||||||
} else if IsMac() {
|
|
||||||
return MAC_APP_DATA_PATH
|
|
||||||
} else {
|
|
||||||
return LINUX_APP_DATA_PATH
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSeparator - gets the separator for OS
|
|
||||||
func GetSeparator() string {
|
|
||||||
if IsWindows() {
|
|
||||||
return "\\"
|
|
||||||
} else {
|
|
||||||
return "/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileWithRetry - retry getting file X number of times before failing
|
|
||||||
func GetFileWithRetry(path string, retryCount int) ([]byte, error) {
|
|
||||||
var data []byte
|
|
||||||
var err error
|
|
||||||
for count := 0; count < retryCount; count++ {
|
|
||||||
data, err = os.ReadFile(path)
|
|
||||||
if err == nil {
|
|
||||||
return data, err
|
|
||||||
} else {
|
|
||||||
logger.Log(1, "failed to retrieve file ", path, ", retrying...")
|
|
||||||
time.Sleep(time.Second >> 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNetclientServerPath - gets netclient server path
|
|
||||||
func GetNetclientServerPath(server string) string {
|
|
||||||
if IsWindows() {
|
|
||||||
return WINDOWS_APP_DATA_PATH + "\\" + server + "\\"
|
|
||||||
} else if IsMac() {
|
|
||||||
return MAC_APP_DATA_PATH + "/" + server + "/"
|
|
||||||
} else {
|
|
||||||
return LINUX_APP_DATA_PATH + "/" + server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNetclientPathSpecific - gets specific netclient config path
|
|
||||||
func GetNetclientPathSpecific() string {
|
|
||||||
if IsWindows() {
|
|
||||||
return WINDOWS_APP_DATA_PATH + "\\"
|
|
||||||
} else if IsMac() {
|
|
||||||
return MAC_APP_DATA_PATH + "/config/"
|
|
||||||
} else {
|
|
||||||
return LINUX_APP_DATA_PATH + "/config/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckIPAddress(ip string) error {
|
|
||||||
if net.ParseIP(ip) == nil {
|
|
||||||
return fmt.Errorf("ip address %s is invalid", ip)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNewIface - Gets the name of the real interface created on Mac
|
|
||||||
func GetNewIface(dir string) (string, error) {
|
|
||||||
files, _ := os.ReadDir(dir)
|
|
||||||
var newestFile string
|
|
||||||
var newestTime int64 = 0
|
|
||||||
var err error
|
|
||||||
for _, f := range files {
|
|
||||||
fi, err := os.Stat(dir + f.Name())
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
currTime := fi.ModTime().Unix()
|
|
||||||
if currTime > newestTime && strings.Contains(f.Name(), ".sock") {
|
|
||||||
newestTime = currTime
|
|
||||||
newestFile = f.Name()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultArr := strings.Split(newestFile, ".")
|
|
||||||
if resultArr[0] == "" {
|
|
||||||
err = errors.New("sock file does not exist")
|
|
||||||
}
|
|
||||||
return resultArr[0], err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetFileAsString - returns the string contents of a given file
|
|
||||||
func GetFileAsString(path string) (string, error) {
|
|
||||||
content, err := os.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(content), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNetclientPathSpecific - gets specific netclient config path
|
|
||||||
func GetWGPathSpecific() string {
|
|
||||||
if IsWindows() {
|
|
||||||
return WINDOWS_APP_DATA_PATH + "\\"
|
|
||||||
} else {
|
|
||||||
return "/etc/wireguard/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy - copies a src file to dest
|
|
||||||
func Copy(src, dst string) error {
|
|
||||||
sourceFileStat, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sourceFileStat.Mode().IsRegular() {
|
|
||||||
return errors.New(src + " is not a regular file")
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer source.Close()
|
|
||||||
|
|
||||||
destination, err := os.Create(dst)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer destination.Close()
|
|
||||||
_, err = io.Copy(destination, source)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = os.Chmod(dst, 0755)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunsCmds - runs cmds
|
|
||||||
func RunCmds(commands []string, printerr bool) error {
|
|
||||||
var err error
|
|
||||||
for _, command := range commands {
|
|
||||||
// prevent panic
|
|
||||||
if len(strings.Trim(command, " ")) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
args := strings.Fields(command)
|
|
||||||
out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command:", command)
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileExists - checks if file exists locally
|
|
||||||
func FileExists(f string) bool {
|
|
||||||
info, err := os.Stat(f)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if err != nil && strings.Contains(err.Error(), "not a directory") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(0, "error reading file: "+f+", "+err.Error())
|
|
||||||
}
|
|
||||||
return !info.IsDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSystemNetworks - get networks locally
|
|
||||||
func GetSystemNetworks() ([]string, error) {
|
|
||||||
var networks []string
|
|
||||||
files, err := filepath.Glob(GetNetclientPathSpecific() + "netconfig-*")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, file := range files {
|
|
||||||
// don't want files such as *.bak, *.swp
|
|
||||||
if filepath.Ext(file) != "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
file := filepath.Base(file)
|
|
||||||
temp := strings.Split(file, "-")
|
|
||||||
networks = append(networks, strings.Join(temp[1:], "-"))
|
|
||||||
}
|
|
||||||
return networks, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShortenString - Brings string down to specified length. Stops names from being too long
|
|
||||||
func ShortenString(input string, length int) string {
|
|
||||||
output := input
|
|
||||||
if len(input) > length {
|
|
||||||
output = input[0:length]
|
|
||||||
}
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
|
|
||||||
// DNSFormatString - Formats a string with correct usage for DNS
|
|
||||||
func DNSFormatString(input string) string {
|
|
||||||
reg, err := regexp.Compile("[^a-zA-Z0-9-]+")
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(0, "error with regex: "+err.Error())
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return reg.ReplaceAllString(input, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetHostname - Gets hostname of machine
|
|
||||||
func GetHostname() string {
|
|
||||||
hostname, err := os.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if len(hostname) > MAX_NAME_LENGTH {
|
|
||||||
hostname = hostname[0:MAX_NAME_LENGTH]
|
|
||||||
}
|
|
||||||
return hostname
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckUID - Checks to make sure user has root privileges
|
|
||||||
func CheckUID() {
|
|
||||||
// start our application
|
|
||||||
out, err := RunCmd("id -u", true)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(out, err)
|
|
||||||
}
|
|
||||||
id, err := strconv.Atoi(string(out[:len(out)-1]))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id != 0 {
|
|
||||||
log.Fatal("This program must be run with elevated privileges (sudo). This program installs a SystemD service and configures WireGuard and networking rules. Please re-run with sudo/root.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckFirewall - checks if iptables of nft install, if not exit
|
|
||||||
func CheckFirewall() {
|
|
||||||
if !IsIPTablesPresent() && !IsNFTablesPresent() {
|
|
||||||
log.Fatal("neither iptables nor nft is installed - please install one or the other and try again")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckWG - Checks if WireGuard is installed. If not, exit
|
|
||||||
func CheckWG() {
|
|
||||||
uspace := GetWireGuard()
|
|
||||||
if !HasWG() {
|
|
||||||
if uspace == "wg" {
|
|
||||||
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
|
|
||||||
}
|
|
||||||
logger.Log(0, "running with userspace wireguard: ", uspace)
|
|
||||||
} else if uspace != "wg" {
|
|
||||||
logger.Log(0, "running userspace WireGuard with ", uspace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasWG - returns true if wg command exists
|
|
||||||
func HasWG() bool {
|
|
||||||
var _, err = exec.LookPath("wg")
|
|
||||||
return err == nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertKeyToBytes - util to convert a key to bytes to use elsewhere
|
// ConvertKeyToBytes - util to convert a key to bytes to use elsewhere
|
||||||
func ConvertKeyToBytes(key *[32]byte) ([]byte, error) {
|
func ConvertKeyToBytes(key *[32]byte) ([]byte, error) {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
@@ -582,16 +33,6 @@ func ConvertBytesToKey(data []byte) (*[32]byte, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerAddrSliceContains - sees if a string slice contains a string element
|
|
||||||
func ServerAddrSliceContains(slice []models.ServerAddr, item models.ServerAddr) bool {
|
|
||||||
for _, s := range slice {
|
|
||||||
if s.Address == item.Address && s.IsLeader == item.IsLeader {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeRandomString - generates a random string of len n
|
// MakeRandomString - generates a random string of len n
|
||||||
func MakeRandomString(n int) string {
|
func MakeRandomString(n int) string {
|
||||||
const validChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
const validChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
@@ -604,40 +45,3 @@ func MakeRandomString(n int) string {
|
|||||||
}
|
}
|
||||||
return string(result)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIPNetFromString(ip string) (net.IPNet, error) {
|
|
||||||
var ipnet *net.IPNet
|
|
||||||
var err error
|
|
||||||
// parsing as a CIDR first. If valid CIDR, append
|
|
||||||
if _, cidr, err := net.ParseCIDR(ip); err == nil {
|
|
||||||
ipnet = cidr
|
|
||||||
} else { // parsing as an IP second. If valid IP, check if ipv4 or ipv6, then append
|
|
||||||
if iplib.Version(net.ParseIP(ip)) == 4 {
|
|
||||||
ipnet = &net.IPNet{
|
|
||||||
IP: net.ParseIP(ip),
|
|
||||||
Mask: net.CIDRMask(32, 32),
|
|
||||||
}
|
|
||||||
} else if iplib.Version(net.ParseIP(ip)) == 6 {
|
|
||||||
ipnet = &net.IPNet{
|
|
||||||
IP: net.ParseIP(ip),
|
|
||||||
Mask: net.CIDRMask(128, 128),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ipnet == nil {
|
|
||||||
err = errors.New(ip + " is not a valid ip or cidr")
|
|
||||||
return net.IPNet{}, err
|
|
||||||
}
|
|
||||||
return *ipnet, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModPort - Change Node Port if UDP Hole Punching or ListenPort is not free
|
|
||||||
func ModPort(node *models.LegacyNode) error {
|
|
||||||
var err error
|
|
||||||
if node.UDPHolePunch == "yes" {
|
|
||||||
node.ListenPort = 0
|
|
||||||
} else {
|
|
||||||
node.ListenPort, err = GetFreePort(node.ListenPort)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
@@ -1,39 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WHITESPACE_PLACEHOLDER - used with RunCMD - if a path has whitespace, use this to avoid running path as 2 args in RunCMD
|
|
||||||
const WHITESPACE_PLACEHOLDER = "+-+-+-+"
|
|
||||||
|
|
||||||
// RunCmd - runs a local command
|
|
||||||
func RunCmd(command string, printerr bool) (string, error) {
|
|
||||||
|
|
||||||
args := strings.Fields(command)
|
|
||||||
// return whitespace after split
|
|
||||||
for i, arg := range args {
|
|
||||||
args[i] = strings.Replace(arg, WHITESPACE_PLACEHOLDER, " ", -1)
|
|
||||||
}
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
cmd.Wait()
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command:", strings.Join(args, " "))
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunCmdFormatted - run a command formatted for MacOS
|
|
||||||
func RunCmdFormatted(command string, printerr bool) (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEmbedded - if files required for MacOS, put here
|
|
||||||
func GetEmbedded() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RunCmdFormatted - run a command formatted for freebsd
|
|
||||||
func RunCmdFormatted(command string, printerr bool) (string, error) {
|
|
||||||
|
|
||||||
args := strings.Fields(command)
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
cmd.Start()
|
|
||||||
cmd.Wait()
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command: ", command)
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEmbedded - if files required for freebsd, put here
|
|
||||||
func GetEmbedded() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runs Commands for FreeBSD
|
|
||||||
func RunCmd(command string, printerr bool) (string, error) {
|
|
||||||
args := strings.Fields(command)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
||||||
defer cancel()
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
|
||||||
go func() {
|
|
||||||
<-ctx.Done()
|
|
||||||
_ = syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
|
||||||
}()
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command:", command)
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RunCmd - runs a local command
|
|
||||||
func RunCmd(command string, printerr bool) (string, error) {
|
|
||||||
args := strings.Fields(command)
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
cmd.Wait()
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, fmt.Sprintf("error running command: %s", command))
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunCmdFormatted - does nothing for linux
|
|
||||||
func RunCmdFormatted(command string, printerr bool) (string, error) {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEmbedded - if files required for linux, put here
|
|
||||||
func GetEmbedded() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"embed"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed windowsdaemon/winsw.exe
|
|
||||||
var winswContent embed.FS
|
|
||||||
|
|
||||||
// RunCmd - runs a local command
|
|
||||||
func RunCmd(command string, printerr bool) (string, error) {
|
|
||||||
args := strings.Fields(command)
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
|
||||||
cmd.Wait()
|
|
||||||
//cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/C \"" + command + "\""}
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command:", command)
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunCmd - runs a local command
|
|
||||||
func RunCmdFormatted(command string, printerr bool) (string, error) {
|
|
||||||
var comSpec = os.Getenv("COMSPEC")
|
|
||||||
if comSpec == "" {
|
|
||||||
comSpec = os.Getenv("SystemRoot") + "\\System32\\cmd.exe"
|
|
||||||
}
|
|
||||||
cmd := exec.Command(comSpec)
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/C \"" + command + "\""}
|
|
||||||
cmd.Wait()
|
|
||||||
out, err := cmd.CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
logger.Log(0, "error running command:", command)
|
|
||||||
logger.Log(0, strings.TrimSuffix(string(out), "\n"))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEmbedded - Gets the Windows daemon creator
|
|
||||||
func GetEmbedded() error {
|
|
||||||
data, err := winswContent.ReadFile("windowsdaemon/winsw.exe")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fileName := fmt.Sprintf("%swinsw.exe", GetNetclientPathSpecific())
|
|
||||||
err = os.WriteFile(fileName, data, 0700)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(0, "could not mount winsw.exe")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@@ -1,97 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetPeers - gets the peers from a given WireGuard interface
|
|
||||||
func GetPeers(iface string) ([]wgtypes.Peer, error) {
|
|
||||||
|
|
||||||
var peers []wgtypes.Peer
|
|
||||||
output, err := RunCmd("wg show "+iface+" dump", true)
|
|
||||||
if err != nil {
|
|
||||||
return peers, err
|
|
||||||
}
|
|
||||||
for i, line := range strings.Split(strings.TrimSuffix(output, "\n"), "\n") {
|
|
||||||
if i == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var allowedIPs []net.IPNet
|
|
||||||
fields := strings.Fields(line)
|
|
||||||
if len(fields) < 4 {
|
|
||||||
logger.Log(0, "error parsing peer: "+line)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pubkeystring := fields[0]
|
|
||||||
endpointstring := fields[2]
|
|
||||||
allowedipstring := fields[3]
|
|
||||||
var pkeepalivestring string
|
|
||||||
if len(fields) > 7 {
|
|
||||||
pkeepalivestring = fields[7]
|
|
||||||
}
|
|
||||||
// AllowedIPs = private IP + defined networks
|
|
||||||
|
|
||||||
pubkey, err := wgtypes.ParseKey(pubkeystring)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log(0, "error parsing peer key "+pubkeystring)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ipstrings := strings.Split(allowedipstring, ",")
|
|
||||||
for _, ipstring := range ipstrings {
|
|
||||||
var netip net.IP
|
|
||||||
if netip = net.ParseIP(strings.Split(ipstring, "/")[0]); netip != nil {
|
|
||||||
allowedIPs = append(
|
|
||||||
allowedIPs,
|
|
||||||
net.IPNet{
|
|
||||||
IP: netip,
|
|
||||||
Mask: netip.DefaultMask(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(allowedIPs) == 0 {
|
|
||||||
logger.Log(0, "error parsing peer "+pubkeystring+", no allowedips found")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var endpointarr []string
|
|
||||||
var endpointip net.IP
|
|
||||||
if endpointarr = strings.Split(endpointstring, ":"); len(endpointarr) != 2 {
|
|
||||||
logger.Log(0, "error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointstring)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if endpointip = net.ParseIP(endpointarr[0]); endpointip == nil {
|
|
||||||
logger.Log(0, "error parsing peer "+pubkeystring+", could not parse endpoint: "+endpointarr[0])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var port int
|
|
||||||
if port, err = strconv.Atoi(endpointarr[1]); err != nil {
|
|
||||||
logger.Log(0, "error parsing peer "+pubkeystring+", could not parse port: "+err.Error())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var endpoint = net.UDPAddr{
|
|
||||||
IP: endpointip,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
var dur time.Duration
|
|
||||||
if pkeepalivestring != "" {
|
|
||||||
if dur, err = time.ParseDuration(pkeepalivestring + "s"); err != nil {
|
|
||||||
logger.Log(0, "error parsing peer "+pubkeystring+", could not parse keepalive: "+err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
peers = append(peers, wgtypes.Peer{
|
|
||||||
PublicKey: pubkey,
|
|
||||||
Endpoint: &endpoint,
|
|
||||||
AllowedIPs: allowedIPs,
|
|
||||||
PersistentKeepaliveInterval: dur,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return peers, err
|
|
||||||
}
|
|
@@ -1,46 +0,0 @@
|
|||||||
package ncutils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PIDFILE - path/name of pid file
|
|
||||||
const PIDFILE = "/var/run/netclient.pid"
|
|
||||||
|
|
||||||
// WindowsPIDError - error returned from pid function on windows
|
|
||||||
type WindowsPIDError struct{}
|
|
||||||
|
|
||||||
// Error generates error for windows os
|
|
||||||
func (*WindowsPIDError) Error() string {
|
|
||||||
return "pid tracking not supported on windows"
|
|
||||||
}
|
|
||||||
|
|
||||||
// SavePID - saves the pid of running program to disk
|
|
||||||
func SavePID() error {
|
|
||||||
if IsWindows() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
pid := os.Getpid()
|
|
||||||
if err := os.WriteFile(PIDFILE, []byte(fmt.Sprintf("%d", pid)), 0644); err != nil {
|
|
||||||
return fmt.Errorf("could not write to pid file %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadPID - reads a previously saved pid from disk
|
|
||||||
func ReadPID() (int, error) {
|
|
||||||
if IsWindows() {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
bytes, err := os.ReadFile(PIDFILE)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("could not read pid file %w", err)
|
|
||||||
}
|
|
||||||
pid, err := strconv.Atoi(string(bytes))
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("pid file contents invalid %w", err)
|
|
||||||
}
|
|
||||||
return pid, nil
|
|
||||||
}
|
|
@@ -1,29 +1,4 @@
|
|||||||
package ncutils
|
package ncutils
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CheckInInterval - the interval for check-in time in units/minute
|
// CheckInInterval - the interval for check-in time in units/minute
|
||||||
const CheckInInterval = 1
|
const CheckInInterval = 1
|
||||||
|
|
||||||
// BackOff - back off any function while there is an error
|
|
||||||
func BackOff(isExponential bool, maxTime int, f interface{}) (interface{}, error) {
|
|
||||||
// maxTime seconds
|
|
||||||
startTime := time.Now()
|
|
||||||
sleepTime := time.Second
|
|
||||||
for time.Now().Before(startTime.Add(time.Second * time.Duration(maxTime))) {
|
|
||||||
if result, err := f.(func() (interface{}, error))(); err == nil {
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
time.Sleep(sleepTime)
|
|
||||||
if isExponential {
|
|
||||||
sleepTime = sleepTime << 1
|
|
||||||
}
|
|
||||||
logger.Log(1, "retrying...")
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("could not find result")
|
|
||||||
}
|
|
||||||
|
Binary file not shown.
@@ -273,9 +273,6 @@ definitions:
|
|||||||
isipv6:
|
isipv6:
|
||||||
type: string
|
type: string
|
||||||
x-go-name: IsIPv6
|
x-go-name: IsIPv6
|
||||||
islocal:
|
|
||||||
type: string
|
|
||||||
x-go-name: IsLocal
|
|
||||||
ispointtosite:
|
ispointtosite:
|
||||||
type: string
|
type: string
|
||||||
x-go-name: IsPointToSite
|
x-go-name: IsPointToSite
|
||||||
@@ -375,9 +372,6 @@ definitions:
|
|||||||
isk8s:
|
isk8s:
|
||||||
type: string
|
type: string
|
||||||
x-go-name: IsK8S
|
x-go-name: IsK8S
|
||||||
islocal:
|
|
||||||
type: string
|
|
||||||
x-go-name: IsLocal
|
|
||||||
ispending:
|
ispending:
|
||||||
type: string
|
type: string
|
||||||
x-go-name: IsPending
|
x-go-name: IsPending
|
||||||
|
Reference in New Issue
Block a user