Browse Source

Add netclient detection of nftables.

cameronts 3 years ago
parent
commit
e6d7c95669
6 changed files with 46 additions and 27 deletions
  1. 3 3
      logic/gateway.go
  2. 1 0
      logic/nodes.go
  3. 0 10
      logic/util.go
  4. 22 14
      models/node.go
  5. 10 0
      netclient/functions/join.go
  6. 10 0
      netclient/ncutils/netclientutils.go

+ 3 - 3
logic/gateway.go

@@ -34,7 +34,7 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	postDownCmd := ""
 	if node.OS == "linux" {
 		// nftables only supported on Linux
-		if IsNFTablesPresent() {
+		if node.IsNFTablesPresent == "yes" {
 			// assumes chains eg FORWARD and POSTROUTING already exist
 			logger.Log(3, "creating egress gateway using nftables")
 			postUpCmd = "nft add rule ip filter FORWARD iifname " + node.Interface + " counter accept ; "
@@ -136,7 +136,7 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
 	if node.IsIngressGateway == "yes" { // check if node is still an ingress gateway before completely deleting postdown/up rules
 		if node.OS == "linux" {
 			// nftables only supported on Linux
-			if IsNFTablesPresent() {
+			if node.IsNFTablesPresent == "yes" {
 				// assumes chains eg FORWARD and POSTROUTING already exist
 				logger.Log(3, "deleting egress gateway using nftables")
 				node.PostUp = "nft add rule ip filter FORWARD iifname " + node.Interface + " counter accept ; "
@@ -196,7 +196,7 @@ func CreateIngressGateway(netid string, nodeid string) (models.Node, error) {
 	}
 	node.IsIngressGateway = "yes"
 	node.IngressGatewayRange = network.AddressRange
-	if IsNFTablesPresent() {
+	if node.IsNFTablesPresent == "yes" {
 		// assumes chains eg FORWARD and POSTROUTING already exist
 		logger.Log(3, "creating ingress gateway using nftables")
 		postUpCmd = "nft add rule ip filter FORWARD iifname " + node.Interface + " counter accept ; "

+ 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()

+ 0 - 10
logic/util.go

@@ -14,20 +14,10 @@ import (
 	"math/rand"
 	"net"
 	"os"
-	"strconv"
 	"strings"
 	"time"
 )
 
-// nfTablesPresent - returns true if nftables is present, false otherwise
-func IsNFTablesPresent() bool {
-	var nftFound bool
-
-	nftFound = FileExists("/etc/nftables.conf")
-	logger.Log(3, "nftables found:", strconv.FormatBool(nftFound))
-	return nftFound
-}
-
 // IsBase64 - checks if a string is in base64 format
 // This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
 func IsBase64(s string) bool {

+ 22 - 14
models/node.go

@@ -71,19 +71,20 @@ type Node struct {
 	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"`
-	DNSOn        string      `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
-	IsServer     string      `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
-	Action       string      `json:"action" bson:"action" yaml:"action"`
-	IsLocal      string      `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
-	LocalRange   string      `json:"localrange" bson:"localrange" yaml:"localrange"`
-	IPForwarding string      `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
-	OS           string      `json:"os" bson:"os" yaml:"os"`
-	MTU          int32       `json:"mtu" bson:"mtu" yaml:"mtu"`
-	Version      string      `json:"version" bson:"version" yaml:"version"`
-	Server       string      `json:"server" bson:"server" yaml:"server"`
-	TrafficKeys  TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
+	IsStatic          string      `json:"isstatic" bson:"isstatic" yaml:"isstatic" validate:"checkyesorno"`
+	UDPHolePunch      string      `json:"udpholepunch" bson:"udpholepunch" yaml:"udpholepunch" validate:"checkyesorno"`
+	DNSOn             string      `json:"dnson" bson:"dnson" yaml:"dnson" validate:"checkyesorno"`
+	IsServer          string      `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
+	Action            string      `json:"action" bson:"action" yaml:"action"`
+	IsLocal           string      `json:"islocal" bson:"islocal" yaml:"islocal" validate:"checkyesorno"`
+	LocalRange        string      `json:"localrange" bson:"localrange" yaml:"localrange"`
+	IPForwarding      string      `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"`
+	OS                string      `json:"os" bson:"os" yaml:"os"`
+	MTU               int32       `json:"mtu" bson:"mtu" yaml:"mtu"`
+	Version           string      `json:"version" bson:"version" yaml:"version"`
+	Server            string      `json:"server" bson:"server" yaml:"server"`
+	TrafficKeys       TrafficKeys `json:"traffickeys" bson:"traffickeys" yaml:"traffickeys"`
+	IsNFTablesPresent string      `json:"isnftablespresent" bson:"isnftablespresent" yaml:"isnftablespresent"`
 }
 
 // NodesArray - used for node sorting
@@ -119,6 +120,13 @@ func (node *Node) SetDefaultMTU() {
 	}
 }
 
+// Node.SetDefaultNFTablesPresent - sets default for nftables check
+func (node *Node) SetDefaultNFTablesPresent() {
+	if node.IsNFTablesPresent == "" {
+		node.IsNFTablesPresent = "no"
+	}
+}
+
 // Node.SetDefaulIsPending - sets ispending default
 func (node *Node) SetDefaulIsPending() {
 	if node.IsPending == "" {
@@ -254,7 +262,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.IsNFTablesPresent = "no" // nftables not supported by FreeBSD
 	}
+
+	if cfg.Node.IsNFTablesPresent == "" {
+		if ncutils.IsNFTablesPresent() {
+			cfg.Node.IsNFTablesPresent = "yes"
+		} else {
+			cfg.Node.IsNFTablesPresent = "no"
+		}
+	}
+
 	// make sure name is appropriate, if not, give blank name
 	cfg.Node.Name = formatName(cfg.Node)
 	cfg.Node.OS = runtime.GOOS

+ 10 - 0
netclient/ncutils/netclientutils.go

@@ -109,6 +109,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("/etc/nftables.conf")
+	logger.Log(3, "nftables found:", strconv.FormatBool(nftFound))
+	return nftFound
+}
+
 // IsKernel - checks if running kernel WireGuard
 func IsKernel() bool {
 	//TODO