From defdd1ccb1e3f89687ddfe4a9145519baa3c96d8 Mon Sep 17 00:00:00 2001
From: Omar Abdulaziz <omarabdul3ziz@gmail.com>
Date: Mon, 16 Sep 2024 14:20:13 +0300
Subject: [PATCH 1/2] configure nft to block outgoing traffic and allow to
 certain ips

---
 cmds/modules/netlightd/main.go |  5 +++
 pkg/environment/config.go      |  3 ++
 pkg/netlight/nft/nft.go        | 73 ++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/cmds/modules/netlightd/main.go b/cmds/modules/netlightd/main.go
index 193f27321..309508449 100644
--- a/cmds/modules/netlightd/main.go
+++ b/cmds/modules/netlightd/main.go
@@ -107,6 +107,11 @@ func action(cli *cli.Context) error {
 		return fmt.Errorf("failed to apply host nft rules: %w", err)
 	}
 	rules.Close()
+
+	if err := nft.UpdateNFTWhitelist(); err != nil {
+		return fmt.Errorf("failed to allow whitelist outgoing traffic")
+	}
+
 	bridge, err := netlight.CreateNDMZBridge()
 	if err != nil {
 		return fmt.Errorf("failed to create ndmz bridge: %w", err)
diff --git a/pkg/environment/config.go b/pkg/environment/config.go
index 9a0595ff8..261863ee4 100644
--- a/pkg/environment/config.go
+++ b/pkg/environment/config.go
@@ -27,6 +27,9 @@ type Config struct {
 	Users struct {
 		Authorized []string `json:"authorized"`
 	} `json:"users"`
+	Whitelist struct {
+		Ips []string `json:"ips"`
+	} `json:"whitelist"`
 }
 
 // Merge, updates current config with cfg merging and override config
diff --git a/pkg/netlight/nft/nft.go b/pkg/netlight/nft/nft.go
index e3486aa57..69a39722f 100644
--- a/pkg/netlight/nft/nft.go
+++ b/pkg/netlight/nft/nft.go
@@ -1,10 +1,14 @@
 package nft
 
 import (
+	"fmt"
 	"io"
 	"os/exec"
+	"time"
 
+	"github.com/go-co-op/gocron"
 	"github.com/rs/zerolog/log"
+	"github.com/threefoldtech/zos/pkg/environment"
 
 	"github.com/pkg/errors"
 )
@@ -32,3 +36,72 @@ func Apply(r io.Reader, ns string) error {
 	}
 	return nil
 }
+
+// UpdateNFTWhitelist periodically pull list of ips from config repo and
+// update the nft white list
+func UpdateNFTWhitelist() error {
+	scheduler := gocron.NewScheduler(time.UTC)
+	cron := "0 * * * *"
+
+	updateWhitelist := func() error {
+		ips, err := whiteList()
+		if err != nil {
+			return err
+		}
+
+		cmds := []string{
+			"nft flush chain inet filter output",
+			"nft add rule inet filter output ct state established,related accept",
+			"nft add rule inet filter output tcp dport 22 accept",
+		}
+
+		ipCmdTemplate := "nft add rule inet filter output ip daddr %s accept"
+		blockCmd := "nft add rule inet filter output drop"
+
+		for _, cmd := range cmds {
+			if err := runCommand(cmd); err != nil {
+				return nil
+			}
+		}
+
+		for _, ip := range ips {
+			if err := runCommand(fmt.Sprintf(ipCmdTemplate, ip)); err != nil {
+				return nil
+			}
+		}
+
+		if err := runCommand(blockCmd); err != nil {
+			return nil
+		}
+
+		return nil
+	}
+
+	if err := updateWhitelist(); err != nil {
+		return err
+	}
+
+	if _, err := scheduler.Cron(cron).Do(updateWhitelist); err != nil {
+		return err
+	}
+	scheduler.StartAsync()
+
+	return nil
+}
+
+func runCommand(cmdStr string) error {
+	cmd := exec.Command("sh", "-c", cmdStr)
+	if output, err := cmd.CombinedOutput(); err != nil {
+		return fmt.Errorf("command failed: %s, output: %s", err, output)
+	}
+	return nil
+}
+
+func whiteList() ([]string, error) {
+	cfg, err := environment.GetConfig()
+	if err != nil {
+		return nil, err
+	}
+
+	return cfg.Whitelist.Ips, nil
+}

