Compare commits

...

185 Commits

Author SHA1 Message Date
Federico Di Pierro
4fc6153160 fix(cmake): properly check that git describe returns a real tag (semversioned).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-07 14:36:27 +01:00
Federico Di Pierro
b3f009ad4c fix(cmake): fixed tag fetching fallback (that is indeed needed).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-07 14:36:27 +01:00
Luca Guerra
b978e71919 new(docs): update Changelog for 0.34.0
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-02-07 11:25:29 +01:00
Lorenzo Susini
6f994ee340 chore: bump falcoctl version to 0.4.0
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-02-06 20:05:27 +01:00
Lorenzo Susini
de63a36ead update: add allowed types to falcoctl artifact follow service
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-02-06 20:05:27 +01:00
Federico Di Pierro
dcaf24164f fix(scripts): force rpm postinstall script to always show dialog, even on upgrade.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-03 18:09:20 +01:00
Andrea Terzolo
1b11a041b5 update: change cpus_for_each_syscall_buffer default value
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-03 12:50:20 +01:00
Luca Guerra
13b66c95ef update(build): update falcoctl to 0.3.0
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-02-02 21:41:15 +01:00
Federico Di Pierro
89b54555d4 fix(scripts): fixed falcoctl config install dir.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-02 18:19:16 +01:00
Roberto Scolaro
3cba495e62 fix(scripts): add retrocompatibility to make /usr/share/falco writable
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2023-02-02 17:59:16 +01:00
Roberto Scolaro
ab8ab8fbd0 fix(scripts): make /usr/share/falco writable
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2023-02-02 17:59:16 +01:00
Luca Guerra
b4ec7c60f3 update(build): update falcoctl version
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-02-02 12:39:13 +01:00
Andrea Terzolo
7ebf4b8dff fix(scripts): revert part of 7a794b70a71896a3eb1971ca66cc0c19b9a104e6
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-31 14:48:05 +01:00
Federico Di Pierro
8e3067361d update(cmake): bumped libs to 0.10.3
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-31 11:56:03 +01:00
Andrea Terzolo
d8fc259309 cleanup: improve falcoctl yaml readability
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
Co-authored-by: Aldo Lacuku <aldo@lacuku.eu>
2023-01-30 17:20:02 +01:00
Andrea Terzolo
e0529746af new(scripts): add falcoctl config into falco pkg
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-30 17:20:02 +01:00
Andrea Terzolo
1d99e3d7b3 fix(ci): remove application rules from docker build
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-30 13:44:17 +01:00
Leonardo Grasso
216d3c0e36 chore(cmake/cpack/debian): remove application_rules.yaml
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-30 13:44:17 +01:00
Leonardo Grasso
99dccc4743 build(cmake): deprecate /etc/falco/rules.available and don't ship application_rules.yaml any more
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-30 13:44:17 +01:00
Federico Di Pierro
132484c158 fix(scripts): switch back to insmod instead of modprobe in driver loader.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-30 11:29:56 +01:00
Federico Di Pierro
207fc65d08 chore(scripts): for local installations, only try the dkms build.
In this way, dkms will gracefully handle kernels updates.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-30 11:29:56 +01:00
Andrea Terzolo
660da98e4c fix: configure_file in CMake
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-28 12:35:47 +01:00
Andrea Terzolo
7bdebf5d93 update(systemd): solve some issues with systemd unit
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-28 12:35:47 +01:00
Andrea Terzolo
11b98512db fix: falcoctl version
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-26 18:46:43 +01:00
Leonardo Grasso
27f0898c73 build(cmake): upgrade falcoctl to v0.3.0-rc6
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-26 18:46:43 +01:00
Leonardo Grasso
d4623609c4 Update PULL_REQUEST_TEMPLATE.md
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-26 18:21:43 +01:00
Leonardo Grasso
30ea744d12 docs(.github): rules are no longer in this repo
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-26 18:21:43 +01:00
Leonardo Grasso
e8d9b5a7e7 build(cmake/modules): bump k8saudit to 0.5.0 and cloudtrail to 0.6.0
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-26 13:27:43 +01:00
Andrea Terzolo
229633ee8a update(CI): mitigate frequent failure in CircleCI jobs
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-26 12:37:43 +01:00
Andrea Terzolo
acd1e0dc28 update: split the build phase in multiple RUN commands
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-26 12:37:43 +01:00
Andrea Terzolo
8eb6fbf32d fix(userspace): use the right path for the cpus_for_each_syscall_buffer
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-26 11:44:44 +01:00
Andrea Terzolo
a7e991bf1c chore: bump libs version
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
059a28184d tests: fix rule paths
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
0918cd0c54 chore: bump rules and falcoctl
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
328c3e0a29 update: add falco alias to kmod unit
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
92a5d770f4 fix: create directory for systemd scripts
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
84db98376e update(cmake): bumped falcoctl to latest version.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
26c00a3948 chore: couple of small fixes.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
3c7fc1a8c5 cleanup: rename plugin unit into custom unit
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
a67657f316 docs: fix some comments
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
7ed5f39da0 scripts: remove falco.target and use require falcoctl with Wants=
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
9b7ab105d8 chore: fix cmake file copy
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
7d355dd2d9 chore(scripts): small fixes to systemd units.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
f96f2179ba fix(scripts): some small fixes around falco and falcoctl systemd services logic.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
3b2732355a update(cmake): bumped falcoctl to 0.3.0-rc2.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
0f22fde7cd update(scripts): multiple renamings to falcoctl service + fixed description.
Moreover, now falcoctl service is enabled by default. It being bound to falco.target
allows us to avoid it running when falco.target is not running.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
2591ed4d68 new(scripts): add a falco.target that consists of falco-X.service units.
falcoctl will then run and bind to falco.target.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
394d495040 update(cmake,scripts): updated falcoctl to 0.3.0-rc1.
Fix up falcoctl.service.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
7bdd0bf646 chore(scripts): updated falcoctl service.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
ffce069c96 update(scripts): added a falcoctl systemd service.
Add a new dialog to choose whether to enable falcoctl feed.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Federico Di Pierro
2a886f7a3d new(cmake): added a cmake module to enforce the download and installation of falcoctl.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-25 17:37:37 +01:00
Andrea Terzolo
77686cb8b9 update: don't expose available CPU feature
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-24 12:41:34 +01:00
Andrea Terzolo
42670a50c7 new: support multiple buffer modes and online CPUs
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-24 12:41:34 +01:00
Federico Di Pierro
e64c14a947 fix(userspace/falco): fixed grpc server shutdown.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-24 11:59:34 +01:00
Jason Dellaluce
f3546a9a55 update(cmake): new rules checksums
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
cf76a09425 chore(RELEASE.md): fix typo
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
97ec861c02 docs(RELEASE.md): update release guidelines
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
4aeb3672e5 fix(test): update rules file reference
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
0ad80350a4 chore(README.md): fix reference to rules in readme
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
0b324f06f3 update(cmake): add rules external project for building packages
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
0ca7fe29fa new: add falcosecurity/rules submodule
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
aafbbdb31f refactor: remove rules directory as moved to another repo
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Jason Dellaluce
32dcb9ffd0 refactor: remove rules_inventory as being moved to another repo
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-21 17:58:08 +01:00
Roberto Scolaro
45f5589b69 fix(scripts): fixed incorrect bash var expansion
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
2023-01-20 17:41:05 +01:00
Jason Dellaluce
099f118e34 fix(scripts): invalidate all signatures at once
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
4bc7d3fa65 fix(scripts): aws cp instead of aws sync
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
9b644d893b fix(scripts): aws sync flags
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
717dcaf473 update(scripts): regenerate repos signatures
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
95940d2e16 chore(scripts): fix typos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
1d0c50e272 update(scripts): allow regenerating signatures without publishing new packages
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
61bc6c8d32 update(scripts): sync regenerated signatures in s3
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
9f4573a26a update(scripts): add option for updating all signatures in publish-rpm
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
ac2555ca3c update(scripts): add option for updating all signatures in publish-deb
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-20 16:56:06 +01:00
Jason Dellaluce
cfc96e899b fix(docker/falco): trust latest GPG key
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-19 12:33:46 +01:00
Federico Di Pierro
306f9ba468 fix(userspace/falco): fixed build.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-17 16:00:23 +01:00
Federico Di Pierro
a8377d544a update(cmake): updated libs to latest 0.10.1 tag.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-01-17 16:00:23 +01:00
Jason Dellaluce
41a5de670a docs(falco.yaml): update webserver config docs
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-16 17:24:54 +01:00
Jason Dellaluce
55a6436ee8 new(userspace/falco): add webserver endpoint for retrieving internal versions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-16 17:24:54 +01:00
Jason Dellaluce
ea48ec70be refactor(userspace/falco): use new utility for printing versions and support
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-16 17:24:54 +01:00
Jason Dellaluce
7724ad940a new(userspace/falco): standaline utility for retrieving internal version numbers
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-16 17:24:54 +01:00
Thomas Labarussias
bb9edea666 install ca-certificates in falco:no-driver image
Signed-off-by: Thomas Labarussias <issif+github@gadz.org>
2023-01-16 10:35:18 +01:00
Jason Dellaluce
c69b198777 chore(userspace/falco): cleanup error message when no output is configured
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
db2f5d5e9c fix(userspace/falco): solve tests issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
4aefb7fd7d fix(userspace/falco): require config file only when needed
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
149c95c3fb fix(userspace/falco): load config before every other action
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
46f15facfe fix(userspace/falco): adapt tests
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
78312c8c15 update(userspace/falco): clean up configuration and allow re-initialization
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
d6bbf5d442 refactor(userspace/falco): isolate yaml helpers (2)
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
2eac8f88cb refactor(userspace/falco): isolate yaml helpers (1)
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
bc3ec30f3e chore(userspace/falco) remove unused var
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
42ef8db26f refactor(userspace/falco): deprecate version-json option and rely on json_output
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
09d9ae135b update(userspace/falco): load default config at app initialization
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
57cafcb65a refator(userspace/falco): allow loading default config with no file
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-15 18:30:15 +01:00
Jason Dellaluce
c1985a7c99 fix(userspace/engine): absolute rule condition position in validation context
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-10 12:55:43 +01:00
Jason Dellaluce
d79d7112a0 fix(userspace/engine): catch YAML parsing and validation errors with right context
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-01-10 12:55:43 +01:00
Luca Guerra
1b2c7ef7d9 new(falco): add --version-json to print version information in json format
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-01-10 12:35:43 +01:00
Leonardo Grasso
280fcfe5d3 update: deprecate Mesos support, --mesos-api, and -pm command-line flags
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-01-09 14:04:55 +01:00
Furkan
8381d58f2c chore(scripts/falco-driver-loader): improve curl resiliency
Fixes #2334

Signed-off-by: Furkan <furkan.turkal@trendyol.com>
2023-01-09 10:12:55 +01:00
Andrea Terzolo
19d5430f5d update: modern falco builder
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-01-09 09:04:54 +01:00
Andrea Terzolo
609171fe14 doc: reword
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-21 14:56:02 +01:00
Andrea Terzolo
de6292ce09 doc(userspace): fix a warning message
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 14:56:02 +01:00
Andrea Terzolo
decabbc519 update(ci): bump also musl job
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 11:26:02 +01:00
Andrea Terzolo
647c085041 ci: bump resource class
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 11:26:02 +01:00
Andrea Terzolo
e1ff4db67a update(ci): support modern bpf with musl build
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 11:26:02 +01:00
Andrea Terzolo
c861f0b02a update(ci): update ci jobs to generate Falco images with modern probe
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 11:26:02 +01:00
Andrea Terzolo
e5ed3284db chore: bump libs/driver version
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-21 11:26:02 +01:00
Federico Di Pierro
9d2f1e0729 new(scripts): add bottlerocket support in falco-driver-loader.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-19 17:33:09 +01:00
Andrea Terzolo
100e92a6fb fix: job step name
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-19 11:48:00 +01:00
Andrea Terzolo
9b41b77d53 cleanup(ci): move static analysis from circle CI to GHA
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-19 11:48:00 +01:00
Oscar Utbult
b17d513251 rules: use list of Falco containers instead of repeating them
Signed-off-by: Oscar Utbult <oscar.utbult@gmail.com>
2022-12-16 12:56:23 +01:00
Luca Guerra
6ea233dd75 new(falco): add engine version to --version
Signed-off-by: Luca Guerra <luca@guerra.sh>
2022-12-16 12:09:24 +01:00
Luca Guerra
dde2fdd67c new(falco): add driver_api_version, driver_schema_version, default_driver_version, libs_version to support
Signed-off-by: Luca Guerra <luca@guerra.sh>
2022-12-16 12:09:24 +01:00
Luca Guerra
a4ff604021 update(falco): update cpp-httplib to 0.11.3
Signed-off-by: Luca Guerra <luca@guerra.sh>
2022-12-16 11:53:23 +01:00
Alberto Pellitteri
d9a9fdf577 Rule: detecting executions from /dev/shm
Signed-off-by: Alberto Pellitteri <albertopellitteri96@gmail.com>
2022-12-16 11:33:23 +01:00
Alberto Pellitteri
68b87a6f13 Rule: detecting executions looking for AWS credentials
Signed-off-by: Alberto Pellitteri <albertopellitteri96@gmail.com>
Co-authored-by: Alessandro Brucato <alessandro.brucato@sysdig.com>
2022-12-16 10:42:23 +01:00
Melissa Kilby
e5f3b724a5 update(docs): reference Falco default rules overview markdown document
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2022-12-15 16:46:20 +01:00
Melissa Kilby
f04ff10bd7 new(rules): init rules_inventory/
* add ad-hoc python script to generate Falco default rules overview markdown document
* init rules_inventory/rules_overview.md doc

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2022-12-15 16:46:20 +01:00
Melissa Kilby
6afe9d9200 update(rules): ehanced rules tagging for inventory / threat modeling
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2022-12-15 16:46:20 +01:00
cappellinsamuele
cec135b4b6 fix(ci): fix rpm sign job dependencies
Signed-off-by: cappellinsamuele <cappellinsamuele@gmail.com>
2022-12-15 16:32:20 +01:00
Leonardo Grasso
73b9273472 chore(scripts): rename env var
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2022-12-15 16:19:20 +01:00
Andrea Bonanno
7e52db2b42 update(script): makes user able to pass additional custom option to driver-loader curl command
Signed-off-by: Andrea Bonanno <andrea@bonanno.cloud>
2022-12-15 16:19:20 +01:00
Federico Di Pierro
a1d68e848f chore(scripts): avoid failing if mkdir/cp/depmod fail.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
d0ac5981a7 update(scripts): typo
Co-authored-by: Andrea Terzolo <andrea.terzolo@polito.it>
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
380dd23a60 update(scripts): typo
Co-authored-by: Andrea Terzolo <andrea.terzolo@polito.it>
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
4c550bbe06 chore(scripts): manage dialog cancel button, and increase dialog vertical size to comprehend all of 5 options.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
76c8a645f1 chore(scripts): properly configure falco-kmod dependency on falco-kmod-inject with PartOf.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Andrea Terzolo
5bb566d613 fix: stop also falco-kmod-inject.service unit
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-15 14:09:19 +01:00
Andrea Terzolo
ee08c4d3de update: remove falco target
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
988256d930 fix(scripts): fixed rpm dialog script.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
a94f26ec43 chore(scripts): fallback at previous insmod method, if modprobe fails.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
d4d2777876 fix(scripts): fixed PartOf in bpf and modern-bpf systemd units.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
4fc10bc774 chore(scripts,cmake): rename modern_bpf to modern-bpf in deb and rpm scripts.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
87416ab67c chore(scripts): try to install kmod system wide.
Then, we can always use `modprobe` to load it instead of `insmod`.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
01f4af480d fix(scripts): fixed some debian issues by directly using systemctl tool.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
cb20cf83ff new(scripts, cmake): added support for modern bpf probe.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
c6f668bc71 cleanup(scripts, cmake): fix switch in deb and rpm postinst scripts.
Cleanup cmake cpackgenerator options.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
1570e9f235 chore(scripts, cmake): add falco-plugin.service to install files.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
cbea78b283 fix(scripts): by default, do not enable any driver.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
ca55e70a33 chore: make dontstart default dialog selection.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
4596c919a6 fix(scripts): improve gcc skip logic.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
4e57670599 chore(scripts): add back a dontstart option.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
91fe2e9e24 chore(scripts): added support for falco@plugin.target.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
b04bb2e32e chore(scripts): renamed Don't Start to Plugin.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
e26aa6a385 chore(scripts): when running in non-interactive mode, do not enable neither start any driver.
Eg: when building Falco docker image, and installing Falco package, we don't want it to build any driver.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
818f717622 chore(scripts,cmake): dialog is an optional dep, do not list it among deps.
Cleaned up unused vars in postinst scripts.
Finally, only show dialog window in interactive shells.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
9232383616 chore(cmake): dkms is actually needed by falco driver loader.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
41ffc90633 cleanup(scripts): allow falco-driver-loader script to manage more gcc versions.
AmazonLinux uses `gcc-$Vers`, like gcc-10, but our regex prevented that to work.
Instead, rely on the fact that **real** gcc has some `--version` fixed output.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
b6078ce1be new(scripts): allow rpm/deb users to decide at configure time which driver to use (kmod or ebpf).
Manage it via a bash dialog interface.
Moreover, use falco-driver-loader instead of dkms to build bpf/kmod after package install.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Federico Di Pierro
06fe9e6985 new(scrips): improve systemd units for rpm and debian.
Unify them; plus, rework systemd units to support eBPF too.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-15 14:09:19 +01:00
Oscar Utbult
f43e6c445a rules: add OpenSSH private key to macro private_key_or_password
Signed-off-by: Oscar Utbult <oscar.utbult@gmail.com>
2022-12-15 13:36:18 +01:00
Nicolas-Peiffer
1f15af1e4f feat: Support for detecting outbound connection to c2 servers with FQDN domains and IP addresses.
Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

feat: Support for detecting outbound connection to c2 servers with FQDN domains and IP addresses.

doc: add comment

Fixing DCO append amend

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

Revert to original C2 rule name

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

modify comments on C2 rule

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

comment

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

clean comments

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

clean comments

Signed-off-by: Nicolas-Peiffer <102670102+Nicolas-Peiffer@users.noreply.github.com>

modify stdout

