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