falco: Combination of default and customized macro not working

Describe the bug

I’m facing issues with combining custom macros with default macro. I created a new macro (combination_macro) combining my customized macro (known_exception) and pre-defined/default macro (write_etc_common). I created the below custom file and I executed vi /etc/falco/rules.d/random to create a random file. When I see the logs, I can see the output of known_exception and write_etc_common macro separately. But falco doesn’t generate an output for the rule where I combine both the above macros into one combination_macro = (known_exception and write_etc_common). PFA output screenshot & my /etc/falco/rules.d/custom_rules.yaml.

How to reproduce it

  1. Install and start falco
  2. Create a new custom rule file, /etc/falco/rules.d/custom_rules.yaml with the below content
- macro: known_exception
  condition: (user.name=root
              and fd.name startswith /etc/falco/rules.d
              and proc.name=vi)
- macro: combination_macro
  condition: (known_exception
              and write_etc_common)
- rule: Known Exception
  desc: Known Exception an attempt to write to any file below /etc
  condition: known_exception
  output: "Known exception below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
  priority: ERROR
  tags: [filesystem, mitre_persistence]
- rule: Write below etc
  desc: an attempt to write to any file below /etc
  condition: write_etc_common
  output: "Actual File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
  priority: ERROR
  tags: [filesystem, mitre_persistence]
- rule: Combination
  desc: Combination Test an attempt to write to any file below /etc
  condition: combination_macro
  output: "Combination below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
  priority: ERROR
  tags: [filesystem, mitre_persistence]
  1. Restart the service
  2. Open a new file in vi in /etc/falco/rules.d directory, write some data & save it.
  3. View falco logs

Expected behaviour

According to expected behavior, all 3 rules should be executed: Known Exception, Write below etc, Combination because all the conditions are true but we get output only for Known Exception and Write below etc.

Screenshots image

Environment

  • Falco version: 0.29.1
  • OS: Linux
  • Installation method: apt-get install

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 25 (8 by maintainers)

Most upvoted comments

Awesome. I didn’t expect it to become a feature as it was left unanswered. This looks great & excited to try it @jasondellaluce

@rewanthtammana If that’s the case, would you consider closing this issue and opening a feature request one?

As for the reasons behind this Falco design choice, you have to consider that Falco consumes a very large number of events per second. Among the CPU-time-expensive tasks Falco does, ruleset evaluation for each event is definitely the most costly we have. By stopping the ruleset evaluation at the first rule triggered by an event, we save plenty of precious CPU-time that allows Falco to sustain a high throughput of events. If you look at the default ruleset, you’ll notice that most rules are designed to “fail fast” for this reason specifically, and I also bet that in many cases folks hitting an high drop rate didn’t tune their custom ruleset in the right way. The faster Falco is able to consume events, the less CPU is used and events are dropped. Maintaining an event drop rate as close as possible to 0, and a low CPU usage overhead, are both top priorities for Falco in order to sustain its security guarantees.

As such, changing the rule triggering policy to keep looking for rule matches even after the first one would be very expensive and would have an high impact on Falco performance and security guarantees. This being said, I still think the issue you are reporting here is a matter of writing “correct rulesets” given the Falco design principles. I agree with you, we could be more explicit in the community about how rulesets should be written. Leaving here few ideas:

  • Better documentation on the website (OFC)
  • Make Falco look for potential rule shadowing like your case, and print warnings when it notices some potential mistake
  • Provide IDE-like support (event online or with something like a VS-code plugin) for Falco rulesets to help folks get up to speed with ruleset development

Sorry, I completely lost track of this. Anyway, after reading the description again, it does not seem like a bug to me. 🤔

rule: Combination will never be triggered because it is shadowed by the other two rules. When an event arrives, Falco evaluates it against each rule and stops on the first match.

/cc @jasondellaluce