Skip to content

Commit

Permalink
drop traffic to peers in same lan
Browse files Browse the repository at this point in the history
  • Loading branch information
Omarabdul3ziz committed Jan 8, 2025
1 parent 0f5fe58 commit f94953c
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmds/modules/networkd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/threefoldtech/zos/pkg/environment"
"github.com/threefoldtech/zos/pkg/network/dhcp"
"github.com/threefoldtech/zos/pkg/network/mycelium"
"github.com/threefoldtech/zos/pkg/network/nft"
"github.com/threefoldtech/zos/pkg/network/public"
"github.com/threefoldtech/zos/pkg/network/types"
"github.com/threefoldtech/zos/pkg/zinit"
Expand Down Expand Up @@ -92,6 +93,10 @@ func action(cli *cli.Context) error {
return errors.Wrap(err, "failed to host firewall rules")
}

if err := nft.DropTrafficToLAN(); err != nil {
return fmt.Errorf("failed to drop traffic to lan: %w", err)
}

public.SetPersistence(root)

pub, err := public.LoadPublicConfig()
Expand Down
88 changes: 88 additions & 0 deletions pkg/network/nft/nft.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package nft

import (
"fmt"
"io"
"net"
"os/exec"

"github.com/rs/zerolog/log"
"github.com/vishvananda/netlink"

"github.com/pkg/errors"
)
Expand Down Expand Up @@ -32,3 +35,88 @@ func Apply(r io.Reader, ns string) error {
}
return nil
}

func applyNftRule(rule []string) error {
if len(rule) == 0 {
return errors.New("invalid nft rule")
}
cmd := exec.Command(rule[0], rule[1:]...)

out, err := cmd.CombinedOutput()
if err != nil {
log.Error().Err(err).Str("output", string(out)).Msg("error during nft")
if eerr, ok := err.(*exec.ExitError); ok {
return errors.Wrapf(err, "failed to execute nft: %v", string(eerr.Stderr))
}
return errors.Wrap(err, "failed to execute nft")
}
return nil
}

// DropTrafficToLAN drops all the outgoing traffic to any peers on
// the same lan network, but allow dicovery port for ygg/myc by accepting
// traffic to/from dest/src ports.
func DropTrafficToLAN() error {
rules := [][]string{
// @th,0,16 and @th,16,16 is raw expression for sport/dport in transport header
// used due to limitation on the installed nft v0.9.1
{
"nft", "add", "rule", "inet", "filter", "forward",
"meta", "l4proto", "{tcp, udp}", "@th,0,16", "{9651, 9650}", "accept",
},
{
"nft", "add", "rule", "inet", "filter", "forward",
"meta", "l4proto", "{tcp, udp}", "@th,16,16", "{9651, 9650}", "accept",
},
}
mac, err := getDefaultGwMac()
log.Debug().Str("mac", mac.String()).Err(err).Msg("default gw return")
rules = append(rules, []string{
"nft", "add", "rule", "inet", "filter", "forward",
"ether", "daddr", "!=", mac.String(), "drop",
})

for _, rule := range rules {
if err := applyNftRule(rule); err != nil {
return fmt.Errorf("failed to apply nft rule: %w", err)
}
}

return nil
}

func getDefaultGwMac() (net.HardwareAddr, error) {
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, fmt.Errorf("failed to list routes: %v", err)
}

var defaultRoute *netlink.Route
for _, route := range routes {
if route.Dst == nil {
defaultRoute = &route
break
}
}

if defaultRoute == nil {
return nil, fmt.Errorf("default route not found")
}

if defaultRoute.Gw == nil {
return nil, fmt.Errorf("default route has no gateway")
}

neighs, err := netlink.NeighList(0, netlink.FAMILY_V4)
if err != nil {
return nil, fmt.Errorf("failed to list neighbors: %v", err)
}

for _, neigh := range neighs {
if neigh.IP.Equal(defaultRoute.Gw) {
return neigh.HardwareAddr, nil
}
}

return nil, errors.New("failed to get default gw")
}

0 comments on commit f94953c

Please sign in to comment.