From 2509d21e305613b666525f6239112067a985fe07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20I=C3=B1iguez=20Goia?= Date: Thu, 13 Feb 2025 01:23:31 +0100 Subject: [PATCH] daemon: allow to filter connections by parent path Some use cases: - Reject connections initiated by certain paths: Deny all connections initiated by cron*: /usr/sbin/cron /usr/bin/curl "action": "reject", "operator: { "type": "list", "operand": "list", "data": "", "list": [ { "type": "regexp", "operand": "process.parent.path", // /usr/bin/crond , /usr/bin/crontab, ... "data": "^/usr/(s|)bin/cron" } ] } - Reject or Allow connections of binaries launched by another app: "action": "allow", "operator": { "type": "list", "operand": "list", "data": "", "list": [ { "type": "simple", "operand": "process.parent.path", "data": "/opt/spotify/bin/spotify" }, { "type": "simple", "operand": "process.path", "data": "/usr/bin/wget" } ] } You can also combine multiple parent paths, to allow a command launched from a specific chain of processes: /usr/lib/systemd/systemd /usr/sbin/cron /bin/sh /usr/bin/curl The order is checked from the newest process to the oldest (curl -> sh -> cron -> systemd) The operand can be used with any of the existing types (simple, regexp, etc). Related: #406 --- daemon/rule/operator.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/daemon/rule/operator.go b/daemon/rule/operator.go index 5c577f76..95b32115 100644 --- a/daemon/rule/operator.go +++ b/daemon/rule/operator.go @@ -43,6 +43,7 @@ const ( OpTrue = Operand("true") OpProcessID = Operand("process.id") OpProcessPath = Operand("process.path") + OpProcessParentPath = Operand("process.parent.path") OpProcessCmd = Operand("process.command") OpProcessEnvPrefix = Operand("process.env.") OpProcessEnvPrefixLen = 12 @@ -389,6 +390,14 @@ func (o *Operator) Match(con *conman.Connection, hasChecksums bool) bool { return o.listMatch(con, hasChecksums) } else if o.Operand == OpProcessPath { return o.cb(con.Process.Path) + } else if o.Operand == OpProcessParentPath { + p := con.Process + for pp := p.Parent; pp != nil; pp = pp.Parent { + if o.cb(pp.Path) { + return true + } + } + return false } else if o.Operand == OpProcessCmd { return o.cb(strings.Join(con.Process.Args, " ")) } else if o.Operand == OpDstHost && con.DstHost != "" {