Browse Source

Merge branch 'develop' into feature_v0.14.8_internet_gateway

Matthew R Kasun 3 years ago
parent
commit
65723e23dd

+ 2 - 1
controllers/config/dnsconfig/netmaker.hosts

@@ -1 +1,2 @@
-10.0.0.2         testnode.skynet myhost.skynet
+10.0.0.1         testnode.skynet
+10.0.0.2         myhost.skynet

+ 130 - 26
logic/gateway.go

@@ -3,6 +3,7 @@ package logic
 import (
 	"encoding/json"
 	"errors"
+	"fmt"
 	"strings"
 	"time"
 
@@ -30,17 +31,25 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	node.IsEgressGateway = "yes"
 	node.EgressGatewayRanges = gateway.Ranges
 	node.EgressGatewayNatEnabled = gateway.NatEnabled
+	node.EgressGatewayRequest = gateway // store entire request for use when preserving the egress gateway
 	postUpCmd := ""
 	postDownCmd := ""
+	logger.Log(3, "creating egress gateway firewall in use is '", node.FirewallInUse, "'")
 	if node.OS == "linux" {
-		postUpCmd = "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; "
-		postUpCmd += "iptables -A FORWARD -o " + node.Interface + " -j ACCEPT"
-		postDownCmd = "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; "
-		postDownCmd += "iptables -D FORWARD -o " + node.Interface + " -j ACCEPT"
-
-		if node.EgressGatewayNatEnabled == "yes" {
-			postUpCmd += "; iptables -t nat -A POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
-			postDownCmd += "; iptables -t nat -D POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
+		switch node.FirewallInUse {
+		case models.FIREWALL_NFTABLES:
+			// nftables only supported on Linux
+			// assumes chains eg FORWARD and POSTROUTING already exist
+			logger.Log(3, "creating egress gateway nftables is present")
+			// down commands don't remove as removal of the rules leaves an empty chain while
+			// removing the chain with rules in it would remove all rules in that section (not safe
+			// if there are remaining rules on the host that need to stay).  In practice the chain is removed
+			// when non-empty even though the removal of a non-empty chain should not be possible per nftables wiki.
+			postUpCmd, postDownCmd = firewallNFTCommandsCreateEgress(node.Interface, gateway.Interface, node.EgressGatewayNatEnabled)
+
+		default: // iptables assumed
+			logger.Log(3, "creating egress gateway nftables is not present")
+			postUpCmd, postDownCmd = firewallIPTablesCommandsCreateEgress(node.Interface, gateway.Interface, node.EgressGatewayNatEnabled)
 		}
 	}
 	if node.OS == "freebsd" {
@@ -115,23 +124,27 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
 
 	node.IsEgressGateway = "no"
 	node.EgressGatewayRanges = []string{}
+	node.EgressGatewayRequest = models.EgressGatewayRequest{} // remove preserved request as the egress gateway is gone
+	// needed in case we don't preserve a gateway (i.e., no ingress to preserve)
 	node.PostUp = ""
 	node.PostDown = ""
+
+	logger.Log(3, "deleting egress gateway firewall in use is '", node.FirewallInUse, "'")
 	if node.IsIngressGateway == "yes" { // check if node is still an ingress gateway before completely deleting postdown/up rules
+		// still have an ingress gateway so preserve it
 		if node.OS == "linux" {
-			node.PostUp = "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT ; "
-			node.PostUp += "iptables -A FORWARD -o " + node.Interface + " -j ACCEPT ; "
-			node.PostUp += "iptables -t nat -A POSTROUTING -o " + node.Interface + " -j MASQUERADE"
-			node.PostDown = "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT ; "
-			node.PostDown += "iptables -D FORWARD -o " + node.Interface + " -j ACCEPT ; "
-			node.PostDown += "iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE"
-		}
-		if node.OS == "freebsd" {
-			node.PostUp = ""
-			node.PostDown = "ipfw delete 64000 ; "
-			node.PostDown += "ipfw delete 65534 ; "
-			node.PostDown += "kldunload ipfw_nat ipfw"
+			switch node.FirewallInUse {
+			case models.FIREWALL_NFTABLES:
+				// nftables only supported on Linux
+				// assumes chains eg FORWARD and POSTROUTING already exist
+				logger.Log(3, "deleting egress gateway nftables is present")
+				node.PostUp, node.PostDown = firewallNFTCommandsCreateIngress(node.Interface)
+			default:
+				logger.Log(3, "deleting egress gateway nftables is not present")
+				node.PostUp, node.PostDown = firewallIPTablesCommandsCreateIngress(node.Interface)
+			}
 		}
+		// no need to preserve ingress gateway on FreeBSD as ingress is not supported on that OS
 	}
 	node.SetLastModified()
 
@@ -151,6 +164,7 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
 // CreateIngressGateway - creates an ingress gateway
 func CreateIngressGateway(netid string, nodeid string) (models.Node, error) {
 
+	var postUpCmd, postDownCmd string
 	node, err := GetNodeByID(nodeid)
 	if node.OS != "linux" { // add in darwin later
 		return models.Node{}, errors.New(node.OS + " is unsupported for ingress gateways")
@@ -166,12 +180,18 @@ func CreateIngressGateway(netid string, nodeid string) (models.Node, error) {
 	}
 	node.IsIngressGateway = "yes"
 	node.IngressGatewayRange = network.AddressRange
-	postUpCmd := "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT ; "
-	postUpCmd += "iptables -A FORWARD -o " + node.Interface + " -j ACCEPT ; "
-	postUpCmd += "iptables -t nat -A POSTROUTING -o " + node.Interface + " -j MASQUERADE"
-	postDownCmd := "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT ; "
-	postDownCmd += "iptables -D FORWARD -o " + node.Interface + " -j ACCEPT ; "
-	postDownCmd += "iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE"
+	logger.Log(3, "creating ingress gateway firewall in use is '", node.FirewallInUse, "'")
+	switch node.FirewallInUse {
+	case models.FIREWALL_NFTABLES:
+		// nftables only supported on Linux
+		// assumes chains eg FORWARD and POSTROUTING already exist
+		logger.Log(3, "creating ingress gateway nftables is present")
+		postUpCmd, postDownCmd = firewallNFTCommandsCreateIngress(node.Interface)
+	default:
+		logger.Log(3, "creating ingress gateway using nftables is not present")
+		postUpCmd, postDownCmd = firewallIPTablesCommandsCreateIngress(node.Interface)
+	}
+
 	if node.PostUp != "" {
 		if !strings.Contains(node.PostUp, postUpCmd) {
 			postUpCmd = node.PostUp + "; " + postUpCmd
@@ -214,12 +234,26 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, error
 	if err = DeleteGatewayExtClients(node.ID, networkName); err != nil {
 		return models.Node{}, err
 	}
+	logger.Log(3, "deleting ingress gateway")
 
 	node.UDPHolePunch = network.DefaultUDPHolePunch
 	node.LastModified = time.Now().Unix()
 	node.IsIngressGateway = "no"
 	node.IngressGatewayRange = ""
 
+	// default to removing postup and postdown
+	node.PostUp = ""
+	node.PostDown = ""
+
+	logger.Log(3, "deleting ingress gateway firewall in use is '", node.FirewallInUse, "' and isEgressGateway is", node.IsEgressGateway)
+	if node.EgressGatewayRequest.NodeID != "" {
+		_, err := CreateEgressGateway(node.EgressGatewayRequest)
+		if err != nil {
+			logger.Log(0, fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
+				node.EgressGatewayRequest.NodeID, node.EgressGatewayRequest.NetID, err))
+		}
+	}
+
 	data, err := json.Marshal(&node)
 	if err != nil {
 		return models.Node{}, err
@@ -248,3 +282,73 @@ func DeleteGatewayExtClients(gatewayID string, networkName string) error {
 	}
 	return nil
 }
+
+// firewallNFTCommandsCreateIngress - used to centralize firewall command maintenance for creating an ingress gateway using the nftables firewall.
+func firewallNFTCommandsCreateIngress(networkInterface string) (string, string) {
+	postUp := "nft add table ip filter ; "
+	postUp += "nft add chain ip filter FORWARD ; "
+	postUp += "nft add rule ip filter FORWARD iifname " + networkInterface + " counter accept ; "
+	postUp += "nft add rule ip filter FORWARD oifname " + networkInterface + " counter accept ; "
+	postUp += "nft add table nat ; "
+	postUp += "nft add chain nat POSTROUTING ; "
+	postUp += "nft add rule ip nat POSTROUTING oifname " + networkInterface + " counter masquerade"
+
+	// doesn't remove potentially empty tables or chains
+	postDown := "nft delete rule ip filter FORWARD iifname " + networkInterface + " counter accept ; "
+	postDown += "nft delete rule ip filter FORWARD oifname " + networkInterface + " counter accept ; "
+	postDown += "nft delete rule ip nat POSTROUTING oifname " + networkInterface + " counter masquerade"
+
+	return postUp, postDown
+}
+
+// firewallNFTCommandsCreateEgress - used to centralize firewall command maintenance for creating an egress gateway using the nftables firewall.
+func firewallNFTCommandsCreateEgress(networkInterface string, gatewayInterface string, egressNatEnabled string) (string, string) {
+	postUp := "nft add table ip filter ; "
+	postUp += "nft add chain ip filter FORWARD ; "
+	postUp += "nft add rule ip filter FORWARD iifname " + networkInterface + " counter accept ; "
+	postUp += "nft add rule ip filter FORWARD oifname " + networkInterface + " counter accept ; "
+
+	postDown := "nft delete rule ip filter FORWARD iifname " + networkInterface + " counter accept ; "
+	postDown += "nft delete rule ip filter FORWARD oifname " + networkInterface + " counter accept ; "
+
+	if egressNatEnabled == "yes" {
+		postUp += "nft add table nat ; "
+		postUp += "nft add chain nat POSTROUTING ; "
+		postUp += "nft add rule ip nat POSTROUTING oifname " + gatewayInterface + " counter masquerade ;"
+
+		postDown += "nft delete rule ip nat POSTROUTING oifname " + gatewayInterface + " counter masquerade ;"
+	}
+
+	return postUp, postDown
+}
+
+// firewallIPTablesCommandsCreateIngress - used to centralize firewall command maintenance for creating an ingress gateway using the iptables firewall.
+func firewallIPTablesCommandsCreateIngress(networkInterface string) (string, string) {
+	postUp := "iptables -A FORWARD -i " + networkInterface + " -j ACCEPT ; "
+	postUp += "iptables -A FORWARD -o " + networkInterface + " -j ACCEPT ; "
+	postUp += "iptables -t nat -A POSTROUTING -o " + networkInterface + " -j MASQUERADE"
+
+	// doesn't remove potentially empty tables or chains
+	postDown := "iptables -D FORWARD -i " + networkInterface + " -j ACCEPT ; "
+	postDown += "iptables -D FORWARD -o " + networkInterface + " -j ACCEPT ; "
+	postDown += "iptables -t nat -D POSTROUTING -o " + networkInterface + " -j MASQUERADE"
+
+	return postUp, postDown
+}
+
+// firewallIPTablesCommandsCreateEgress - used to centralize firewall command maintenance for creating an egress gateway using the iptables firewall.
+func firewallIPTablesCommandsCreateEgress(networkInterface string, gatewayInterface string, egressNatEnabled string) (string, string) {
+
+	postUp := "iptables -A FORWARD -i " + networkInterface + " -j ACCEPT; "
+	postUp += "iptables -A FORWARD -o " + networkInterface + " -j ACCEPT"
+	postDown := "iptables -D FORWARD -i " + networkInterface + " -j ACCEPT; "
+	postDown += "iptables -D FORWARD -o " + networkInterface + " -j ACCEPT"
+
+	if egressNatEnabled == "yes" {
+		postUp += "; iptables -t nat -A POSTROUTING -o " + gatewayInterface + " -j MASQUERADE"
+		postDown += "; iptables -t nat -D POSTROUTING -o " + gatewayInterface + " -j MASQUERADE"
+	}
+
+	return postUp, postDown
+
+}

+ 1 - 0
logic/nodes.go

@@ -427,6 +427,7 @@ func SetNodeDefaults(node *models.Node) {
 	node.SetDefaultIngressGateway()
 	node.SetDefaulIsPending()
 	node.SetDefaultMTU()
+	node.SetDefaultNFTablesPresent()
 	node.SetDefaultIsRelayed()
 	node.SetDefaultIsRelay()
 	node.SetDefaultIsDocker()

+ 49 - 36
models/node.go

@@ -28,6 +28,10 @@ const (
 	NODE_NOOP = "noop"
 	// NODE_FORCE_UPDATE - indicates a node should pull all changes
 	NODE_FORCE_UPDATE = "force"
+	// FIREWALL_IPTABLES - indicates that iptables is the firewall in use
+	FIREWALL_IPTABLES = "iptables"
+	// FIREWALL_NFTABLES - indicates nftables is in use (Linux only)
+	FIREWALL_NFTABLES = "nftables"
 )
 
 var seededRand *rand.Rand = rand.New(
@@ -35,41 +39,42 @@ var seededRand *rand.Rand = rand.New(
 
 // Node - struct for node model
 type Node struct {
-	ID                      string   `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5" validate:"id_unique`
-	Address                 string   `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
-	Address6                string   `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
-	LocalAddress            string   `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
-	Name                    string   `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"`
-	NetworkSettings         Network  `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
-	ListenPort              int32    `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
-	LocalListenPort         int32    `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"`
-	PublicKey               string   `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
-	Endpoint                string   `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
-	PostUp                  string   `json:"postup" bson:"postup" yaml:"postup"`
-	PostDown                string   `json:"postdown" bson:"postdown" yaml:"postdown"`
-	AllowedIPs              []string `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
-	PersistentKeepalive     int32    `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
-	IsHub                   string   `json:"ishub" bson:"ishub" yaml:"ishub" validate:"checkyesorno"`
-	AccessKey               string   `json:"accesskey" bson:"accesskey" yaml:"accesskey"`
-	Interface               string   `json:"interface" bson:"interface" yaml:"interface"`
-	LastModified            int64    `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"`
-	ExpirationDateTime      int64    `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
-	LastPeerUpdate          int64    `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
-	LastCheckIn             int64    `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
-	MacAddress              string   `json:"macaddress" bson:"macaddress" yaml:"macaddress"`
-	Password                string   `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`
-	Network                 string   `json:"network" bson:"network" yaml:"network" validate:"network_exists"`
-	IsRelayed               string   `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
-	IsPending               string   `json:"ispending" bson:"ispending" yaml:"ispending"`
-	IsRelay                 string   `json:"isrelay" bson:"isrelay" yaml:"isrelay" validate:"checkyesorno"`
-	IsDocker                string   `json:"isdocker" bson:"isdocker" yaml:"isdocker" validate:"checkyesorno"`
-	IsK8S                   string   `json:"isk8s" bson:"isk8s" yaml:"isk8s" validate:"checkyesorno"`
-	IsEgressGateway         string   `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway"`
-	IsIngressGateway        string   `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway"`
-	EgressGatewayRanges     []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
-	EgressGatewayNatEnabled string   `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"`
-	RelayAddrs              []string `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"`
-	IngressGatewayRange     string   `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
+	ID                      string               `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5" validate:"id_unique`
+	Address                 string               `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
+	Address6                string               `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
+	LocalAddress            string               `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"`
+	Name                    string               `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"`
+	NetworkSettings         Network              `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
+	ListenPort              int32                `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
+	LocalListenPort         int32                `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"`
+	PublicKey               string               `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
+	Endpoint                string               `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
+	PostUp                  string               `json:"postup" bson:"postup" yaml:"postup"`
+	PostDown                string               `json:"postdown" bson:"postdown" yaml:"postdown"`
+	AllowedIPs              []string             `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
+	PersistentKeepalive     int32                `json:"persistentkeepalive" bson:"persistentkeepalive" yaml:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
+	IsHub                   string               `json:"ishub" bson:"ishub" yaml:"ishub" validate:"checkyesorno"`
+	AccessKey               string               `json:"accesskey" bson:"accesskey" yaml:"accesskey"`
+	Interface               string               `json:"interface" bson:"interface" yaml:"interface"`
+	LastModified            int64                `json:"lastmodified" bson:"lastmodified" yaml:"lastmodified"`
+	ExpirationDateTime      int64                `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
+	LastPeerUpdate          int64                `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
+	LastCheckIn             int64                `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
+	MacAddress              string               `json:"macaddress" bson:"macaddress" yaml:"macaddress"`
+	Password                string               `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`
+	Network                 string               `json:"network" bson:"network" yaml:"network" validate:"network_exists"`
+	IsRelayed               string               `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
+	IsPending               string               `json:"ispending" bson:"ispending" yaml:"ispending"`
+	IsRelay                 string               `json:"isrelay" bson:"isrelay" yaml:"isrelay" validate:"checkyesorno"`
+	IsDocker                string               `json:"isdocker" bson:"isdocker" yaml:"isdocker" validate:"checkyesorno"`
+	IsK8S                   string               `json:"isk8s" bson:"isk8s" yaml:"isk8s" validate:"checkyesorno"`
+	IsEgressGateway         string               `json:"isegressgateway" bson:"isegressgateway" yaml:"isegressgateway"`
+	IsIngressGateway        string               `json:"isingressgateway" bson:"isingressgateway" yaml:"isingressgateway"`
+	EgressGatewayRanges     []string             `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
+	EgressGatewayNatEnabled string               `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"`
+	EgressGatewayRequest    EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"`
+	RelayAddrs              []string             `json:"relayaddrs" bson:"relayaddrs" yaml:"relayaddrs"`
+	IngressGatewayRange     string               `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
 	// IsStatic - refers to if the Endpoint is set manually or dynamically
 	IsStatic        string      `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"`
 	UDPHolePunch    string      `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
@@ -84,6 +89,7 @@ type Node struct {
 	Version         string      `json:"version" bson:"version" yaml:"version"`
 	Server          string      `json:"server" bson:"server" yaml:"server"`
 	TrafficKeys     TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
+  FirewallInUse string      `json:"firewallinuse" bson:"firewallinuse" yaml:"firewallinuse"`
 	InternetGateway string      `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"`
 }
 
@@ -120,6 +126,13 @@ func (node *Node) SetDefaultMTU() {
 	}
 }
 
+// Node.SetDefaultNFTablesPresent - sets default for nftables check
+func (node *Node) SetDefaultNFTablesPresent() {
+	if node.FirewallInUse == "" {
+		node.FirewallInUse = FIREWALL_IPTABLES // default to iptables
+	}
+}
+
 // Node.SetDefaulIsPending - sets ispending default
 func (node *Node) SetDefaulIsPending() {
 	if node.IsPending == "" {
@@ -255,7 +268,7 @@ func (node *Node) SetDefaultName() {
 }
 
 // Node.Fill - fills other node data into calling node data if not set on calling node
-func (newNode *Node) Fill(currentNode *Node) {
+func (newNode *Node) Fill(currentNode *Node) { // TODO add new field for nftables present
 	newNode.ID = currentNode.ID
 
 	if newNode.Address == "" {

+ 10 - 0
netclient/functions/join.go

@@ -114,7 +114,17 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
 
 	if ncutils.IsFreeBSD() {
 		cfg.Node.UDPHolePunch = "no"
+		cfg.Node.FirewallInUse = models.FIREWALL_IPTABLES // nftables not supported by FreeBSD
 	}
+
+	if cfg.Node.FirewallInUse == "" {
+		if ncutils.IsNFTablesPresent() {
+			cfg.Node.FirewallInUse = models.FIREWALL_NFTABLES
+		} else {
+			cfg.Node.FirewallInUse = models.FIREWALL_IPTABLES
+		}
+	}
+
 	// make sure name is appropriate, if not, give blank name
 	cfg.Node.Name = formatName(cfg.Node)
 	cfg.Node.OS = runtime.GOOS

+ 12 - 0
netclient/functions/mqpublish.go

@@ -13,6 +13,7 @@ import (
 
 	"github.com/cloverstd/tcping/ping"
 	"github.com/gravitl/netmaker/logger"
+	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/netclient/auth"
 	"github.com/gravitl/netmaker/netclient/config"
 	"github.com/gravitl/netmaker/netclient/ncutils"
@@ -43,6 +44,17 @@ func checkin() {
 		var nodeCfg config.ClientConfig
 		nodeCfg.Network = network
 		nodeCfg.ReadConfig()
+		// check for nftables present if on Linux
+		if ncutils.IsLinux() {
+			if ncutils.IsNFTablesPresent() {
+				nodeCfg.Node.FirewallInUse = models.FIREWALL_NFTABLES
+			} else {
+				nodeCfg.Node.FirewallInUse = models.FIREWALL_IPTABLES
+			}
+		} else {
+			// defaults to iptables for now, may need another default for non-Linux OSes
+			nodeCfg.Node.FirewallInUse = models.FIREWALL_IPTABLES
+		}
 		if nodeCfg.Node.IsStatic != "yes" {
 			extIP, err := ncutils.GetPublicIP()
 			if err != nil {

+ 10 - 0
netclient/ncutils/netclientutils.go

@@ -110,6 +110,16 @@ func GetWireGuard() string {
 	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 {
+	var nftFound bool
+
+	nftFound = FileExists("/usr/sbin/nft")
+	logger.Log(3, "nftables found:", strconv.FormatBool(nftFound))
+	return nftFound
+}
+
 // IsKernel - checks if running kernel WireGuard
 func IsKernel() bool {
 	//TODO

+ 0 - 35
scripts/netmaker-server.sh

@@ -1,35 +0,0 @@
-#!/bin/sh
-set -e
-
-mkdir -p /etc/netmaker/config/environments
-wget -O /etc/netmaker/netmaker https://github.com/gravitl/netmaker/releases/download/latest/netmaker
-chmod +x /etc/netmaker/netmaker
-
-cat >/etc/netmaker/config/environments/dev.yaml<<EOL
-server:
-  host:
-  apiport: "8081"
-  masterkey: "secretkey"
-  allowedorigin: "*"
-  restbackend: true            
-  agentbackend: true
-  dnsmode: "on"
-EOL
-
-cat >/etc/systemd/system/netmaker.service<<EOL
-[Unit]
-Description=Netmaker Server
-After=network.target
-
-[Service]
-Type=simple
-Restart=on-failure
-
-WorkingDirectory=/etc/netmaker
-ExecStart=/etc/netmaker/netmaker
-
-[Install]
-WantedBy=multi-user.target
-EOL
-systemctl daemon-reload
-systemctl start netmaker.service