Add support for chain priority configuration in nftables

- Introduced `input_priority`, `output_priority`, and `forward_priority` options in `firewall.toml`.
- Updated `chains` and chain creation functions to include priority handling.
- Added validation for priority values to ensure they remain within the acceptable range (-50 to 50).
- Adjusted `reloadInput`, `reloadOutput`, and `reloadForward` to respect priority settings.
This commit is contained in:
2025-11-29 15:38:58 +05:00
parent 6e7b6093f1
commit 57948fb639
11 changed files with 99 additions and 18 deletions

View File

@@ -2,9 +2,15 @@
***
#### Русский
* Добавлен параметр clear_mode в firewall.toml. Он позволяет переключать режим очистки всех правил в nftables или только таблицу относящие к программе.
* Добавлен параметр input_priority в firewall.toml. Можно указать приоритет от -50 по 50 к chain input.
* Добавлен параметр output_priority в firewall.toml. Можно указать приоритет от -50 по 50 к chain output.
* Добавлен параметр forward_priority в firewall.toml. Можно указать приоритет от -50 по 50 к chain forward.
***
#### English
* Added the clear_mode parameter to firewall.toml. It allows you to toggle clearing of all rules in nftables or only the program-specific table.
* Added the input_priority parameter to firewall.toml. You can specify a priority from -50 to 50 for chain input.
* Added the output_priority parameter to firewall.toml. You can specify a priority from -50 to 50 for chain output.
* Added the forward_priority parameter to firewall.toml. You can specify a priority from -50 to 50 for chain forward.
***
## 0.1.0 (8.11.2025)
***

View File

@@ -429,6 +429,21 @@ default_allow_forward = false
###
input_drop = "drop"
###
# Приоритет chain для input.
# От: -50
# По: 50
#
# По умолчанию: -10
# ***
# Chain priority for input.
# From: -50
# To: 50
#
# Default: -10
###
input_priority = -10
###
# Как заблокировать исходящий трафик. Блокировать молча или с обратной связью.
# Допустимые значения:
@@ -446,6 +461,21 @@ input_drop = "drop"
###
output_drop = "reject"
###
# Приоритет chain для output.
# От: -50
# По: 50
#
# По умолчанию: -10
# ***
# Chain priority for output.
# From: -50
# To: 50
#
# Default: -10
###
output_priority = -10
###
# Как заблокировать трафик forward. Блокировать молча или с обратной связью.
# Допустимые значения:
@@ -463,6 +493,21 @@ output_drop = "reject"
###
forward_drop = "drop"
###
# Приоритет chain для forward.
# От: -50
# По: 50
#
# По умолчанию: -10
# ***
# Chain priority for forward.
# From: -50
# To: 50
#
# Default: -10
###
forward_priority = -10
###############################################################################
# РАЗДЕЛ:Именование метаданных
# ***

View File