Signed-off-by: thedetective <nicolas@lrasc.fr>
2022-12-15 13:27:18 +01:00
Andrea Terzolo
39753b6130 update(ci): remove 2 usages of falco-builder
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-15 12:31:19 +01:00
Andrea Terzolo
b758206cf1 cleanup(ci): remove some no more useful jobs
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-15 12:31:19 +01:00
Leonardo Grasso
9c04622bd6 chore(proposals): fix typo found by FedeDP
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2022-12-14 17:32:14 +01:00
Leonardo Grasso
0200ec288e chore(proposals): fix typo found by codespell
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2022-12-14 17:32:14 +01:00
Leonardo Grasso
50c169987e docs(proposal): new artifacts distribution proposal
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2022-12-14 17:32:14 +01:00
Jason Dellaluce
5552bcab76 chore: fix typo
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-12-13 15:06:10 +01:00
Jason Dellaluce
cb58ea9c57 test: add regression tests for ref loops in lists and macros
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-12-13 15:06:10 +01:00
Jason Dellaluce
0a6db28783 fix(test/engine): solve compilation issues with macro resolver
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-12-13 15:06:10 +01:00
Jason Dellaluce
25ddc3c6a2 update(userspace/engine): broader err catching support in macro resolver
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-12-13 15:06:10 +01:00
Jason Dellaluce
35dd0fc153 fix(userspace/engine): implement loop detection in macro resolver
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-12-13 15:06:10 +01:00
Federico Di Pierro
0c39776557 chore(ci): properly checkout pull request HEAD instead of merge commit in gh actions.
See https://github.com/actions/checkout#checkout-pull-request-head-commit-instead-of-merge-commit.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-12 11:11:44 +01:00
Federico Di Pierro
4696948754 fix(cmake): properly fetch dev version by appending latest Falco tag, delta between master and tag, and hash.
`describe` can no more be used as tags are now made on release branches.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-12 11:11:44 +01:00
dependabot[bot]
ec04b758e6 chore(deps): Bump certifi from 2020.4.5.1 to 2022.12.7 in /test
Bumps [certifi](https://github.com/certifi/python-certifi) from 2020.4.5.1 to 2022.12.7.
- [Release notes](https://github.com/certifi/python-certifi/releases)
- [Commits](https://github.com/certifi/python-certifi/compare/2020.04.05.1...2022.12.07)

---
updated-dependencies:
- dependency-name: certifi
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-12 11:01:44 +01:00
Andrea Terzolo
52ee61b800 chore(userspace): add njson lib as a dependency for falco_engine
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-10 17:07:06 +01:00
gentooise
70dfdb2e75 support older rhel distros in falco-driver-loader
Tested on RHEL 6

Signed-off-by: gentooise <andrea.genuise@ibm.com>
2022-12-09 12:03:13 +01:00
Federico Di Pierro
1b227cf90b update(cmake): bumped libs and driver to latest RC.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-06 12:59:50 +01:00
Andrea Terzolo
ff3a38415d fix: remove conflicting helper methods
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-06 12:59:50 +01:00
Andrea Terzolo
94ed56df95 chore: bump libs
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-06 12:59:50 +01:00
Andrea Terzolo
6a972272c0 update: the capture will be stopped in the inspector destructor
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-06 12:59:50 +01:00
Andrea Terzolo
55deb452d8 update: start/stop capture inside do_inspect
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-12-06 12:59:50 +01:00
Federico Di Pierro
87371492c5 update(userspace/engine): updated checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-06 12:59:50 +01:00
Federico Di Pierro
17dfe4f55d fix(userspace/falco): properly start/stop capture.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-06 12:59:50 +01:00
Federico Di Pierro
928ad6625b update(cmake): update libs to 8eef2e445364d892dba12564d20f9651232eba7c
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2022-12-06 12:59:50 +01:00
Mark Stemm
356a4a0749 Also copy ruleset when copying falco source
In the copy constructor and assignment operator for falco_source, also
copy the ruleset along with factories/name.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-12-01 17:07:52 +01:00
Mark Stemm
910b8ff858 Fix(engine) Save parse positions when finding unresolved macros
Now that ASTs contain parse positions, use them when reporting errors
about unknown macros.

When doing the first pass to find all macro references, save macros as
a map<macro name,parse position> instead of a set<macro name>. While
making that change, change the visitor struct to use references
instead of pointers.

In the second pass, when reporting any unresolved macro references,
also report the parse position.

The unit tests also check that the positions of macros are properly
returned in the resolved/unresolved maps.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-12-01 17:03:52 +01:00
Mark Stemm
83b12bab1d Fix(engine): include parse positions in compile errors
Now that ASTs have parse positions and the compiler will return the
position of the last error, use that in falco rules to return errors
within condition strings instead of reporting the position as the
beginning of the condition.

This led to a change in the filter_ruleset interface--now, an ast is
compiled to a filter before being passed to the filter_ruleset
object. That avoids polluting the interface with a lot of details
about rule_loader contexts, errors, etc. The ast is still provided in
case the filter_ruleset wants to do indexing/analysis of the filter.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-12-01 17:03:52 +01:00
Lorenzo Susini
ecc1853d60 update(rule): improve insmod detection within container using CAP_SYS_MODULE
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2022-12-01 11:17:50 +01:00
Andrea Terzolo
fbd6628693 new(config): add the simulate_drops config explicitly
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2022-11-30 19:26:47 +01:00
Jason Dellaluce
ba61706557 update(userspace/falco): enable using zlib with webserver
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2022-11-30 19:24:47 +01:00
vin01
234026e14b rule(macro rpm_procs): let salt-call write to rpm database
Signed-off-by: vin01 <vinc.i@protonmail.ch>
2022-11-30 19:20:47 +01:00
vin01
d03826379b rule(Read sensitive file untrusted): let salt-call read sensitive files
Signed-off-by: vin01 <vinc.i@protonmail.ch>
2022-11-30 19:20:47 +01:00
Alessandro Brucato
3697d1fae2 Fixed typo
Signed-off-by: Alessandro Brucato <alessandro.brucato@sysdig.com>
2022-11-30 19:12:47 +01:00
Alessandro Brucato
e76c31b493 Added PTRACE_SEIZE, PTRACE_POKETEXT, PTRACE_POKEDATA, PTRACE_SETREGS and whitelist macro
Signed-off-by: Alessandro Brucato <alessandro.brucato@sysdig.com>
2022-11-30 19:12:47 +01:00
Alessandro Brucato
d95e36b526 Rule: PTRACE attached to process
Signed-off-by: Alessandro Brucato <alessandro.brucato@sysdig.com>
2022-11-30 19:12:47 +01:00
99 changed files with 2307 additions and 4506 deletions

View File

@@ -3,56 +3,60 @@ jobs:
"build-arm64":
machine:
enabled: true
image: ubuntu-2004:202101-01
resource_class: arm.medium
image: ubuntu-2204:2022.10.2
resource_class: arm.large
steps:
# Install dependencies to build the modern BPF probe skeleton.
- run:
name: Install deps ⛓️
command: |
sudo apt update
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 git pkg-config autoconf automake libelf-dev
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90
sudo update-alternatives --install /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-14 90
git clone https://github.com/libbpf/bpftool.git --branch v7.0.0 --single-branch
cd bpftool
git submodule update --init
cd src && sudo make install
# Path to the source code
- checkout:
path: /tmp/source-arm64/falco
# Build the skeleton
- run:
name: Prepare project
name: Build modern BPF skeleton 🐝
command: |
mkdir -p /tmp/build-arm64 && mkdir -p /tmp/build-arm64/release && \
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
falcosecurity/falco-builder:latest \
cmake
mkdir -p /tmp/source-arm64/falco/skeleton-build
cd /tmp/source-arm64/falco/skeleton-build && cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_FALCO_MODERN_BPF=ON -DCREATE_TEST_TARGETS=Off ../
make ProbeSkeleton
# Build the Falco packages (tar, deb, rpm) inside the centos7 builder.
# This dockerfile returns as output:
# - the build directory. (under /tmp/${DEST_BUILD_DIR})
# - the 3 packages: tar, deb, rpm. (under /tmp/packages)
- run:
name: Build
name: Build Falco packages 🏗️
command: |
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
falcosecurity/falco-builder:latest \
all
- run:
name: Run unit tests
command: |
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
falcosecurity/falco-builder:latest \
tests
- run:
name: Build packages
command: |
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
falcosecurity/falco-builder:latest \
package
- run:
name: Prepare Artifacts
command: |
mkdir -p /tmp/packages
cp /tmp/build-arm64/release/*.deb /tmp/packages
cp /tmp/build-arm64/release/*.tar.gz /tmp/packages
cp /tmp/build-arm64/release/*.rpm /tmp/packages
DOCKER_BUILDKIT=1 docker build -f /tmp/source-arm64/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off" --build-arg DEST_BUILD_DIR=/build-arm64/release /tmp/source-arm64/falco
- store_artifacts:
path: /tmp/packages
destination: /packages
- persist_to_workspace:
root: /tmp
paths:
- build-arm64/release
- source-arm64
# Build a statically linked Falco release binary using musl
# This build is 100% static, there are no host dependencies
"build-musl":
docker:
- image: alpine:3.12
- image: alpine:3.17
resource_class: large
steps:
- checkout:
path: /source-static/falco
@@ -61,23 +65,23 @@ jobs:
command: apk update
- run:
name: Install build dependencies
command: apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils
command: apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils bpftool clang
- run:
name: Prepare project
command: |
mkdir -p /build-static/release
cd /build-static/release
cmake -DCPACK_GENERATOR=TGZ -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DUSE_BUNDLED_LIBELF=Off -DMUSL_OPTIMIZED_BUILD=On -DFALCO_ETC_DIR=/etc/falco /source-static/falco
cmake -DCPACK_GENERATOR=TGZ -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DUSE_BUNDLED_LIBELF=Off -DBUILD_LIBSCAP_MODERN_BPF=ON -DMUSL_OPTIMIZED_BUILD=On -DFALCO_ETC_DIR=/etc/falco /source-static/falco
- run:
name: Build
command: |
cd /build-static/release
make -j4 all
make -j6 all
- run:
name: Package
command: |
cd /build-static/release
make -j4 package
make -j6 package
- run:
name: Run unit tests
command: |
@@ -96,43 +100,58 @@ jobs:
paths:
- build-static/release
- source-static
# Build using our own builder base image using centos 7
# This build is static, dependencies are bundled in the Falco binary
"build-centos7":
docker:
- image: falcosecurity/falco-builder:latest
environment:
BUILD_TYPE: "release"
machine:
enabled: true
image: ubuntu-2204:2022.10.2
resource_class: large
steps:
- checkout:
path: /source/falco
# Install dependencies to build the modern BPF probe skeleton.
- run:
name: Prepare project
command: /usr/bin/entrypoint cmake
- run:
name: Build
command: /usr/bin/entrypoint all
- run:
name: Run unit tests
command: /usr/bin/entrypoint tests
- run:
name: Build packages
command: /usr/bin/entrypoint package
- persist_to_workspace:
root: /
paths:
- build/release
- source
- run:
name: Prepare artifacts
name: Install deps ⛓️
command: |
mkdir -p /tmp/packages
cp /build/release/*.deb /tmp/packages
cp /build/release/*.tar.gz /tmp/packages
cp /build/release/*.rpm /tmp/packages
sudo apt update
sudo apt install -y --no-install-recommends ca-certificates cmake build-essential clang-14 git pkg-config autoconf automake libelf-dev
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90
sudo update-alternatives --install /usr/bin/llvm-strip llvm-strip /usr/bin/llvm-strip-14 90
git clone https://github.com/libbpf/bpftool.git --branch v7.0.0 --single-branch
cd bpftool
git submodule update --init
cd src && sudo make install
# Path for the source code
- checkout:
path: /tmp/source/falco
- run:
name: Build modern BPF skeleton 🐝
command: |
mkdir -p /tmp/source/falco/skeleton-build
cd /tmp/source/falco/skeleton-build && cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_FALCO_MODERN_BPF=ON -DCREATE_TEST_TARGETS=Off ../
make ProbeSkeleton
# Build the Falco packages (tar, deb, rpm) inside the centos7 builder.
# This dockerfile returns as output:
# - the build directory. (under /tmp/${DEST_BUILD_DIR})
# - the 3 packages: tar, deb, rpm. (under /tmp/packages)
- run:
name: Build Falco packages 🏗️
command: |
DOCKER_BUILDKIT=1 docker build -f /tmp/source/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off" --build-arg DEST_BUILD_DIR=/build/release /tmp/source/falco
- store_artifacts:
path: /tmp/packages
destination: /packages
- persist_to_workspace:
root: /tmp
paths:
- build/release
- source
# Execute integration tests based on the build results coming from the "build-centos7" job
"tests-integration":
docker:
@@ -194,37 +213,11 @@ jobs:
- run:
name: Execute driver-loader integration tests
command: /tmp/ws/source/falco/test/driver-loader/run_test.sh /tmp/ws/build/release/
# Code quality
"quality-static-analysis":
docker:
- image: falcosecurity/falco-builder:latest
environment:
BUILD_TYPE: "release"
steps:
- run:
name: Install cppcheck
command: |
yum update -y
yum install epel-release -y
yum install cppcheck cppcheck-htmlreport -y
- checkout:
path: /source/falco
- run:
name: Prepare project
command: /usr/bin/entrypoint cmake
- run:
name: cppcheck
command: /usr/bin/entrypoint cppcheck
- run:
name: cppcheck html report
command: /usr/bin/entrypoint cppcheck_htmlreport
- store_artifacts:
path: /build/release/static-analysis-reports
destination: /static-analysis-reports
# Sign rpm packages
"rpm-sign":
docker:
- image: falcosecurity/falco-builder:latest
- image: docker.io/centos:7
steps:
- attach_workspace:
at: /
@@ -232,7 +225,7 @@ jobs:
name: Install rpmsign
command: |
yum update -y
yum install rpm-sign -y
yum install rpm-sign expect which -y
- run:
name: Prepare
command: |
@@ -265,6 +258,7 @@ jobs:
paths:
- build/release/*.rpm
- build-arm64/release/*.rpm
# Publish the dev packages
"publish-packages-dev":
docker:
@@ -754,7 +748,6 @@ workflows:
- "build-musl"
- "build-arm64"
- "build-centos7"
- "quality-static-analysis"
- "tests-integration":
requires:
- "build-centos7"

View File

@@ -1,8 +1,7 @@
<!-- Thanks for sending a pull request! Here are some tips for you:
1. If this is your first time, please read our contributor guidelines in the [CONTRIBUTING.md](https://github.com/falcosecurity/.github/blob/master/CONTRIBUTING.md) file and learn how to compile Falco from source [here](https://falco.org/docs/source).
<!-- Thanks for sending a pull request! Here are some tips for you:
1. If this is your first time, please read our contributor guidelines in the https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md file.
2. Please label this pull request according to what type of issue you are addressing.
3. . Please add a release note!
3. Please add a release note!
4. If the PR is unfinished while opening it specify a wip in the title before the actual title, for example, "wip: my awesome feature"
-->
@@ -24,12 +23,6 @@
> /kind release
> If contributing rules or changes to rules, please make sure to also uncomment one of the following line:
> /kind rule-update
> /kind rule-create
<!--
Please remove the leading whitespace before the `/kind <>` you uncommented.
-->
@@ -42,8 +35,6 @@ Please remove the leading whitespace before the `/kind <>` you uncommented.
> /area engine
> /area rules
> /area tests
> /area proposals
@@ -71,11 +62,13 @@ Fixes #
**Does this PR introduce a user-facing change?**:
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below.
If the PR requires additional action from users switching to the new release, prepend the string "action required:".
For example, `action required: change the API interface of the rule engine`.
If NO, just write "NONE" in the release-note block below.
If YES, a release note is required, enter your release note in the block below.
The convention is the same as for commit messages: https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md#commit-convention
If the PR introduces non-backward compatible changes, please add a line starting with "BREAKING CHANGE:" and describe what changed.
For example, `BREAKING CHANGE: the API interface of the rule engine has changed`.
Your note will be included in the changelog.
-->
```release-note

View File

@@ -14,6 +14,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Update base image
run: sudo apt update -y
@@ -47,6 +48,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Update base image
run: sudo apt update -y
@@ -80,6 +82,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Update base image
run: sudo apt update -y
@@ -105,66 +108,3 @@ jobs:
pushd build
make tests
popd
build-ubuntu-bionic:
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Update base image
run: sudo apt update -y
- name: Install build dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt install cmake build-essential clang llvm git linux-headers-$(uname -r) pkg-config autoconf libtool libelf-dev -y
- name: Prepare project
run: |
mkdir build
pushd build
cmake -DBUILD_BPF=On -DUSE_BUNDLED_DEPS=On ..
popd
- name: Build
run: |
pushd build
KERNELDIR=/lib/modules/$(uname -r)/build make -j4 all
popd
- name: Run unit tests
run: |
pushd build
make tests
popd
build-centos7-debug:
runs-on: ubuntu-latest
container:
image: falcosecurity/falco-builder:latest
env:
BUILD_TYPE: "debug"
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
path: falco
- name: Link falco repo to /source/falco
run: |
mkdir -p /source
ln -s "$GITHUB_WORKSPACE/falco" /source/falco
- name: Prepare project
run: /usr/bin/entrypoint cmake
- name: Build
run: /usr/bin/entrypoint all
- name: Run unit tests
run: /usr/bin/entrypoint tests
- name: Build packages
run: /usr/bin/entrypoint package

31
.github/workflows/staticanalysis.yaml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: StaticAnalysis
on:
pull_request:
jobs:
staticanalysis:
runs-on: ubuntu-22.04
steps:
- name: Checkout ⤵️
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install build dependencies ⛓️
run: |
sudo apt update -y
sudo apt install build-essential git cppcheck cmake -y
- name: Build and run cppcheck 🏎️
run: |
mkdir build
cd build && cmake -DUSE_BUNDLED_DEPS=On -DBUILD_WARNINGS_AS_ERRORS=ON -DCREATE_TEST_TARGETS=Off -DCMAKE_BUILD_TYPE="release" -DBUILD_BPF=Off -DBUILD_DRIVER=Off ..
make -j4 cppcheck
make -j4 cppcheck_htmlreport
- name: Upload reports ⬆️
uses: actions/upload-artifact@v3
with:
name: static-analysis-reports
path: ./build/static-analysis-reports

4
.gitmodules vendored Normal file
View File

@@ -0,0 +1,4 @@
[submodule "submodules/falcosecurity-rules"]
path = submodules/falcosecurity-rules
url = https://github.com/falcosecurity/rules.git
branch = main

View File

@@ -1,5 +1,111 @@
# Change Log
## v0.34.0
Released on 2023-02-07
### Major Changes
* BREAKING CHANGE: if you relied upon `application_rules.yaml` you can download it from https://github.com/falcosecurity/rules/tree/main/rules and manually install it. [[#2389](https://github.com/falcosecurity/falco/pull/2389)] - [@leogr](https://github.com/leogr)
* new(rules): New rule to detect attempts to inject code into a process using PTRACE [[#2226](https://github.com/falcosecurity/falco/pull/2226)] - [@Brucedh](https://github.com/Brucedh)
* new(engine): Also include exact locations for rule condition compile errors (missing macros, etc). [[#2216](https://github.com/falcosecurity/falco/pull/2216)] - [@mstemm](https://github.com/mstemm)
* new(scripts): Support older RHEL distros in falco-driver-loader script [[#2312](https://github.com/falcosecurity/falco/pull/2312)] - [@gentooise](https://github.com/gentooise)
* new(scripts): add `falcoctl` config into Falco package [[#2390](https://github.com/falcosecurity/falco/pull/2390)] - [@Andreagit97](https://github.com/Andreagit97)
* new(userspace/falco): [EXPERIMENTAL] allow modern bpf probe to assign more than one CPU to a single ring buffer [[#2363](https://github.com/falcosecurity/falco/pull/2363)] - [@Andreagit97](https://github.com/Andreagit97)
* new(userspace/falco): add webserver endpoint for retrieving internal version numbers [[#2356](https://github.com/falcosecurity/falco/pull/2356)] - [@jasondellaluce](https://github.com/jasondellaluce)
* new(falco): add --version-json to print version information in json format [[#2331](https://github.com/falcosecurity/falco/pull/2331)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(scripts): support multiple drivers in systemd units [[#2242](https://github.com/falcosecurity/falco/pull/2242)] - [@FedeDP](https://github.com/FedeDP)
* new(scripts): add bottlerocket support in falco-driver-loader [[#2318](https://github.com/falcosecurity/falco/pull/2318)] - [@FedeDP](https://github.com/FedeDP)
* new(falco): add more version fields to --support and --version [[#2325](https://github.com/falcosecurity/falco/pull/2325)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(config): explicitly add the `simulate_drops` config [[#2260](https://github.com/falcosecurity/falco/pull/2260)] - [@Andreagit97](https://github.com/Andreagit97)
### Minor Changes
* build: upgrade to `falcoctl` v0.4.0 [[#2406](https://github.com/falcosecurity/falco/pull/2406)] - [@loresuso](https://github.com/loresuso)
* update(userspace): change `modern_bpf.cpus_for_each_syscall_buffer` default value [[#2404](https://github.com/falcosecurity/falco/pull/2404)] - [@Andreagit97](https://github.com/Andreagit97)
* update(build): update falcoctl to 0.3.0 [[#2401](https://github.com/falcosecurity/falco/pull/2401)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(build): update falcoctl to 0.3.0-rc7 [[#2396](https://github.com/falcosecurity/falco/pull/2396)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(cmake): bump libs to 0.10.3 [[#2392](https://github.com/falcosecurity/falco/pull/2392)] - [@FedeDP](https://github.com/FedeDP)
* build: `/etc/falco/rules.available` has been deprecated [[#2389](https://github.com/falcosecurity/falco/pull/2389)] - [@leogr](https://github.com/leogr)
* build: `application_rules.yaml` is not shipped anymore with Falco [[#2389](https://github.com/falcosecurity/falco/pull/2389)] - [@leogr](https://github.com/leogr)
* build: upgrade k8saudit plugin to v0.5.0 [[#2381](https://github.com/falcosecurity/falco/pull/2381)] - [@leogr](https://github.com/leogr)
* build: upgrade cloudtrail plugin to v0.6.0 [[#2381](https://github.com/falcosecurity/falco/pull/2381)] - [@leogr](https://github.com/leogr)
* new!: ship falcoctl inside Falco [[#2345](https://github.com/falcosecurity/falco/pull/2345)] - [@FedeDP](https://github.com/FedeDP)
* refactor: remove rules and add submodule to falcosecurity/rules [[#2359](https://github.com/falcosecurity/falco/pull/2359)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(scripts): add option for regenerating signatures of all dev and release packages [[#2364](https://github.com/falcosecurity/falco/pull/2364)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update: print JSON version output when json_output is enabled [[#2351](https://github.com/falcosecurity/falco/pull/2351)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(cmake): updated libs to 0.10.1 tag. [[#2362](https://github.com/falcosecurity/falco/pull/2362)] - [@FedeDP](https://github.com/FedeDP)
* Install the certificates of authorities in falco:no-driver docker image [[#2355](https://github.com/falcosecurity/falco/pull/2355)] - [@Issif](https://github.com/Issif)
* update: Mesos support is now deprecated and will be removed in the next version. [[#2328](https://github.com/falcosecurity/falco/pull/2328)] - [@leogr](https://github.com/leogr)
* update(scripts/falco-driver-loader): optimize the resiliency of module download script for air-gapped environments [[#2336](https://github.com/falcosecurity/falco/pull/2336)] - [@Dentrax](https://github.com/Dentrax)
* doc(userspace): provide users with a correct message when some syscalls are not defined [[#2329](https://github.com/falcosecurity/falco/pull/2329)] - [@Andreagit97](https://github.com/Andreagit97)
* update(ci): update ci jobs to generate Falco images with the modern BPF probe [[#2320](https://github.com/falcosecurity/falco/pull/2320)] - [@Andreagit97](https://github.com/Andreagit97)
* rules: add Falco container lists [[#2290](https://github.com/falcosecurity/falco/pull/2290)] - [@oscr](https://github.com/oscr)
* rules(macro: private_key_or_password): now also check for OpenSSH private keys [[#2284](https://github.com/falcosecurity/falco/pull/2284)] - [@oscr](https://github.com/oscr)
* update(cmake): bump libs and driver to latest RC. [[#2302](https://github.com/falcosecurity/falco/pull/2302)] - [@FedeDP](https://github.com/FedeDP)
* Ensure that a ruleset object is copied properly in falco_engine::add_source(). [[#2271](https://github.com/falcosecurity/falco/pull/2271)] - [@mstemm](https://github.com/mstemm)
* update(userspace/falco): enable using zlib with webserver [[#2125](https://github.com/falcosecurity/falco/pull/2125)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(falco): add container-gvisor and kubernetes-gvisor print options [[#2288](https://github.com/falcosecurity/falco/pull/2288)] - [@LucaGuerra](https://github.com/LucaGuerra)
* cleanup: always use bundled libz and libelf in BUNDLED_DEPS mode. [[#2277](https://github.com/falcosecurity/falco/pull/2277)] - [@FedeDP](https://github.com/FedeDP)
* update: updated libs and driver to version dd443b67c6b04464cb8ee2771af8ada8777e7fac [[#2277](https://github.com/falcosecurity/falco/pull/2277)] - [@FedeDP](https://github.com/FedeDP)
* update(falco.yaml): `open_params` under plugins configuration is now trimmed from surrounding whitespace [[#2267](https://github.com/falcosecurity/falco/pull/2267)] - [@yardenshoham](https://github.com/yardenshoham)
### Bug Fixes
* fix(engine): Avoid crash related to caching syscall source when the falco engine uses multiple sources at the same time. [[#2272](https://github.com/falcosecurity/falco/pull/2272)] - [@mstemm](https://github.com/mstemm)
* fix(scripts): use falco-driver-loader only into install scripts [[#2391](https://github.com/falcosecurity/falco/pull/2391)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(userspace/falco): fix grpc server shutdown [[#2350](https://github.com/falcosecurity/falco/pull/2350)] - [@FedeDP](https://github.com/FedeDP)
* fix(docker/falco): trust latest GPG key [[#2365](https://github.com/falcosecurity/falco/pull/2365)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(userspace/engine): improve rule loading validation results [[#2344](https://github.com/falcosecurity/falco/pull/2344)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix: graceful error handling for macros/lists reference loops [[#2311](https://github.com/falcosecurity/falco/pull/2311)] - [@jasondellaluce](https://github.com/jasondellaluce)
### Rule Changes
* rules(tagging): enhanced rules tagging for inventory / threat modeling [[#2167](https://github.com/falcosecurity/falco/pull/2167)] - [@incertum](https://github.com/incertum)
* rule(Outbound Connection to C2 Server): Update the "Outbound connection to C2 server" rule to match both FQDN and IP addresses. Prior to this change, the rule only matched IP addresses and not FQDN. [[#2241](https://github.com/falcosecurity/falco/pull/2241)] - [@Nicolas-Peiffer](https://github.com/Nicolas-Peiffer)
* rule(Execution from /dev/shm): new rule to detect execution from /dev/shm [[#2225](https://github.com/falcosecurity/falco/pull/2225)] - [@AlbertoPellitteri](https://github.com/AlbertoPellitteri)
* rule(Find AWS Credentials): new rule to detect executions looking for AWS credentials [[#2224](https://github.com/falcosecurity/falco/pull/2224)] - [@AlbertoPellitteri](https://github.com/AlbertoPellitteri)
* rule(Linux Kernel Module Injection Detected): improve insmod detection within container using CAP_SYS_MODULE [[#2305](https://github.com/falcosecurity/falco/pull/2305)] - [@loresuso](https://github.com/loresuso)
* rule(Read sensitive file untrusted): let salt-call read sensitive files [[#2291](https://github.com/falcosecurity/falco/pull/2291)] - [@vin01](https://github.com/vin01)
* rule(macro: rpm_procs): let salt-call write to rpm database [[#2291](https://github.com/falcosecurity/falco/pull/2291)] - [@vin01](https://github.com/vin01)
### Non user-facing changes
* fix(ci): fix rpm sign job dependencies [[#2324](https://github.com/falcosecurity/falco/pull/2324)] - [@cappellinsamuele](https://github.com/cappellinsamuele)
* chore(userspace): add `njson` lib as a dependency for `falco_engine` [[#2316](https://github.com/falcosecurity/falco/pull/2316)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(scripts): force rpm postinstall script to always show dialog, even on upgrade [[#2405](https://github.com/falcosecurity/falco/pull/2405)] - [@FedeDP](https://github.com/FedeDP)
* fix(scripts): fixed falcoctl config install dir. [[#2399](https://github.com/falcosecurity/falco/pull/2399)] - [@FedeDP](https://github.com/FedeDP)
* fix(scripts): make /usr writable [[#2398](https://github.com/falcosecurity/falco/pull/2398)] - [@therealbobo](https://github.com/therealbobo)
* fix(scripts): driver loader insmod [[#2388](https://github.com/falcosecurity/falco/pull/2388)] - [@FedeDP](https://github.com/FedeDP)
* update(systemd): solve some issues with systemd unit [[#2385](https://github.com/falcosecurity/falco/pull/2385)] - [@Andreagit97](https://github.com/Andreagit97)
* build(cmake): upgrade falcoctl to v0.3.0-rc6 [[#2383](https://github.com/falcosecurity/falco/pull/2383)] - [@leogr](https://github.com/leogr)
* docs(.github): rules are no longer in this repo [[#2382](https://github.com/falcosecurity/falco/pull/2382)] - [@leogr](https://github.com/leogr)
* update(CI): mitigate frequent failure in CircleCI jobs [[#2375](https://github.com/falcosecurity/falco/pull/2375)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(userspace): use the right path for the `cpus_for_each_syscall_buffer` config [[#2378](https://github.com/falcosecurity/falco/pull/2378)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(scripts): fixed incorrect bash var expansion [[#2367](https://github.com/falcosecurity/falco/pull/2367)] - [@therealbobo](https://github.com/therealbobo)
* update(CI): upgrade toolchain in modern falco builder dockerfile [[#2337](https://github.com/falcosecurity/falco/pull/2337)] - [@Andreagit97](https://github.com/Andreagit97)
* cleanup(ci): move static analysis job from circle CI to GHA [[#2332](https://github.com/falcosecurity/falco/pull/2332)] - [@Andreagit97](https://github.com/Andreagit97)
* update(falco): update cpp-httplib to 0.11.3 [[#2327](https://github.com/falcosecurity/falco/pull/2327)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(script): makes user able to pass custom option to driver-loade… [[#1901](https://github.com/falcosecurity/falco/pull/1901)] - [@andreabonanno](https://github.com/andreabonanno)
* cleanup(ci): remove some unused jobs and remove some `falco-builder` reference where possible [[#2322](https://github.com/falcosecurity/falco/pull/2322)] - [@Andreagit97](https://github.com/Andreagit97)
* docs(proposal): new artifacts distribution proposal [[#2304](https://github.com/falcosecurity/falco/pull/2304)] - [@leogr](https://github.com/leogr)
* fix(cmake): properly fetch dev version by appending latest Falco tag, delta between master and tag, and hash [[#2292](https://github.com/falcosecurity/falco/pull/2292)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump certifi from 2020.4.5.1 to 2022.12.7 in /test [[#2313](https://github.com/falcosecurity/falco/pull/2313)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore: remove string view lite [[#2307](https://github.com/falcosecurity/falco/pull/2307)] - [@leogr](https://github.com/leogr)
* new(CHANGELOG): add entry for 0.33.1 (in master branch this time) [[#2303](https://github.com/falcosecurity/falco/pull/2303)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(docs): add overview and versioning sections to falco release.md [[#2205](https://github.com/falcosecurity/falco/pull/2205)] - [@incertum](https://github.com/incertum)
* Add Xenit AB to adopters [[#2285](https://github.com/falcosecurity/falco/pull/2285)] - [@NissesSenap](https://github.com/NissesSenap)
* fix(userspace/falco): verify engine fields only for syscalls [[#2281](https://github.com/falcosecurity/falco/pull/2281)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(output): do not print syscall_buffer_size when gvisor is enabled [[#2283](https://github.com/falcosecurity/falco/pull/2283)] - [@alacuku](https://github.com/alacuku)
* fix(engine): fix warning about redundant std::move [[#2286](https://github.com/falcosecurity/falco/pull/2286)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(scripts): force falco-driver-loader script to try to compile the driver anyway even on unsupported platforms [[#2219](https://github.com/falcosecurity/falco/pull/2219)] - [@FedeDP](https://github.com/FedeDP)
* fix(ci): fixed version bucket for release jobs. [[#2266](https://github.com/falcosecurity/falco/pull/2266)] - [@FedeDP](https://github.com/FedeDP)
## v0.33.1
Released on 2022-11-24

View File

@@ -201,7 +201,7 @@ if(NOT MINIMAL_BUILD)
endif()
# Rules
add_subdirectory(rules)
include(rules)
# Dockerfiles
add_subdirectory(docker)
@@ -228,5 +228,7 @@ if(NOT MUSL_OPTIMIZED_BUILD)
include(plugins)
endif()
include(falcoctl)
# Packages configuration
include(CPackConfig)

View File

@@ -80,6 +80,8 @@ For example, Falco can easily detect incidents including but not limited to:
- A standard system binary, such as `ls`, is making an outbound network connection.
- A privileged pod is started in a Kubernetes cluster.
The official Falco rules are maintained and released in [falcosecurity/rules](https://github.com/falcosecurity/rules/). That repository also contains the Falco rules inventory [document](https://github.com/falcosecurity/rules/blob/main/rules_inventory/rules_overview.md), which provides additional details around the default rules Falco ships with.
## Installing Falco
If you would like to run Falco in **production** please adhere to the [official installation guide](https://falco.org/docs/getting-started/installation/).

View File

@@ -21,15 +21,17 @@ Finally, the release process follows a transparent process described in more det
### Falco Binaries, Rules and Sources Artifacts - Quick Links
The Falco project publishes all sources and the Falco userspace binaries as GitHub releases. Rules are also released in the GitHub tree Falco release tag.
The Falco project publishes all sources and the Falco userspace binaries as GitHub releases.
- [Falco Releases](https://github.com/falcosecurity/falco/releases)
- `tgz`, `rpm` and `deb` Falco binary packages (contains sources, including driver sources, Falco rules as well as k8saudit and cloudtrail plugins)
- `tgz`, `zip` source code
- [Libs Releases](https://github.com/falcosecurity/libs/releases)
- `tgz`, `zip` source code
- Falco Rules (GitHub tree approach)
- RELEASE="x.y.z", `https://github.com/falcosecurity/falco/tree/${RELEASE}/rules`
- [Libs Releases](https://github.com/falcosecurity/libs/releases)
- `tgz`, `zip` source code
- [Falco Rules Releases](https://github.com/falcosecurity/rules/releases)
- `tgz`, `zip` source code, each ruleset is tagged separately in a mono-repo fashion, see the [rules release guidelines](https://github.com/falcosecurity/rules/blob/main/RELEASE.md)
Alternatively Falco binaries or plugins can be downloaded from the Falco Artifacts repo.
@@ -65,7 +67,7 @@ At a high level each Falco release needs to follow a pre-determined sequencing o
- [1 - 3] `libs` (+ `driver`) and `plugins` components releases
- [4] Falco driver pre-compiled object files push to Falco's Artifacts repo
- [5] Falco userspace binary + rules release
- [5] Falco userspace binary release
Finally, on the proposed due date the assignees for the upcoming release proceed with the processes described below.
@@ -189,7 +191,7 @@ This section provides more details around the versioning of all components that
### Falco repo (this repo)
- Falco version is a git tag (`x.y.z`), see [Procedures](#procedures) section. Note that the Falco version is a sem-ver-like schema, but not fully compatible with sem-ver.
- [FALCO_ENGINE_VERSION](https://github.com/falcosecurity/falco/blob/master/userspace/engine/falco_engine_version.h) is not sem-ver and must be bumped either when a backward incompatible change has been introduced to the rules files syntax or `falco --list -N | sha256sum` has changed. Breaking changes introduced in the Falco engine are not necessarily tied to the drivers or libs versions. The primary idea behind the hash is that when new filter / display fields (see currently supported [Falco fields](https://falco.org/docs/rules/supported-fields/)) are introduced a version bump indicates that this field was not available in previous engine versions. In case a new Falco rule uses new fields, the [Falco rules](https://github.com/falcosecurity/falco/blob/master/rules/falco_rules.yaml) file needs to bump this version as well via setting `required_engine_version` to the new version.
- [FALCO_ENGINE_VERSION](https://github.com/falcosecurity/falco/blob/master/userspace/engine/falco_engine_version.h) is not sem-ver and must be bumped either when a backward incompatible change has been introduced to the rules files syntax or `falco --list -N | sha256sum` has changed. Breaking changes introduced in the Falco engine are not necessarily tied to the drivers or libs versions. The primary idea behind the hash is that when new filter / display fields (see currently supported [Falco fields](https://falco.org/docs/rules/supported-fields/)) are introduced a version bump indicates that this field was not available in previous engine versions. See the [rules release guidelines](https://github.com/falcosecurity/rules/blob/main/RELEASE.md#versioning-a-ruleset) to understand how this affects the versioning of Falco rules.
- During development and release preparation, libs and driver reference commits are often bumped in Falco's cmake setup ([falcosecurity-libs cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/falcosecurity-libs.cmake#L30) and [driver cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/driver.cmake#L29)) in order to merge new Falco features. In practice they are mostly bumped at the same time referencing the same `libs` commit. However, for the official Falco build `FALCOSECURITY_LIBS_VERSION` flag that references the stable Libs version is used (read below).
- Similarly, Falco plugins versions are bumped in Falco's cmake setup ([plugins cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/plugins.cmake)) and those versions are the ones used for the Falco release.
- At release time Plugin, Libs and Driver versions are compatible with Falco.
@@ -200,6 +202,7 @@ This section provides more details around the versioning of all components that
Falco version: x.y.z (sem-ver like)
Libs version: x.y.z (sem-ver like)
Plugin API: x.y.z (sem-ver like)
Engine: x
Driver:
API version: x.y.z (sem-ver)
Schema version: x.y.z (sem-ver)
@@ -216,3 +219,8 @@ Driver:
- Plugins version is a git tag (`x.y.z`)
- See [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) for more information.
### Rules repo
- Rulesets are versioned individually through git tags
- See [rules release doc](https://github.com/falcosecurity/rules/blob/main/RELEASE.md) for more information.
- See [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) for more information about plugins rulesets.

View File

@@ -1,13 +1,11 @@
if(CPACK_GENERATOR MATCHES "DEB")
if(CPACK_GENERATOR MATCHES "DEB" OR CPACK_GENERATOR MATCHES "RPM")
list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/debian/falco.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/debian/falco_inject_kmod.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
endif()
if(CPACK_GENERATOR MATCHES "RPM")
list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/rpm/falco.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/rpm/falco_inject_kmod.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-kmod-inject.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-kmod.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-modern-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-custom.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falcoctl-artifact-follow.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
endif()
if(CPACK_GENERATOR MATCHES "TGZ")

View File

@@ -1,3 +1,3 @@
/etc/falco/falco.yaml
/etc/falco/rules.available/application_rules.yaml
/etc/falco/falcoctl.yaml
/etc/falco/falco_rules.local.yaml

View File

@@ -16,18 +16,39 @@ include(GetGitRevisionDescription)
# Create the falco version variable according to git index
if(NOT FALCO_VERSION)
string(STRIP "${FALCO_HASH}" FALCO_HASH)
# Try to obtain the exact git tag
git_get_exact_tag(FALCO_TAG)
if(NOT FALCO_TAG)
# Obtain the closest tag
git_describe(FALCO_VERSION "--always" "--tags" "--abbrev=7")
# Fallback version
if(FALCO_VERSION MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
endif()
# Format FALCO_VERSION to be semver with prerelease and build part
string(REPLACE "-g" "+" FALCO_VERSION "${FALCO_VERSION}")
# Obtain the closest tag
git_describe(FALCO_VERSION "--always" "--tags" "--abbrev=7")
string(REGEX MATCH "^[0-9]+.[0-9]+.[0-9]+$" FALCO_TAG ${FALCO_VERSION})
if(FALCO_VERSION MATCHES "NOTFOUND$" OR FALCO_TAG STREQUAL "")
# Fetch current hash
get_git_head_revision(refspec FALCO_HASH)
if(NOT FALCO_HASH OR FALCO_HASH MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Obtain the closest tag
git_get_latest_tag(FALCO_LATEST_TAG)
if(NOT FALCO_LATEST_TAG OR FALCO_LATEST_TAG MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Compute commit delta since tag
git_get_delta_from_tag(FALCO_DELTA ${FALCO_LATEST_TAG} ${FALCO_HASH})
if(NOT FALCO_DELTA OR FALCO_DELTA MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Cut hash to 7 bytes
string(SUBSTRING ${FALCO_HASH} 0 7 FALCO_HASH)
# Format FALCO_VERSION to be semver with prerelease and build part
set(FALCO_VERSION
"${FALCO_LATEST_TAG}-${FALCO_DELTA}+${FALCO_HASH}")
endif()
endif()
endif()
endif()
# Format FALCO_VERSION to be semver with prerelease and build part
string(REPLACE "-g" "+" FALCO_VERSION "${FALCO_VERSION}")
else()
# A tag has been found: use it as the Falco version
set(FALCO_VERSION "${FALCO_TAG}")

View File

@@ -86,29 +86,36 @@ function(get_git_head_revision _refspecvar _hashvar)
PARENT_SCOPE)
endfunction()
function(git_describe _var)
function(git_get_latest_tag _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
# We use git describe --tags `git rev-list --tags --max-count=1`
execute_process(COMMAND
"${GIT_EXECUTABLE}"
rev-list
--tags
--max-count=1
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND tail -n1
RESULT_VARIABLE
res
OUTPUT_VARIABLE
tag_hash
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${tag_hash}-${res}-NOTFOUND" PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
--tags
${tag_hash}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
@@ -120,10 +127,108 @@ function(git_describe _var)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_delta_from_tag _var tag hash)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
# Count commits in HEAD
execute_process(COMMAND
"${GIT_EXECUTABLE}"
rev-list
--count
${hash}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out_counter_head
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(${_var} "HEADCOUNT-NOTFOUND" PARENT_SCOPE)
return()
endif()
# Count commits in latest tag
execute_process(COMMAND
"${GIT_EXECUTABLE}"
rev-list
--count
${tag}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out_counter_tag
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(${_var} "TAGCOUNT-NOTFOUND" PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
expr
${out_counter_head} - ${out_counter_tag}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out_delta
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(${_var} "DELTA-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(${_var} "${out_delta}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var}
"GIT-NOTFOUND"
PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var}
"HEAD-HASH-NOTFOUND"
PARENT_SCOPE)
return()
endif()
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var}
"${out}"
PARENT_SCOPE)
"${out}"
PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)

View File

@@ -24,8 +24,8 @@ else()
ExternalProject_Add(cpp-httplib
PREFIX "${PROJECT_BINARY_DIR}/cpp-httplib-prefix"
URL "https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.10.4.tar.gz"
URL_HASH "SHA256=7719ff9f309c807dd8a574048764836b6a12bcb7d6ae9e129e7e4289cfdb4bd4"
URL "https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.11.3.tar.gz"
URL_HASH "SHA256=799b2daa0441d207f6cd1179ae3a34869722084a434da6614978be1682c1e12d"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")

View File

@@ -26,8 +26,8 @@ else()
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
# ie., `cmake -DDRIVER_VERSION=dev ..`
if(NOT DRIVER_VERSION)
set(DRIVER_VERSION "dd443b67c6b04464cb8ee2771af8ada8777e7fac")
set(DRIVER_CHECKSUM "SHA256=df373099d0f4cd4417a0103bb57f26c7412ffa86cde2bb2d579c6feba841626d")
set(DRIVER_VERSION "4.0.0+driver")
set(DRIVER_CHECKSUM "SHA256=0f71a4e4492847ce6ca35fe6f9ecdf682f603c878397e57d7628a0cd60a29aed")
endif()
# cd /path/to/build && cmake /path/to/source

View File

@@ -0,0 +1,36 @@
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
include(ExternalProject)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
set(FALCOCTL_VERSION "0.4.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "13c88e612efe955bc014918a7af30bae28dc5ba99b2962af57e36b1b87f527f9")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "0f8898853e99a2cd1b4dd6b161e8545cf20ce0e3ce79cddc539f6002257d5de5")
endif()
ExternalProject_Add(
falcoctl
URL "https://github.com/falcosecurity/falcoctl/releases/download/v${FALCOCTL_VERSION}/falcoctl_${FALCOCTL_VERSION}_${FALCOCTL_SYSTEM_NAME}_${FALCOCTL_SYSTEM_PROC_GO}.tar.gz"
URL_HASH "SHA256=${FALCOCTL_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(PROGRAMS "${PROJECT_BINARY_DIR}/falcoctl-prefix/src/falcoctl/falcoctl" DESTINATION "${FALCO_BIN_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")

View File

@@ -27,8 +27,8 @@ else()
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "dd443b67c6b04464cb8ee2771af8ada8777e7fac")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=df373099d0f4cd4417a0103bb57f26c7412ffa86cde2bb2d579c6feba841626d")
set(FALCOSECURITY_LIBS_VERSION "0.10.3")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=be6c771b9182fcd8fcd52cb56022c380edf6e051d1b0eee1983e093494ac0837")
endif()
# cd /path/to/build && cmake /path/to/source

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2021 The Falco Authors.
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -19,11 +19,11 @@ if(NOT DEFINED PLUGINS_COMPONENT_NAME)
set(PLUGINS_COMPONENT_NAME "${CMAKE_PROJECT_NAME}-plugins")
endif()
set(PLUGIN_K8S_AUDIT_VERSION "0.4.0")
set(PLUGIN_K8S_AUDIT_VERSION "0.5.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_K8S_AUDIT_HASH "ded0b5419f40084547620ccc48b19768e5e89457b85cfe8fbe496ca72267a3a4")
set(PLUGIN_K8S_AUDIT_HASH "c4abb288df018940be8e548340a74d39623b69142304e01523ea189bc698bc80")
else() # aarch64
set(PLUGIN_K8S_AUDIT_HASH "775cba666612114bc5b0c36f2e3c4557f5adbffcca2d77e72be87c6fcbf51ceb")
set(PLUGIN_K8S_AUDIT_HASH "3bcc849d9f95a3fa519b4592d0947149e492b530fb935a3f98f098e234b7baa7")
endif()
ExternalProject_Add(
@@ -39,18 +39,18 @@ install(FILES "${PROJECT_BINARY_DIR}/k8saudit-plugin-prefix/src/k8saudit-plugin/
ExternalProject_Add(
k8saudit-rules
URL "https://download.falco.org/plugins/stable/k8saudit-rules-${PLUGIN_K8S_AUDIT_VERSION}.tar.gz"
URL_HASH "SHA256=53948fac0345e718d673142a992ac820135f771141dfaa9719c7575ac8ae6878"
URL_HASH "SHA256=4383c69ba0ad63a127667c05618c37effc5297e6a7e68a1492acb0e48386540e"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
set(PLUGIN_CLOUDTRAIL_VERSION "0.6.0")
set(PLUGIN_CLOUDTRAIL_VERSION "0.7.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_CLOUDTRAIL_HASH "80e0c33f30c01a90efb7e9a671d978ff9679c462e3105020238abf31230e49a9")
set(PLUGIN_CLOUDTRAIL_HASH "85d94d8f5915804d5a30ff2f056e51de27d537f1fd1115050b4f4be6d32588cf")
else() # aarch64
set(PLUGIN_CLOUDTRAIL_HASH "a3e739932e66d44be848a68857fa15f56134d5246a1b9ab912c81f91b68fb23f")
set(PLUGIN_CLOUDTRAIL_HASH "61ae471ee41e76680da9ab66f583d1ec43a2e48fbad8c157caecef56e4aa5fb7")
endif()
ExternalProject_Add(
@@ -66,7 +66,7 @@ install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plu
ExternalProject_Add(
cloudtrail-rules
URL "https://download.falco.org/plugins/stable/cloudtrail-rules-${PLUGIN_CLOUDTRAIL_VERSION}.tar.gz"
URL_HASH "SHA256=e0dccb7b0f1d24b1e526a33ffd973ea5f2ac2879dbc999e119419ebfd24305ff"
URL_HASH "SHA256=c805be29ddc14fbffa29f7d6ee4f7e968a3bdb42da5f5483e5e6de273e8850c8"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")

View File

@@ -1,5 +1,5 @@
#
# Copyright (C) 2019 The Falco Authors.
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -11,8 +11,26 @@
# specific language governing permissions and limitations under the License.
#
# GNU standard installation directories' definitions
include(GNUInstallDirs)
include(ExternalProject)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-0.1.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM "SHA256=0d3705a4650f09d10e7831b16e7af59c1da34ff19e788896e9ee77010014db4d")
set(FALCOSECURITY_RULES_FALCO_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml")
ExternalProject_Add(
falcosecurity-rules-falco
URL "https://download.falco.org/rules/${FALCOSECURITY_RULES_FALCO_VERSION}.tar.gz"
URL_HASH "${FALCOSECURITY_RULES_FALCO_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
# falco_rules.local.yaml
set(FALCOSECURITY_RULES_LOCAL_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-local-prefix/falco_rules.local.yaml")
file(WRITE "${FALCOSECURITY_RULES_LOCAL_PATH}" "# Your custom rules!\n")
if(NOT DEFINED FALCO_ETC_DIR)
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
@@ -21,40 +39,32 @@ endif()
if(NOT DEFINED FALCO_RULES_DEST_FILENAME)
set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml")
set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml")
set(FALCO_APP_RULES_DEST_FILENAME "application_rules.yaml")
endif()
if(DEFINED FALCO_COMPONENT) # Allow a slim version of Falco to be embedded in other projects, intentionally *not* installing all rulesets.
install(
FILES falco_rules.yaml
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}")
install(
FILES falco_rules.local.yaml
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
else() # Default Falco installation
install(
FILES falco_rules.yaml
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES falco_rules.local.yaml
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES application_rules.yaml
DESTINATION "${FALCO_ETC_DIR}/rules.available"
RENAME "${FALCO_APP_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}")
install(DIRECTORY DESTINATION "${FALCO_ETC_DIR}/rules.d" COMPONENT "${FALCO_COMPONENT_NAME}")
endif()

8
docker/builder/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Builder folder
* We use `Dockerfile` to build the `centos7` Falco builder image.
* We use `modern-falco-builder.Dockerfile` to build Falco with the modern probe and return it as a Dockerfile output. This Dockerfile doesn't generate a Docker image but returns as output (through the `--output` command):
* Falco `tar.gz`.
* Falco `deb` package.
* Falco `rpm` package.
* Falco build directory, used by other CI jobs.

View File

@@ -0,0 +1,61 @@
FROM centos:7 AS build-stage
# To build Falco you need to pass the cmake option
ARG CMAKE_OPTIONS=""
ARG MAKE_JOBS=6
# Install all the dependencies
WORKDIR /
RUN yum -y install centos-release-scl; \
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++; \
source scl_source enable devtoolset-9; \
yum install -y git wget make m4 rpm-build
# With some previous cmake versions it fails when downloading `zlib` with curl in the libs building phase
RUN curl -L -o /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-$(uname -m).tar.gz; \
gzip -d /tmp/cmake.tar.gz; \
tar -xpf /tmp/cmake.tar --directory=/tmp; \
cp -R /tmp/cmake-3.22.5-linux-$(uname -m)/* /usr; \
rm -rf /tmp/cmake-3.22.5-linux-$(uname -m)/
# Copy Falco folder from the build context
COPY . /source
WORKDIR /build/release
RUN source scl_source enable devtoolset-9; \
cmake ${CMAKE_OPTIONS} /source; \
make falco -j${MAKE_JOBS}
RUN make package
# We need `make tests` and `make all` for integration tests.
RUN make tests -j${MAKE_JOBS}
RUN make all -j${MAKE_JOBS}
FROM scratch AS export-stage
ARG DEST_BUILD_DIR="/build"
COPY --from=build-stage /build/release/falco-*.tar.gz /packages/
COPY --from=build-stage /build/release/falco-*.deb /packages/
COPY --from=build-stage /build/release/falco-*.rpm /packages/
# This is what we need for integration tests. We don't export all the build directory
# outside the container since its size is almost 6 GB, we export only what is strictly necessary
# for integration tests.
# This is just a workaround to fix the CI build until we replace our actual testing framework.
COPY --from=build-stage /build/release/cloudtrail-plugin-prefix ${DEST_BUILD_DIR}/cloudtrail-plugin-prefix
COPY --from=build-stage /build/release/cloudtrail-rules-prefix ${DEST_BUILD_DIR}/cloudtrail-rules-prefix
COPY --from=build-stage /build/release/falcosecurity-rules-falco-prefix ${DEST_BUILD_DIR}/falcosecurity-rules-falco-prefix
COPY --from=build-stage /build/release/falcosecurity-rules-local-prefix ${DEST_BUILD_DIR}/falcosecurity-rules-local-prefix
COPY --from=build-stage /build/release/json-plugin-prefix ${DEST_BUILD_DIR}/json-plugin-prefix
COPY --from=build-stage /build/release/k8saudit-plugin-prefix ${DEST_BUILD_DIR}/k8saudit-plugin-prefix
COPY --from=build-stage /build/release/k8saudit-rules-prefix ${DEST_BUILD_DIR}/k8saudit-rules-prefix
COPY --from=build-stage /build/release/scripts ${DEST_BUILD_DIR}/scripts
COPY --from=build-stage /build/release/test ${DEST_BUILD_DIR}/test
COPY --from=build-stage /build/release/userspace/falco/falco ${DEST_BUILD_DIR}/userspace/falco/falco
COPY --from=build-stage /build/release/userspace/falco/config_falco.h ${DEST_BUILD_DIR}/userspace/falco/config_falco.h
COPY --from=build-stage /build/release/falco-*.tar.gz ${DEST_BUILD_DIR}/
COPY --from=build-stage /build/release/falco-*.deb ${DEST_BUILD_DIR}/
COPY --from=build-stage /build/release/falco-*.rpm ${DEST_BUILD_DIR}/

View File

@@ -88,7 +88,7 @@ RUN rm -rf /usr/bin/clang \
&& ln -s /usr/bin/clang-7 /usr/bin/clang \
&& ln -s /usr/bin/llc-7 /usr/bin/llc
RUN curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add - \
RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& echo "deb https://download.falco.org/packages/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
&& apt-get update -y \
&& if [ "$FALCO_VERSION" = "latest" ]; then apt-get install -y --no-install-recommends falco; else apt-get install -y --no-install-recommends falco=${FALCO_VERSION}; fi \

View File

@@ -6,7 +6,7 @@ ARG VERSION_BUCKET=bin
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
RUN apt-get -y update && apt-get -y install gridsite-clients curl
RUN apt-get -y update && apt-get -y install gridsite-clients curl ca-certificates
WORKDIR /

View File

@@ -15,7 +15,7 @@ RUN if [ "$TARGETARCH" = "amd64" ] ; then curl -L -o grpcurl.tar.gz \
https://github.com/fullstorydev/grpcurl/releases/download/v1.8.6/grpcurl_1.8.6_linux_arm64.tar.gz; \
fi;
RUN dnf install -y python-pip python docker findutils jq unzip && dnf clean all
RUN dnf install -y python-pip python docker findutils jq unzip sed curl && dnf clean all
ENV PATH="/root/.local/bin/:${PATH}"
RUN pip install --user avocado-framework==69.0
RUN pip install --user avocado-framework-plugin-varianter-yaml-to-mux==69.0

View File

@@ -150,6 +150,7 @@ syscall_event_drops:
- alert
rate: .03333
max_burst: 1
simulate_drops: false
# Falco uses a shared buffer between the kernel and userspace to receive
# the events (eg., system call information) in userspace.
@@ -224,6 +225,73 @@ syscall_event_timeouts:
syscall_buf_size_preset: 4
############## [EXPERIMENTAL] Modern BPF probe specific ##############
# Please note: these configs regard only the modern BPF probe. They
# are experimental so they could change over releases.
#
# `cpus_for_each_syscall_buffer`
#
# --- [Description]
#
# This is an index that controls how many CPUs you want to assign to a single
# syscall buffer (ring buffer). By default, every syscall buffer is associated to
# 2 CPUs, so the mapping is 1:2. The modern BPF probe allows you to choose different
# mappings, for example, 1:1 would mean a syscall buffer for each CPU.
#
# --- [Usage]
#
# You can choose between different indexes: from `0` to `MAX_NUMBER_ONLINE_CPUs`.
# `0` is a special value and it means a single syscall buffer shared between all
# your online CPUs. `0` has the same effect as `MAX_NUMBER_ONLINE_CPUs`, the rationale
# is that `0` allows you to create a single buffer without knowing the number of online
# CPUs on your system.
# Let's consider an example to better understand it:
#
# Consider a system with 7 online CPUs:
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
#
# - `1` means a syscall buffer for each CPU so 7 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 1 2 3 4 5 6
#
# - `2` (Default value) means a syscall buffer for each CPU pair, so 4 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 1 1 2 2 3
#
# Please note that we need 4 buffers, 3 buffers are associated with CPU pairs, the last
# one is mapped with just 1 CPU since we have an odd number of CPUs.
#
# - `0` or `MAX_NUMBER_ONLINE_CPUs` mean a syscall buffer shared between all CPUs, so 1 buffer
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 0 0 0 0 0
#
# Moreover you can combine this param with `syscall_buf_size_preset`
# index, for example, you could create a huge single syscall buffer
# shared between all your online CPUs of 512 MB (so `syscall_buf_size_preset=10`).
#
# --- [Suggestions]
#
# We chose index `2` (so one syscall buffer for each CPU pair) as default because the modern bpf probe
# follows a different memory allocation strategy with respect to the other 2 drivers (bpf and kernel module).
# By the way, you are free to find the preferred configuration for your system.
# Considering a fixed `syscall_buf_size_preset` and so a fixed buffer dimension:
# - a lower number of buffers can speed up your system (lower memory footprint)
# - a too lower number of buffers could increase contention in the kernel causing an
# overall slowdown of the system.
# If you don't have huge events throughputs and you are not experimenting with tons of drops
# you can try to reduce the number of buffers to have a lower memory footprint
modern_bpf:
cpus_for_each_syscall_buffer: 2
############## [EXPERIMENTAL] Modern BPF probe specific ##############
# Falco continuously monitors outputs performance. When an output channel does not allow
# to deliver an alert within a given deadline, an error is reported indicating
# which output is blocking notifications.
@@ -282,10 +350,17 @@ file_output:
stdout_output:
enabled: true
# Falco contains an embedded webserver that is used to implement an health
# endpoint for checking if Falco is up and running. These config options control
# the behavior of that webserver. By default, the webserver is enabled and
# the endpoint is /healthz.
# Falco supports an embedded webserver and exposes the following endpoints:
# - /healthz: health endpoint useful for checking if Falco is up and running
# (the endpoint name is configurable).
# - /versions: responds with a JSON object containing version numbers of the
# internal Falco components (similar output as `falco --version -o json_output=true`).
#
# # NOTE: the /versions endpoint is useful to other services (such as falcoctl)
# to retrieve info about a running Falco instance. Make sure the webserver is
# enabled if you're using falcoctl either locally or with Kubernetes.
#
# The following options control the behavior of that webserver (enabled by default).
#
# The ssl_certificate is a combination SSL Certificate and corresponding
# key contained in a single file. You can generate a key/cert as follows:

View File

@@ -0,0 +1,173 @@
# Artifacts distribution
This proposal aims to define guidelines for the official distribution of artifacts published by Falcosecurity.
Therefore, to create a unified management of the distribution of artifacts, this document supersedes (for the parts concerning the distributions of artifacts) proposals [Falco Artifacts Scope - Part 1](https://github.com/falcosecurity/falco/blob/master/proposals/20200506-artifacts-scope-part-1.md), [Falco Artifacts Scope - Part 2](https://github.com/falcosecurity/falco/blob/master/proposals/20200506-artifacts-scope-part-2.md), and [Falco Drivers Storage S3](https://github.com/falcosecurity/falco/blob/master/proposals/20201025-drivers-storage-s3.md) and also extends and generalizes the proposal [Falco Rules and Plugin distribution](https://github.com/falcosecurity/falcoctl/blob/main/proposals/20220916-rules-and-plugin-distribution.md) for [falcoctl](https://github.com/falcosecurity/falcoctl).
## Goals
- Allow users to consume artifacts in a consistent way
- Define official artifacts
- Unify distribution mechanism, infrastructure and tooling
- Provide generic guidelines applicable to any artifact to be distributed
## Non-Goals
- Infra/CI implementation details
- Supply chain security topics
## Proposal
With officially supported artifacts, we mean that set of artifacts published
by Falcosecurity as part of Falco or its ecosystem.
At the time of writing, the Falcosecurity organization distributes several kinds of artifacts in the form of files or container images. They include:
- Installation packages
- Helm charts
- Drivers (eg, kmod, eBPF)
- Rule files
- Plugins
- Other kinds may be added in the future.
Features shipped with **official artifacts are intended for general availability(GA)**, unless otherwise specified (eg. if experimental or non-production ready features are present, they must be indicated in the release notes).
The same artifacts can be distributed via multiple distribution channels, and each channel can be mirrored. **The [falco.org](https://falco.org/) website must list all official distribution channels and mirrors**. Any distribution channel not listed on our official website must not be considered part of the official distribution. However, maintainers can still use other channels for experimentation or incubating projects eventually.
### Distribution channels
#### HTTP Distribution
Distributing artifacts as plain files via HTTP is mostly intended for **humans, simple and legacy clients** (e.g., a shell script that downloads a file).
The allowed publishing channels are:
- **[download.falco.org](https://download.falco.org/)** where most of the file artifacts lives
- **endpoints made available by GitHub** for the Falcosecurity organization (e.g., release download URL, GitHub pages, etc.).
Typically, all official artifacts that can be shipped as plain files should be published at [download.falco.org](https://download.falco.org/) and available for download.
Using the GitHub platform is allowed as an alternative assuming that artifacts are published under the Falcosecurity organization and the GitHub platform usage limitations are being respected (a notable example is publishing a [Helm chart index file using GitHub pages](https://falcosecurity.github.io/charts/)).
It is allowed to publish other non-official artifacts (for example, [development builds](https://download.falco.org/?prefix=packages/bin-dev/)), taking that those are correctly denoted.
Introducing other HTTP channels is discouraged. Providing mirrors is discouraged unless required for technical reasons.
#### OCI Distribution
Some artifacts are in the form of Open Container Initiative (OCI) images and require OCI registries to be distributed. Nevertheless, since the [OCI Distribution Spec](https://specs.opencontainers.org/distribution-spec/?v=v1.0.0) allows any content, even regular files can be stored in OCI registries and distributed likewise. Notably, the [Helm project in early 2022 started storing charts in OCI](https://helm.sh/blog/storing-charts-in-oci/) registries. One our tool [falcoctl did the same](https://github.com/falcosecurity/falcoctl/blob/main/proposals/20220916-rules-and-plugin-distribution.md) later.
Distributing artifacts via OCI registries is intended for all compatible consumers (i.e., [falcoctl](https://github.com/falcosecurity/falcoctl)). It is **allowed and encouraged for any artifacts**. All official artifacts should be published so.
The allowed publishing channels are:
| Registry | Name | Account URL |
| -------- | -------- | -------- |
| `docker.io` | Docker Hub | https://hub.docker.com/u/falcosecurity |
| `ghcr.io` | Github Packages Container registry | https://github.com/orgs/falcosecurity/packages |
Both channels are equivalent and may publish the same artifacts. However, for historical reasons and to avoid confusion, the **`docker.io` registry should only be used for container images** and not for other kinds of artifacts (e.g., plugins, rules, etc.).
Mirrors are allowed and encouraged if they facilitate artifacts consumption by our users. This proposal reccomends to enable mirrors on the major public OCI registry, such as [Amazon ECR](https://gallery.ecr.aws/) (which is already implentend in our infra at the time of writing).
Official **channels and mirrors must be listed at [falco.org](https://falco.org/)**.
It is allowed to publish other non-official artifacts, even using image tags, taking that those are correctly denoted.
#### Other channels
At the time of writing, no other distribution channels are present or needed. However, in case a new kind of artifact will require a particular distribution mechanism (for example, in case an existing package manager system need to consume the artifact using its protocol), the rule of thumb is first to use the available GitHub features for the Falcosecurity organization, if possible. Users will quickly recognize the association between the artifact and the publisher (i.e., falcosecurity), and for that reason is usually preferable.
In all other cases, introducing a new distribution channel must require extensive discussion among maintainers. Nevertheless, **introducing too many distribution channels is discouraged** because it disperses the effort and can mislead users.
### Publishing
#### Source repository
Artifacts must always be built starting from the originating source code and thru an auditable and reproducible process that runs on our infra. It's recommended that the naming and versioning of the published artifact consistently match the originating repository's naming and versioning. For example, the package `falco-0.33.0-x86_64.tar.gz` must match the source code of the git tag [0.33.0](https://github.com/falcosecurity/falco/tree/0.33.0) of the [falco](https://github.com/falcosecurity/falco) repository.
It's recommended that **each repository publish only one kind of artifact** associated with it.
Exceptions are allowed for:
- mono repos (notably [charts](https://github.com/falcosecurity/charts) and [plugins](https://github.com/falcosecurity/plugins)),
- or whenever technical constraints impose a different approach (notably, our Driver Build Grid lives on [test-infra](https://github.com/falcosecurity/test-infra), but the source code is in [libs](https://github.com/falcosecurity/libs)).
Exceptions should be documented to avoid the users and contributors might be confused.
#### Namespacing
As a general rule, to avoid name clashing among different projects under the Falcosecurity organization, all **published artifacts should reflect the originating repository name** in their publishing URL. For example, all artifacts generated by the [falcosecurity/plugins](https://github.com/falcosecurity/plugins) repository should have `falcosecurity/plugins` as the URL's base path.
Exceptions are allowed for:
- legacy and already published artifacts (to avoid disruption);
- justified technical reasons.
#### Versioning
All published artifacts must be labeled with version numbers following the **[Semantic Versioning 2 specification](https://semver.org/)**.
For the [HTTP Distribution](#http-distribution), the version number must be reflected in the file name (including build metadata like the targeted arch and platform).
For the [OCI Distribution](#oci-distribution), the version number must be reflected in the image tag (build metadata may be avoided if included in the manifest).
### Tooling
Tooling is essential to deliver a consistent and straightforward UX to our users since the limited set of distribution channels is acceptable to provide just one (or a limited set of) tool(s) capable of working with various artifacts published by the Falcosecurity organization.
In this regard, this proposal follows up the [Falco Rules and Plugin distribution](https://github.com/falcosecurity/falcoctl/blob/main/proposals/20220916-rules-and-plugin-distribution.md) proposal and recommends to use of **[falcoctl](https://github.com/falcosecurity/falcoctl) as the tool to managing artifacts specifically intended for Falco**. The tool's design should consider that other kinds of artifacts may be added in the future.
Likewise, relying on existing **third-party tools for generic or well-known kinds of artifacts** (for example, Helm charts) is recommended.
### Ecosystem
Compatibility with other tools on the broader cloud native ecosystem should be considered when dealing with artifacts and their distribution.
It is also recommended to use third-party solutions and projects that facilitate our users' discovery of published artifacts (for example, https://artifacthub.io/).
## Action items
The following subsections indicate major action items to be executed in order to transition from the current to the desiderate state of the art, as noted in this proposal.
### Move [Falco rules](https://github.com/falcosecurity/falco/tree/master/rules) to their own repo
Falco rules files (i.e., the ruleset for the data source syscall) are currently only distributed in bundles with Falco. However, now falcoctl can manage rules artifacts so that we can ship them separately.
The benefits of having rules living in their repository are:
- dedicated versioning
- rules release will not be tied anymore to a Falco release (e.g., no need to wait for the scheduled Falco release to publish a new rule aiming to detect the latest published CVE)
- consistent installation/update mechanism with other rulesets (plugins rules are already published in their repository and can be consumed by falcoctl)
Note that this change will not introduce a breaking change: Falco will continue shipping the default ruleset by including the published ruleset package.
### Make `falcoctl` official
Considering the centrality of falcoctl for managing official artifacts for Falco, the falcoctl project must be promoted to "Official" status, and its repository assumed to be [core](https://github.com/falcosecurity/evolution/blob/main/GOVERNANCE.md#core-repositories).
### Deprecate `falco-driver-loader`
At the time of writing, `falco-driver-loader` is a shell script shipped in a bundle with Falco that has the responsibility of installing a driver by either downloading it from our distribution channels or trying to build it on-the-fly.
Our experience showed all the limitations of this approach, and it's now clear that such as script is hard to maintain. Furthermore, its responsibility overlaps with our aim to use `falcoctl` as the tool for managing artifacts.
Thus, this proposal mandates to deprecate of `falco-driver-loader` in favor of `falcoctl.`
However, to avoid user disruption and breaking legacy use case, it's recommended to provide still a faced script that exposes the same command line usage of `falco-driver-loader` but forward its execution to the new tool `falcoctl`.
This implicitly requires that `falcoctl` be shipped in a bundle with Falco.
### Update the documentation
This proposal mandates making use of official documentation (i.e., falco.org) to state official items, such as artifacts, distribution channels, and mirrors.
For that reason, it becomes imperative to update the documentation periodically concerning the list of officially supported distribution channels and mirrors.
### Usage of GitHub Packages
Since GitHub is the primary platform where the Falcosecurity organization hosts its code and infrastructure, its provided features should be preferred whenever possible.
This proposal recommends using the GitHub Packages feature when the need to distribute a new kind of artifact arises. Such as convention should be adopted among all repositories of the organization.

1
rules Symbolic link
View File

@@ -0,0 +1 @@
./submodules/falcosecurity-rules/rules

View File

@@ -1,10 +0,0 @@
approvers:
- mstemm
reviewers:
- leodido
- fntlnz
- mfdii
- kaizhe
- darryk10
labels:
- area/rules

View File

@@ -1,188 +0,0 @@
#
# Copyright (C) 2019 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
- required_engine_version: 2
################################################################
# By default all application-related rules are disabled for
# performance reasons. Depending on the application(s) you use,
# uncomment the corresponding rule definitions for
# application-specific activity monitoring.
################################################################
# Elasticsearch ports
- macro: elasticsearch_cluster_port
condition: fd.sport=9300
- macro: elasticsearch_api_port
condition: fd.sport=9200
- macro: elasticsearch_port
condition: elasticsearch_cluster_port or elasticsearch_api_port
# - rule: Elasticsearch unexpected network inbound traffic
# desc: inbound network traffic to elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and inbound and not elasticsearch_port
# output: "Inbound network traffic to Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Elasticsearch unexpected network outbound traffic
# desc: outbound network traffic from elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and outbound and not elasticsearch_cluster_port
# output: "Outbound network traffic from Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# ActiveMQ ports
- macro: activemq_cluster_port
condition: fd.sport=61616
- macro: activemq_web_port
condition: fd.sport=8161
- macro: activemq_port
condition: activemq_web_port or activemq_cluster_port
# - rule: Activemq unexpected network inbound traffic
# desc: inbound network traffic to activemq on a port other than the standard ports
# condition: user.name = activemq and inbound and not activemq_port
# output: "Inbound network traffic to ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Activemq unexpected network outbound traffic
# desc: outbound network traffic from activemq on a port other than the standard ports
# condition: user.name = activemq and outbound and not activemq_cluster_port
# output: "Outbound network traffic from ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# Cassandra ports
# https://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureFireWall_r.html
- macro: cassandra_thrift_client_port
condition: fd.sport=9160
- macro: cassandra_cql_port
condition: fd.sport=9042
- macro: cassandra_cluster_port
condition: fd.sport=7000
- macro: cassandra_ssl_cluster_port
condition: fd.sport=7001
- macro: cassandra_jmx_port
condition: fd.sport=7199
- macro: cassandra_port
condition: >
cassandra_thrift_client_port or
cassandra_cql_port or cassandra_cluster_port or
cassandra_ssl_cluster_port or cassandra_jmx_port
# - rule: Cassandra unexpected network inbound traffic
# desc: inbound network traffic to cassandra on a port other than the standard ports
# condition: user.name = cassandra and inbound and not cassandra_port
# output: "Inbound network traffic to Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Cassandra unexpected network outbound traffic
# desc: outbound network traffic from cassandra on a port other than the standard ports
# condition: user.name = cassandra and outbound and not (cassandra_ssl_cluster_port or cassandra_cluster_port)
# output: "Outbound network traffic from Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# Couchdb ports
# https://github.com/davisp/couchdb/blob/master/etc/couchdb/local.ini
- macro: couchdb_httpd_port
condition: fd.sport=5984
- macro: couchdb_httpd_ssl_port
condition: fd.sport=6984
# xxx can't tell what clustering ports are used. not writing rules for this
# yet.
# Fluentd ports
- macro: fluentd_http_port
condition: fd.sport=9880
- macro: fluentd_forward_port
condition: fd.sport=24224
# - rule: Fluentd unexpected network inbound traffic
# desc: inbound network traffic to fluentd on a port other than the standard ports
# condition: user.name = td-agent and inbound and not (fluentd_forward_port or fluentd_http_port)
# output: "Inbound network traffic to Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Tdagent unexpected network outbound traffic
# desc: outbound network traffic from fluentd on a port other than the standard ports
# condition: user.name = td-agent and outbound and not fluentd_forward_port
# output: "Outbound network traffic from Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# Gearman ports
# http://gearman.org/protocol/
# - rule: Gearman unexpected network outbound traffic
# desc: outbound network traffic from gearman on a port other than the standard ports
# condition: user.name = gearman and outbound and outbound and not fd.sport = 4730
# output: "Outbound network traffic from Gearman on unexpected port (connection=%fd.name)"
# priority: WARNING
# Zookeeper
- macro: zookeeper_port
condition: fd.sport = 2181
# Kafka ports
# - rule: Kafka unexpected network inbound traffic
# desc: inbound network traffic to kafka on a port other than the standard ports
# condition: user.name = kafka and inbound and fd.sport != 9092
# output: "Inbound network traffic to Kafka on unexpected port (connection=%fd.name)"
# priority: WARNING
# Memcached ports
# - rule: Memcached unexpected network inbound traffic
# desc: inbound network traffic to memcached on a port other than the standard ports
# condition: user.name = memcached and inbound and fd.sport != 11211
# output: "Inbound network traffic to Memcached on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Memcached unexpected network outbound traffic
# desc: any outbound network traffic from memcached. memcached never initiates outbound connections.
# condition: user.name = memcached and outbound
# output: "Unexpected Memcached outbound connection (connection=%fd.name)"
# priority: WARNING
# MongoDB ports
- macro: mongodb_server_port
condition: fd.sport = 27017
- macro: mongodb_shardserver_port
condition: fd.sport = 27018
- macro: mongodb_configserver_port
condition: fd.sport = 27019
- macro: mongodb_webserver_port
condition: fd.sport = 28017
# - rule: Mongodb unexpected network inbound traffic
# desc: inbound network traffic to mongodb on a port other than the standard ports
# condition: >
# user.name = mongodb and inbound and not (mongodb_server_port or
# mongodb_shardserver_port or mongodb_configserver_port or mongodb_webserver_port)
# output: "Inbound network traffic to MongoDB on unexpected port (connection=%fd.name)"
# priority: WARNING
# MySQL ports
# - rule: Mysql unexpected network inbound traffic
# desc: inbound network traffic to mysql on a port other than the standard ports
# condition: user.name = mysql and inbound and fd.sport != 3306
# output: "Inbound network traffic to MySQL on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: HTTP server unexpected network inbound traffic
# desc: inbound network traffic to a http server program on a port other than the standard ports
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING

View File

@@ -1,30 +0,0 @@
#
# Copyright (C) 2019 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
####################
# Your custom rules!
####################
# Add new rules, like this one
# - rule: The program "sudo" is run in a container
# desc: An event will trigger every time you run sudo in a container
# condition: evt.type = execve and evt.dir=< and container.id != host and proc.name = sudo
# output: "Sudo run in container (user=%user.name %container.info parent=%proc.pname cmdline=%proc.cmdline)"
# priority: ERROR
# tags: [users, container]
# Or override/append to any rule, macro, or list from the Default Rules

File diff suppressed because it is too large Load Diff

View File

@@ -15,28 +15,39 @@
# limitations under the License.
#
configure_file(debian/postinst.in debian/postinst)
configure_file(debian/postrm.in debian/postrm)
configure_file(debian/prerm.in debian/prerm)
# Systemd
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/scripts/systemd)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod-inject.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-modern-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-custom.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falcoctl-artifact-follow.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
file(COPY "${PROJECT_SOURCE_DIR}/scripts/debian/falco.service"
DESTINATION "${PROJECT_BINARY_DIR}/scripts/debian")
# Debian
configure_file(debian/postinst.in debian/postinst COPYONLY)
configure_file(debian/postrm.in debian/postrm COPYONLY)
configure_file(debian/prerm.in debian/prerm COPYONLY)
file(COPY "${PROJECT_SOURCE_DIR}/scripts/debian/falco_inject_kmod.service"
DESTINATION "${PROJECT_BINARY_DIR}/scripts/debian")
configure_file(rpm/postinstall.in rpm/postinstall)
configure_file(rpm/postuninstall.in rpm/postuninstall)
configure_file(rpm/preuninstall.in rpm/preuninstall)
file(COPY "${PROJECT_SOURCE_DIR}/scripts/rpm/falco.service"
DESTINATION "${PROJECT_BINARY_DIR}/scripts/rpm")
file(COPY "${PROJECT_SOURCE_DIR}/scripts/rpm/falco_inject_kmod.service"
DESTINATION "${PROJECT_BINARY_DIR}/scripts/rpm")
# Rpm
configure_file(rpm/postinstall.in rpm/postinstall COPYONLY)
configure_file(rpm/postuninstall.in rpm/postuninstall COPYONLY)
configure_file(rpm/preuninstall.in rpm/preuninstall COPYONLY)
configure_file(falco-driver-loader falco-driver-loader @ONLY)
# Install Falcoctl config file
if(NOT DEFINED FALCOCTL_ETC_DIR)
set(FALCOCTL_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falcoctl")
endif()
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/falcoctl/falcoctl.yaml DESTINATION "${FALCOCTL_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
install(PROGRAMS ${PROJECT_BINARY_DIR}/scripts/falco-driver-loader
DESTINATION ${FALCO_BIN_DIR} COMPONENT "${FALCO_COMPONENT_NAME}")

View File

@@ -1,13 +0,0 @@
[Unit]
Description=Falco: Container Native Runtime Security
Documentation=https://falco.org/docs/
Before=falco.service
Wants=falco.service
[Service]
Type=oneshot
User=root
ExecStart=/sbin/modprobe falco
[Install]
WantedBy=multi-user.target

View File

@@ -15,60 +15,85 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
chosen_driver=
# Every time we call this script we want to stat from a clean state.
echo "[POST-INSTALL] Disable all possible 'falco' services:"
systemctl --system stop 'falco-kmod.service' || true
systemctl --system stop 'falco-bpf.service' || true
systemctl --system stop 'falco-modern-bpf.service' || true
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
systemctl --system disable 'falco-kmod.service' || true
systemctl --system disable 'falco-bpf.service' || true
systemctl --system disable 'falco-modern-bpf.service' || true
systemctl --system disable 'falco-custom.service' || true
systemctl --system disable 'falcoctl-artifact-follow.service' || true
# unmask falcoctl if it was masked
systemctl --system unmask falcoctl-artifact-follow.service || true
if [ "$1" = "configure" ]; then
if [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
# If dialog is installed, create a dialog to let users choose the correct driver for them
CHOICE=$(dialog --clear --title "Falco drivers" --menu "Choose your preferred driver:" 12 55 4 \
1 "Manual configuration (no unit is started)" \
2 "Kmod" \
3 "eBPF" \
4 "Modern eBPF" \
2>&1 >/dev/tty)
case $CHOICE in
2)
chosen_driver="kmod"
;;
3)
chosen_driver="bpf"
;;
4)
chosen_driver="modern-bpf"
;;
esac
if [ -n "$chosen_driver" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
case $CHOICE in
2)
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
;;
esac
fi
clear
fi
fi
set -e
DKMS_PACKAGE_NAME="@PACKAGE_NAME@"
DKMS_VERSION="@DRIVER_VERSION@"
NAME="@PACKAGE_NAME@"
echo "[POST-INSTALL] Trigger deamon-reload:"
systemctl --system daemon-reload || true
postinst_found=0
case "$1" in
configure)
for DKMS_POSTINST in /usr/lib/dkms/common.postinst /usr/share/$DKMS_PACKAGE_NAME/postinst; do
if [ -f $DKMS_POSTINST ]; then
$DKMS_POSTINST $DKMS_PACKAGE_NAME $DKMS_VERSION /usr/share/$DKMS_PACKAGE_NAME "" $2
postinst_found=1
break
fi
done
if [ "$postinst_found" -eq 0 ]; then
echo "ERROR: DKMS version is too old and $DKMS_PACKAGE_NAME was not"
echo "built with legacy DKMS support."
echo "You must either rebuild $DKMS_PACKAGE_NAME with legacy postinst"
echo "support or upgrade DKMS to a more current version."
exit 1
fi
;;
# If needed, try to load/compile the driver through falco-driver-loader
case "$chosen_driver" in
"kmod")
# Only compile for kmod, in this way we use dkms
echo "[POST-INSTALL] Call 'falco-driver-loader --compile module':"
falco-driver-loader --compile module
;;
"bpf")
echo "[POST-INSTALL] Call 'falco-driver-loader bpf':"
falco-driver-loader bpf
;;
esac
# Based off what debhelper dh_systemd_enable/13.3.4 would have added
# ref: https://www.debian.org/doc/manuals/debmake-doc/ch05.en.html#debhelper
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask 'falco.service' >/dev/null || true
# was-enabled defaults to true, so new installations run enable.
if deb-systemd-helper --quiet was-enabled 'falco.service'; then
# Enables the unit on first installation, creates new
# symlinks on upgrades if the unit file has changed.
deb-systemd-helper enable 'falco.service' >/dev/null || true
else
# Update the statefile to add new symlinks (if any), which need to be
# cleaned up on purge. Also remove old symlinks.
deb-systemd-helper update-state 'falco.service' >/dev/null || true
fi
fi
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
deb-systemd-invoke $_dh_action 'falco.service' >/dev/null || true
if [ -n "$chosen_driver" ]; then
# we do this in 2 steps because `enable --now` is not always supported
echo "[POST-INSTALL] Enable 'falco-$chosen_driver.service':"
systemctl --system enable "falco-$chosen_driver.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_driver.service':"
systemctl --system start "falco-$chosen_driver.service" || true
fi
fi

View File

@@ -22,18 +22,13 @@
set -e
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
systemctl --system daemon-reload >/dev/null || true
fi
echo "[POST-REMOVE] Disable all Falco services:"
systemctl --system disable 'falco-kmod.service' || true
systemctl --system disable 'falco-bpf.service' || true
systemctl --system disable 'falco-modern-bpf.service' || true
systemctl --system disable 'falco-custom.service' || true
systemctl --system disable 'falcoctl-artifact-follow.service' || true
if [ "$1" = "remove" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper mask 'falco.service' >/dev/null || true
fi
fi
if [ "$1" = "purge" ]; then
if [ -x "/usr/bin/deb-systemd-helper" ]; then
deb-systemd-helper purge 'falco.service' >/dev/null || true
deb-systemd-helper unmask 'falco.service' >/dev/null || true
fi
echo "[POST-REMOVE] Trigger deamon-reload:"
systemctl --system daemon-reload || true
fi

View File

@@ -21,12 +21,16 @@ set -e
# ref: https://www.debian.org/doc/manuals/debmake-doc/ch05.en.html#debhelper
# Currently running falco service uses the driver, so stop it before driver cleanup
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
deb-systemd-invoke stop 'falco.service' >/dev/null || true
fi
case "$1" in
remove|upgrade|deconfigure)
/usr/bin/falco-driver-loader --clean
;;
remove|upgrade|deconfigure)
echo "[PRE-REMOVE] Stop all Falco services:"
systemctl --system stop 'falco-kmod.service' || true
systemctl --system stop 'falco-bpf.service' || true
systemctl --system stop 'falco-modern-bpf.service' || true
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
echo "[PRE-REMOVE] Call 'falco-driver-loader --clean:'"
falco-driver-loader --clean
;;
esac

View File

@@ -113,6 +113,9 @@ get_target_id() {
elif [ -f "${HOST_ROOT}/etc/centos-release" ]; then
# Older CentOS distros
OS_ID=centos
elif [ -f "${HOST_ROOT}/etc/redhat-release" ]; then
# Older RHEL distros
OS_ID=rhel
else
return 1
fi
@@ -159,6 +162,16 @@ get_target_id() {
exit 1
fi
;;
("bottlerocket")
TARGET_ID="${OS_ID}"
# variant_id has been sourced from os-release. Get only the first variant part
if [[ -n ${VARIANT_ID} ]]; then
# take just first part (eg: VARIANT_ID=aws-k8s-1.15 -> aws)
VARIANT_ID_CUT=${VARIANT_ID%%-*}
fi
# version_id has been sourced from os-release. Build a kernel version like: 1_1.11.0-aws
KERNEL_VERSION="1_${VERSION_ID}-${VARIANT_ID_CUT}"
;;
(*)
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
@@ -211,7 +224,13 @@ load_kernel_module_compile() {
fi
# Try to compile using all the available gcc versions
for CURRENT_GCC in $(which gcc) $(ls "$(dirname "$(which gcc)")"/gcc-* | grep 'gcc-[0-9]\+' | sort -n -r -k 2 -t -); do
for CURRENT_GCC in $(ls "$(dirname "$(which gcc)")"/gcc*); do
# Filter away gcc-{ar,nm,...}
# Only gcc compiler has `-print-search-dirs` option.
${CURRENT_GCC} -print-search-dirs 2>&1 | grep "install:"
if [ "$?" -ne "0" ]; then
continue
fi
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
@@ -232,14 +251,13 @@ load_kernel_module_compile() {
return
fi
echo "* ${DRIVER_NAME} module found: ${KO_FILE}"
echo "* Trying insmod"
echo "* Trying to insmod"
chcon -t modules_object_t "$KO_FILE" > /dev/null 2>&1 || true
if insmod "$KO_FILE" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
exit 0
else
echo "* Unable to insmod ${DRIVER_NAME} module"
fi
echo "* Unable to insmod ${DRIVER_NAME} module"
else
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
if [ -f "${DKMS_LOG}" ]; then
@@ -257,15 +275,14 @@ load_kernel_module_download() {
local URL=$(echo "${1}/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)
echo "* Trying to download a prebuilt ${DRIVER_NAME} module from ${URL}"
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
if curl -L --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
echo "* Download succeeded"
chcon -t modules_object_t "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
if insmod "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}"; then
echo "* Success: ${DRIVER_NAME} module found and inserted"
exit 0
else
>&2 echo "Unable to insmod the prebuilt ${DRIVER_NAME} module"
fi
fi
>&2 echo "Unable to insmod the prebuilt ${DRIVER_NAME} module"
else
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module"
return
@@ -484,7 +501,7 @@ load_bpf_probe_compile() {
mkdir -p /tmp/kernel
cd /tmp/kernel || exit
cd "$(mktemp -d -p /tmp/kernel)" || exit
if ! curl -L -o kernel-sources.tgz --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then
if ! curl -L -o kernel-sources.tgz --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} "${BPF_KERNEL_SOURCES_URL}"; then
>&2 echo "Unable to download the kernel sources"
return
fi
@@ -526,7 +543,7 @@ load_bpf_probe_download() {
echo "* Trying to download a prebuilt eBPF probe from ${URL}"
if ! curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" "${URL}"; then
if ! curl -L --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" "${URL}"; then
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} eBPF probe"
return 1
fi
@@ -598,6 +615,7 @@ print_usage() {
echo " DRIVERS_REPO specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " DRIVER_NAME specify a different name for the driver"
echo " DRIVER_INSECURE_DOWNLOAD whether you want to allow insecure downloads or not"
echo " DRIVER_CURL_OPTIONS specify additional options to be passed to curl command used to download Falco drivers"
echo ""
echo "Versions:"
echo " Falco version ${FALCO_VERSION}"
@@ -617,13 +635,15 @@ KERNEL_VERSION=$(uname -v | sed 's/#\([[:digit:]]\+\).*/\1/')
DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"}
FALCO_DRIVER_CURL_OPTIONS="-fsS --connect-timeout 5 --max-time 60 --retry 3 --retry-max-time 120"
if [ -n "$DRIVER_INSECURE_DOWNLOAD" ]
then
FALCO_DRIVER_CURL_OPTIONS=-fsSk
else
FALCO_DRIVER_CURL_OPTIONS=-fsS
FALCO_DRIVER_CURL_OPTIONS+=" -k"
fi
FALCO_DRIVER_CURL_OPTIONS+=" "${DRIVER_CURL_OPTIONS}
if [[ -z "$MAX_RMMOD_WAIT" ]]; then
MAX_RMMOD_WAIT=60
fi

View File

@@ -0,0 +1,9 @@
artifact:
follow:
every: 6h0m0s
falcoVersions: http://localhost:8765/versions
refs:
- falco-rules:0
indexes:
- name: falcosecurity
url: https://falcosecurity.github.io/falcoctl/index.yaml

View File

@@ -2,7 +2,7 @@
set -e
usage() {
echo "usage: $0 -f <package_x86_64.deb> -f <package_aarch64.deb> -r <deb|deb-dev>"
echo "usage: $0 -f <package_x86_64.deb> -f <package_aarch64.deb> -r <deb|deb-dev> [-s]"
exit 1
}
@@ -21,6 +21,18 @@ join_arr() {
echo "$*"
}
# Updates the signature of a DEB package in the local repository
#
# $1: path of the repository.
# $2: suite (eg. "stable")
# $3: path of the DEB file.
sign_deb() {
pushd $1/$2 > /dev/null
rm -f $(basename -- $3).asc
gpg --detach-sign --digest-algo SHA256 --armor $(basename -- $3)
popd > /dev/null
}
# Add a package to the local DEB repository
#
# $1: path of the repository.
@@ -28,10 +40,7 @@ join_arr() {
# $3: path of the DEB file.
add_deb() {
cp -f $3 $1/$2
pushd $1/$2 > /dev/null
rm -f $(basename -- $3).asc
gpg --detach-sign --digest-algo SHA256 --armor $(basename -- $3)
popd > /dev/null
sign_deb $1 $2 $3
# Get package architecture from dpkg
local arch=$(dpkg --info $3 | awk '/Architecture/ {printf "%s", $2}')
@@ -54,6 +63,27 @@ falco_arch_from_deb_arch() {
esac
}
# Sign the local DEB repository
#
# $1: path of the repository
# $2: suite (eg. "stable")
sign_repo() {
local release_dir=dists/$2
pushd $1 > /dev/null
# release signature - Release.gpg file
gpg --detach-sign --digest-algo SHA256 --armor ${release_dir}/Release
rm -f ${release_dir}/Release.gpg
mv ${release_dir}/Release.asc ${release_dir}/Release.gpg
# release signature - InRelease file
gpg --armor --sign --clearsign --digest-algo SHA256 ${release_dir}/Release
rm -f ${release_dir}/InRelease
mv ${release_dir}/Release.asc ${release_dir}/InRelease
popd > /dev/null
}
# Update the local DEB repository
#
# $1: path of the repository
@@ -88,21 +118,11 @@ update_repo() {
-o APT::FTPArchive::Release::Architectures="$(join_arr , "${architectures[@]}")" \
${release_dir} > ${release_dir}/Release
# release signature - Release.gpg file
gpg --detach-sign --digest-algo SHA256 --armor ${release_dir}/Release
rm -f ${release_dir}/Release.gpg
mv ${release_dir}/Release.asc ${release_dir}/Release.gpg
# release signature - InRelease file
gpg --armor --sign --clearsign --digest-algo SHA256 ${release_dir}/Release
rm -f ${release_dir}/InRelease
mv ${release_dir}/Release.asc ${release_dir}/InRelease
popd > /dev/null
}
# parse options
while getopts ":f::r:" opt; do
while getopts ":f::r::s" opt; do
case "${opt}" in
f )
files+=("${OPTARG}")
@@ -111,6 +131,9 @@ while getopts ":f::r:" opt; do
repo="${OPTARG}"
[[ "${repo}" == "deb" || "${repo}" == "deb-dev" ]] || usage
;;
s )
sign_all="true"
;;
: )
echo "invalid option: ${OPTARG} requires an argument" 1>&2
exit 1
@@ -124,7 +147,7 @@ done
shift $((OPTIND-1))
# check options
if [ ${#files[@]} -eq 0 ] || [ -z "${repo}" ]; then
if ([ ${#files[@]} -eq 0 ] && [ -z "${sign_all}" ]) || [ -z "${repo}" ]; then
usage
fi
@@ -147,24 +170,45 @@ echo "Fetching ${s3_bucket_repo}..."
mkdir -p ${tmp_repo_path}
aws s3 cp ${s3_bucket_repo} ${tmp_repo_path} --recursive
# update the repo
for file in "${files[@]}"; do
echo "Adding ${file}..."
add_deb ${tmp_repo_path} ${debSuite} ${file}
done
update_repo ${tmp_repo_path} ${debSuite}
# update signatures for all existing packages
if [ "${sign_all}" ]; then
for file in ${tmp_repo_path}/${debSuite}/*; do
if [ -f "$file" ]; then # exclude directories, symlinks, etc...
if [[ ! $file == *.asc ]]; then # exclude signature files
package=$(basename -- ${file})
echo "Signing ${package}..."
sign_deb ${tmp_repo_path} ${debSuite} ${file}
# publish
for file in "${files[@]}"; do
package=$(basename -- ${file})
echo "Publishing ${package} to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${debSuite}/${package} ${s3_bucket_repo}/${debSuite}/${package} --acl public-read
aws s3 cp ${tmp_repo_path}/${debSuite}/${package}.asc ${s3_bucket_repo}/${debSuite}/${package}.asc --acl public-read
echo "Syncing ${package}.asc to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${debSuite}/${package}.asc ${s3_bucket_repo}/${debSuite}/${package}.asc --acl public-read
fi
fi
done
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/*.asc
sign_repo ${tmp_repo_path} ${debSuite}
fi
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}.asc
done
# update the repo by adding new packages
if ! [ ${#files[@]} -eq 0 ]; then
for file in "${files[@]}"; do
echo "Adding ${file}..."
add_deb ${tmp_repo_path} ${debSuite} ${file}
done
update_repo ${tmp_repo_path} ${debSuite}
sign_repo ${tmp_repo_path} ${debSuite}
# publish
for file in "${files[@]}"; do
package=$(basename -- ${file})
echo "Publishing ${package} to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${debSuite}/${package} ${s3_bucket_repo}/${debSuite}/${package} --acl public-read
aws s3 cp ${tmp_repo_path}/${debSuite}/${package}.asc ${s3_bucket_repo}/${debSuite}/${package}.asc --acl public-read
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}.asc
done
fi
# sync dists
aws s3 sync ${tmp_repo_path}/dists ${s3_bucket_repo}/dists --delete --acl public-read
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/dists/*
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/dists/*

View File

@@ -2,7 +2,7 @@
set -e
usage() {
echo "usage: $0 -f <package_x86_64.rpm> -f <package_aarch64.rpm> -r <rpm|rpm-dev>"
echo "usage: $0 -f <package_x86_64.rpm> -f <package_aarch64.rpm> -r <rpm|rpm-dev> [-s]"
exit 1
}
@@ -14,15 +14,33 @@ check_program() {
fi
}
# Updates the signature of a RPM package in the local repository
#
# $1: path of the repository.
# $2: path of the RPM file.
sign_rpm() {
pushd $1 > /dev/null
rm -f $(basename -- $2).asc
gpg --detach-sign --digest-algo SHA256 --armor $(basename -- $2)
popd > /dev/null
}
# Add a package to the local RPM repository
#
# $1: path of the repository.
# $2: path of the RPM file.
add_rpm() {
cp -f $2 $1
sign_rpm $1 $2
}
# Sign the local RPM repository
#
# $1: path of the repository.
sign_repo() {
pushd $1 > /dev/null
rm -f $(basename -- $2).asc
gpg --detach-sign --digest-algo SHA256 --armor $(basename -- $2)
rm -f repodata/repomd.xml.asc
gpg --detach-sign --digest-algo SHA256 --armor repodata/repomd.xml
popd > /dev/null
}
@@ -32,14 +50,11 @@ add_rpm() {
update_repo() {
pushd $1 > /dev/null
createrepo --update --no-database .
rm -f repodata/repomd.xml.asc
gpg --detach-sign --digest-algo SHA256 --armor repodata/repomd.xml
popd > /dev/null
}
# parse options
while getopts ":f::r:" opt; do
while getopts ":f::r::s" opt; do
case "${opt}" in
f )
files+=("${OPTARG}")
@@ -48,6 +63,9 @@ while getopts ":f::r:" opt; do
repo="${OPTARG}"
[[ "${repo}" == "rpm" || "${repo}" == "rpm-dev" ]] || usage
;;
s )
sign_all="true"
;;
: )
echo "invalid option: ${OPTARG} requires an argument" 1>&2
exit 1
@@ -60,7 +78,7 @@ while getopts ":f::r:" opt; do
done
shift $((OPTIND-1))
if [ ${#files[@]} -eq 0 ] || [ -z "${repo}" ]; then
if ([ ${#files[@]} -eq 0 ] && [ -z "${sign_all}" ]) || [ -z "${repo}" ]; then
usage
fi
@@ -79,24 +97,45 @@ echo "Fetching ${s3_bucket_repo}..."
mkdir -p ${tmp_repo_path}
aws s3 cp ${s3_bucket_repo} ${tmp_repo_path} --recursive
# update the repo
for file in "${files[@]}"; do
echo "Adding ${file}..."
add_rpm ${tmp_repo_path} ${file}
done
update_repo ${tmp_repo_path}
# update signatures for all existing packages
if [ "${sign_all}" ]; then
for file in ${tmp_repo_path}/*; do
if [ -f "$file" ]; then # exclude directories, symlinks, etc...
if [[ ! $file == *.asc ]]; then # exclude signature files
package=$(basename -- ${file})
echo "Signing ${package}..."
sign_rpm ${tmp_repo_path} ${file}
# publish
for file in "${files[@]}"; do
package=$(basename -- ${file})
echo "Publishing ${package} to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${package} ${s3_bucket_repo}/${package} --acl public-read
aws s3 cp ${tmp_repo_path}/${package}.asc ${s3_bucket_repo}/${package}.asc --acl public-read
echo "Syncing ${package}.asc to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${package}.asc ${s3_bucket_repo}/${package}.asc --acl public-read
fi
fi
done
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/*.asc
sign_repo ${tmp_repo_path}
fi
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}.asc
done
# update the repo by adding new packages
if ! [ ${#files[@]} -eq 0 ]; then
for file in "${files[@]}"; do
echo "Adding ${file}..."
add_rpm ${tmp_repo_path} ${file}
done
update_repo ${tmp_repo_path}
sign_repo ${tmp_repo_path}
# publish
for file in "${files[@]}"; do
package=$(basename -- ${file})
echo "Publishing ${package} to ${s3_bucket_repo}..."
aws s3 cp ${tmp_repo_path}/${package} ${s3_bucket_repo}/${package} --acl public-read
aws s3 cp ${tmp_repo_path}/${package}.asc ${s3_bucket_repo}/${package}.asc --acl public-read
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}.asc
done
fi
# sync repodata
aws s3 sync ${tmp_repo_path}/repodata ${s3_bucket_repo}/repodata --delete --acl public-read
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/repodata/*
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/repodata/*

View File

@@ -1,13 +0,0 @@
[Unit]
Description=Falco: Container Native Runtime Security
Documentation=https://falco.org/docs/
Before=falco.service
Wants=falco.service
[Service]
Type=oneshot
User=root
ExecStart=/sbin/modprobe falco
[Install]
WantedBy=multi-user.target

View File

@@ -14,22 +14,78 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
chosen_driver=
# Every time we call this script we want to stat from a clean state.
echo "[POST-INSTALL] Disable all possible enabled 'falco' service:"
systemctl --system stop 'falco-kmod.service' || true
systemctl --system stop 'falco-bpf.service' || true
systemctl --system stop 'falco-modern-bpf.service' || true
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
systemctl --system disable 'falco-kmod.service' || true
systemctl --system disable 'falco-bpf.service' || true
systemctl --system disable 'falco-modern-bpf.service' || true
systemctl --system disable 'falco-custom.service' || true
systemctl --system disable 'falcoctl-artifact-follow.service' || true
# unmask falcoctl if it was masked
systemctl --system unmask falcoctl-artifact-follow.service || true
if [ $1 -ge 1 ]; then
if [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
# If dialog is installed, create a dialog to let users choose the correct driver for them
CHOICE=$(dialog --clear --title "Falco drivers" --menu "Choose your preferred driver:" 12 55 4 \
1 "Manual configuration (no unit is started)" \
2 "Kmod" \
3 "eBPF" \
4 "Modern eBPF" \
2>&1 >/dev/tty)
case $CHOICE in
2)
chosen_driver="kmod"
;;
3)
chosen_driver="bpf"
;;
4)
chosen_driver="modern-bpf"
;;
esac
if [ -n "$chosen_driver" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
case $CHOICE in
2)
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
;;
esac
fi
clear
fi
fi
set -e
mod_version="@DRIVER_VERSION@"
dkms add -m falco -v $mod_version --rpm_safe_upgrade
if [ `uname -r | grep -c "BOOT"` -eq 0 ] && [ -e /lib/modules/`uname -r`/build/include ]; then
dkms build -m falco -v $mod_version
dkms install --force -m falco -v $mod_version
elif [ `uname -r | grep -c "BOOT"` -gt 0 ]; then
echo -e ""
echo -e "Module build for the currently running kernel was skipped since you"
echo -e "are running a BOOT variant of the kernel."
else
echo -e ""
echo -e "Module build for the currently running kernel was skipped since the"
echo -e "kernel source for this kernel does not seem to be installed."
fi
echo "[POST-INSTALL] Trigger deamon-reload:"
systemctl --system daemon-reload || true
# If needed, try to load/compile the driver through falco-driver-loader
case "$chosen_driver" in
"kmod")
# Only compile for kmod, in this way we use dkms
echo "[POST-INSTALL] Call 'falco-driver-loader --compile module':"
falco-driver-loader --compile module
;;
"bpf")
echo "[POST-INSTALL] Call 'falco-driver-loader bpf':"
falco-driver-loader bpf
;;
esac
# validate rpm macros by `rpm -qp --scripts <rpm>`
# RPM scriptlets: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd
@@ -38,27 +94,14 @@ fi
# systemd_post macro expands to
# if postinst:
# `systemd-update-helper install-system-units <service>`
%systemd_post 'falco.service'
%systemd_post "falco-$chosen_driver.service"
# post install mirrored from .deb
if [ $1 -eq 1 ]; then
# This will only remove masks created on package removal.
/usr/bin/systemctl --system unmask 'falco.service' >/dev/null || true
# enable falco on installation
# note: DEB postinstall script checks for changed symlinks
/usr/bin/systemctl --system enable 'falco.service' >/dev/null || true
# start falco on installation
/usr/bin/systemctl --system start 'falco.service' >/dev/null || true
fi
# post upgrade mirrored from .deb
if [ $1 -gt 1 ]; then
if [ -d /run/systemd/system ]; then
/usr/bin/systemctl --system daemon-reload >/dev/null || true
# restart falco on upgrade if service is already running
/usr/bin/systemctl --system condrestart 'falco.service' >/dev/null || true
fi
# post install/upgrade mirrored from .deb
if [ $1 -ge 1 ]; then
if [ -n "$chosen_driver" ]; then
echo "[POST-INSTALL] Enable 'falco-$chosen_driver.service':"
systemctl --system enable "falco-$chosen_driver.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_driver.service':"
systemctl --system start "falco-$chosen_driver.service" || true
fi
fi

View File

@@ -17,17 +17,14 @@
set -e
# post uninstall mirrored from .deb
if [ -d /run/systemd/system ] && [ "$1" = 0 ]; then
/usr/bin/systemctl --system daemon-reload >/dev/null || true
/usr/bin/systemctl --system mask 'falco.service' >/dev/null || true
if [ -d /run/systemd/system ] && [ $1 -eq 0 ]; then
echo "[POST-REMOVE] Disable all Falco services:"
systemctl --system disable 'falco-kmod.service'|| true
systemctl --system disable 'falco-bpf.service' || true
systemctl --system disable 'falco-modern-bpf.service' || true
systemctl --system disable 'falco-custom.service' || true
systemctl --system disable 'falcoctl-artifact-follow.service' || true
echo "[POST-REMOVE] Trigger deamon-reload:"
systemctl --system daemon-reload || true
fi
# validate rpm macros by `rpm -qp --scripts <rpm>`
# RPM scriptlets: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_syntax
# systemd_postun_with_restart macro expands to
# if package upgrade, not uninstall:
# `systemd-update-helper mark-restart-system-units <service>`
%systemd_postun_with_restart 'falco.service'

View File

@@ -16,14 +16,16 @@
#
set -e
# pre uninstall mirrored from .deb
# Currently running falco service uses the driver, so stop it before driver cleanup
if [ -d /run/systemd/system ] && [ $1 -eq 0 ]; then
# stop falco service before uninstall
/usr/bin/systemctl --system stop 'falco.service' >/dev/null || true
fi
echo "[PRE-REMOVE] Stop all Falco services:"
systemctl --system stop 'falco-kmod.service' || true
systemctl --system stop 'falco-bpf.service' || true
systemctl --system stop 'falco-modern-bpf.service' || true
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
/usr/bin/falco-driver-loader --clean
echo "[PRE-REMOVE] Call 'falco-driver-loader --clean:'"
falco-driver-loader --clean
# validate rpm macros by `rpm -qp --scripts <rpm>`
# RPM scriptlets: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd
@@ -32,4 +34,8 @@ fi
# systemd_preun macro expands to
# if preuninstall:
# `systemd-update-helper remove-system-units <service>`
%systemd_preun 'falco.service'
%systemd_preun 'falco-kmod.service'
%systemd_preun 'falco-bpf.service'
%systemd_preun 'falco-modern-bpf.service'
%systemd_preun 'falco-custom.service'
%systemd_preun 'falcoctl-artifact-follow.service'

View File

@@ -1,14 +1,14 @@
[Unit]
Description=Falco: Container Native Runtime Security
Description=Falco: Container Native Runtime Security with ebpf
Documentation=https://falco.org/docs/
After=falco_inject_kmod.service
Requires=falco_inject_kmod.service
Before=falcoctl-artifact-follow.service
Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
Environment=FALCO_BPF_PROBE=
ExecStart=/usr/bin/falco --pidfile=/var/run/falco.pid
ExecStopPost=/sbin/rmmod falco
UMask=0077
TimeoutSec=30
RestartSec=15s
@@ -18,7 +18,6 @@ NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=full
ProtectKernelTunables=true
ReadWritePaths=/sys/module/falco
RestrictRealtime=true
RestrictAddressFamilies=~AF_PACKET
StandardOutput=null

View File

@@ -1,14 +1,13 @@
[Unit]
Description=Falco: Container Native Runtime Security
Description=Falco: Container Native Runtime Security with custom configuration
Documentation=https://falco.org/docs/
After=falco_inject_kmod.service
Requires=falco_inject_kmod.service
Before=falcoctl-artifact-follow.service
Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
User=%u
ExecStart=/usr/bin/falco --pidfile=/var/run/falco.pid
ExecStopPost=/sbin/rmmod falco
UMask=0077
TimeoutSec=30
RestartSec=15s
@@ -18,9 +17,9 @@ NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=full
ProtectKernelTunables=true
ReadWritePaths=/sys/module/falco
RestrictRealtime=true
RestrictAddressFamilies=~AF_PACKET
StandardOutput=null
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,11 @@
[Unit]
Description=Falco: Container Native Runtime Security with kmod, inject.
Documentation=https://falco.org/docs/
PartOf=falco-kmod.service
[Service]
Type=oneshot
RemainAfterExit=yes
User=root
ExecStart=/sbin/modprobe falco
ExecStop=/sbin/rmmod falco

View File

@@ -0,0 +1,29 @@
[Unit]
Description=Falco: Container Native Runtime Security with kmod
Documentation=https://falco.org/docs/
After=falco-kmod-inject.service
Requires=falco-kmod-inject.service
Before=falcoctl-artifact-follow.service
Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falco --pidfile=/var/run/falco.pid
UMask=0077
TimeoutSec=30
RestartSec=15s
Restart=on-failure
PrivateTmp=true
NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=full
ProtectKernelTunables=true
ReadWriteDirectories=/sys/module/falco
RestrictRealtime=true
RestrictAddressFamilies=~AF_PACKET
StandardOutput=null
[Install]
WantedBy=multi-user.target
Alias=falco.service

View File

@@ -0,0 +1,25 @@
[Unit]
Description=Falco: Container Native Runtime Security with modern ebpf
Documentation=https://falco.org/docs/
Before=falcoctl-artifact-follow.service
Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falco --pidfile=/var/run/falco.pid --modern-bpf
UMask=0077
TimeoutSec=30
RestartSec=15s
Restart=on-failure
PrivateTmp=true
NoNewPrivileges=yes
ProtectHome=read-only
ProtectSystem=full
ProtectKernelTunables=true
RestrictRealtime=true
RestrictAddressFamilies=~AF_PACKET
StandardOutput=null
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,22 @@
[Unit]
Description=Falcoctl Artifact Follow: automatic artifacts update service
Documentation=https://falco.org/docs/
PartOf=falco-bpf.service falco-kmod.service falco-modern-bpf.service falco-custom.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falcoctl artifact follow --allowed-types=rulesfile
UMask=0077
TimeoutSec=30
RestartSec=15s
Restart=on-failure
PrivateTmp=true
NoNewPrivileges=yes
ProtectSystem=true
ReadWriteDirectories=/usr/share/falco
ProtectKernelTunables=true
RestrictRealtime=true
[Install]
WantedBy=multi-user.target

View File

@@ -1,4 +1,6 @@
add_subdirectory(trace_files)
add_subdirectory(plugins)
add_subdirectory(confs/plugins)
if(NOT MUSL_OPTIMIZED_BUILD)
add_subdirectory(plugins)
add_subdirectory(confs/plugins)
endif()

View File

@@ -21,7 +21,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4/allow_only_apache_container.yaml
detect_counts:
@@ -33,7 +33,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4/allow_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -44,7 +44,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
detect_counts:
- Create Privileged Pod: 1
@@ -55,7 +55,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
@@ -66,7 +66,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_unprivileged.json
@@ -76,7 +76,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
detect_counts:
- Create HostNetwork Pod: 1
@@ -87,7 +87,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
@@ -99,7 +99,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_namespace_foo.yaml
detect_counts:
@@ -111,7 +111,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_namespace_foo.yaml
- ./rules/k8s_audit/allow_user_some-user.yaml
@@ -124,7 +124,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_only_apache_container.yaml
detect_counts:
@@ -136,7 +136,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -147,7 +147,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create Privileged Pod: 1
@@ -159,7 +159,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create Privileged Pod: 1
@@ -171,7 +171,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create Privileged Pod: 1
@@ -182,7 +182,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -192,7 +192,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_unprivileged.json
@@ -201,7 +201,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -212,7 +212,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create Sensitive Mount Pod: 1
@@ -224,7 +224,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create Sensitive Mount Pod: 1
@@ -235,7 +235,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -245,7 +245,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_unsensitive_mount.json
@@ -254,7 +254,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -265,7 +265,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Create HostNetwork Pod: 1
@@ -276,7 +276,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -286,7 +286,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_nohostnetwork.json
@@ -295,7 +295,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -306,7 +306,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/disallow_kactivity.yaml
detect_counts:
@@ -318,7 +318,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/disallow_kactivity.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -329,7 +329,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/disallow_kactivity.yaml
detect_counts:
@@ -341,7 +341,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/disallow_kactivity.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
@@ -352,7 +352,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Anonymous Request Allowed: 1
@@ -364,7 +364,7 @@ trace_files: !mux
detect_level: NOTICE
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Attach/Exec Pod: 1
@@ -376,7 +376,7 @@ trace_files: !mux
detect_level: NOTICE
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Attach/Exec Pod: 1
@@ -388,7 +388,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_user_some-user.yaml
detect_counts:
@@ -400,7 +400,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_namespace_foo.yaml
- ./rules/k8s_audit/disallow_kactivity.yaml
@@ -412,7 +412,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Pod Created in Kube Namespace: 1
@@ -424,7 +424,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Pod Created in Kube Namespace: 1
@@ -436,7 +436,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Service Account Created in Kube Namespace: 1
@@ -448,7 +448,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Service Account Created in Kube Namespace: 1
@@ -460,7 +460,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- System ClusterRole Modified/Deleted: 1
@@ -472,7 +472,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- System ClusterRole Modified/Deleted: 1
@@ -484,7 +484,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- Attach to cluster-admin Role: 1
@@ -496,7 +496,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- ClusterRole With Wildcard Created: 1
@@ -508,7 +508,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- ClusterRole With Wildcard Created: 1
@@ -520,7 +520,7 @@ trace_files: !mux
detect_level: NOTICE
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- ClusterRole With Write Privileges Created: 1
@@ -532,7 +532,7 @@ trace_files: !mux
detect_level: WARNING
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- ClusterRole With Pod Exec Created: 1
@@ -544,7 +544,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Deployment Created: 1
@@ -556,7 +556,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Deployment Deleted: 1
@@ -568,7 +568,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Service Created: 1
@@ -580,7 +580,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Service Deleted: 1
@@ -592,7 +592,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s ConfigMap Created: 1
@@ -604,7 +604,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s ConfigMap Deleted: 1
@@ -616,7 +616,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/allow_namespace_foo.yaml
- ./rules/k8s_audit/allow_user_some-user.yaml
@@ -630,7 +630,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Namespace Deleted: 1
@@ -642,7 +642,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Serviceaccount Created: 1
@@ -654,7 +654,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Serviceaccount Deleted: 1
@@ -666,7 +666,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Role/Clusterrole Created: 1
@@ -678,7 +678,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Role/Clusterrole Deleted: 1
@@ -690,7 +690,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Role/Clusterrolebinding Created: 1
@@ -702,7 +702,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Role/Clusterrolebinding Deleted: 1
@@ -714,7 +714,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Secret Created: 1
@@ -727,7 +727,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_service_account_token_secret.json
@@ -737,7 +737,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_kube_system_secret.json
@@ -747,7 +747,7 @@ trace_files: !mux
detect_level: INFO
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
detect_counts:
- K8s Secret Deleted: 1
@@ -758,7 +758,7 @@ trace_files: !mux
detect: False
enable_source: k8s_audit
rules_file:
- ../rules/falco_rules.yaml
- BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/fal_01_003.json
@@ -773,4 +773,4 @@ trace_files: !mux
detect_counts:
- json_pointer_example: 1
conf_file: BUILD_DIR/test/confs/plugins/k8s_audit.yaml
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_unprivileged.json
addl_cmdline_opts: -o plugins[0].open_params=trace_files/k8s_audit/create_nginx_pod_unprivileged.json

View File

@@ -99,7 +99,7 @@ class FalcoTest(Test):
self.addl_cmdline_opts = self.params.get('addl_cmdline_opts', '*', default='')
self.enable_source = self.params.get('enable_source', '*', default='')
self.rules_file = self.params.get(
'rules_file', '*', default=os.path.join(self.basedir, '../rules/falco_rules.yaml'))
'rules_file', '*', default='BUILD_DIR/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml')
if not isinstance(self.rules_file, list):
self.rules_file = [self.rules_file]

View File

@@ -358,6 +358,16 @@ trace_files: !mux
validate_rules_file:
- rules/invalid_macro_without_condition.yaml
trace_file: trace_files/cat_write.scap
invalid_macro_loop:
exit_status: 1
validate_errors:
- item_type: macro
item_name: macro_a
code: LOAD_ERR_VALIDATE
message_contains: "reference loop in macro"
validate_rules_file:
- rules/invalid_macro_loop.yaml
invalid_rule_without_output:
exit_status: 1
@@ -403,6 +413,16 @@ trace_files: !mux
- rules/list_append_failure.yaml
trace_file: trace_files/cat_write.scap
invalid_list_loop:
exit_status: 1
validate_errors:
- item_type: rule
item_name: sample rule
code: LOAD_ERR_COMPILE_CONDITION
message: "unknown event type list_a"
validate_rules_file:
- rules/invalid_list_loop.yaml
invalid_rule_append_dangling:
exit_status: 1
validate_errors:

View File

@@ -1,6 +1,6 @@
avocado-framework==69.0
avocado-framework-plugin-varianter-yaml-to-mux==69.0
certifi==2020.4.5.1
certifi==2022.12.7
chardet==3.0.4
idna==2.9
pathtools==0.1.2

View File

@@ -0,0 +1,17 @@
- list: list_a
items: [open]
- list: list_b
items: [list_a]
- list: list_a
items: [list_b]
- macro: macro_a
condition: evt.type in (list_a)
- rule: sample rule
priority: WARNING
output: test
desc: testdesc
condition: macro_a

View File

@@ -0,0 +1,8 @@
- macro: macro_a
condition: evt.type=open
- macro: macro_b
condition: macro_a
- macro: macro_a
condition: macro_b

View File

@@ -23,7 +23,7 @@ set(
engine/test_filter_evttype_resolver.cpp
engine/test_filter_warning_resolver.cpp
engine/test_plugin_requirements.cpp
falco/test_configuration.cpp
falco/test_yaml_helper.cpp
)
set(FALCO_TESTED_LIBRARIES falco_engine ${YAMLCPP_LIB})

View File

@@ -20,9 +20,20 @@ limitations under the License.
using namespace std;
using namespace libsinsp::filter::ast;
static std::vector<filter_macro_resolver::value_info>::const_iterator find_value(
const std::vector<filter_macro_resolver::value_info>& values,
const std::string& ref)
{
return std::find_if(
values.begin(),
values.end(),
[&ref](const filter_macro_resolver::value_info& v) { return v.first == ref; });
}
TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(12, 85, 27);
SECTION("in the general case")
{
@@ -31,7 +42,7 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
std::vector<std::unique_ptr<expr>> filter_and;
filter_and.push_back(unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(not_expr::create(value_expr::create(macro_name)));
filter_and.push_back(not_expr::create(value_expr::create(macro_name, macro_pos)));
std::shared_ptr<expr> filter = std::move(and_expr::create(filter_and));
std::vector<std::unique_ptr<expr>> expected_and;
@@ -45,7 +56,8 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(*resolver.get_resolved_macros().begin() == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected.get()));
@@ -61,7 +73,7 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
std::shared_ptr<expr> macro = std::move(
unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
@@ -71,7 +83,8 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
REQUIRE(resolver.run(filter) == true);
REQUIRE(filter.get() != old_filter_ptr);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(*resolver.get_resolved_macros().begin() == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(macro.get()));
@@ -89,14 +102,17 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(11, 75, 43);
pos_info b_macro_pos(91, 21, 9);
std::shared_ptr<expr> a_macro = std::move(
unary_check_expr::create("one.field", "", "exists"));
std::shared_ptr<expr> b_macro = std::move(
unary_check_expr::create("another.field", "", "exists"));
std::vector<std::unique_ptr<expr>> filter_or;
filter_or.push_back(value_expr::create(a_macro_name));
filter_or.push_back(value_expr::create(b_macro_name));
filter_or.push_back(value_expr::create(a_macro_name, a_macro_pos));
filter_or.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> filter = std::move(or_expr::create(filter_or));
std::vector<std::unique_ptr<expr>> expected_or;
@@ -111,11 +127,16 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 2);
REQUIRE(resolver.get_resolved_macros().find(a_macro_name)
!= resolver.get_resolved_macros().end());
REQUIRE(resolver.get_resolved_macros().find(b_macro_name)
!= resolver.get_resolved_macros().end());
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(a_resolved_itr->first == a_macro_name);
REQUIRE(a_resolved_itr->second == a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(b_resolved_itr->first == b_macro_name);
REQUIRE(b_resolved_itr->second == b_macro_pos);
REQUIRE(filter->is_equal(expected_filter.get()));
// second run
@@ -130,15 +151,18 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(47, 1, 76);
pos_info b_macro_pos(111, 65, 2);
std::vector<std::unique_ptr<expr>> a_macro_and;
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(value_expr::create(b_macro_name));
a_macro_and.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> a_macro = std::move(and_expr::create(a_macro_and));
std::shared_ptr<expr> b_macro = std::move(
unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name, a_macro_pos));
std::vector<std::unique_ptr<expr>> expected_and;
expected_and.push_back(unary_check_expr::create("one.field", "", "exists"));
@@ -152,10 +176,17 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 2);
REQUIRE(resolver.get_resolved_macros().find(a_macro_name)
!= resolver.get_resolved_macros().end());
REQUIRE(resolver.get_resolved_macros().find(b_macro_name)
!= resolver.get_resolved_macros().end());
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(a_resolved_itr->first == a_macro_name);
REQUIRE(a_resolved_itr->second == a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(b_resolved_itr->first == b_macro_name);
REQUIRE(b_resolved_itr->second == b_macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected_filter.get()));
@@ -170,18 +201,20 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
TEST_CASE("Should find unknown macros", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(9, 4, 2);
SECTION("in the general case")
{
std::vector<std::unique_ptr<expr>> filter_and;
filter_and.push_back(unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(not_expr::create(value_expr::create(macro_name)));
filter_and.push_back(not_expr::create(value_expr::create(macro_name, macro_pos)));
std::shared_ptr<expr> filter = std::move(and_expr::create(filter_and));
filter_macro_resolver resolver;
REQUIRE(resolver.run(filter) == false);
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(*resolver.get_unknown_macros().begin() == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->first == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_resolved_macros().empty());
}
@@ -190,12 +223,15 @@ TEST_CASE("Should find unknown macros", "[rule_loader]")
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(32, 84, 9);
pos_info b_macro_pos(1, 0, 5);
std::vector<std::unique_ptr<expr>> a_macro_and;
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(value_expr::create(b_macro_name));
a_macro_and.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> a_macro = std::move(and_expr::create(a_macro_and));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name, a_macro_pos));
auto expected_filter = clone(a_macro.get());
filter_macro_resolver resolver;
@@ -204,9 +240,11 @@ TEST_CASE("Should find unknown macros", "[rule_loader]")
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(*resolver.get_resolved_macros().begin() == a_macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->first == a_macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == a_macro_pos);
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(*resolver.get_unknown_macros().begin() == b_macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->first == b_macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == b_macro_pos);
REQUIRE(filter->is_equal(expected_filter.get()));
}
}
@@ -214,15 +252,19 @@ TEST_CASE("Should find unknown macros", "[rule_loader]")
TEST_CASE("Should undefine macro", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos_1(12, 9, 3);
pos_info macro_pos_2(9, 6, 3);
std::shared_ptr<expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> a_filter = std::move(value_expr::create(macro_name));
std::shared_ptr<expr> b_filter = std::move(value_expr::create(macro_name));
std::shared_ptr<expr> a_filter = std::move(value_expr::create(macro_name, macro_pos_1));
std::shared_ptr<expr> b_filter = std::move(value_expr::create(macro_name, macro_pos_2));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
REQUIRE(resolver.run(a_filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(*resolver.get_resolved_macros().begin() == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos_1);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(a_filter->is_equal(macro.get()));
@@ -230,21 +272,24 @@ TEST_CASE("Should undefine macro", "[rule_loader]")
REQUIRE(resolver.run(b_filter) == false);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(*resolver.get_unknown_macros().begin() == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->first == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == macro_pos_2);
}
// checks that the macro AST is cloned and not shared across resolved filters
TEST_CASE("Should clone macro AST", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(5, 2, 8888);
std::shared_ptr<unary_check_expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(*resolver.get_resolved_macros().begin() == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(macro.get()));

View File

@@ -27,30 +27,51 @@ static uint16_t other_non_default_ruleset = 2;
static std::set<std::string> tags = {"some_tag", "some_other_tag"};
static std::set<uint16_t> evttypes = { ppm_event_type::PPME_GENERIC_E };
static std::shared_ptr<libsinsp::filter::ast::expr> create_filter()
static std::shared_ptr<gen_event_filter_factory> create_factory()
{
libsinsp::filter::parser parser("evt.type=open");
std::shared_ptr<libsinsp::filter::ast::expr> ret(parser.parse());
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL));
return ret;
}
static std::shared_ptr<filter_ruleset> create_ruleset()
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(
std::shared_ptr<gen_event_filter_factory> f)
{
libsinsp::filter::parser parser("evt.type=open");
std::shared_ptr<libsinsp::filter::ast::expr> ret(parser.parse());
return ret;
}
static std::shared_ptr<gen_event_filter> create_filter(
std::shared_ptr<gen_event_filter_factory> f,
std::shared_ptr<libsinsp::filter::ast::expr> ast)
{
sinsp_filter_compiler compiler(f, ast.get());
std::shared_ptr<gen_event_filter> filter(compiler.compile());
return filter;
}
static std::shared_ptr<filter_ruleset> create_ruleset(
std::shared_ptr<gen_event_filter_factory> f)
{
std::shared_ptr<gen_event_filter_factory> f(new sinsp_filter_factory(NULL));
std::shared_ptr<filter_ruleset> ret(new evttype_index_ruleset(f));
return ret;
}
TEST_CASE("Should enable/disable on ruleset", "[rulesets]")
{
auto r = create_ruleset();
auto filter = create_filter();
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);
falco_rule rule;
rule.name = "one_rule";
rule.source = falco_common::syscall_source;
rule.tags = tags;
r->add(rule, filter);
r->add(rule, filter, ast);
SECTION("Should enable/disable for exact match w/ default ruleset")
{
@@ -184,21 +205,23 @@ TEST_CASE("Should enable/disable on ruleset", "[rulesets]")
TEST_CASE("Should enable/disable on ruleset for incremental adding tags", "[rulesets]")
{
auto r = create_ruleset();
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto rule1_filter = create_filter();
auto rule1_filter = create_filter(f, ast);
falco_rule rule1;
rule1.name = "one_rule";
rule1.source = falco_common::syscall_source;
rule1.tags = {"rule1_tag"};
r->add(rule1, rule1_filter);
r->add(rule1, rule1_filter, ast);
auto rule2_filter = create_filter();
auto rule2_filter = create_filter(f, ast);
falco_rule rule2;
rule2.name = "two_rule";
rule2.source = falco_common::syscall_source;
rule2.tags = {"rule2_tag"};
r->add(rule2, rule2_filter);
r->add(rule2, rule2_filter, ast);
std::set<std::string> want_tags;

View File

@@ -32,7 +32,7 @@ string sample_yaml =
TEST_CASE("configuration must load YAML data", "[configuration]")
{
yaml_configuration conf;
yaml_helper conf;
SECTION("broken YAML")
{
@@ -58,7 +58,7 @@ TEST_CASE("configuration must load YAML data", "[configuration]")
TEST_CASE("configuration must read YAML fields", "[configuration]")
{
yaml_configuration conf;
yaml_helper conf;
conf.load_from_string(sample_yaml);
SECTION("base level")
@@ -96,7 +96,7 @@ TEST_CASE("configuration must read YAML fields", "[configuration]")
TEST_CASE("configuration must modify YAML fields", "[configuration]")
{
string key = "base_value.subvalue.subvalue2.boolean";
yaml_configuration conf;
yaml_helper conf;
conf.load_from_string(sample_yaml);
REQUIRE(conf.get_scalar<bool>(key, false) == true);
conf.set_scalar<bool>(key, false);

View File

@@ -30,7 +30,7 @@ set(FALCO_ENGINE_SOURCE_FILES
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
if(USE_BUNDLED_DEPS)
add_dependencies(falco_engine yamlcpp)
add_dependencies(falco_engine yamlcpp njson)
endif()
if(MINIMAL_BUILD)

View File

@@ -153,12 +153,11 @@ void evttype_index_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint1
void evttype_index_ruleset::add(
const falco_rule& rule,
std::shared_ptr<gen_event_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition)
{
try
{
sinsp_filter_compiler compiler(m_filter_factory, condition.get());
shared_ptr<gen_event_filter> filter(compiler.compile());
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
wrap->rule = rule;
wrap->filter = filter;

View File

@@ -41,6 +41,7 @@ public:
void add(
const falco_rule& rule,
std::shared_ptr<gen_event_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) override;
void clear() override;

View File

@@ -21,4 +21,4 @@ limitations under the License.
// This is the result of running "falco --list -N | sha256sum" and
// represents the fields supported by this version of Falco. It's used
// at build time to detect a changed set of fields.
#define FALCO_FIELDS_CHECKSUM "674c6cf2bc1c105038c8676f018fa3d1431d86597df428453441f5d859cad284"
#define FALCO_FIELDS_CHECKSUM "cc9d32916c719ce5aea164cdadb56207cbeff20033e278b99101964be7aa77a1"

View File

@@ -31,12 +31,14 @@ struct falco_source
falco_source& operator = (falco_source&&) = default;
falco_source(const falco_source& s):
name(s.name),
ruleset(s.ruleset),
ruleset_factory(s.ruleset_factory),
filter_factory(s.filter_factory),
formatter_factory(s.formatter_factory) { };
falco_source& operator = (const falco_source& s)
{
name = s.name;
ruleset = s.ruleset;
ruleset_factory = s.ruleset_factory;
filter_factory = s.filter_factory;
formatter_factory = s.formatter_factory;

View File

@@ -15,18 +15,18 @@ limitations under the License.
*/
#include "filter_macro_resolver.h"
#include "falco_common.h"
using namespace std;
using namespace libsinsp::filter;
bool filter_macro_resolver::run(libsinsp::filter::ast::expr*& filter)
{
visitor v;
m_unknown_macros.clear();
m_resolved_macros.clear();
v.m_unknown_macros = &m_unknown_macros;
v.m_resolved_macros = &m_resolved_macros;
v.m_macros = &m_macros;
m_errors.clear();
visitor v(m_errors, m_unknown_macros, m_resolved_macros, m_macros);
v.m_node_substitute = nullptr;
filter->accept(&v);
if (v.m_node_substitute)
@@ -39,12 +39,11 @@ bool filter_macro_resolver::run(libsinsp::filter::ast::expr*& filter)
bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& filter)
{
visitor v;
m_unknown_macros.clear();
m_resolved_macros.clear();
v.m_unknown_macros = &m_unknown_macros;
v.m_resolved_macros = &m_resolved_macros;
v.m_macros = &m_macros;
m_errors.clear();
visitor v(m_errors, m_unknown_macros, m_resolved_macros, m_macros);
v.m_node_substitute = nullptr;
filter->accept(&v);
if (v.m_node_substitute)
@@ -61,12 +60,17 @@ void filter_macro_resolver::set_macro(
m_macros[name] = macro;
}
const unordered_set<string>& filter_macro_resolver::get_unknown_macros() const
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_unknown_macros() const
{
return m_unknown_macros;
}
const unordered_set<string>& filter_macro_resolver::get_resolved_macros() const
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_errors() const
{
return m_errors;
}
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_resolved_macros() const
{
return m_resolved_macros;
}
@@ -129,9 +133,21 @@ void filter_macro_resolver::visitor::visit(ast::value_expr* e)
// we are supposed to get here only in case
// of identier-only children from either a 'not',
// an 'and' or an 'or'.
auto macro = m_macros->find(e->value);
if (macro != m_macros->end() && macro->second) // skip null-ptr macros
const auto& macro = m_macros.find(e->value);
if (macro != m_macros.end() && macro->second) // skip null-ptr macros
{
// note: checks for loop detection
const auto& prevref = std::find(m_macros_path.begin(), m_macros_path.end(), macro->first);
if (prevref != m_macros_path.end())
{
auto msg = "reference loop in macro '" + macro->first + "'";
m_errors.push_back({msg, e->get_pos()});
m_node_substitute = nullptr;
m_unknown_macros.push_back({e->value, e->get_pos()});
return;
}
m_macros_path.push_back(macro->first);
m_node_substitute = nullptr;
auto new_node = ast::clone(macro->second.get());
new_node->accept(this);
@@ -141,11 +157,12 @@ void filter_macro_resolver::visitor::visit(ast::value_expr* e)
{
m_node_substitute = std::move(new_node);
}
m_resolved_macros->insert(e->value);
m_resolved_macros.push_back({e->value, e->get_pos()});
m_macros_path.pop_back();
}
else
{
m_node_substitute = nullptr;
m_unknown_macros->insert(e->value);
m_unknown_macros.push_back({e->value, e->get_pos()});
}
}

View File

@@ -40,7 +40,7 @@ class filter_macro_resolver
\return true if at least one of the defined macros is resolved
*/
bool run(libsinsp::filter::ast::expr*& filter);
/*!
\brief Version of run() that works with shared pointers
*/
@@ -58,12 +58,18 @@ class filter_macro_resolver
std::string name,
std::shared_ptr<libsinsp::filter::ast::expr> macro);
/*!
\brief used in get_{resolved,unknown}_macros and get_errors
to represent an identifier/string value along with an AST position.
*/
typedef std::pair<std::string,libsinsp::filter::ast::pos_info> value_info;
/*!
\brief Returns a set containing the names of all the macros
substituted during the last invocation of run(). Should be
non-empty if the last invocation of run() returned true.
*/
const std::unordered_set<std::string>& get_resolved_macros() const;
const std::vector<value_info>& get_resolved_macros() const;
/*!
\brief Returns a set containing the names of all the macros
@@ -71,8 +77,14 @@ class filter_macro_resolver
A macro remains unresolved if it is found inside the processed
filter but it was not defined with set_macro();
*/
const std::unordered_set<std::string>& get_unknown_macros() const;
const std::vector<value_info>& get_unknown_macros() const;
/*!
\brief Returns a list of errors occurred during
the latest invocation of run().
*/
const std::vector<value_info>& get_errors() const;
private:
typedef std::unordered_map<
std::string,
@@ -81,16 +93,26 @@ class filter_macro_resolver
struct visitor : public libsinsp::filter::ast::expr_visitor
{
visitor() = default;
visitor(
std::vector<value_info>& errors,
std::vector<value_info>& unknown_macros,
std::vector<value_info>& resolved_macros,
macro_defs& macros):
m_errors(errors),
m_unknown_macros(unknown_macros),
m_resolved_macros(resolved_macros),
m_macros(macros) {}
visitor(visitor&&) = default;
visitor& operator = (visitor&&) = default;
visitor(const visitor&) = delete;
visitor& operator = (const visitor&) = delete;
std::vector<std::string> m_macros_path;
std::unique_ptr<libsinsp::filter::ast::expr> m_node_substitute;
std::unordered_set<std::string>* m_unknown_macros;
std::unordered_set<std::string>* m_resolved_macros;
macro_defs* m_macros;
std::vector<value_info>& m_errors;
std::vector<value_info>& m_unknown_macros;
std::vector<value_info>& m_resolved_macros;
macro_defs& m_macros;
void visit(libsinsp::filter::ast::and_expr* e) override;
void visit(libsinsp::filter::ast::or_expr* e) override;
@@ -101,7 +123,8 @@ class filter_macro_resolver
void visit(libsinsp::filter::ast::binary_check_expr* e) override;
};
std::unordered_set<std::string> m_unknown_macros;
std::unordered_set<std::string> m_resolved_macros;
std::vector<value_info> m_errors;
std::vector<value_info> m_unknown_macros;
std::vector<value_info> m_resolved_macros;
macro_defs m_macros;
};

View File

@@ -32,16 +32,20 @@ public:
virtual ~filter_ruleset() = default;
/*!
\brief Adds a rule and its filtering condition inside the manager.
An exception is thrown is case of error. This method only adds the rule
inside the internal collection, but does not enable it for any ruleset.
The rule must be enabled for one or more rulesets with the enable() or
enable_tags() methods.
\brief Adds a rule and its filtering filter + condition inside the manager.
This method only adds the rule inside the internal collection,
but does not enable it for any ruleset. The rule must be enabled
for one or more rulesets with the enable() or enable_tags() methods.
The ast representation of the rule's condition is provided to allow
the filter_ruleset object to parse the ast to obtain event types
or do other analysis/indexing of the condition.
\param rule The rule to be added
\param the filter representing the rule's filtering condition.
\param condition The AST representing the rule's filtering condition
*/
virtual void add(
const falco_rule& rule,
std::shared_ptr<gen_event_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) = 0;
/*!

View File

@@ -64,6 +64,11 @@ rule_loader::context::context(const YAML::Node &item,
init(parent.name(), position(item.Mark()), item_type, item_name, parent);
}
rule_loader::context::context(const YAML::Mark &mark, const context& parent)
{
init(parent.name(), position(mark), item_type::VALUE_FOR, "", parent);
}
rule_loader::context::context(const libsinsp::filter::ast::pos_info& pos,
const std::string& condition,
const context& parent)
@@ -87,9 +92,10 @@ rule_loader::context::context(const libsinsp::filter::ast::pos_info& pos,
// parser line/columns are 1-indexed while yaml marks are
// 0-indexed, though.
position condpos;
condpos.pos = pos.idx;
condpos.line = pos.line-1;
condpos.column = pos.col-1;
auto& lastpos = parent.m_locs.back();
condpos.pos = pos.idx + lastpos.pos.pos;
condpos.line = pos.line + lastpos.pos.line;
condpos.column = pos.col + lastpos.pos.column;
init(name, condpos, rule_loader::context::CONDITION_EXPRESSION, item_name, parent);
}

View File

@@ -113,6 +113,9 @@ namespace rule_loader
item_type item_type,
const std::string& item_name,
const context& parent);
context(
const YAML::Mark &mark,
const context& parent);
// Build a context from a condition expression +
// parser position. This does not use the original

View File

@@ -234,6 +234,7 @@ static bool resolve_list(std::string& cnd, const rule_loader::list_info& list)
static void resolve_macros(
indexed_vector<rule_loader::macro_info>& macros,
std::shared_ptr<ast::expr>& ast,
const std::string& condition,
uint32_t visibility,
const rule_loader::context &ctx)
{
@@ -247,16 +248,24 @@ static void resolve_macros(
}
macro_resolver.run(ast);
// Note: only complaining about the first unknown macro
THROW(!macro_resolver.get_unknown_macros().empty(),
std::string("Undefined macro '")
+ *macro_resolver.get_unknown_macros().begin()
+ "' used in filter.",
ctx);
for (auto &m : macro_resolver.get_resolved_macros())
// Note: only complaining about the first error or unknown macro
const auto& errors_macros = macro_resolver.get_errors();
const auto& unresolved_macros = macro_resolver.get_unknown_macros();
if(!errors_macros.empty() || !unresolved_macros.empty())
{
macros.at(m)->used = true;
auto errpos = !errors_macros.empty()
? errors_macros.begin()->second
: unresolved_macros.begin()->second;
std::string errmsg = !errors_macros.empty()
? errors_macros.begin()->first
: ("Undefined macro '" + unresolved_macros.begin()->first + "' used in filter.");
const rule_loader::context cond_ctx(errpos, condition, ctx);
THROW(true, errmsg, cond_ctx);
}
for (auto &it : macro_resolver.get_resolved_macros())
{
macros.at(it.first)->used = true;
}
}
@@ -363,7 +372,7 @@ void rule_loader::compiler::compile_macros_infos(
for (auto &m : out)
{
resolve_macros(out, m.cond_ast, m.visibility, m.ctx);
resolve_macros(out, m.cond_ast, m.cond, m.visibility, m.ctx);
}
}
@@ -404,7 +413,7 @@ void rule_loader::compiler::compile_rule_infos(
r.exceptions, rule.exception_fields, condition);
}
auto ast = parse_condition(condition, lists, r.cond_ctx);
resolve_macros(macros, ast, MAX_VISIBILITY, r.ctx);
resolve_macros(macros, ast, condition, MAX_VISIBILITY, r.ctx);
// check for warnings in the filtering condition
warn_codes.clear();
@@ -444,10 +453,12 @@ void rule_loader::compiler::compile_rule_infos(
// This also compiles the filter, and might throw a
// falco_exception with details on the compilation
// failure.
sinsp_filter_compiler compiler(cfg.sources.at(r.source)->filter_factory, ast.get());
try {
source->ruleset->add(*out.at(rule_id), ast);
shared_ptr<gen_event_filter> filter(compiler.compile());
source->ruleset->add(*out.at(rule_id), filter, ast);
}
catch (const falco_exception& e)
catch (const sinsp_exception& e)
{
// Allow errors containing "nonexistent field" if
// skip_if_unknown_filter is true
@@ -463,10 +474,14 @@ void rule_loader::compiler::compile_rule_infos(
}
else
{
rule_loader::context ctx(compiler.get_pos(),
condition,
r.cond_ctx);
throw rule_loader::rule_load_exception(
falco::load_result::load_result::LOAD_ERR_COMPILE_CONDITION,
e.what(),
r.cond_ctx);
ctx);
}
}

View File

@@ -437,23 +437,32 @@ static void read_item(
bool rule_loader::reader::read(rule_loader::configuration& cfg, collector& collector)
{
std::vector<YAML::Node> docs;
rule_loader::context ctx(cfg.name);
try
{
docs = YAML::LoadAll(cfg.content);
}
catch(const exception& e)
catch (YAML::ParserException& e)
{
rule_loader::context ictx(e.mark, ctx);
cfg.res->add_error(falco::load_result::LOAD_ERR_YAML_PARSE, e.what(), ictx);
return false;
}
catch (std::exception& e)
{
rule_loader::context ctx(cfg.name);
cfg.res->add_error(falco::load_result::LOAD_ERR_YAML_PARSE, e.what(), ctx);
return false;
}
catch (...)
{
cfg.res->add_error(falco::load_result::LOAD_ERR_YAML_PARSE, "unknown YAML parsing error", ctx);
return false;
}
for (auto doc = docs.begin(); doc != docs.end(); doc++)
{
if (doc->IsDefined() && !doc->IsNull())
{
rule_loader::context ctx(cfg.name);
try {
THROW(!doc->IsMap() && !doc->IsSequence(),
"Rules content is not yaml",
@@ -479,7 +488,23 @@ bool rule_loader::reader::read(rule_loader::configuration& cfg, collector& colle
// as it's effectively a new rules file, for
// consistency we stop at the first error.
return false;
};
}
catch (YAML::ParserException& e)
{
rule_loader::context ictx(e.mark, ctx);
cfg.res->add_error(falco::load_result::LOAD_ERR_YAML_VALIDATE, e.what(), ictx);
return false;
}
catch (std::exception& e)
{
cfg.res->add_error(falco::load_result::LOAD_ERR_VALIDATE, e.what(), ctx);
return false;
}
catch (...)
{
cfg.res->add_error(falco::load_result::LOAD_ERR_VALIDATE, "unknown validation error", ctx);
return false;
}
}
}

View File

@@ -54,6 +54,7 @@ set(
outputs_syslog.cpp
event_drops.cpp
stats_writer.cpp
versions_info.cpp
falco.cpp
)

View File

@@ -21,7 +21,7 @@ using namespace falco::app;
application::run_result application::init_clients()
{
#ifndef MINIMAL_BUILD
// k8s and mesos clients are useful only if syscall source is enabled
// k8s is useful only if the syscall source is enabled
if (m_state->enabled_sources.find(falco_common::syscall_source) == m_state->enabled_sources.end())
{
return run_result::ok();
@@ -59,7 +59,9 @@ application::run_result application::init_clients()
}
//
// DEPRECATED!
// Run mesos, if required
// todo(leogr): remove in Falco 0,.35
//
if(!m_options.mesos_api.empty())
{
@@ -67,10 +69,12 @@ application::run_result application::init_clients()
// passes a pointer but the inspector does
// *not* own it and does not use it after
// init_mesos_client() returns.
falco_logger::log(LOG_WARNING, "Mesos support has been DEPRECATED and will be removed in the next version!\n");
inspector->init_mesos_client(&(m_options.mesos_api), m_options.verbose);
}
else if(char* mesos_api_env = getenv("FALCO_MESOS_API"))
{
falco_logger::log(LOG_WARNING, "Mesos support has been DEPRECATED and will be removed in the next version!\n");
std::string mesos_api_copy = mesos_api_env;
inspector->init_mesos_client(&mesos_api_copy, m_options.verbose);
}

View File

@@ -23,6 +23,11 @@ using namespace falco::app;
application::run_result application::init_outputs()
{
if (m_state->config->m_outputs.empty())
{
return run_result::fatal("No output configured, please make sure at least one output is configured and enabled.");
}
// read hostname
std::string hostname;
char* env_hostname = getenv("FALCO_HOSTNAME");

View File

@@ -20,20 +20,42 @@ using namespace falco::app;
application::run_result application::load_config()
{
try
{
if (!m_options.conf_filename.empty())
{
m_state->config->init(m_options.conf_filename, m_options.cmdline_config_options);
}
else
{
m_state->config->init(m_options.cmdline_config_options);
}
}
catch (std::exception& e)
{
return run_result::fatal(e.what());
}
// log after config init because config determines where logs go
falco_logger::set_time_format_iso_8601(m_state->config->m_time_format_iso_8601);
falco_logger::log(LOG_INFO, "Falco version: " + std::string(FALCO_VERSION) + " (" + std::string(FALCO_TARGET_ARCH) + ")\n");
if (!m_state->cmdline.empty())
{
falco_logger::log(LOG_DEBUG, "CLI args: " + m_state->cmdline);
}
if (!m_options.conf_filename.empty())
{
m_state->config->init(m_options.conf_filename, m_options.cmdline_config_options);
falco_logger::set_time_format_iso_8601(m_state->config->m_time_format_iso_8601);
// log after config init because config determines where logs go
falco_logger::log(LOG_INFO, "Falco version: " + std::string(FALCO_VERSION) + " (" + std::string(FALCO_TARGET_ARCH) + ")\n");
if (!m_state->cmdline.empty())
{
falco_logger::log(LOG_DEBUG, "CLI args: " + m_state->cmdline);
}
falco_logger::log(LOG_INFO, "Falco initialized with configuration file: " + m_options.conf_filename + "\n");
}
else
m_state->config->m_buffered_outputs = !m_options.unbuffered_outputs;
return run_result::ok();
}
application::run_result application::require_config_file()
{
if (m_options.conf_filename.empty())
{
#ifndef BUILD_TYPE_RELEASE
return run_result::fatal(std::string("You must create a config file at ") + FALCO_SOURCE_CONF_FILE + ", " + FALCO_INSTALL_CONF_FILE + " or by passing -c");
@@ -41,8 +63,5 @@ application::run_result application::load_config()
return run_result::fatal(std::string("You must create a config file at ") + FALCO_INSTALL_CONF_FILE + " or by passing -c");
#endif
}
m_state->config->m_buffered_outputs = !m_options.unbuffered_outputs;
return run_result::ok();
}
}

View File

@@ -67,7 +67,7 @@ void application::check_for_ignored_events()
std::cerr << (first ? "" : ", ") << it.c_str();
first = false;
}
std::cerr << std::endl << "But these events are not returned unless running falco with -A" << std::endl;
std::cerr << std::endl << "These events might be associated with syscalls undefined on your architecture (please take a look here: https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html). If syscalls are instead defined, you have to run Falco with `-A` to catch these events" << std::endl;
}
application::run_result application::load_rules_files()
@@ -172,6 +172,14 @@ application::run_result application::load_rules_files()
check_for_ignored_events();
}
if(m_options.all_events && m_options.modern_bpf)
{
/* Right now the modern BPF probe doesn't support the -A flag, we implemented just
* the "simple set" syscalls.
*/
falco_logger::log(LOG_INFO, "The '-A' flag has no effect with the modern BPF probe, no further syscalls will be added\n");
}
if (m_options.describe_all_rules)
{
m_state->engine->describe_rule(NULL);

View File

@@ -77,8 +77,9 @@ application::run_result application::open_live_inspector(
}
else if(m_options.modern_bpf) /* modern BPF engine. */
{
falco_logger::log(LOG_INFO, "Opening capture with modern BPF probe");
inspector->open_modern_bpf(m_state->syscall_buffer_bytes_size, m_state->ppm_sc_of_interest, m_state->tp_of_interest);
falco_logger::log(LOG_INFO, "Opening capture with modern BPF probe.");
falco_logger::log(LOG_INFO, "One ring buffer every '" + std::to_string(m_state->config->m_cpus_for_each_syscall_buffer) + "' CPUs.");
inspector->open_modern_bpf(m_state->syscall_buffer_bytes_size, m_state->config->m_cpus_for_each_syscall_buffer, true, m_state->ppm_sc_of_interest, m_state->tp_of_interest);
}
else if(getenv(FALCO_BPF_ENV_VARIABLE) != NULL) /* BPF engine. */
{

View File

@@ -16,7 +16,7 @@ limitations under the License.
#include <sys/utsname.h>
#include "falco_engine_version.h"
#include "versions_info.h"
#include "application.h"
using namespace falco::app;
@@ -43,14 +43,16 @@ application::run_result application::print_support()
return run_result::fatal(string("Could not uname() to find system info: ") + strerror(errno));
}
support["version"] = FALCO_VERSION;
const versions_info infos(m_state->offline_inspector);
support["version"] = infos.falco_version;
support["engine_info"] = infos.as_json();
support["system_info"]["sysname"] = sysinfo.sysname;
support["system_info"]["nodename"] = sysinfo.nodename;
support["system_info"]["release"] = sysinfo.release;
support["system_info"]["version"] = sysinfo.version;
support["system_info"]["machine"] = sysinfo.machine;
support["cmdline"] = m_state->cmdline;
support["engine_info"]["engine_version"] = FALCO_ENGINE_VERSION;
support["config"] = read_file(m_options.conf_filename);
support["rules_files"] = nlohmann::json::array();
for(auto filename : m_state->config->m_loaded_rules_filenames)

View File

@@ -14,8 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include "config_falco.h"
#include <nlohmann/json.hpp>
#include "application.h"
#include "versions_info.h"
using namespace falco::app;
@@ -23,26 +25,24 @@ application::run_result application::print_version()
{
if(m_options.print_version_info)
{
std::unique_ptr<sinsp> s(new sinsp());
printf("Falco version: %s\n", FALCO_VERSION);
printf("Libs version: %s\n", FALCOSECURITY_LIBS_VERSION);
printf("Plugin API: %s\n", s->get_plugin_api_version());
// todo(leogr): move string conversion to scap
auto driver_api_version = s->get_scap_api_version();
unsigned long driver_api_major = PPM_API_VERSION_MAJOR(driver_api_version);
unsigned long driver_api_minor = PPM_API_VERSION_MINOR(driver_api_version);
unsigned long driver_api_patch = PPM_API_VERSION_PATCH(driver_api_version);
auto driver_schema_version = s->get_scap_schema_version();
unsigned long driver_schema_major = PPM_API_VERSION_MAJOR(driver_schema_version);
unsigned long driver_schema_minor = PPM_API_VERSION_MINOR(driver_schema_version);
unsigned long driver_schema_patch = PPM_API_VERSION_PATCH(driver_schema_version);
printf("Driver:\n");
printf(" API version: %lu.%lu.%lu\n", driver_api_major, driver_api_minor, driver_api_patch);
printf(" Schema version: %lu.%lu.%lu\n", driver_schema_major, driver_schema_minor, driver_schema_patch);
printf(" Default driver: %s\n", DRIVER_VERSION);
const versions_info info(m_state->offline_inspector);
if(m_state->config->m_json_output)
{
printf("%s\n", info.as_json().dump().c_str());
}
else
{
printf("Falco version: %s\n", info.falco_version.c_str());
printf("Libs version: %s\n", info.libs_version.c_str());
printf("Plugin API: %s\n", info.plugin_api_version.c_str());
printf("Engine: %s\n", info.engine_version.c_str());
printf("Driver:\n");
printf(" API version: %s\n", info.driver_api_version.c_str());
printf(" Schema version: %s\n", info.driver_schema_version.c_str());
printf(" Default driver: %s\n", info.default_driver_version.c_str());
}
return run_result::exit();
}
return run_result::ok();
}

View File

@@ -50,8 +50,8 @@ application::run_result application::do_inspect(
uint64_t duration_to_tot_ns,
uint64_t &num_evts)
{
int32_t rc;
sinsp_evt* ev;
int32_t rc = 0;
sinsp_evt* ev = NULL;
stats_writer::collector stats_collector(statsw);
uint64_t duration_start = 0;
uint32_t timeouts_since_last_success_or_msg = 0;
@@ -91,6 +91,11 @@ application::run_result application::do_inspect(
m_state->config->m_syscall_evt_simulate_drops);
}
//
// Start capture
//
inspector->start_capture();
//
// Loop through the events
//

View File

@@ -34,6 +34,7 @@ application::run_result application::start_webserver()
+ ssl_option + "\n");
m_state->webserver.start(
m_state->offline_inspector,
m_state->config->m_webserver_threadiness,
m_state->config->m_webserver_listen_port,
m_state->config->m_webserver_k8s_healthz_endpoint,

View File

@@ -190,14 +190,14 @@ void cmdline_options::define()
("list-plugins", "Print info on all loaded plugins and exit.", cxxopts::value(list_plugins)->default_value("false"))
#endif
#ifndef MINIMAL_BUILD
("m,mesos-api", "Enable Mesos support by connecting to the API server specified as argument. E.g. \"http://admin:password@127.0.0.1:5050\". Marathon url is optional and defaults to Mesos address, port 8080. The API servers can also be specified via the environment variable FALCO_MESOS_API.", cxxopts::value(mesos_api), "<url[,marathon_url]>")
("m,mesos-api", "This feature has been DEPRECATED and will be removed in the next version.", cxxopts::value(mesos_api), "<url[,marathon_url]>")
#endif
("M", "Stop collecting after <num_seconds> reached.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
("N", "When used with --list, only print field names.", cxxopts::value(names_only)->default_value("false"))
("o,option", "Set the value of option <opt> to <val>. Overrides values in configuration file. <opt> can be identified using its location in configuration file using dot notation. Elements which are entries of lists can be accessed via square brackets [].\n E.g. base.id = val\n base.subvalue.subvalue2 = val\n base.list[1]=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
("plugin-info", "Print info for a single plugin and exit.\nThis includes all descriptivo info like name and author, along with the\nschema format for the init configuration and a list of suggested open parameters.\n<plugin_name> can be the name of the plugin or its configured library_path.", cxxopts::value(print_plugin_info), "<plugin_name>")
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nWith -pm or -pmesos will use a mesos-friendly format.\nAdditionally, specifying -pc/-pk/-pm will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nAdditionally, specifying -pc/-pk will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
("P,pidfile", "When run as a daemon, write pid to specified file", cxxopts::value(pidfilename)->default_value("/var/run/falco.pid"), "<pid_file>")
("r", "Rules file/directory (defaults to value set in configuration file, or /etc/falco_rules.yaml). This option can be passed multiple times to read from multiple files/directories.", cxxopts::value<std::vector<std::string>>(), "<rules_file>")
("s", "If specified, append statistics related to Falco's reading/processing of events to this file (only useful in live mode).", cxxopts::value(stats_filename), "<stats_file>")

View File

@@ -172,13 +172,14 @@ bool application::run(std::string &errstr, bool &restart)
// dependencies are honored (e.g. don't process events before
// loading plugins, opening inspector, etc.).
std::list<std::function<run_result()>> run_steps = {
std::bind(&application::load_config, this),
std::bind(&application::print_help, this),
std::bind(&application::print_version, this),
std::bind(&application::print_page_size, this),
std::bind(&application::print_generated_gvisor_config, this),
std::bind(&application::print_ignored_events, this),
std::bind(&application::print_syscall_events, this),
std::bind(&application::load_config, this),
std::bind(&application::require_config_file, this),
std::bind(&application::print_plugin_info, this),
std::bind(&application::list_plugins, this),
std::bind(&application::load_plugins, this),

View File

@@ -315,6 +315,7 @@ private:
run_result list_fields();
run_result list_plugins();
run_result load_config();
run_result require_config_file();
run_result load_plugins();
run_result load_rules_files();
run_result create_requested_paths();

View File

@@ -16,8 +16,6 @@ limitations under the License.
#pragma once
#define FALCO_BRANCH "@FALCO_REF@"
#define FALCO_HASH "@FALCO_HASH@"
#define FALCO_VERSION "@FALCO_VERSION@"
#define FALCO_VERSION_MAJOR @FALCO_VERSION_MAJOR@
#define FALCO_VERSION_MINOR @FALCO_VERSION_MINOR@

View File

@@ -57,38 +57,44 @@ falco_configuration::falco_configuration():
m_metadata_download_chunk_wait_us(1000),
m_metadata_download_watch_freq_sec(1),
m_syscall_buf_size_preset(4),
m_config(NULL)
m_cpus_for_each_syscall_buffer(2)
{
}
falco_configuration::~falco_configuration()
void falco_configuration::init(const std::vector<std::string>& cmdline_options)
{
if(m_config)
{
delete m_config;
}
yaml_helper config;
config.load_from_string("");
init_cmdline_options(config, cmdline_options);
load_yaml("default", config);
}
void falco_configuration::init(const string& conf_filename, const vector<string> &cmdline_options)
void falco_configuration::init(const std::string& conf_filename, const std::vector<std::string> &cmdline_options)
{
string m_config_file = conf_filename;
m_config = new yaml_configuration();
yaml_helper config;
try
{
m_config->load_from_file(m_config_file);
config.load_from_file(conf_filename);
}
catch(const std::exception& e)
{
std::cerr << "Cannot read config file (" + m_config_file + "): " + e.what() + "\n";
std::cerr << "Cannot read config file (" + conf_filename + "): " + e.what() + "\n";
throw e;
}
init_cmdline_options(cmdline_options);
init_cmdline_options(config, cmdline_options);
load_yaml(conf_filename, config);
}
void falco_configuration::load_yaml(const std::string& config_name, const yaml_helper& config)
{
list<string> rules_files;
m_config->get_sequence<list<string>>(rules_files, string("rules_file"));
config.get_sequence<list<string>>(rules_files, string("rules_file"));
m_rules_filenames.clear();
m_loaded_rules_filenames.clear();
m_loaded_rules_folders.clear();
for(auto &file : rules_files)
{
// Here, we only include files that exist
@@ -99,23 +105,24 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
}
}
m_json_output = m_config->get_scalar<bool>("json_output", false);
m_json_include_output_property = m_config->get_scalar<bool>("json_include_output_property", true);
m_json_include_tags_property = m_config->get_scalar<bool>("json_include_tags_property", true);
m_json_output = config.get_scalar<bool>("json_output", false);
m_json_include_output_property = config.get_scalar<bool>("json_include_output_property", true);
m_json_include_tags_property = config.get_scalar<bool>("json_include_tags_property", true);
m_outputs.clear();
falco::outputs::config file_output;
file_output.name = "file";
if(m_config->get_scalar<bool>("file_output.enabled", false))
if(config.get_scalar<bool>("file_output.enabled", false))
{
string filename, keep_alive;
filename = m_config->get_scalar<string>("file_output.filename", "");
filename = config.get_scalar<string>("file_output.filename", "");
if(filename == string(""))
{
throw logic_error("Error reading config file (" + m_config_file + "): file output enabled but no filename in configuration block");
throw logic_error("Error reading config file (" + config_name + "): file output enabled but no filename in configuration block");
}
file_output.options["filename"] = filename;
keep_alive = m_config->get_scalar<string>("file_output.keep_alive", "");
keep_alive = config.get_scalar<string>("file_output.keep_alive", "");
file_output.options["keep_alive"] = keep_alive;
m_outputs.push_back(file_output);
@@ -123,31 +130,31 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
falco::outputs::config stdout_output;
stdout_output.name = "stdout";
if(m_config->get_scalar<bool>("stdout_output.enabled", false))
if(config.get_scalar<bool>("stdout_output.enabled", false))
{
m_outputs.push_back(stdout_output);
}
falco::outputs::config syslog_output;
syslog_output.name = "syslog";
if(m_config->get_scalar<bool>("syslog_output.enabled", false))
if(config.get_scalar<bool>("syslog_output.enabled", false))
{
m_outputs.push_back(syslog_output);
}
falco::outputs::config program_output;
program_output.name = "program";
if(m_config->get_scalar<bool>("program_output.enabled", false))
if(config.get_scalar<bool>("program_output.enabled", false))
{
string program, keep_alive;
program = m_config->get_scalar<string>("program_output.program", "");
program = config.get_scalar<string>("program_output.program", "");
if(program == string(""))
{
throw logic_error("Error reading config file (" + m_config_file + "): program output enabled but no program in configuration block");
throw logic_error("Error reading config file (" + config_name + "): program output enabled but no program in configuration block");
}
program_output.options["program"] = program;
keep_alive = m_config->get_scalar<string>("program_output.keep_alive", "");
keep_alive = config.get_scalar<string>("program_output.keep_alive", "");
program_output.options["keep_alive"] = keep_alive;
m_outputs.push_back(program_output);
@@ -155,90 +162,86 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
falco::outputs::config http_output;
http_output.name = "http";
if(m_config->get_scalar<bool>("http_output.enabled", false))
if(config.get_scalar<bool>("http_output.enabled", false))
{
string url;
url = m_config->get_scalar<string>("http_output.url", "");
url = config.get_scalar<string>("http_output.url", "");
if(url == string(""))
{
throw logic_error("Error reading config file (" + m_config_file + "): http output enabled but no url in configuration block");
throw logic_error("Error reading config file (" + config_name + "): http output enabled but no url in configuration block");
}
http_output.options["url"] = url;
string user_agent;
user_agent = m_config->get_scalar<string>("http_output.user_agent","falcosecurity/falco");
user_agent = config.get_scalar<string>("http_output.user_agent","falcosecurity/falco");
http_output.options["user_agent"] = user_agent;
m_outputs.push_back(http_output);
}
m_grpc_enabled = m_config->get_scalar<bool>("grpc.enabled", false);
m_grpc_bind_address = m_config->get_scalar<string>("grpc.bind_address", "0.0.0.0:5060");
m_grpc_threadiness = m_config->get_scalar<uint32_t>("grpc.threadiness", 0);
m_grpc_enabled = config.get_scalar<bool>("grpc.enabled", false);
m_grpc_bind_address = config.get_scalar<string>("grpc.bind_address", "0.0.0.0:5060");
m_grpc_threadiness = config.get_scalar<uint32_t>("grpc.threadiness", 0);
if(m_grpc_threadiness == 0)
{
m_grpc_threadiness = falco::utils::hardware_concurrency();
}
// todo > else limit threadiness to avoid oversubscription?
m_grpc_private_key = m_config->get_scalar<string>("grpc.private_key", "/etc/falco/certs/server.key");
m_grpc_cert_chain = m_config->get_scalar<string>("grpc.cert_chain", "/etc/falco/certs/server.crt");
m_grpc_root_certs = m_config->get_scalar<string>("grpc.root_certs", "/etc/falco/certs/ca.crt");
m_grpc_private_key = config.get_scalar<string>("grpc.private_key", "/etc/falco/certs/server.key");
m_grpc_cert_chain = config.get_scalar<string>("grpc.cert_chain", "/etc/falco/certs/server.crt");
m_grpc_root_certs = config.get_scalar<string>("grpc.root_certs", "/etc/falco/certs/ca.crt");
falco::outputs::config grpc_output;
grpc_output.name = "grpc";
// gRPC output is enabled only if gRPC server is enabled too
if(m_config->get_scalar<bool>("grpc_output.enabled", true) && m_grpc_enabled)
if(config.get_scalar<bool>("grpc_output.enabled", true) && m_grpc_enabled)
{
m_outputs.push_back(grpc_output);
}
if(m_outputs.size() == 0)
{
throw logic_error("Error reading config file (" + m_config_file + "): No outputs configured. Please configure at least one output file output enabled but no filename in configuration block");
}
m_log_level = m_config->get_scalar<string>("log_level", "info");
m_log_level = config.get_scalar<string>("log_level", "info");
falco_logger::set_level(m_log_level);
falco_logger::set_sinsp_logging(
m_config->get_scalar<bool>("libs_logger.enabled", false),
m_config->get_scalar<std::string>("libs_logger.severity", "debug"),
config.get_scalar<bool>("libs_logger.enabled", false),
config.get_scalar<std::string>("libs_logger.severity", "debug"),
"[libs]: ");
m_output_timeout = m_config->get_scalar<uint32_t>("output_timeout", 2000);
m_output_timeout = config.get_scalar<uint32_t>("output_timeout", 2000);
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs.rate", 0);
m_notifications_max_burst = m_config->get_scalar<uint32_t>("outputs.max_burst", 1000);
m_notifications_rate = config.get_scalar<uint32_t>("outputs.rate", 0);
m_notifications_max_burst = config.get_scalar<uint32_t>("outputs.max_burst", 1000);
string priority = m_config->get_scalar<string>("priority", "debug");
string priority = config.get_scalar<string>("priority", "debug");
if (!falco_common::parse_priority(priority, m_min_priority))
{
throw logic_error("Unknown priority \"" + priority + "\"--must be one of emergency, alert, critical, error, warning, notice, informational, debug");
}
m_buffered_outputs = m_config->get_scalar<bool>("buffered_outputs", false);
m_time_format_iso_8601 = m_config->get_scalar<bool>("time_format_iso_8601", false);
m_buffered_outputs = config.get_scalar<bool>("buffered_outputs", false);
m_time_format_iso_8601 = config.get_scalar<bool>("time_format_iso_8601", false);
falco_logger::log_stderr = m_config->get_scalar<bool>("log_stderr", false);
falco_logger::log_syslog = m_config->get_scalar<bool>("log_syslog", true);
falco_logger::log_stderr = config.get_scalar<bool>("log_stderr", false);
falco_logger::log_syslog = config.get_scalar<bool>("log_syslog", true);
m_webserver_enabled = m_config->get_scalar<bool>("webserver.enabled", false);
m_webserver_threadiness = m_config->get_scalar<uint32_t>("webserver.threadiness", 0);
m_webserver_listen_port = m_config->get_scalar<uint32_t>("webserver.listen_port", 8765);
m_webserver_k8s_healthz_endpoint = m_config->get_scalar<string>("webserver.k8s_healthz_endpoint", "/healthz");
m_webserver_ssl_enabled = m_config->get_scalar<bool>("webserver.ssl_enabled", false);
m_webserver_ssl_certificate = m_config->get_scalar<string>("webserver.ssl_certificate", "/etc/falco/falco.pem");
m_webserver_enabled = config.get_scalar<bool>("webserver.enabled", false);
m_webserver_threadiness = config.get_scalar<uint32_t>("webserver.threadiness", 0);
m_webserver_listen_port = config.get_scalar<uint32_t>("webserver.listen_port", 8765);
m_webserver_k8s_healthz_endpoint = config.get_scalar<string>("webserver.k8s_healthz_endpoint", "/healthz");
m_webserver_ssl_enabled = config.get_scalar<bool>("webserver.ssl_enabled", false);
m_webserver_ssl_certificate = config.get_scalar<string>("webserver.ssl_certificate", "/etc/falco/falco.pem");
if(m_webserver_threadiness == 0)
{
m_webserver_threadiness = falco::utils::hardware_concurrency();
}
std::list<string> syscall_event_drop_acts;
m_config->get_sequence(syscall_event_drop_acts, "syscall_event_drops.actions");
config.get_sequence(syscall_event_drop_acts, "syscall_event_drops.actions");
m_syscall_evt_drop_actions.clear();
for(std::string &act : syscall_event_drop_acts)
{
if(act == "ignore")
@@ -249,7 +252,7 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
{
if(m_syscall_evt_drop_actions.count(syscall_evt_drop_action::IGNORE))
{
throw logic_error("Error reading config file (" + m_config_file + "): syscall event drop action \"" + act + "\" does not make sense with the \"ignore\" action");
throw logic_error("Error reading config file (" + config_name + "): syscall event drop action \"" + act + "\" does not make sense with the \"ignore\" action");
}
m_syscall_evt_drop_actions.insert(syscall_evt_drop_action::LOG);
}
@@ -257,7 +260,7 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
{
if(m_syscall_evt_drop_actions.count(syscall_evt_drop_action::IGNORE))
{
throw logic_error("Error reading config file (" + m_config_file + "): syscall event drop action \"" + act + "\" does not make sense with the \"ignore\" action");
throw logic_error("Error reading config file (" + config_name + "): syscall event drop action \"" + act + "\" does not make sense with the \"ignore\" action");
}
m_syscall_evt_drop_actions.insert(syscall_evt_drop_action::ALERT);
}
@@ -267,7 +270,7 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
}
else
{
throw logic_error("Error reading config file (" + m_config_file + "): available actions for syscall event drops are \"ignore\", \"log\", \"alert\", and \"exit\"");
throw logic_error("Error reading config file (" + config_name + "): available actions for syscall event drops are \"ignore\", \"log\", \"alert\", and \"exit\"");
}
}
@@ -276,56 +279,62 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
m_syscall_evt_drop_actions.insert(syscall_evt_drop_action::IGNORE);
}
m_syscall_evt_drop_threshold = m_config->get_scalar<double>("syscall_event_drops.threshold", .1);
m_syscall_evt_drop_threshold = config.get_scalar<double>("syscall_event_drops.threshold", .1);
if(m_syscall_evt_drop_threshold < 0 || m_syscall_evt_drop_threshold > 1)
{
throw logic_error("Error reading config file (" + m_config_file + "): syscall event drops threshold must be a double in the range [0, 1]");
throw logic_error("Error reading config file (" + config_name + "): syscall event drops threshold must be a double in the range [0, 1]");
}
m_syscall_evt_drop_rate = m_config->get_scalar<double>("syscall_event_drops.rate", .03333);
m_syscall_evt_drop_max_burst = m_config->get_scalar<double>("syscall_event_drops.max_burst", 1);
m_syscall_evt_simulate_drops = m_config->get_scalar<bool>("syscall_event_drops.simulate_drops", false);
m_syscall_evt_drop_rate = config.get_scalar<double>("syscall_event_drops.rate", .03333);
m_syscall_evt_drop_max_burst = config.get_scalar<double>("syscall_event_drops.max_burst", 1);
m_syscall_evt_simulate_drops = config.get_scalar<bool>("syscall_event_drops.simulate_drops", false);
m_syscall_evt_timeout_max_consecutives = m_config->get_scalar<uint32_t>("syscall_event_timeouts.max_consecutives", 1000);
m_syscall_evt_timeout_max_consecutives = config.get_scalar<uint32_t>("syscall_event_timeouts.max_consecutives", 1000);
if(m_syscall_evt_timeout_max_consecutives == 0)
{
throw logic_error("Error reading config file(" + m_config_file + "): the maximum consecutive timeouts without an event must be an unsigned integer > 0");
throw logic_error("Error reading config file(" + config_name + "): the maximum consecutive timeouts without an event must be an unsigned integer > 0");
}
m_metadata_download_max_mb = m_config->get_scalar<uint32_t>("metadata_download.max_mb", 100);
m_metadata_download_max_mb = config.get_scalar<uint32_t>("metadata_download.max_mb", 100);
if(m_metadata_download_max_mb > 1024)
{
throw logic_error("Error reading config file(" + m_config_file + "): metadata download maximum size should be < 1024 Mb");
throw logic_error("Error reading config file(" + config_name + "): metadata download maximum size should be < 1024 Mb");
}
m_metadata_download_chunk_wait_us = m_config->get_scalar<uint32_t>("metadata_download.chunk_wait_us", 1000);
m_metadata_download_watch_freq_sec = m_config->get_scalar<uint32_t>("metadata_download.watch_freq_sec", 1);
m_metadata_download_chunk_wait_us = config.get_scalar<uint32_t>("metadata_download.chunk_wait_us", 1000);
m_metadata_download_watch_freq_sec = config.get_scalar<uint32_t>("metadata_download.watch_freq_sec", 1);
if(m_metadata_download_watch_freq_sec == 0)
{
throw logic_error("Error reading config file(" + m_config_file + "): metadata download watch frequency seconds must be an unsigned integer > 0");
throw logic_error("Error reading config file(" + config_name + "): metadata download watch frequency seconds must be an unsigned integer > 0");
}
/* We put this value in the configuration file because in this way we can change the dimension at every reload.
* The default value is `4` -> 8 MB.
*/
m_syscall_buf_size_preset = m_config->get_scalar<uint16_t>("syscall_buf_size_preset", 4);
m_syscall_buf_size_preset = config.get_scalar<uint16_t>("syscall_buf_size_preset", 4);
m_cpus_for_each_syscall_buffer = config.get_scalar<uint16_t>("modern_bpf.cpus_for_each_syscall_buffer", 2);
std::set<std::string> load_plugins;
bool load_plugins_node_defined = m_config->is_defined("load_plugins");
bool load_plugins_node_defined = config.is_defined("load_plugins");
m_config->get_sequence<set<string>>(load_plugins, "load_plugins");
config.get_sequence<set<string>>(load_plugins, "load_plugins");
std::list<falco_configuration::plugin_config> plugins;
try
{
m_config->get_sequence<std::list<falco_configuration::plugin_config>>(plugins, string("plugins"));
if (config.is_defined("plugins"))
{
config.get_sequence<std::list<falco_configuration::plugin_config>>(plugins, string("plugins"));
}
}
catch (exception &e)
{
// Might be thrown due to not being able to open files
throw logic_error("Error reading config file(" + m_config_file + "): could not load plugins config: " + e.what());
throw logic_error("Error reading config file(" + config_name + "): could not load plugins config: " + e.what());
}
// If load_plugins was specified, only save plugins matching those in values
m_plugins.clear();
for (auto &p : plugins)
{
// If load_plugins was not specified at all, every
@@ -337,7 +346,7 @@ void falco_configuration::init(const string& conf_filename, const vector<string>
}
}
m_watch_config_files = m_config->get_scalar<bool>("watch_config_files", true);
m_watch_config_files = config.get_scalar<bool>("watch_config_files", true);
}
void falco_configuration::read_rules_file_directory(const string &path, list<string> &rules_filenames, list<string> &rules_folders)
@@ -420,15 +429,15 @@ static bool split(const string &str, char delim, pair<string, string> &parts)
return true;
}
void falco_configuration::init_cmdline_options(const vector<string> &cmdline_options)
void falco_configuration::init_cmdline_options(yaml_helper& config, const vector<string> &cmdline_options)
{
for(const string &option : cmdline_options)
{
set_cmdline_option(option);
set_cmdline_option(config, option);
}
}
void falco_configuration::set_cmdline_option(const string &opt)
void falco_configuration::set_cmdline_option(yaml_helper& config, const string &opt)
{
pair<string, string> keyval;
@@ -437,5 +446,5 @@ void falco_configuration::set_cmdline_option(const string &opt)
throw logic_error("Error parsing config option \"" + opt + "\". Must be of the form key=val or key.subkey=val");
}
m_config->set_scalar(keyval.first, keyval.second);
config.set_scalar(keyval.first, keyval.second);
}

View File

@@ -28,179 +28,10 @@ limitations under the License.
#include <fstream>
#include "config_falco.h"
#include "yaml_helper.h"
#include "event_drops.h"
#include "falco_outputs.h"
class yaml_configuration
{
public:
/**
* Load the YAML document represented by the input string.
*/
void load_from_string(const std::string& input)
{
m_root = YAML::Load(input);
}
/**
* Load the YAML document from the given file path.
*/
void load_from_file(const std::string& path)
{
m_root = YAML::LoadFile(path);
}
/**
* Clears the internal loaded document.
*/
void clear()
{
m_root = YAML::Node();
}
/**
* Get a scalar value from the node identified by key.
*/
template<typename T>
const T get_scalar(const std::string& key, const T& default_value)
{
YAML::Node node;
get_node(node, key);
if(node.IsDefined())
{
return node.as<T>();
}
return default_value;
}
/**
* Set the node identified by key to value.
*/
template<typename T>
void set_scalar(const std::string& key, const T& value)
{
YAML::Node node;
get_node(node, key);
node = value;
}
/**
* Get the sequence value from the node identified by key.
*/
template<typename T>
void get_sequence(T& ret, const std::string& key)
{
YAML::Node node;
get_node(node, key);
return get_sequence_from_node<T>(ret, node);
}
/**
* Return true if the node identified by key is defined.
*/
bool is_defined(const std::string& key)
{
YAML::Node node;
get_node(node, key);
return node.IsDefined();
}
private:
YAML::Node m_root;
std::string m_input;
bool m_is_from_file;
/**
* Key is a string representing a node in the YAML document.
* The provided key string can navigate the document in its
* nested nodes, with arbitrary depth. The key string follows
* this regular language:
*
* Key := NodeKey ('.' NodeKey)*
* NodeKey := (any)+ ('[' (integer)+ ']')*
*
* Some examples of accepted key strings:
* - NodeName
* - ListValue[3].subvalue
* - MatrixValue[1][3]
* - value1.subvalue2.subvalue3
*/
void get_node(YAML::Node &ret, const std::string &key)
{
try
{
char c;
bool should_shift;
std::string nodeKey;
ret.reset(m_root);
for(std::string::size_type i = 0; i < key.size(); ++i)
{
c = key[i];
should_shift = c == '.' || c == '[' || i == key.size() - 1;
if (c != '.' && c != '[')
{
if (i > 0 && nodeKey.empty() && key[i - 1] != '.')
{
throw runtime_error(
"Parsing error: expected '.' character at pos "
+ to_string(i - 1));
}
nodeKey += c;
}
if (should_shift)
{
if (nodeKey.empty())
{
throw runtime_error(
"Parsing error: unexpected character at pos "
+ to_string(i));
}
ret.reset(ret[nodeKey]);
nodeKey.clear();
}
if (c == '[')
{
auto close_param_idx = key.find(']', i);
int nodeIdx = std::stoi(key.substr(i + 1, close_param_idx - i - 1));
ret.reset(ret[nodeIdx]);
i = close_param_idx;
if (i < key.size() - 1 && key[i + 1] == '.')
{
i++;
}
}
}
}
catch(const std::exception& e)
{
throw runtime_error("Config error at key \"" + key + "\": " + string(e.what()));
}
}
template<typename T>
void get_sequence_from_node(T& ret, const YAML::Node& node)
{
if(node.IsDefined())
{
if(node.IsSequence())
{
for(const YAML::Node& item : node)
{
ret.insert(ret.end(), item.as<typename T::value_type>());
}
}
else if(node.IsScalar())
{
ret.insert(ret.end(), node.as<typename T::value_type>());
}
}
}
};
class falco_configuration
{
public:
@@ -214,7 +45,7 @@ public:
} plugin_config;
falco_configuration();
virtual ~falco_configuration();
virtual ~falco_configuration() = default;
void init(const std::string& conf_filename, const std::vector<std::string>& cmdline_options);
void init(const std::vector<std::string>& cmdline_options);
@@ -272,10 +103,15 @@ public:
// Index corresponding to the syscall buffer dimension.
uint16_t m_syscall_buf_size_preset;
// Number of CPUs associated with a single ring buffer.
uint16_t m_cpus_for_each_syscall_buffer;
std::vector<plugin_config> m_plugins;
private:
void init_cmdline_options(const std::vector<std::string>& cmdline_options);
void load_yaml(const std::string& config_name, const yaml_helper& config);
void init_cmdline_options(yaml_helper& config, const std::vector<std::string>& cmdline_options);
/**
* Given a <key>=<value> specifier, set the appropriate option
@@ -283,63 +119,10 @@ private:
* characters for nesting. Currently only 1- or 2- level keys
* are supported and only scalar values are supported.
*/
void set_cmdline_option(const std::string& spec);
yaml_configuration* m_config;
void set_cmdline_option(yaml_helper& config, const std::string& spec);
};
namespace YAML {
template<>
struct convert<nlohmann::json> {
static bool decode(const Node& node, nlohmann::json& res)
{
int int_val;
double double_val;
bool bool_val;
std::string str_val;
switch (node.Type()) {
case YAML::NodeType::Map:
for (auto &&it: node)
{
nlohmann::json sub{};
YAML::convert<nlohmann::json>::decode(it.second, sub);
res[it.first.as<std::string>()] = sub;
}
break;
case YAML::NodeType::Sequence:
for (auto &&it : node)
{
nlohmann::json sub{};
YAML::convert<nlohmann::json>::decode(it, sub);
res.emplace_back(sub);
}
break;
case YAML::NodeType::Scalar:
if (YAML::convert<int>::decode(node, int_val))
{
res = int_val;
}
else if (YAML::convert<double>::decode(node, double_val))
{
res = double_val;
}
else if (YAML::convert<bool>::decode(node, bool_val))
{
res = bool_val;
}
else if (YAML::convert<std::string>::decode(node, str_val))
{
res = str_val;
}
default:
break;
}
return true;
}
};
template<>
struct convert<falco_configuration::plugin_config> {

View File

@@ -222,10 +222,7 @@ void falco::grpc::server::run()
}
// todo(leodido) > log "gRPC server running: threadiness=m_threads.size()"
while(server_impl::is_running())
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
m_server->Wait();
// todo(leodido) > log "stopping gRPC server"
stop();
}
@@ -233,7 +230,6 @@ void falco::grpc::server::run()
void falco::grpc::server::stop()
{
falco_logger::log(LOG_INFO, "Shutting down gRPC server. Waiting until external connections are closed by clients\n");
m_server->Shutdown();
m_completion_queue->Shutdown();
falco_logger::log(LOG_INFO, "Waiting for the gRPC threads to complete\n");

View File

@@ -56,7 +56,6 @@ private:
std::string m_cert_chain;
std::string m_root_certs;
std::unique_ptr<::grpc::Server> m_server;
std::vector<std::thread> m_threads;
::grpc::ServerBuilder m_server_builder;
void init_mtls_server_builder();

View File

@@ -87,4 +87,5 @@ void falco::grpc::server_impl::version(const context& ctx, const version::reques
void falco::grpc::server_impl::shutdown()
{
m_stop = true;
m_server->Shutdown();
}

View File

@@ -43,6 +43,8 @@ protected:
// Version
void version(const context& ctx, const version::request& req, version::response& res);
std::unique_ptr<::grpc::Server> m_server;
private:
std::atomic<bool> m_stop{false};
};

View File

@@ -0,0 +1,80 @@
/*
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "versions_info.h"
#include "config_falco.h"
#include "falco_engine_version.h"
#include <plugin_manager.h>
// todo: move string conversion to scap
static std::string get_driver_api_version(const std::shared_ptr<sinsp>& s)
{
auto driver_api_version = s->get_scap_api_version();
unsigned long driver_api_major = PPM_API_VERSION_MAJOR(driver_api_version);
unsigned long driver_api_minor = PPM_API_VERSION_MINOR(driver_api_version);
unsigned long driver_api_patch = PPM_API_VERSION_PATCH(driver_api_version);
char driver_api_version_string[32];
snprintf(driver_api_version_string, sizeof(driver_api_version_string), "%lu.%lu.%lu", driver_api_major, driver_api_minor, driver_api_patch);
return std::string(driver_api_version_string);
}
// todo: move string conversion to scap
static inline std::string get_driver_schema_version(const std::shared_ptr<sinsp>& s)
{
auto driver_schema_version = s->get_scap_schema_version();
unsigned long driver_schema_major = PPM_API_VERSION_MAJOR(driver_schema_version);
unsigned long driver_schema_minor = PPM_API_VERSION_MINOR(driver_schema_version);
unsigned long driver_schema_patch = PPM_API_VERSION_PATCH(driver_schema_version);
char driver_schema_version_string[32];
snprintf(driver_schema_version_string, sizeof(driver_schema_version_string), "%lu.%lu.%lu", driver_schema_major, driver_schema_minor, driver_schema_patch);
return std::string(driver_schema_version_string);
}
falco::versions_info::versions_info(const std::shared_ptr<sinsp>& inspector)
{
falco_version = FALCO_VERSION;
engine_version = std::to_string(FALCO_ENGINE_VERSION);
libs_version = FALCOSECURITY_LIBS_VERSION;
plugin_api_version = inspector->get_plugin_api_version();
driver_api_version = get_driver_api_version(inspector);
driver_schema_version = get_driver_schema_version(inspector);
default_driver_version = DRIVER_VERSION;
for (const auto &p : inspector->get_plugin_manager()->plugins())
{
plugin_versions[p->name()] = p->plugin_version().as_string();
}
}
nlohmann::json falco::versions_info::as_json() const
{
nlohmann::json version_info;
version_info["falco_version"] = falco_version;
version_info["libs_version"] = libs_version;
version_info["plugin_api_version"] = plugin_api_version;
version_info["driver_api_version"] = driver_api_version;
version_info["driver_schema_version"] = driver_schema_version;
version_info["default_driver_version"] = default_driver_version;
version_info["engine_version"] = engine_version;
for (const auto& pv : plugin_versions)
{
version_info["plugin_versions"][pv.first] = pv.second;
}
return version_info;
}

View File

@@ -0,0 +1,54 @@
/*
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <memory>
#include <string>
#include <unordered_map>
#include <sinsp.h>
#include <nlohmann/json.hpp>
namespace falco
{
/**
* @brief Container for the version of Falco components
*/
struct versions_info
{
/**
* @brief Construct a versions info by using an inspector to obtain
* versions about the drivers and the loaded plugins.
*/
versions_info(const std::shared_ptr<sinsp>& inspector);
versions_info(versions_info&&) = default;
versions_info& operator = (versions_info&&) = default;
versions_info(const versions_info& s) = default;
versions_info& operator = (const versions_info& s) = default;
/**
* @brief Encode the versions info as a JSON object
*/
nlohmann::json as_json() const;
std::string falco_version;
std::string engine_version;
std::string libs_version;
std::string plugin_api_version;
std::string driver_api_version;
std::string driver_schema_version;
std::string default_driver_version;
std::unordered_map<std::string, std::string> plugin_versions;
};
};

View File

@@ -16,6 +16,7 @@ limitations under the License.
#include "webserver.h"
#include "falco_utils.h"
#include "versions_info.h"
#include <atomic>
falco_webserver::~falco_webserver()
@@ -24,6 +25,7 @@ falco_webserver::~falco_webserver()
}
void falco_webserver::start(
const std::shared_ptr<sinsp>& inspector,
uint32_t threadiness,
uint32_t listen_port,
std::string& healthz_endpoint,
@@ -56,6 +58,13 @@ void falco_webserver::start(
[](const httplib::Request &, httplib::Response &res) {
res.set_content("{\"status\": \"ok\"}", "application/json");
});
// setup versions endpoint
const auto versions_json_str = falco::versions_info(inspector).as_json().dump();
m_server->Get("/versions",
[versions_json_str](const httplib::Request &, httplib::Response &res) {
res.set_content(versions_json_str, "application/json");
});
// run server in a separate thread
if (!m_server->is_valid())

View File

@@ -16,8 +16,11 @@ limitations under the License.
#pragma once
#define CPPHTTPLIB_OPENSSL_SUPPORT
#define CPPHTTPLIB_ZLIB_SUPPORT
#include <httplib.h>
#include <thread>
#include <memory>
#include <sinsp.h>
#include "configuration.h"
class falco_webserver
@@ -25,6 +28,7 @@ class falco_webserver
public:
virtual ~falco_webserver();
virtual void start(
const std::shared_ptr<sinsp>& inspector,
uint32_t threadiness,
uint32_t listen_port,
std::string& healthz_endpoint,

View File

@@ -0,0 +1,258 @@
/*
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <yaml-cpp/yaml.h>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <iostream>
#include <fstream>
#include "config_falco.h"
#include "event_drops.h"
#include "falco_outputs.h"
/**
* @brief An helper class for reading and editing YAML documents
*/
class yaml_helper
{
public:
/**
* Load the YAML document represented by the input string.
*/
void load_from_string(const std::string& input)
{
m_root = YAML::Load(input);
}
/**
* Load the YAML document from the given file path.
*/
void load_from_file(const std::string& path)
{
m_root = YAML::LoadFile(path);
}
/**
* Clears the internal loaded document.
*/
void clear()
{
m_root = YAML::Node();
}
/**
* Get a scalar value from the node identified by key.
*/
template<typename T>
const T get_scalar(const std::string& key, const T& default_value) const
{
YAML::Node node;
get_node(node, key);
if(node.IsDefined())
{
return node.as<T>();
}
return default_value;
}
/**
* Set the node identified by key to value.
*/
template<typename T>
void set_scalar(const std::string& key, const T& value)
{
YAML::Node node;
get_node(node, key);
node = value;
}
/**
* Get the sequence value from the node identified by key.
*/
template<typename T>
void get_sequence(T& ret, const std::string& key) const
{
YAML::Node node;
get_node(node, key);
return get_sequence_from_node<T>(ret, node);
}
/**
* Return true if the node identified by key is defined.
*/
bool is_defined(const std::string& key) const
{
YAML::Node node;
get_node(node, key);
return node.IsDefined();
}
private:
YAML::Node m_root;
std::string m_input;
/**
* Key is a string representing a node in the YAML document.
* The provided key string can navigate the document in its
* nested nodes, with arbitrary depth. The key string follows
* this regular language:
*
* Key := NodeKey ('.' NodeKey)*
* NodeKey := (any)+ ('[' (integer)+ ']')*
*
* Some examples of accepted key strings:
* - NodeName
* - ListValue[3].subvalue
* - MatrixValue[1][3]
* - value1.subvalue2.subvalue3
*/
void get_node(YAML::Node &ret, const std::string &key) const
{
try
{
char c;
bool should_shift;
std::string nodeKey;
ret.reset(m_root);
for(std::string::size_type i = 0; i < key.size(); ++i)
{
c = key[i];
should_shift = c == '.' || c == '[' || i == key.size() - 1;
if (c != '.' && c != '[')
{
if (i > 0 && nodeKey.empty() && key[i - 1] != '.')
{
throw runtime_error(
"Parsing error: expected '.' character at pos "
+ to_string(i - 1));
}
nodeKey += c;
}
if (should_shift)
{
if (nodeKey.empty())
{
throw runtime_error(
"Parsing error: unexpected character at pos "
+ to_string(i));
}
ret.reset(ret[nodeKey]);
nodeKey.clear();
}
if (c == '[')
{
auto close_param_idx = key.find(']', i);
int nodeIdx = std::stoi(key.substr(i + 1, close_param_idx - i - 1));
ret.reset(ret[nodeIdx]);
i = close_param_idx;
if (i < key.size() - 1 && key[i + 1] == '.')
{
i++;
}
}
}
}
catch(const std::exception& e)
{
throw runtime_error("Config error at key \"" + key + "\": " + string(e.what()));
}
}
template<typename T>
void get_sequence_from_node(T& ret, const YAML::Node& node) const
{
if(node.IsDefined())
{
if(node.IsSequence())
{
for(const YAML::Node& item : node)
{
ret.insert(ret.end(), item.as<typename T::value_type>());
}
}
else if(node.IsScalar())
{
ret.insert(ret.end(), node.as<typename T::value_type>());
}
}
}
};
// define a yaml-cpp conversion function for nlohmann json objects
namespace YAML {
template<>
struct convert<nlohmann::json> {
static bool decode(const Node& node, nlohmann::json& res)
{
int int_val;
double double_val;
bool bool_val;
std::string str_val;
switch (node.Type()) {
case YAML::NodeType::Map:
for (auto &&it: node)
{
nlohmann::json sub{};
YAML::convert<nlohmann::json>::decode(it.second, sub);
res[it.first.as<std::string>()] = sub;
}
break;
case YAML::NodeType::Sequence:
for (auto &&it : node)
{
nlohmann::json sub{};
YAML::convert<nlohmann::json>::decode(it, sub);
res.emplace_back(sub);
}
break;
case YAML::NodeType::Scalar:
if (YAML::convert<int>::decode(node, int_val))
{
res = int_val;
}
else if (YAML::convert<double>::decode(node, double_val))
{
res = double_val;
}
else if (YAML::convert<bool>::decode(node, bool_val))
{
res = bool_val;
}
else if (YAML::convert<std::string>::decode(node, str_val))
{
res = str_val;
}
default:
break;
}
return true;
}
};
}