From 515beadfbf656ee39cf0e667b4357b394e778737 Mon Sep 17 00:00:00 2001
From: Omar Abdulaziz <omarabdul3ziz@gmail.com>
Date: Mon, 16 Sep 2024 15:29:35 +0300
Subject: [PATCH 2/2] provide a kernel param to configure the base repo for
 configurations

---
 cmds/modules/netlightd/main.go |  5 ++++-
 pkg/environment/config.go      | 13 +++++++++++++
 pkg/netlight/nft/nft.go        | 22 ++++++++++++++++------
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/cmds/modules/netlightd/main.go b/cmds/modules/netlightd/main.go
index 309508449..3ef51572f 100644
--- a/cmds/modules/netlightd/main.go
+++ b/cmds/modules/netlightd/main.go
@@ -11,6 +11,7 @@ import (
 
 	"github.com/oasisprotocol/curve25519-voi/primitives/x25519"
 	"github.com/pkg/errors"
+	"github.com/threefoldtech/zos/pkg/kernel"
 	"github.com/threefoldtech/zos/pkg/netlight"
 	"github.com/threefoldtech/zos/pkg/netlight/nft"
 	"github.com/threefoldtech/zos/pkg/netlight/resource"
@@ -68,6 +69,8 @@ func action(cli *cli.Context) error {
 		workerNr uint   = cli.Uint("workers")
 	)
 
+	configFileUrl, _ := kernel.GetParams().GetOne("config-url")
+
 	if err := os.MkdirAll(root, 0755); err != nil {
 		return errors.Wrap(err, "fail to create module root")
 	}
@@ -108,7 +111,7 @@ func action(cli *cli.Context) error {
 	}
 	rules.Close()
 
-	if err := nft.UpdateNFTWhitelist(); err != nil {
+	if err := nft.UpdateNFTWhitelist(configFileUrl); err != nil {
 		return fmt.Errorf("failed to allow whitelist outgoing traffic")
 	}
 
diff --git a/pkg/environment/config.go b/pkg/environment/config.go
index 261863ee4..1640a1ab7 100644
--- a/pkg/environment/config.go
+++ b/pkg/environment/config.go
@@ -58,6 +58,19 @@ func GetConfigForMode(mode RunMode) (Config, error) {
 	return getConfig(mode, baseExtendedURL, httpClient)
 }
 
+func GetConfigForUrl(configRepo string) (Config, error) {
+	env, err := Get()
+	if err != nil {
+		return Config{}, err
+	}
+
+	httpClient := &http.Client{
+		Timeout: defaultHttpTimeout,
+	}
+
+	return getConfig(env.RunningMode, configRepo, httpClient)
+}
+
 func uniqueStr(slice []string) []string {
 	keys := make(map[string]struct{})
 	list := slice[:0]
diff --git a/pkg/netlight/nft/nft.go b/pkg/netlight/nft/nft.go
index 69a39722f..9c6880b36 100644
--- a/pkg/netlight/nft/nft.go
+++ b/pkg/netlight/nft/nft.go
@@ -39,12 +39,12 @@ func Apply(r io.Reader, ns string) error {
 
 // UpdateNFTWhitelist periodically pull list of ips from config repo and
 // update the nft white list
-func UpdateNFTWhitelist() error {
+func UpdateNFTWhitelist(configFileUrl string) error {
 	scheduler := gocron.NewScheduler(time.UTC)
 	cron := "0 * * * *"
 
 	updateWhitelist := func() error {
-		ips, err := whiteList()
+		ips, err := whiteList(configFileUrl)
 		if err != nil {
 			return err
 		}
@@ -97,10 +97,20 @@ func runCommand(cmdStr string) error {
 	return nil
 }
 
-func whiteList() ([]string, error) {
-	cfg, err := environment.GetConfig()
-	if err != nil {
-		return nil, err
+func whiteList(configFileUrl string) ([]string, error) {
+	var cfg environment.Config
+	var err error
+
+	if configFileUrl != "" {
+		cfg, err = environment.GetConfigForUrl(configFileUrl)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		cfg, err = environment.GetConfig()
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	return cfg.Whitelist.Ips, nil