Compare commits

...

2 Commits

4 changed files with 150 additions and 0 deletions

30
family_type.go Normal file
View File

@@ -0,0 +1,30 @@
package nft
import "fmt"
type FamilyType int8
const (
IP FamilyType = iota + 1
IP6
INET
ARP
BRIDGE
)
func (f FamilyType) String() string {
switch f {
case IP:
return "ip"
case IP6:
return "ip6"
case INET:
return "inet"
case ARP:
return "arp"
case BRIDGE:
return "bridge"
default:
return fmt.Sprintf("Encoding(%d)", f)
}
}

3
go.mod Normal file
View File

@@ -0,0 +1,3 @@
module git.kor-elf.net/kor-elf-shield/go-nftables-client
go 1.25

53
nft.go Normal file
View File

@@ -0,0 +1,53 @@
package nft
import (
"errors"
)
// NFT A client for working with nftables
type NFT interface {
// Clear clears all rules.
Clear() error
// AddTable adds a new table.
AddTable(family FamilyType, name string) error
}
type nft struct {
path string
}
// New Returns a client for working with nftables.
// Searches for nft in paths: nft, /usr/sbin/nft, /sbin/nft
func New() (NFT, error) {
paths := []string{"nft", "/usr/sbin/nft", "/sbin/nft"}
for _, path := range paths {
nftClient, err := NewWithPath(path)
if err == nil {
return nftClient, nil
}
}
return nil, errors.New("nft not found")
}
// NewWithPath Returns the client for working with nftables with its path specified.
func NewWithPath(path string) (NFT, error) {
if err := checkingNFT(path); err != nil {
return nil, err
}
return &nft{
path: path,
}, nil
}
func (n *nft) Clear() error {
args := []string{"flush", "ruleset"}
return executeCommand(n.path, args...)
}
func (n *nft) AddTable(family FamilyType, name string) error {
args := []string{"add", "table", family.String(), name}
return executeCommand(n.path, args...)
}

64
utils.go Normal file
View File

@@ -0,0 +1,64 @@
package nft
import (
"errors"
"fmt"
"os/exec"
"regexp"
"strings"
)
func executeCommand(name string, arg ...string) error {
cmd := exec.Command(name, arg...)
out, err := cmd.CombinedOutput()
if err != nil {
if len(out) > 0 {
return errors.New(string(out))
}
return err
}
return nil
}
func checkingNFT(path string) error {
if path == "" {
return errors.New("path is empty")
}
cmd := exec.Command(path, "-V")
out, err := cmd.CombinedOutput()
if err != nil {
return errors.New("nftables not found")
}
lines := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
json := false
for index, line := range lines {
line = strings.TrimSpace(line)
if index == 0 {
if !strings.HasPrefix(line, "nftables") {
return errors.New("nftables not found")
}
continue
}
if strings.HasPrefix(line, "json:") && strings.HasSuffix(line, "yes") {
json = true
}
}
if !json {
return errors.New("nftables disabled json")
}
cmd = exec.Command(path, "list", "ruleset")
out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("nftables is not available or not supported by the kernel: %s", string(out))
}
return nil
}