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:
@@ -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)
|
||||
***
|
||||
|
||||
@@ -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
|
||||
|
||||
###############################################################################
|
||||
# РАЗДЕЛ:Именование метаданных
|
||||
# ***
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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: "",
|
||||
}
|
||||
|
||||
@@ -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: "",
|
||||
}
|
||||
|
||||
@@ -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: "",
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user