Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1eaf009e56 |
@@ -10,7 +10,6 @@ Go-низкоуровневая обёртка для управления [nfta
|
|||||||
- Абстракции для работы с IP/IP6/inet/arp/bridge/netdev families
|
- Абстракции для работы с IP/IP6/inet/arp/bridge/netdev families
|
||||||
- Интерфейс для выполнения CLI-команд nftables напрямую
|
- Интерфейс для выполнения CLI-команд nftables напрямую
|
||||||
- Простой и минималистичный API для быстрой интеграции
|
- Простой и минималистичный API для быстрой интеграции
|
||||||
- Добавлена возможность формировать batch-команды и отправлять их в nftables одним вызовом.
|
|
||||||
|
|
||||||
## Установка
|
## Установка
|
||||||
```sh
|
```sh
|
||||||
@@ -30,13 +29,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
nftClient, err := nft.New()
|
nft, err := nft.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("nft not found: %v", err)
|
log.Fatalf("nft not found: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Добавить таблицу
|
// Добавить таблицу
|
||||||
if err := nftClient.Table().Add(family.IP, "test"); err != nil {
|
if err := nft.Table().Add(family.IP, "test"); err != nil {
|
||||||
log.Fatalf("table add failed: %v", err)
|
log.Fatalf("table add failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,78 +43,16 @@ func main() {
|
|||||||
chainType.Hook = chain.HookOutput
|
chainType.Hook = chain.HookOutput
|
||||||
chainType.Priority = 0
|
chainType.Priority = 0
|
||||||
chainType.Policy = chain.PolicyAccept
|
chainType.Policy = chain.PolicyAccept
|
||||||
if err := nftClient.Chain().Add(family.IP, "test", "test", chainType); err != nil {
|
if err := nft.Chain().Add(family.IP, "test", "test", chainType); err != nil {
|
||||||
log.Fatalf("table add failed: %v", err)
|
log.Fatalf("table add failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Добавить правило (пример: дропать пакеты от 1.2.3.4)
|
// Добавить правило (пример: дропать пакеты от 1.2.3.4)
|
||||||
if err := nftClient.Rule().Add(family.IP, "test", "test", "ip", "saddr", "1.2.3.4", "drop"); err != nil {
|
if err := nft.Rule().Add(family.IP, "test", "test", "ip", "saddr", "1.2.3.4", "drop"); err != nil {
|
||||||
log.Fatalf("rule add failed: %v", err)
|
log.Fatalf("rule add failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
### Batch commands
|
|
||||||
|
|
||||||
Библиотека поддерживает отправку команд в `nft` через batch-файлы.
|
|
||||||
|
|
||||||
Это позволяет заранее сформировать набор команд, например для таблиц, цепочек и правил,
|
|
||||||
а затем выполнить их одной операцией.
|
|
||||||
|
|
||||||
## Пример использования
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/chain"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
nftClient, err := nft.New()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("nft not found: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
batchBuilder, err := nft.NewBatchBuilder("/tmp/nft_batch")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("batch builder init failed: %v", err)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = batchBuilder.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Добавить таблицу
|
|
||||||
if err := batchBuilder.Table().Add(family.IP, "test"); err != nil {
|
|
||||||
log.Fatalf("table add failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
chainType := chain.NewBaseChainOptions(chain.TypeFilter)
|
|
||||||
chainType.Hook = chain.HookOutput
|
|
||||||
chainType.Priority = 0
|
|
||||||
chainType.Policy = chain.PolicyAccept
|
|
||||||
if err := batchBuilder.Chain().Add(family.IP, "test", "test", chainType); err != nil {
|
|
||||||
log.Fatalf("table add failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Добавить правило (пример: дропать пакеты от 1.2.3.4)
|
|
||||||
if err := batchBuilder.Rule().Add(family.IP, "test", "test", "ip", "saddr", "1.2.3.4", "drop"); err != nil {
|
|
||||||
log.Fatalf("rule add failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
batch := batchBuilder.Build()
|
|
||||||
defer func() {
|
|
||||||
_ = batch.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Выполняет пакет команд после проверки их корректности
|
|
||||||
if err := nftClient.ExecuteBatchAfterCheck(batch); err != nil {
|
|
||||||
log.Fatalf("batch execute failed: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Краткое описание API
|
## Краткое описание API
|
||||||
|
|
||||||
@@ -139,12 +76,6 @@ nft.Rule().Delete(family family.Type, table, chain string, handle uint64) error
|
|||||||
nft.Clear() error // flush ruleset
|
nft.Clear() error // flush ruleset
|
||||||
nft.Version() (Version, error) // информация о версии nftables
|
nft.Version() (Version, error) // информация о версии nftables
|
||||||
nft.Command() command.NFT // ручное выполнение любых nft-команд
|
nft.Command() command.NFT // ручное выполнение любых nft-команд
|
||||||
|
|
||||||
// ExecuteBatchAfterCheck Выполняет пакет команд после проверки их корректности
|
|
||||||
nft.ExecuteBatchAfterCheck(batch Batch) error
|
|
||||||
|
|
||||||
// ExecuteBatch Выполняет пакет команд
|
|
||||||
nft.ExecuteBatch(batch Batch) error
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
package nft
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
|
|
||||||
contractBatch "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/batch"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/chain"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/rule"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/table"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
|
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
|
||||||
)
|
|
||||||
|
|
||||||
type batchBuilder struct {
|
|
||||||
command contract.CommandRun
|
|
||||||
file *pkg.File
|
|
||||||
|
|
||||||
table contractBatch.Table
|
|
||||||
chain contractBatch.Chain
|
|
||||||
rule contractBatch.Rule
|
|
||||||
|
|
||||||
isBuildBatch bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBatchBuilder(dir string) (contract.BatchBuilder, error) {
|
|
||||||
file, err := pkg.CreateRandomTmpFile(dir)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
command := batch.NewCommand(file)
|
|
||||||
|
|
||||||
return &batchBuilder{
|
|
||||||
command: command,
|
|
||||||
file: file,
|
|
||||||
|
|
||||||
table: table.New(command),
|
|
||||||
chain: chain.New(command),
|
|
||||||
rule: rule.New(command),
|
|
||||||
|
|
||||||
isBuildBatch: false,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Command() contract.CommandRun {
|
|
||||||
return b.command
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Clear() error {
|
|
||||||
args := nftCommand.Clear()
|
|
||||||
return b.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Table() contractBatch.Table {
|
|
||||||
return b.table
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Chain() contractBatch.Chain {
|
|
||||||
return b.chain
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Rule() contractBatch.Rule {
|
|
||||||
return b.rule
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Build() contract.Batch {
|
|
||||||
b.isBuildBatch = true
|
|
||||||
return batch.NewBatch(b.file)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batchBuilder) Close() error {
|
|
||||||
if b.isBuildBatch {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return b.file.Remove()
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package contract
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/batch"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BatchBuilder is an API for building a batch of commands.
|
|
||||||
type BatchBuilder interface {
|
|
||||||
// Command returns the command to run.
|
|
||||||
Command() CommandRun
|
|
||||||
|
|
||||||
// Clear clears all rules.
|
|
||||||
//
|
|
||||||
// This command is equivalent to:
|
|
||||||
// nft flush ruleset
|
|
||||||
Clear() error
|
|
||||||
|
|
||||||
// Table returns an API for working with tables.
|
|
||||||
Table() batch.Table
|
|
||||||
|
|
||||||
// Chain returns an API for working with chains.
|
|
||||||
Chain() batch.Chain
|
|
||||||
|
|
||||||
// Rule returns an API for working with rules.
|
|
||||||
Rule() batch.Rule
|
|
||||||
|
|
||||||
// Build returns a batch of commands.
|
|
||||||
Build() Batch
|
|
||||||
|
|
||||||
// Close closes the batch.
|
|
||||||
Close() error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Batch interface {
|
|
||||||
// Args returns the arguments of the batch.
|
|
||||||
Args() []string
|
|
||||||
|
|
||||||
// Check checks the validity of the batch.
|
|
||||||
Check(command Command) error
|
|
||||||
|
|
||||||
// Close closes the batch.
|
|
||||||
Close() error
|
|
||||||
|
|
||||||
// MoveFile moves the batch file to the specified path.
|
|
||||||
MoveFile(path string) error
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package batch
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package batch
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package batch
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package contract
|
|
||||||
|
|
||||||
type CommandRun interface {
|
|
||||||
// Run executes nft command.
|
|
||||||
Run(arg ...string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Command interface {
|
|
||||||
CommandRun
|
|
||||||
|
|
||||||
// RunWithOutput Run nft command with output.
|
|
||||||
RunWithOutput(arg ...string) (string, error)
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
// ExecuteBatchAfterCheck executes a batch of commands after checking the validity of the batch.
|
|
||||||
ExecuteBatchAfterCheck(batch Batch) error
|
|
||||||
|
|
||||||
// ExecuteBatch executes a batch of commands.
|
|
||||||
ExecuteBatch(batch Batch) error
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package batch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type batch struct {
|
|
||||||
file *pkg.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBatch(file *pkg.File) contract.Batch {
|
|
||||||
return &batch{
|
|
||||||
file: file,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batch) Args() []string {
|
|
||||||
return []string{"-f", b.file.Path()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batch) Check(command contract.Command) error {
|
|
||||||
return command.Run("-c", "-f", b.file.Path())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batch) Close() error {
|
|
||||||
return b.file.Remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *batch) MoveFile(path string) error {
|
|
||||||
return b.file.Move(path)
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package chain
|
|
||||||
|
|
||||||
import (
|
|
||||||
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"
|
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
|
||||||
)
|
|
||||||
|
|
||||||
type chain struct {
|
|
||||||
command contract.CommandRun
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(command contract.CommandRun) nft.Chain {
|
|
||||||
return &chain{
|
|
||||||
command: command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
|
||||||
args := nftCommand.ChainAdd(family, tableName, chainName, baseChain)
|
|
||||||
return c.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
|
||||||
args := nftCommand.ChainCreate(family, tableName, chainName, baseChain)
|
|
||||||
return c.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chain) Delete(family family.Type, tableName string, chainName string) error {
|
|
||||||
args := nftCommand.ChainDelete(family, tableName, chainName)
|
|
||||||
return c.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chain) Clear(family family.Type, tableName string, chainName string) error {
|
|
||||||
args := nftCommand.ChainClear(family, tableName, chainName)
|
|
||||||
return c.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error {
|
|
||||||
args := nftCommand.ChainRename(family, tableName, oldChainName, newChainName)
|
|
||||||
return c.command.Run(args...)
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package batch
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type commandRun struct {
|
|
||||||
file *pkg.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCommand(file *pkg.File) contract.CommandRun {
|
|
||||||
return &commandRun{
|
|
||||||
file: file,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *commandRun) Run(args ...string) error {
|
|
||||||
_, err := c.file.Write([]byte(fmt.Sprintf("%s\n", strings.Join(args, " "))))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package rule
|
|
||||||
|
|
||||||
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"
|
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
|
||||||
)
|
|
||||||
|
|
||||||
type rule struct {
|
|
||||||
command contract.CommandRun
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(command contract.CommandRun) nft.Rule {
|
|
||||||
return &rule{
|
|
||||||
command: command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error {
|
|
||||||
args := nftCommand.RuleAdd(family, tableName, chainName, expr...)
|
|
||||||
return r.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error {
|
|
||||||
args := nftCommand.RuleInsert(family, tableName, chainName, expr...)
|
|
||||||
return r.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error {
|
|
||||||
args := nftCommand.RuleReplace(family, tableName, chainName, handle, expr...)
|
|
||||||
return r.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error {
|
|
||||||
args := nftCommand.RuleDelete(family, tableName, chainName, handle)
|
|
||||||
return r.command.Run(args...)
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package table
|
|
||||||
|
|
||||||
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"
|
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
|
||||||
)
|
|
||||||
|
|
||||||
type table struct {
|
|
||||||
command contract.CommandRun
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(command contract.CommandRun) nft.Table {
|
|
||||||
return &table{
|
|
||||||
command: command,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *table) Add(family family.Type, tableName string) error {
|
|
||||||
args := nftCommand.TableAdd(family, tableName)
|
|
||||||
return t.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *table) Delete(family family.Type, tableName string) error {
|
|
||||||
args := nftCommand.TableDelete(family, tableName)
|
|
||||||
return t.command.Run(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *table) Clear(family family.Type, tableName string) error {
|
|
||||||
args := nftCommand.TableClear(family, tableName)
|
|
||||||
return t.command.Run(args...)
|
|
||||||
}
|
|
||||||
+49
-11
@@ -2,43 +2,81 @@ 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"
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type chain struct {
|
// API for working with chains.
|
||||||
command contract.Command
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(command contract.Command) nft.Chain {
|
type chain struct {
|
||||||
|
command command.NFT
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(command command.NFT) API {
|
||||||
return &chain{
|
return &chain{
|
||||||
command: command,
|
command: command,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
||||||
args := nftCommand.ChainAdd(family, tableName, chainName, baseChain)
|
args := []string{"add", "chain", family.String(), tableName, chainName, baseChain.String()}
|
||||||
return c.command.Run(args...)
|
return c.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
|
||||||
args := nftCommand.ChainCreate(family, tableName, chainName, baseChain)
|
args := []string{"create", "chain", family.String(), tableName, chainName, baseChain.String()}
|
||||||
return c.command.Run(args...)
|
return c.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chain) Delete(family family.Type, tableName string, chainName string) error {
|
func (c *chain) Delete(family family.Type, tableName string, chainName string) error {
|
||||||
args := nftCommand.ChainDelete(family, tableName, chainName)
|
args := []string{"delete", "chain", family.String(), tableName, chainName}
|
||||||
return c.command.Run(args...)
|
return c.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chain) Clear(family family.Type, tableName string, chainName string) error {
|
func (c *chain) Clear(family family.Type, tableName string, chainName string) error {
|
||||||
args := nftCommand.ChainClear(family, tableName, chainName)
|
args := []string{"flush", "chain", family.String(), tableName, chainName}
|
||||||
return c.command.Run(args...)
|
return c.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error {
|
func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error {
|
||||||
args := nftCommand.ChainRename(family, tableName, oldChainName, newChainName)
|
args := []string{"rename", "chain", family.String(), tableName, oldChainName, newChainName}
|
||||||
return c.command.Run(args...)
|
return c.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,21 @@ 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) (contract.Command, error) {
|
func New(path string) (NFT, error) {
|
||||||
if err := checkingNFT(path); err != nil {
|
if err := checkingNFT(path); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package pkg
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
filepath string
|
|
||||||
file *os.File
|
|
||||||
|
|
||||||
isMoved bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateRandomTmpFile(dir string) (*File, error) {
|
|
||||||
if err := os.MkdirAll(dir, 0750); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tmpFile := filepath.Join(dir, time.Now().Format(time.RFC3339)+"_"+rand.Text()+".tmp")
|
|
||||||
file, err := os.Create(tmpFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &File{
|
|
||||||
filepath: tmpFile,
|
|
||||||
file: file,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *File) Write(p []byte) (n int, err error) {
|
|
||||||
return f.file.Write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *File) Path() string {
|
|
||||||
return f.filepath
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *File) Remove() error {
|
|
||||||
if f.isMoved {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.Remove(f.filepath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *File) Move(path string) error {
|
|
||||||
if f.isMoved {
|
|
||||||
return fmt.Errorf("file already moved")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Rename(f.filepath, path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
f.isMoved = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
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"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ChainAdd(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) []string {
|
|
||||||
return []string{"add", "chain", family.String(), tableName, chainName, baseChain.String()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChainCreate(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) []string {
|
|
||||||
return []string{"create", "chain", family.String(), tableName, chainName, baseChain.String()}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChainDelete(family family.Type, tableName string, chainName string) []string {
|
|
||||||
return []string{"delete", "chain", family.String(), tableName, chainName}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChainClear(family family.Type, tableName string, chainName string) []string {
|
|
||||||
return []string{"flush", "chain", family.String(), tableName, chainName}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ChainRename(family family.Type, tableName string, oldChainName string, newChainName string) []string {
|
|
||||||
return []string{"rename", "chain", family.String(), tableName, oldChainName, newChainName}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package nft
|
|
||||||
|
|
||||||
func Clear() []string {
|
|
||||||
return []string{"flush", "ruleset"}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package nft
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
|
|
||||||
)
|
|
||||||
|
|
||||||
func RuleAdd(family family.Type, tableName string, chainName string, expr ...string) []string {
|
|
||||||
args := []string{"add", "rule", family.String(), tableName, chainName}
|
|
||||||
args = append(args, expr...)
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func RuleInsert(family family.Type, tableName string, chainName string, expr ...string) []string {
|
|
||||||
args := []string{"insert", "rule", family.String(), tableName, chainName}
|
|
||||||
args = append(args, expr...)
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func RuleReplace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) []string {
|
|
||||||
args := []string{"replace", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
|
|
||||||
args = append(args, expr...)
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func RuleDelete(family family.Type, tableName string, chainName string, handle uint64) []string {
|
|
||||||
args := []string{"delete", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package nft
|
|
||||||
|
|
||||||
import "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
|
|
||||||
|
|
||||||
func TableAdd(family family.Type, tableName string) []string {
|
|
||||||
return []string{"add", "table", family.String(), tableName}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TableDelete(family family.Type, tableName string) []string {
|
|
||||||
return []string{"delete", "table", family.String(), tableName}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TableClear(family family.Type, tableName string) []string {
|
|
||||||
return []string{"flush", "table", family.String(), tableName}
|
|
||||||
}
|
|
||||||
+40
-10
@@ -1,38 +1,68 @@
|
|||||||
package rule
|
package rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
|
"strconv"
|
||||||
"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"
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rule struct {
|
type API interface {
|
||||||
command contract.Command
|
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(command contract.Command) nft.Rule {
|
type rule struct {
|
||||||
|
command command.NFT
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(command command.NFT) API {
|
||||||
return &rule{
|
return &rule{
|
||||||
command: command,
|
command: command,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error {
|
func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error {
|
||||||
args := nftCommand.RuleAdd(family, tableName, chainName, expr...)
|
args := []string{"add", "rule", family.String(), tableName, chainName}
|
||||||
|
args = append(args, expr...)
|
||||||
return r.command.Run(args...)
|
return r.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error {
|
func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error {
|
||||||
args := nftCommand.RuleInsert(family, tableName, chainName, expr...)
|
args := []string{"insert", "rule", family.String(), tableName, chainName}
|
||||||
|
args = append(args, expr...)
|
||||||
return r.command.Run(args...)
|
return r.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error {
|
func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error {
|
||||||
args := nftCommand.RuleReplace(family, tableName, chainName, handle, expr...)
|
args := []string{"replace", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
|
||||||
|
args = append(args, expr...)
|
||||||
return r.command.Run(args...)
|
return r.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error {
|
func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error {
|
||||||
args := nftCommand.RuleDelete(family, tableName, chainName, handle)
|
args := []string{"delete", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
|
||||||
return r.command.Run(args...)
|
return r.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-9
@@ -1,33 +1,52 @@
|
|||||||
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"
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
type table struct {
|
// API for working with tables.
|
||||||
command contract.Command
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(command contract.Command) nft.Table {
|
type table struct {
|
||||||
|
command command.NFT
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(command command.NFT) API {
|
||||||
return &table{
|
return &table{
|
||||||
command: command,
|
command: command,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *table) Add(family family.Type, tableName string) error {
|
func (t *table) Add(family family.Type, tableName string) error {
|
||||||
args := nftCommand.TableAdd(family, tableName)
|
args := []string{"add", "table", family.String(), tableName}
|
||||||
return t.command.Run(args...)
|
return t.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *table) Delete(family family.Type, tableName string) error {
|
func (t *table) Delete(family family.Type, tableName string) error {
|
||||||
args := nftCommand.TableDelete(family, tableName)
|
args := []string{"delete", "table", family.String(), tableName}
|
||||||
return t.command.Run(args...)
|
return t.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *table) Clear(family family.Type, tableName string) error {
|
func (t *table) Clear(family family.Type, tableName string) error {
|
||||||
args := nftCommand.TableClear(family, tableName)
|
args := []string{"flush", "table", family.String(), tableName}
|
||||||
return t.command.Run(args...)
|
return t.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,50 @@ 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"
|
||||||
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
|
|
||||||
"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 contract.Command
|
command command.NFT
|
||||||
table nftContract.Table
|
table table.API
|
||||||
chain nftContract.Chain
|
chain chain.API
|
||||||
rule nftContract.Rule
|
rule rule.API
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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() (contract.NFT, error) {
|
func New() (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)
|
||||||
@@ -36,7 +61,7 @@ func New() (contract.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) (contract.NFT, error) {
|
func NewWithPath(path string) (NFT, error) {
|
||||||
nftCommand, err := command.New(path)
|
nftCommand, err := command.New(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -51,11 +76,11 @@ func NewWithPath(path string) (contract.NFT, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Clear() error {
|
func (n *nft) Clear() error {
|
||||||
args := nftCommand.Clear()
|
args := []string{"flush", "ruleset"}
|
||||||
return n.command.Run(args...)
|
return n.command.Run(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Version() (nftContract.Version, error) {
|
func (n *nft) Version() (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 {
|
||||||
@@ -89,29 +114,18 @@ func (n *nft) Version() (nftContract.Version, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Table() nftContract.Table {
|
func (n *nft) Table() table.API {
|
||||||
return n.table
|
return n.table
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Chain() nftContract.Chain {
|
func (n *nft) Chain() chain.API {
|
||||||
return n.chain
|
return n.chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Rule() nftContract.Rule {
|
func (n *nft) Rule() rule.API {
|
||||||
return n.rule
|
return n.rule
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) Command() contract.Command {
|
func (n *nft) Command() command.NFT {
|
||||||
return n.command
|
return n.command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *nft) ExecuteBatchAfterCheck(batch contract.Batch) error {
|
|
||||||
if err := batch.Check(n.command); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return n.command.Run(batch.Args()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *nft) ExecuteBatch(batch contract.Batch) error {
|
|
||||||
return n.command.Run(batch.Args()...)
|
|
||||||
}
|
|
||||||
|
|||||||
+9
-2
@@ -1,14 +1,21 @@
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user