2018-04-02 05:25:32 +02:00
|
|
|
package firewall
|
|
|
|
|
|
|
|
import (
|
2022-05-03 22:05:12 +02:00
|
|
|
"fmt"
|
|
|
|
|
2023-01-30 13:43:44 +01:00
|
|
|
"github.com/evilsocket/opensnitch/daemon/firewall/common"
|
2024-05-14 23:41:25 +02:00
|
|
|
"github.com/evilsocket/opensnitch/daemon/firewall/config"
|
2021-06-07 01:32:05 +02:00
|
|
|
"github.com/evilsocket/opensnitch/daemon/firewall/iptables"
|
|
|
|
"github.com/evilsocket/opensnitch/daemon/firewall/nftables"
|
2020-12-09 18:18:42 +01:00
|
|
|
"github.com/evilsocket/opensnitch/daemon/log"
|
2022-05-03 22:05:12 +02:00
|
|
|
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
2020-02-22 00:27:35 +01:00
|
|
|
)
|
2018-04-02 05:25:32 +02:00
|
|
|
|
2021-06-07 01:32:05 +02:00
|
|
|
// Firewall is the interface that all firewalls (iptables, nftables) must implement.
|
|
|
|
type Firewall interface {
|
2024-10-19 10:51:40 +02:00
|
|
|
Init(uint16, string, string, bool)
|
2021-06-07 01:32:05 +02:00
|
|
|
Stop()
|
|
|
|
Name() string
|
|
|
|
IsRunning() bool
|
2024-05-14 23:41:25 +02:00
|
|
|
SetQueueNum(num uint16)
|
2021-06-07 01:32:05 +02:00
|
|
|
|
2022-05-03 22:05:12 +02:00
|
|
|
SaveConfiguration(rawConfig string) error
|
|
|
|
|
|
|
|
EnableInterception()
|
|
|
|
DisableInterception(bool)
|
2021-06-07 01:32:05 +02:00
|
|
|
QueueDNSResponses(bool, bool) (error, error)
|
|
|
|
QueueConnections(bool, bool) (error, error)
|
|
|
|
CleanRules(bool)
|
|
|
|
|
2022-12-23 00:50:22 +01:00
|
|
|
AddSystemRules(bool, bool)
|
|
|
|
DeleteSystemRules(bool, bool, bool)
|
2020-04-19 20:13:31 +02:00
|
|
|
|
2022-05-03 22:05:12 +02:00
|
|
|
Serialize() (*protocol.SysFirewall, error)
|
|
|
|
Deserialize(sysfw *protocol.SysFirewall) ([]byte, error)
|
2023-07-15 20:32:42 +02:00
|
|
|
|
|
|
|
ErrorsChan() <-chan string
|
|
|
|
ErrChanEmpty() bool
|
2020-07-25 21:23:53 +02:00
|
|
|
}
|
|
|
|
|
2022-05-03 22:05:12 +02:00
|
|
|
var (
|
2024-05-14 23:41:25 +02:00
|
|
|
fw Firewall
|
|
|
|
queueNum = uint16(0)
|
2022-05-03 22:05:12 +02:00
|
|
|
)
|
2020-04-19 20:13:31 +02:00
|
|
|
|
2021-06-07 01:32:05 +02:00
|
|
|
// Init initializes the firewall and loads firewall rules.
|
2022-05-03 22:05:12 +02:00
|
|
|
// 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.
|
2024-10-19 10:51:40 +02:00
|
|
|
func Init(fwType, configPath, monitorInterval string, bypassQueue bool, qNum uint16) (err error) {
|
2021-08-09 00:21:43 +02:00
|
|
|
if fwType == iptables.Name {
|
|
|
|
fw, err = iptables.Fw()
|
|
|
|
if err != nil {
|
|
|
|
log.Warning("iptables not available: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if fwType == nftables.Name || err != nil {
|
|
|
|
fw, err = nftables.Fw()
|
|
|
|
if err != nil {
|
|
|
|
log.Warning("nftables not available: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
2022-12-11 11:41:47 +01:00
|
|
|
return fmt.Errorf("firewall error: %s, not iptables nor nftables are available or are usable. Please, report it on github", err)
|
2021-08-09 00:21:43 +02:00
|
|
|
}
|
|
|
|
|
2021-06-07 01:32:05 +02:00
|
|
|
if fw == nil {
|
2022-10-13 00:08:52 +02:00
|
|
|
return fmt.Errorf("Firewall not initialized")
|
2020-04-19 20:13:31 +02:00
|
|
|
}
|
2024-05-14 23:41:25 +02:00
|
|
|
if configPath == "" {
|
|
|
|
configPath = config.DefaultConfigFile
|
|
|
|
}
|
2021-08-09 00:21:43 +02:00
|
|
|
fw.Stop()
|
2024-10-19 10:51:40 +02:00
|
|
|
fw.Init(qNum, configPath, monitorInterval, bypassQueue)
|
2024-05-14 23:41:25 +02:00
|
|
|
queueNum = qNum
|
2020-04-19 20:13:31 +02:00
|
|
|
|
2021-06-07 01:32:05 +02:00
|
|
|
log.Info("Using %s firewall", fw.Name())
|
2022-10-13 00:08:52 +02:00
|
|
|
|
|
|
|
return
|
2020-04-19 20:13:31 +02:00
|
|
|
}
|
2022-05-03 22:05:12 +02:00
|
|
|
|
|
|
|
// IsRunning returns if the firewall is running or not.
|
|
|
|
func IsRunning() bool {
|
|
|
|
return fw != nil && fw.IsRunning()
|
|
|
|
}
|
|
|
|
|
2023-07-15 20:32:42 +02:00
|
|
|
// ErrorsChan returns the channel where the errors are sent to.
|
|
|
|
func ErrorsChan() <-chan string {
|
|
|
|
return fw.ErrorsChan()
|
|
|
|
}
|
|
|
|
|
|
|
|
// ErrChanEmpty checks if the errors channel is empty.
|
|
|
|
func ErrChanEmpty() bool {
|
|
|
|
return fw.ErrChanEmpty()
|
|
|
|
}
|
|
|
|
|
2022-05-03 22:05:12 +02:00
|
|
|
// CleanRules deletes the rules we added.
|
|
|
|
func CleanRules(logErrors bool) {
|
|
|
|
if fw == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fw.CleanRules(logErrors)
|
|
|
|
}
|
|
|
|
|
2023-12-20 21:32:45 +01:00
|
|
|
// Reload stops current firewall and initializes a new one.
|
2024-10-19 10:51:40 +02:00
|
|
|
func Reload(fwtype, configPath, monitorInterval string, bypassQueue bool, queueNum uint16) (err error) {
|
2022-12-16 17:03:36 +01:00
|
|
|
Stop()
|
2024-10-19 10:51:40 +02:00
|
|
|
err = Init(fwtype, configPath, monitorInterval, bypassQueue, queueNum)
|
2022-12-16 17:03:36 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-05-03 22:05:12 +02:00
|
|
|
// ReloadSystemRules deletes existing rules, and add them again
|
|
|
|
func ReloadSystemRules() {
|
2023-01-30 13:43:44 +01:00
|
|
|
fw.DeleteSystemRules(!common.ForcedDelRules, common.RestoreChains, true)
|
|
|
|
fw.AddSystemRules(common.ReloadRules, common.BackupChains)
|
2022-05-03 22:05:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// EnableInterception removes the rules to intercept outbound connections.
|
|
|
|
func EnableInterception() error {
|
|
|
|
if fw == nil {
|
|
|
|
return fmt.Errorf("firewall not initialized when trying to enable interception, report please")
|
|
|
|
}
|
|
|
|
fw.EnableInterception()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// DisableInterception removes the rules to intercept outbound connections.
|
|
|
|
func DisableInterception() error {
|
|
|
|
if fw == nil {
|
|
|
|
return fmt.Errorf("firewall not initialized when trying to disable interception, report please")
|
|
|
|
}
|
|
|
|
fw.DisableInterception(true)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop deletes the firewall rules, allowing network traffic.
|
|
|
|
func Stop() {
|
|
|
|
if fw == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fw.Stop()
|
|
|
|
}
|
|
|
|
|
|
|
|
// SaveConfiguration saves configuration string to disk
|
|
|
|
func SaveConfiguration(rawConfig []byte) error {
|
|
|
|
return fw.SaveConfiguration(string(rawConfig))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize transforms firewall json configuration to protobuf
|
|
|
|
func Serialize() (*protocol.SysFirewall, error) {
|
|
|
|
return fw.Serialize()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deserialize transforms firewall json configuration to protobuf
|
|
|
|
func Deserialize(sysfw *protocol.SysFirewall) ([]byte, error) {
|
|
|
|
return fw.Deserialize(sysfw)
|
|
|
|
}
|