v0.2.0 #3

Merged
kor-elf merged 22 commits from develop into main 2026-04-26 16:50:47 +05:00
12 changed files with 182 additions and 154 deletions
Showing only changes of commit 3c47e7566b - Show all commits
+12
View File
@@ -0,0 +1,12 @@
package contract
// Run is a function that executes nft command.
type Run func(arg ...string) error
type Command interface {
// Run nft command.
Run(arg ...string) error
// RunWithOutput Run nft command with output.
RunWithOutput(arg ...string) (string, error)
}
+31
View File
@@ -0,0 +1,31 @@
package contract
import "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
// NFT A client for working with nftables
type NFT interface {
// Command returns the command used to execute nft.
// You can execute your raw request.
Command() Command
// Clear clears all rules.
//
// This command is equivalent to:
// nft flush ruleset
Clear() error
// Version returns the version of nftables.
//
// This command is equivalent to:
// nft -V
Version() (nft.Version, error)
// Table returns an API for working with tables.
Table() nft.Table
// Chain returns an API for working with chains.
Chain() nft.Chain
// Rule returns an API for working with rules.
Rule() nft.Rule
}
+46
View File
@@ -0,0 +1,46 @@
package nft
import (
chain2 "git.kor-elf.net/kor-elf-shield/go-nftables-client/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
)
// Chain for working with chains.
type Chain interface {
// Add adds a new chain.
//
// This command is equivalent to:
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|prerouting|forward|input|output|postrouting|egress) priority (priority_value = int32) ;}'
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type filter hook (forward|input|output) priority (priority_value = int32) ; policy (accept|drop) ;}'
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|egress) device {device} priority (priority_value = int32) ;}'
Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error
// Create creates a new chain.
// Similar to the Add, but returns an error if the chain already exists.
//
// This command is equivalent to:
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|prerouting|forward|input|output|postrouting|egress) priority (priority_value = int32) ;}'
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type filter hook (forward|input|output) priority (priority_value = int32) ; policy (accept|drop) ;}'
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|egress) device {device} priority (priority_value = int32) ;}'
Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error
// Delete deletes a chain.
//
// This command is equivalent to:
// nft delete chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
Delete(family family.Type, tableName string, chainName string) error
// Clear clears all rules in a chain.
//
// This command is equivalent to:
// nft flush chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
Clear(family family.Type, tableName string, chainName string) error
// Rename renames a chain.
//
// This command is equivalent to:
// nft rename chain (ip|ip6|inet|arp|bridge) {table_name} {old_chain_name} {new_chain_name}
Rename(family family.Type, tableName string, oldChainName string, newChainName string) error
}
+31
View File
@@ -0,0 +1,31 @@
package nft
import "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
// Rule is the interface for rule manipulation.
type Rule interface {
// Add adds a new rule.
//
// This command is equivalent to:
// nft add rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }'
Add(family family.Type, tableName string, chainName string, expr ...string) error
// Insert inserts a new rule.
// Inserted rules are placed at the beginning of the chain, by default.
//
// This command is equivalent to:
// nft insert rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }'
Insert(family family.Type, tableName string, chainName string, expr ...string) error
// Replace replaces a rule.
//
// This command is equivalent to:
// nft replace rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle} '{ expr }'
Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error
// Delete deletes a rule.
//
// This command is equivalent to:
// nft delete rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle}
Delete(family family.Type, tableName string, chainName string, handle uint64) error
}
+24
View File
@@ -0,0 +1,24 @@
package nft
import "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
// Table for working with tables.
type Table interface {
// AddTable adds a new table.
//
// This command is equivalent to:
// nft add table (ip|ip6|inet|arp|bridge) {table_name}
Add(family family.Type, tableName string) error
// DeleteTable deletes a table.
//
// This command is equivalent to:
// nft delete table (ip|ip6|inet|arp|bridge) {table_name}
Delete(family family.Type, tableName string) error
// ClearTable clears all rules in a table.
//
// This command is equivalent to:
// nft flush table (ip|ip6|inet|arp|bridge) {table_name}
Clear(family family.Type, tableName string) error
}
+8
View File
@@ -0,0 +1,8 @@
package nft
type Version interface {
// Version returns the version of the nftables client.
Version() string
// Opts returns the options of the nftables client.
Opts() map[string]string
}
+4 -43
View File
@@ -2,55 +2,16 @@ package chain
import ( import (
chain2 "git.kor-elf.net/kor-elf-shield/go-nftables-client/chain" chain2 "git.kor-elf.net/kor-elf-shield/go-nftables-client/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
) )
// API for working with chains.
type API interface {
// Add adds a new chain.
//
// This command is equivalent to:
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|prerouting|forward|input|output|postrouting|egress) priority (priority_value = int32) ;}'
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type filter hook (forward|input|output) priority (priority_value = int32) ; policy (accept|drop) ;}'
// nft add chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|egress) device {device} priority (priority_value = int32) ;}'
Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error
// Create creates a new chain.
// Similar to the Add, but returns an error if the chain already exists.
//
// This command is equivalent to:
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|prerouting|forward|input|output|postrouting|egress) priority (priority_value = int32) ;}'
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type filter hook (forward|input|output) priority (priority_value = int32) ; policy (accept|drop) ;}'
// nft create chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ type (filter|route|nat) hook (ingress|egress) device {device} priority (priority_value = int32) ;}'
Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error
// Delete deletes a chain.
//
// This command is equivalent to:
// nft delete chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
Delete(family family.Type, tableName string, chainName string) error
// Clear clears all rules in a chain.
//
// This command is equivalent to:
// nft flush chain (ip|ip6|inet|arp|bridge) {table_name} {chain_name}
Clear(family family.Type, tableName string, chainName string) error
// Rename renames a chain.
//
// This command is equivalent to:
// nft rename chain (ip|ip6|inet|arp|bridge) {table_name} {old_chain_name} {new_chain_name}
Rename(family family.Type, tableName string, oldChainName string, newChainName string) error
}
type chain struct { type chain struct {
command command.NFT command contract.Command
} }
func New(command command.NFT) API { func New(command contract.Command) nft.Chain {
return &chain{ return &chain{
command: command, command: command,
} }
+3 -9
View File
@@ -3,21 +3,15 @@ package command
import ( import (
"errors" "errors"
"os/exec" "os/exec"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
) )
type NFT interface {
// Run nft command.
Run(arg ...string) error
// RunWithOutput Run nft command with output.
RunWithOutput(arg ...string) (string, error)
}
type execNFT struct { type execNFT struct {
nftPath string nftPath string
} }
func New(path string) (NFT, error) { func New(path string) (contract.Command, error) {
if err := checkingNFT(path); err != nil { if err := checkingNFT(path); err != nil {
return nil, err return nil, err
} }
+4 -30
View File
@@ -3,42 +3,16 @@ package rule
import ( import (
"strconv" "strconv"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
) )
type API interface {
// Add adds a new rule.
//
// This command is equivalent to:
// nft add rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }'
Add(family family.Type, tableName string, chainName string, expr ...string) error
// Insert inserts a new rule.
// Inserted rules are placed at the beginning of the chain, by default.
//
// This command is equivalent to:
// nft insert rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} '{ expr }'
Insert(family family.Type, tableName string, chainName string, expr ...string) error
// Replace replaces a rule.
//
// This command is equivalent to:
// nft replace rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle} '{ expr }'
Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error
// Delete deletes a rule.
//
// This command is equivalent to:
// nft delete rule (ip|ip6|inet|arp|bridge) {table_name} {chain_name} {handle}
Delete(family family.Type, tableName string, chainName string, handle uint64) error
}
type rule struct { type rule struct {
command command.NFT command contract.Command
} }
func New(command command.NFT) API { func New(command contract.Command) nft.Rule {
return &rule{ return &rule{
command: command, command: command,
} }
+4 -24
View File
@@ -1,36 +1,16 @@
package table package table
import ( import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
) )
// API for working with tables.
type API interface {
// AddTable adds a new table.
//
// This command is equivalent to:
// nft add table (ip|ip6|inet|arp|bridge) {table_name}
Add(family family.Type, tableName string) error
// DeleteTable deletes a table.
//
// This command is equivalent to:
// nft delete table (ip|ip6|inet|arp|bridge) {table_name}
Delete(family family.Type, tableName string) error
// ClearTable clears all rules in a table.
//
// This command is equivalent to:
// nft flush table (ip|ip6|inet|arp|bridge) {table_name}
Clear(family family.Type, tableName string) error
}
type table struct { type table struct {
command command.NFT command contract.Command
} }
func New(command command.NFT) API { func New(command contract.Command) nft.Table {
return &table{ return &table{
command: command, command: command,
} }
+13 -39
View File
@@ -5,50 +5,24 @@ import (
"regexp" "regexp"
"strings" "strings"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
nftContract "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/chain" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/rule" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/rule"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/table" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/table"
) )
// NFT A client for working with nftables
type NFT interface {
// Command returns the command used to execute nft.
// You can execute your raw request.
Command() command.NFT
// Clear clears all rules.
//
// This command is equivalent to:
// nft flush ruleset
Clear() error
// Version returns the version of nftables.
//
// This command is equivalent to:
// nft -V
Version() (Version, error)
// Table returns an API for working with tables.
Table() table.API
// Chain returns an API for working with chains.
Chain() chain.API
// Rule returns an API for working with rules.
Rule() rule.API
}
type nft struct { type nft struct {
command command.NFT command contract.Command
table table.API table nftContract.Table
chain chain.API chain nftContract.Chain
rule rule.API rule nftContract.Rule
} }
// New Returns a client for working with nftables. // New Returns a client for working with nftables.
// Searches for nft in paths: nft, /usr/sbin/nft, /sbin/nft // Searches for nft in paths: nft, /usr/sbin/nft, /sbin/nft
func New() (NFT, error) { func New() (contract.NFT, error) {
paths := []string{"nft", "/usr/sbin/nft", "/sbin/nft"} paths := []string{"nft", "/usr/sbin/nft", "/sbin/nft"}
for _, path := range paths { for _, path := range paths {
nftClient, err := NewWithPath(path) nftClient, err := NewWithPath(path)
@@ -61,7 +35,7 @@ func New() (NFT, error) {
} }
// NewWithPath Returns the client for working with nftables with its path specified. // NewWithPath Returns the client for working with nftables with its path specified.
func NewWithPath(path string) (NFT, error) { func NewWithPath(path string) (contract.NFT, error) {
nftCommand, err := command.New(path) nftCommand, err := command.New(path)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -80,7 +54,7 @@ func (n *nft) Clear() error {
return n.command.Run(args...) return n.command.Run(args...)
} }
func (n *nft) Version() (Version, error) { func (n *nft) Version() (nftContract.Version, error) {
args := []string{"-V"} args := []string{"-V"}
out, err := n.command.RunWithOutput(args...) out, err := n.command.RunWithOutput(args...)
if err != nil { if err != nil {
@@ -114,18 +88,18 @@ func (n *nft) Version() (Version, error) {
}, nil }, nil
} }
func (n *nft) Table() table.API { func (n *nft) Table() nftContract.Table {
return n.table return n.table
} }
func (n *nft) Chain() chain.API { func (n *nft) Chain() nftContract.Chain {
return n.chain return n.chain
} }
func (n *nft) Rule() rule.API { func (n *nft) Rule() nftContract.Rule {
return n.rule return n.rule
} }
func (n *nft) Command() command.NFT { func (n *nft) Command() contract.Command {
return n.command return n.command
} }
+2 -9
View File
@@ -1,21 +1,14 @@
package nft package nft
type Version interface {
// Version returns the version of the nftables client.
Version() string
// Opts returns the options of the nftables client.
Opts() map[string]string
}
type version struct { type version struct {
version string version string
opts map[string]string opts map[string]string
} }
func (v version) Version() string { func (v *version) Version() string {
return v.version return v.version
} }
func (v version) Opts() map[string]string { func (v *version) Opts() map[string]string {
return v.opts return v.opts
} }