@@ -11,13 +11,13 @@ type Chains interface {
NewPacketFilter(enable bool) error
PacketFilter() PacketFilter
NewInput(chain string, defaultAllow bool) error
NewInput(chain string, defaultAllow bool, priority int) error
Input() Input
NewOutput(chain string, defaultAllow bool) error
NewOutput(chain string, defaultAllow bool, priority int) error
Output() Output
NewForward(chain string, defaultAllow bool) error
NewForward(chain string, defaultAllow bool, priority int) error
Forward() Forward
NewLocalInput() error
@@ -75,8 +75,8 @@ func (c *chains) PacketFilter() PacketFilter {
return c.packetFilter
}
func (c *chains) NewInput(chain string, defaultAllow bool) error {
input, err := newInput(c.nft, c.family, c.table, chain, defaultAllow)
func (c *chains) NewInput(chain string, defaultAllow bool, priority int) error {
input, err := newInput(c.nft, c.family, c.table, chain, defaultAllow, priority)
if err != nil {
return err
}
@@ -89,8 +89,8 @@ func (c *chains) Input() Input {
return c.input
}
func (c *chains) NewOutput(chain string, defaultAllow bool) error {
output, err := newOutput(c.nft, c.family, c.table, chain, defaultAllow)
func (c *chains) NewOutput(chain string, defaultAllow bool, priority int) error {
output, err := newOutput(c.nft, c.family, c.table, chain, defaultAllow, priority)
if err != nil {
return err
}
@@ -103,8 +103,8 @@ func (c *chains) Output() Output {
return c.output
}
func (c *chains) NewForward(chain string, defaultAllow bool) error {
forward, err := newForward(c.nft, c.family, c.table, chain, defaultAllow)
func (c *chains) NewForward(chain string, defaultAllow bool, priority int) error {
forward, err := newForward(c.nft, c.family, c.table, chain, defaultAllow, priority)
if err != nil {
return err
}

View File

@@ -17,7 +17,7 @@ type forward struct {
chain string
}
func newForward(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool) (Forward, error) {
func newForward(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool, priority int) (Forward, error) {
policy := nftChain.PolicyDrop
if defaultAllow {
policy = nftChain.PolicyAccept
@@ -26,7 +26,7 @@ func newForward(nft nft.NFT, family family.Type, table string, chain string, def
baseChain := nftChain.BaseChainOptions{
Type: nftChain.TypeFilter,
Hook: nftChain.HookForward,
Priority: 0,
Priority: int32(priority),
Policy: policy,
Device: "",
}

View File

@@ -17,7 +17,7 @@ type input struct {
chain string
}
func newInput(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool) (Input, error) {
func newInput(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool, priority int) (Input, error) {
policy := nftChain.PolicyDrop
if defaultAllow {
policy = nftChain.PolicyAccept
@@ -26,7 +26,7 @@ func newInput(nft nft.NFT, family family.Type, table string, chain string, defau
baseChain := nftChain.BaseChainOptions{
Type: nftChain.TypeFilter,
Hook: nftChain.HookInput,
Priority: 0,
Priority: int32(priority),
Policy: policy,
Device: "",
}

View File

@@ -17,7 +17,7 @@ type output struct {
chain string
}
func newOutput(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool) (Output, error) {
func newOutput(nft nft.NFT, family family.Type, table string, chain string, defaultAllow bool, priority int) (Output, error) {
policy := nftChain.PolicyDrop
if defaultAllow {
policy = nftChain.PolicyAccept
@@ -26,7 +26,7 @@ func newOutput(nft nft.NFT, family family.Type, table string, chain string, defa
baseChain := nftChain.BaseChainOptions{
Type: nftChain.TypeFilter,
Hook: nftChain.HookOutput,
Priority: 0,
Priority: int32(priority),
Policy: policy,
Device: "",
}

View File

@@ -33,8 +33,11 @@ type ConfigPolicy struct {
DefaultAllowOutput bool
DefaultAllowForward bool
InputDrop PolicyDrop
InputPriority int
OutputDrop PolicyDrop
OutputPriority int
ForwardDrop PolicyDrop
ForwardPriority int
}
type PolicyDrop int8

View File

@@ -2,7 +2,7 @@ package firewall
func (f *firewall) reloadForward() error {
f.logger.Debug("Reloading forward chain")
err := f.chains.NewForward(f.config.MetadataNaming.ChainForwardName, f.config.Policy.DefaultAllowForward)
err := f.chains.NewForward(f.config.MetadataNaming.ChainForwardName, f.config.Policy.DefaultAllowForward, f.config.Policy.ForwardPriority)
if err != nil {
return err
}

View File

@@ -10,7 +10,7 @@ import (
func (f *firewall) reloadInput() error {
f.logger.Debug("Reloading input chain")
err := f.chains.NewInput(f.config.MetadataNaming.ChainInputName, f.config.Policy.DefaultAllowInput)
err := f.chains.NewInput(f.config.MetadataNaming.ChainInputName, f.config.Policy.DefaultAllowInput, f.config.Policy.InputPriority)
if err != nil {
return err
}

View File

@@ -10,7 +10,7 @@ import (
func (f *firewall) reloadOutput() error {
f.logger.Debug("Reloading output chain")
err := f.chains.NewOutput(f.config.MetadataNaming.ChainOutputName, f.config.Policy.DefaultAllowOutput)
err := f.chains.NewOutput(f.config.MetadataNaming.ChainOutputName, f.config.Policy.DefaultAllowOutput, f.config.Policy.OutputPriority)
if err != nil {
return err
}

View File

@@ -11,8 +11,11 @@ type policy struct {
DefaultAllowOutput bool `mapstructure:"default_allow_output"`
DefaultAllowForward bool `mapstructure:"default_allow_forward"`
InputDrop string `mapstructure:"input_drop"`
InputPriority int `mapstructure:"input_priority"`
OutputDrop string `mapstructure:"output_drop"`
OutputPriority int `mapstructure:"output_priority"`
ForwardDrop string `mapstructure:"forward_drop"`
ForwardPriority int `mapstructure:"forward_priority"`
}
func defaultPolicy() policy {
@@ -21,8 +24,11 @@ func defaultPolicy() policy {
DefaultAllowOutput: false,
DefaultAllowForward: false,
InputDrop: "drop",
InputPriority: -10,
OutputDrop: "reject",
OutputPriority: -10,
ForwardDrop: "drop",
ForwardPriority: -10,
}
}
@@ -47,8 +53,11 @@ func (p policy) ToConfigPolicy() (firewall.ConfigPolicy, error) {
DefaultAllowOutput: p.DefaultAllowOutput,
DefaultAllowForward: p.DefaultAllowForward,
InputDrop: inputDrop,
InputPriority: p.InputPriority,
OutputDrop: outputDrop,
OutputPriority: p.OutputPriority,
ForwardDrop: forwardDrop,
ForwardPriority: p.ForwardPriority,
}, nil
}
@@ -70,12 +79,23 @@ func (p policy) Validate() error {
if err := validateDrop(p.InputDrop, "input_drop"); err != nil {
return err
}
if err := validatePriority(p.InputPriority, "input_priority"); err != nil {
return err
}
if err := validateDrop(p.OutputDrop, "output_drop"); err != nil {
return err
}
if err := validatePriority(p.OutputPriority, "output_priority"); err != nil {
return err
}
if err := validateDrop(p.ForwardDrop, "forward_drop"); err != nil {
return err
}
if err := validatePriority(p.ForwardPriority, "forward_priority"); err != nil {
return err
}
return nil
}
@@ -86,3 +106,10 @@ func validateDrop(drop string, parameterName string) error {
}
return fmt.Errorf("invalid %s. Must be drop or reject", parameterName)
}
func validatePriority(priority int, parameterName string) error {
if priority < -50 || priority > 50 {
return fmt.Errorf("%s must be in range -50-50", parameterName)
}
return nil
}