allow to configure unknown conns interception

/etc/opensnitchd/default-config.json can now contain
"intercept_unknown": true|false
This commit is contained in:
Gustavo Iñiguez Goia 2019-11-01 01:00:10 +01:00
parent 0773f8c01e
commit 7eec749498
4 changed files with 53 additions and 13 deletions

View file

@ -28,7 +28,10 @@ type Connection struct {
pkt *netfilter.Packet
}
func Parse(nfp netfilter.Packet) *Connection {
var showUnknownCons = false
func Parse(nfp netfilter.Packet, interceptUnknown bool) *Connection {
showUnknownCons = interceptUnknown
ipLayer := nfp.Packet.Layer(layers.LayerTypeIPv4)
ipLayer6 := nfp.Packet.Layer(layers.LayerTypeIPv6)
if ipLayer == nil && ipLayer6 == nil {
@ -85,7 +88,7 @@ func newConnectionImpl(nfp *netfilter.Packet, c *Connection) (cr *Connection, er
pid := procmon.GetPIDFromINode(c.Entry.INode, fmt.Sprint(c.Entry.INode,c.SrcIP,c.SrcPort,c.DstIP,c.DstPort))
if pid == os.Getpid() {
return nil, nil
} else if c.Process = procmon.FindProcess(pid); c.Process == nil {
} else if c.Process = procmon.FindProcess(pid, showUnknownCons); c.Process == nil {
return nil, fmt.Errorf("Could not find process by its pid %d for: %s", pid, c)
}
return c, nil

View file

@ -145,7 +145,7 @@ func onPacket(packet netfilter.Packet) {
}
// Parse the connection state
con := conman.Parse(packet)
con := conman.Parse(packet, uiClient.InterceptUnknown())
if con == nil {
if uiClient.DefaultAction() == rule.Allow {
packet.SetVerdict(netfilter.NF_ACCEPT)

View file

@ -184,8 +184,8 @@ func parseEnv(proc *Process) {
}
}
func FindProcess(pid int) *Process {
if pid < 0 {
func FindProcess(pid int, interceptUnknown bool) *Process {
if interceptUnknown && pid < 0 {
return NewProcess(0, "")
}
linkName := fmt.Sprint("/proc/", pid, "/exe")

View file

@ -17,6 +17,7 @@ import (
"golang.org/x/net/context"
"github.com/fsnotify/fsnotify"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
)
@ -25,11 +26,14 @@ var (
configFile = "/etc/opensnitchd/default-config.json"
clientDisconnectedRule = rule.Create("ui.client.disconnected", rule.Allow, rule.Once, rule.NewOperator(rule.Simple, rule.OpTrue, "", make([]rule.Operator, 0)))
clientErrorRule = rule.Create("ui.client.error", rule.Allow, rule.Once, rule.NewOperator(rule.Simple, rule.OpTrue, "", make([]rule.Operator, 0)))
config Config
)
type Config struct {
sync.RWMutex
Default_Action string
Default_Duration string
Intercept_Unknown bool
}
type Client struct {
@ -40,6 +44,7 @@ type Client struct {
isUnixSocket bool
con *grpc.ClientConn
client protocol.UIClient
configWatcher *fsnotify.Watcher
}
func NewClient(path string, stats *statistics.Statistics) *Client {
@ -48,34 +53,55 @@ func NewClient(path string, stats *statistics.Statistics) *Client {
stats: stats,
isUnixSocket: false,
}
if watcher, err := fsnotify.NewWatcher(); err == nil {
c.configWatcher = watcher
}
if strings.HasPrefix(c.socketPath, "unix://") == true {
c.isUnixSocket = true
c.socketPath = c.socketPath[7:]
}
c.loadConfiguration()
c.loadConfiguration(false)
go c.poller()
return c
}
func (c *Client) loadConfiguration() {
func (c *Client) loadConfiguration(reload bool) {
raw, err := ioutil.ReadFile(configFile)
if err != nil {
fmt.Errorf("Error loading configuration %s: %s", configFile, err)
}
var conf Config
err = json.Unmarshal(raw, &conf)
config.Lock()
defer config.Unlock()
err = json.Unmarshal(raw, &config)
if err != nil {
fmt.Errorf("Error parsing configuration %s: %s", configFile, err)
}
if conf.Default_Action != "" {
clientDisconnectedRule.Action = rule.Action(conf.Default_Action)
if config.Default_Action != "" {
clientDisconnectedRule.Action = rule.Action(config.Default_Action)
}
if conf.Default_Duration != "" {
clientDisconnectedRule.Duration = rule.Duration(conf.Default_Duration)
if config.Default_Duration != "" {
clientDisconnectedRule.Duration = rule.Duration(config.Default_Duration)
}
if err := c.configWatcher.Add(configFile); err != nil {
log.Error("Could not watch path: %s", err)
return
}
if reload == true {
return
}
go c.monitorConfigWorker()
}
func (c *Client) InterceptUnknown() bool {
config.RLock()
defer config.RUnlock()
return config.Intercept_Unknown
}
func (c *Client) DefaultAction() rule.Action {
@ -219,3 +245,14 @@ func (c *Client) Ask(con *conman.Connection) (*rule.Rule, bool) {
return rule.Deserialize(reply), true
}
func(c *Client) monitorConfigWorker () {
for {
select {
case event := <-c.configWatcher.Events:
if (event.Op&fsnotify.Write == fsnotify.Write) || (event.Op&fsnotify.Remove == fsnotify.Remove) {
c.loadConfiguration(true)
}
}
}
}