fw: allow to configure interception queue number

- Added new configuration field to allow configure fw interception
   number queue (default to 0):
   "FwOptions": {
      "QueueNum": 0
   }
   (we still need to reconfigure nfqueue queues in order for this to
take effect).
 - If the fw configuration path is not supplied, default to
   /etc/opensnitchd/system-fw.json
This commit is contained in:
Gustavo Iñiguez Goia 2024-05-14 23:41:25 +02:00
parent 9afadcb009
commit efc05663eb
Failed to generate hash of commit
8 changed files with 34 additions and 25 deletions

View file

@ -84,14 +84,10 @@ func (c *Common) SetRulesCheckerInterval(interval string) {
// SetQueueNum sets the queue number used by the firewall.
// It's the queue where all intercepted connections will be sent.
func (c *Common) SetQueueNum(qNum *int) {
func (c *Common) SetQueueNum(qNum uint16) {
c.Lock()
defer c.Unlock()
if qNum != nil {
c.QueueNum = uint16(*qNum)
}
c.QueueNum = qNum
}
// IsRunning returns if the firewall is running or not.

View file

@ -18,6 +18,11 @@ import (
"github.com/fsnotify/fsnotify"
)
var (
// DefaultConfigFile ..
DefaultConfigFile = "/etc/opensnitchd/system-fw.json"
)
// ExprValues holds the statements' options:
// "Name": "ct",
// "Values": [

View file

@ -93,7 +93,7 @@ func (ipt *Iptables) Name() string {
// Init inserts the firewall rules and starts monitoring for firewall
// changes.
func (ipt *Iptables) Init(qNum *int, configPath, monitorInterval string) {
func (ipt *Iptables) Init(qNum uint16, configPath, monitorInterval string) {
if ipt.IsRunning() {
return
}

View file

@ -71,7 +71,7 @@ func (n *Nft) Name() string {
// Init inserts the firewall rules and starts monitoring for firewall
// changes.
func (n *Nft) Init(qNum *int, configPath, monitorInterval string) {
func (n *Nft) Init(qNum uint16, configPath, monitorInterval string) {
if n.IsRunning() {
return
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/evilsocket/opensnitch/daemon/firewall/common"
"github.com/evilsocket/opensnitch/daemon/firewall/config"
"github.com/evilsocket/opensnitch/daemon/firewall/iptables"
"github.com/evilsocket/opensnitch/daemon/firewall/nftables"
"github.com/evilsocket/opensnitch/daemon/log"
@ -12,11 +13,11 @@ import (
// Firewall is the interface that all firewalls (iptables, nftables) must implement.
type Firewall interface {
Init(*int, string, string)
Init(uint16, string, string)
Stop()
Name() string
IsRunning() bool
SetQueueNum(num *int)
SetQueueNum(num uint16)
SaveConfiguration(rawConfig string) error
@ -37,19 +38,15 @@ type Firewall interface {
}
var (
fw Firewall
queueNum = 0
DefaultConfig = "/etc/opensnitchd/system-fw.json"
fw Firewall
queueNum = uint16(0)
)
// Init initializes the firewall and loads firewall rules.
// We'll try to use the firewall configured in the configuration (iptables/nftables).
// If iptables is not installed, we can add nftables rules directly to the kernel,
// without relying on any binaries.
func Init(fwType, configPath, monitorInterval string, qNum *int) (err error) {
if configPath == "" {
configPath = DefaultConfig
}
func Init(fwType, configPath, monitorInterval string, qNum uint16) (err error) {
if fwType == iptables.Name {
fw, err = iptables.Fw()
if err != nil {
@ -71,9 +68,12 @@ func Init(fwType, configPath, monitorInterval string, qNum *int) (err error) {
if fw == nil {
return fmt.Errorf("Firewall not initialized")
}
if configPath == "" {
configPath = config.DefaultConfigFile
}
fw.Stop()
fw.Init(qNum, configPath, monitorInterval)
queueNum = *qNum
queueNum = qNum
log.Info("Using %s firewall", fw.Name())
@ -104,9 +104,9 @@ func CleanRules(logErrors bool) {
}
// Reload stops current firewall and initializes a new one.
func Reload(fwtype, configPath, monitorInterval string) (err error) {
func Reload(fwtype, configPath, monitorInterval string, queueNum uint16) (err error) {
Stop()
err = Init(fwtype, configPath, monitorInterval, &queueNum)
err = Init(fwtype, configPath, monitorInterval, queueNum)
return
}

View file

@ -151,19 +151,19 @@ func overwriteLogging() bool {
return debug || warning || important || errorlog || logFile != "" || logMicro
}
func setupQueues() {
func setupQueues(qNum uint16) {
// prepare the queue
var err error
queue, err = netfilter.NewQueue(uint16(queueNum))
queue, err = netfilter.NewQueue(qNum)
if err != nil {
msg := fmt.Sprintf("Error creating queue #%d: %s", queueNum, err)
msg := fmt.Sprintf("Error creating queue #%d: %s", qNum, err)
uiClient.SendWarningAlert(msg)
log.Warning("Is opensnitchd already running?")
log.Fatal(msg)
}
pktChan = queue.Packets()
repeatQueueNum = queueNum + 1
repeatQueueNum = int(qNum) + 1
repeatQueue, err = netfilter.NewQueue(uint16(repeatQueueNum))
if err != nil {
@ -173,6 +173,7 @@ func setupQueues() {
log.Warning(msg)
}
repeatPktChan = repeatQueue.Packets()
log.Info("Listening on queue number %d ...", qNum)
}
func setupLogging() {
@ -581,6 +582,10 @@ func main() {
}
log.Info("Using system fw configuration %s ...", fwConfigFile)
if uint16(queueNum) != cfg.FwOptions.QueueNum && queueNum > 0 {
cfg.FwOptions.QueueNum = uint16(queueNum)
}
setupSignals()
log.Info("Loading rules from %s ...", rulesPath)
@ -596,7 +601,7 @@ func main() {
uiClient = ui.NewClient(uiSocket, configFile, stats, rules, loggerMgr)
setupWorkers()
setupQueues()
setupQueues(cfg.FwOptions.QueueNum)
// queue and firewall rules should be ready by now

View file

@ -58,6 +58,7 @@ type (
ConfigPath string `json:"ConfigPath"`
BypassQueue string `json:"BypassQueue"`
MonitorInterval string `json:"MonitorInterval"`
QueueNum uint16 `json:"QueueNum"`
}
// EbpfOptions struct

View file

@ -167,6 +167,7 @@ func (c *Client) reloadConfiguration(reload bool, newConfig config.Config) *moni
if c.GetFirewallType() != newConfig.Firewall ||
newConfig.FwOptions.ConfigPath != c.config.FwOptions.ConfigPath ||
newConfig.FwOptions.QueueNum != c.config.FwOptions.QueueNum ||
newConfig.FwOptions.MonitorInterval != c.config.FwOptions.MonitorInterval {
log.Debug("[config] reloading config.firewall")
@ -174,6 +175,7 @@ func (c *Client) reloadConfiguration(reload bool, newConfig config.Config) *moni
newConfig.Firewall,
newConfig.FwOptions.ConfigPath,
newConfig.FwOptions.MonitorInterval,
newConfig.FwOptions.QueueNum,
)
} else {
log.Debug("[config] config.firewall not changed")