mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-21 04:02:14 +00:00
Compare commits
129 Commits
embed-lua-
...
add-app-ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e0be46ede | ||
|
|
07fe221abf | ||
|
|
cec0f8c6cc | ||
|
|
4e5f6c0517 | ||
|
|
2585462f81 | ||
|
|
fbabe9efab | ||
|
|
a2fb776e66 | ||
|
|
80078cb641 | ||
|
|
9109fe6913 | ||
|
|
5554294bc7 | ||
|
|
ebef16f28f | ||
|
|
b5878010ed | ||
|
|
59f78696cf | ||
|
|
529b9d9724 | ||
|
|
4adf4e9603 | ||
|
|
b00bf53d88 | ||
|
|
066f799227 | ||
|
|
867a10bb76 | ||
|
|
572e4af528 | ||
|
|
7b45b2c354 | ||
|
|
fcd67307f6 | ||
|
|
63123c405f | ||
|
|
f635e93910 | ||
|
|
642399fa7a | ||
|
|
0dfd9147e3 | ||
|
|
e0feeeaa40 | ||
|
|
2c1c23830a | ||
|
|
f92abafb46 | ||
|
|
8d258b11f8 | ||
|
|
6524dcf5f5 | ||
|
|
5d5c7d324a | ||
|
|
990ce338ce | ||
|
|
c569ff5604 | ||
|
|
36a95398dd | ||
|
|
e9d15a7500 | ||
|
|
dd1119374b | ||
|
|
7b20367ae9 | ||
|
|
40e018a531 | ||
|
|
5c104d3f90 | ||
|
|
64722728dd | ||
|
|
16703be1f9 | ||
|
|
f78c816abd | ||
|
|
1d76df3831 | ||
|
|
335d79e79c | ||
|
|
ef6888181d | ||
|
|
d3083cde92 | ||
|
|
83353985f7 | ||
|
|
83b036bc0e | ||
|
|
216f56b73b | ||
|
|
17d8eea3bc | ||
|
|
d74c8d6d4d | ||
|
|
888c15c6ee | ||
|
|
eedb794fd5 | ||
|
|
83c527dd91 | ||
|
|
cbcc680c77 | ||
|
|
ad90209177 | ||
|
|
204f9ff875 | ||
|
|
87c410e49e | ||
|
|
b9925577ef | ||
|
|
ae5342c54b | ||
|
|
1324522721 | ||
|
|
7999e33aea | ||
|
|
f49a95f334 | ||
|
|
9e8687401d | ||
|
|
6ead925f51 | ||
|
|
8a3a4c4d57 | ||
|
|
ff21544186 | ||
|
|
ee2f7c50e8 | ||
|
|
5da10a3b89 | ||
|
|
f86423db76 | ||
|
|
5eed3a6638 | ||
|
|
d585343483 | ||
|
|
9e57b5b4ba | ||
|
|
47f38c8ae2 | ||
|
|
332d828204 | ||
|
|
75c6cfb414 | ||
|
|
a4199814a0 | ||
|
|
24e7e84153 | ||
|
|
70bfb2426c | ||
|
|
ce3598f801 | ||
|
|
8e6ffc6fc9 | ||
|
|
6a42f4a133 | ||
|
|
8d9dd4440f | ||
|
|
c49093005d | ||
|
|
69767bb51b | ||
|
|
7750b6f209 | ||
|
|
8c705448cc | ||
|
|
6b9fafb75f | ||
|
|
fdcd7bffd0 | ||
|
|
d989e9c2d5 | ||
|
|
996ccf555c | ||
|
|
2f82a9baa1 | ||
|
|
dfb743838e | ||
|
|
c7609192c7 | ||
|
|
4d3fc354fa | ||
|
|
43bdfce6e5 | ||
|
|
a3976463d5 | ||
|
|
1a485c3447 | ||
|
|
96529300f6 | ||
|
|
27922faa27 | ||
|
|
8a1de131f4 | ||
|
|
e1e8715a0f | ||
|
|
9ae8d281f5 | ||
|
|
c705623f9e | ||
|
|
3640871725 | ||
|
|
6d507b054c | ||
|
|
f19a1d81c6 | ||
|
|
18c7b6500d | ||
|
|
8239fa41f4 | ||
|
|
a9e7512936 | ||
|
|
f67e8bdad7 | ||
|
|
a94e6de458 | ||
|
|
3e9f8c1ef1 | ||
|
|
d20a326e09 | ||
|
|
0c290d98f8 | ||
|
|
1befb053d0 | ||
|
|
ae57718bda | ||
|
|
55ce38cf3a | ||
|
|
18571eb20d | ||
|
|
9c449901f3 | ||
|
|
4ab8d6db98 | ||
|
|
5e354859a9 | ||
|
|
f4b79296fc | ||
|
|
6bf8f34d9f | ||
|
|
f8f053c7fa | ||
|
|
b88a1cbb09 | ||
|
|
c86615f68c | ||
|
|
08df1c63cf | ||
|
|
10512b9ef9 |
@@ -176,38 +176,6 @@ jobs:
|
||||
pushd build
|
||||
make tests
|
||||
popd
|
||||
# Build using CentOS 8
|
||||
# This build is static, dependencies are bundled in the Falco binary
|
||||
"build/centos8":
|
||||
docker:
|
||||
- image: centos:8
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update base image
|
||||
command: dnf update -y
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: dnf install gcc gcc-c++ git make cmake autoconf automake pkg-config patch libtool elfutils-libelf-devel diffutils kernel-devel kernel-headers kernel-core clang llvm which -y
|
||||
- run:
|
||||
name: Prepare project
|
||||
command: |
|
||||
mkdir build
|
||||
pushd build
|
||||
cmake -DBUILD_BPF=On -DUSE_BUNDLED_DEPS=On ..
|
||||
popd
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
pushd build
|
||||
KERNELDIR=/lib/modules/$(ls /lib/modules)/build make -j4 all
|
||||
popd
|
||||
- run:
|
||||
name: Run unit tests
|
||||
command: |
|
||||
pushd build
|
||||
make tests
|
||||
popd
|
||||
# Build using our own builder base image using centos 7
|
||||
# This build is static, dependencies are bundled in the Falco binary
|
||||
"build/centos7":
|
||||
@@ -391,9 +359,15 @@ jobs:
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm-dev
|
||||
- run:
|
||||
name: Publish bin-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
|
||||
- run:
|
||||
name: Publish bin-static-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
|
||||
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin-dev -a x86_64
|
||||
"publish/packages-deb-dev":
|
||||
docker:
|
||||
- image: docker.io/debian:stable
|
||||
@@ -505,9 +479,15 @@ jobs:
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm
|
||||
- run:
|
||||
name: Publish bin
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
|
||||
- run:
|
||||
name: Publish bin-static
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
|
||||
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin -a x86_64
|
||||
"publish/packages-deb":
|
||||
docker:
|
||||
- image: docker.io/debian:stable
|
||||
@@ -618,7 +598,6 @@ workflows:
|
||||
- "build/ubuntu-focal"
|
||||
- "build/ubuntu-focal-debug"
|
||||
- "build/ubuntu-bionic"
|
||||
- "build/centos8"
|
||||
- "build/centos7"
|
||||
- "build/centos7-debug"
|
||||
- "tests/integration":
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -10,11 +10,8 @@ test/.phoronix-test-suite
|
||||
test/results*.json.*
|
||||
test/build
|
||||
|
||||
userspace/engine/lua/lyaml
|
||||
userspace/engine/lua/lyaml.lua
|
||||
|
||||
.vscode/*
|
||||
|
||||
.luacheckcache
|
||||
|
||||
*.idea*
|
||||
*.idea*
|
||||
|
||||
@@ -64,7 +64,7 @@ This is a list of production adopters of Falco (in alphabetical order):
|
||||
|
||||
* [Yahoo! JAPAN](https://www.yahoo.co.jp/) Yahoo! JAPAN is a leading company of internet in Japan. We build an AI Platform in our private cloud and provide it to scientists in our company. AI Platform is a multi-tenant Kubernetes environment and more flexible, faster, more efficient Machine Learning environment. Falco is used to detect unauthorized commands and malicious access and our AI Platform is monitored and alerted by Falco.
|
||||
|
||||
* [Sysdig](https://www.sysdig.com/) Sysdig originally created Falco in 2016 to detect unexpected or suspicious activity using a rules engine on top of the data that comes from the sysdig kernel system call probe. Sysdig provides tooling to help with vulnerability management, compliance, detection, incident response and forensics in Cloud-native environments. Sysdig Secure has extended Falco to include: a rule library, the ability to update macros, lists & rules via the user interface and API, automated tuning of rules, and rule creation based on profiling known system behavior. On top of the basic Falco rules, Sysdig Secure implements the concept of a "Security policy" that can comprise several rules which are evaluated for a user-defined infrastructure scope like Kubernetes namespaces, OpenShift clusters, deployment workload, cloud regions etc.
|
||||
* [Sysdig](https://www.sysdig.com/) Sysdig originally created Falco in 2016 to detect unexpected or suspicious activity using a rules engine on top of the data that comes from the sysdig kernel system call driver. Sysdig provides tooling to help with vulnerability management, compliance, detection, incident response and forensics in Cloud-native environments. Sysdig Secure has extended Falco to include: a rule library, the ability to update macros, lists & rules via the user interface and API, automated tuning of rules, and rule creation based on profiling known system behavior. On top of the basic Falco rules, Sysdig Secure implements the concept of a "Security policy" that can comprise several rules which are evaluated for a user-defined infrastructure scope like Kubernetes namespaces, OpenShift clusters, deployment workload, cloud regions etc.
|
||||
|
||||
## Projects that use Falco libs
|
||||
|
||||
|
||||
94
CHANGELOG.md
94
CHANGELOG.md
@@ -1,5 +1,99 @@
|
||||
# Change Log
|
||||
|
||||
## v0.31.0
|
||||
|
||||
Released on 2022-01-31
|
||||
|
||||
### Major Changes
|
||||
|
||||
|
||||
* new: add support for plugins to extend Falco functionality to new event sources and custom fields [[#1753](https://github.com/falcosecurity/falco/pull/1753)] - [@mstemm](https://github.com/mstemm)
|
||||
* new: add ability to set User-Agent http header when sending http output. Provide default value of 'falcosecurit/falco'. [[#1850](https://github.com/falcosecurity/falco/pull/1850)] - [@yoshi314](https://github.com/yoshi314)
|
||||
* new(configuration): support defining plugin init config as a YAML [[#1852](https://github.com/falcosecurity/falco/pull/1852)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
|
||||
|
||||
### Minor Changes
|
||||
|
||||
* rules: add the official Falco ECR repository to rules [[#1817](https://github.com/falcosecurity/falco/pull/1817)] - [@calvinbui](https://github.com/calvinbui)
|
||||
* build: update CircleCI machine image for eBPF tests to a newer version of ubuntu [[#1764](https://github.com/falcosecurity/falco/pull/1764)] - [@mstemm](https://github.com/mstemm)
|
||||
* update(engine): refactor Falco engine to be agnostic to specific event sources [[#1715](https://github.com/falcosecurity/falco/pull/1715)] - [@mstemm](https://github.com/mstemm)
|
||||
* build: upgrade civetweb to v1.15 [[#1782](https://github.com/falcosecurity/falco/pull/1782)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update: driver version is 319368f1ad778691164d33d59945e00c5752cd27 now [[#1861](https://github.com/falcosecurity/falco/pull/1861)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* build: allow using local libs source dir by setting `FALCOSECURITY_LIBS_SOURCE_DIR` in cmake [[#1791](https://github.com/falcosecurity/falco/pull/1791)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* build: the statically linked binary package is now published with the `-static` suffix [[#1873](https://github.com/falcosecurity/falco/pull/1873)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* update!: removed "--alternate-lua-dir" cmdline option as lua scripts are now embedded in Falco executable. [[#1872](https://github.com/falcosecurity/falco/pull/1872)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* build: switch to dynamic build for the binary package (`.tar.gz`) [[#1853](https://github.com/falcosecurity/falco/pull/1853)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* update: simpleconsumer filtering is now being done at kernel level [[#1846](https://github.com/falcosecurity/falco/pull/1846)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update(scripts/falco-driver-loader): first try to load the latest kmod version, then fallback to an already installed if any [[#1863](https://github.com/falcosecurity/falco/pull/1863)] - [@leogr](https://github.com/leogr)
|
||||
* refactor: clean up --list output with better formatting and no duplicate sections across event sources. [[#1816](https://github.com/falcosecurity/falco/pull/1816)] - [@mstemm](https://github.com/mstemm)
|
||||
* update: embed .lua files used to load/compile rules into the main falco executable, for simplicity and to avoid tampering. [[#1843](https://github.com/falcosecurity/falco/pull/1843)] - [@mstemm](https://github.com/mstemm)
|
||||
* update: support non-enumerable event sources in gRPC outputs service [[#1840](https://github.com/falcosecurity/falco/pull/1840)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* docs: add jasondellaluce to OWNERS [[#1818](https://github.com/falcosecurity/falco/pull/1818)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* chore: --list option can be used to selectively list fields related to new sources that are introduced by plugins [[#1839](https://github.com/falcosecurity/falco/pull/1839)] - [@loresuso](https://github.com/loresuso)
|
||||
* update(userspace/falco): support arbitrary-depth nested values in YAML configuration [[#1792](https://github.com/falcosecurity/falco/pull/1792)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* build: bump FakeIt version to 2.0.9 [[#1797](https://github.com/falcosecurity/falco/pull/1797)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* update: allow append of new exceptions to rules [[#1780](https://github.com/falcosecurity/falco/pull/1780)] - [@sai-arigeli](https://github.com/sai-arigeli)
|
||||
* update: Linux packages are now signed with SHA256 [[#1758](https://github.com/falcosecurity/falco/pull/1758)] - [@twa16](https://github.com/twa16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix(scripts/falco-driver-loader): fix for SELinux insmod denials [[#1756](https://github.com/falcosecurity/falco/pull/1756)] - [@dwindsor](https://github.com/dwindsor)
|
||||
* fix(scripts/falco-driver-loader): correctly clean loaded drivers when using `--clean` [[#1795](https://github.com/falcosecurity/falco/pull/1795)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix(userspace/falco): in case output_file cannot be opened, throw a falco exception [[#1773](https://github.com/falcosecurity/falco/pull/1773)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(userspace/engine): support jsonpointer escaping in rule parser [[#1777](https://github.com/falcosecurity/falco/pull/1777)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix(scripts/falco-driver-loader): support kernel object files in `.zst` and `.gz` compression formats [[#1863](https://github.com/falcosecurity/falco/pull/1863)] - [@leogr](https://github.com/leogr)
|
||||
* fix(engine): correctly format json output in json_event [[#1847](https://github.com/falcosecurity/falco/pull/1847)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix: set http output contenttype to text/plain when json output is disabled [[#1829](https://github.com/falcosecurity/falco/pull/1829)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(userspace/falco): accept 'Content-Type' header that contains "application/json", but it is not strictly equal to it [[#1800](https://github.com/falcosecurity/falco/pull/1800)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(userspace/engine): supporting enabled-only overwritten rules [[#1775](https://github.com/falcosecurity/falco/pull/1775)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
|
||||
|
||||
### Rule Changes
|
||||
|
||||
* rule(Create Symlink Over Sensitive File): corrected typo in rule output [[#1820](https://github.com/falcosecurity/falco/pull/1820)] - [@deepskyblue86](https://github.com/deepskyblue86)
|
||||
* rule(macro open_write): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* rule(macro open_read): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* rule(macro open_directory): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* rule(Create files below dev): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* rule(Container Drift Detected (open+create)): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* rule(macro sensitive_mount): add containerd socket [[#1815](https://github.com/falcosecurity/falco/pull/1815)] - [@loresuso](https://github.com/loresuso)
|
||||
* rule(macro spawned_process): monitor also processes spawned by `execveat` [[#1868](https://github.com/falcosecurity/falco/pull/1868)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* rule(Create Hardlink Over Sensitive Files): new rule to detect hard links created over sensitive files [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
|
||||
* rule(Detect crypto miners using the Stratum protocol): add `stratum2+tcp` and `stratum+ssl` protocols detection [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
|
||||
* rule(Sudo Potential Privilege Escalation): correct special case for the CVE-2021-3156 exploit [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
|
||||
* rule(list falco_hostnetwork_images): moved to k8s_audit_rules.yaml to avoid a warning when usng falco_rules.yaml only [[#1681](https://github.com/falcosecurity/falco/pull/1681)] - [@leodido](https://github.com/leodido)
|
||||
* rule(list deb_binaries): remove `apt-config` [[#1860](https://github.com/falcosecurity/falco/pull/1860)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* rule(Launch Remote File Copy Tools in Container): add additional binaries: curl and wget. [[#1771](https://github.com/falcosecurity/falco/pull/1771)] - [@ec4n6](https://github.com/ec4n6)
|
||||
* rule(list known_sa_list): add coredns, coredns-autoscaler, endpointslicemirroring-controller, horizontal-pod-autoscaler, job-controller, node-controller (nodelifecycle), persistent-volume-binder, pv-protection-controller, pvc-protection-controller, root-ca-cert-publisher and service-account-controller as allowed service accounts in the kube-system namespace [[#1760](https://github.com/falcosecurity/falco/pull/1760)] - [@sboschman](https://github.com/sboschman)
|
||||
|
||||
|
||||
### Non user-facing changes
|
||||
|
||||
* fix: force-set evt.type for plugin source events [[#1878](https://github.com/falcosecurity/falco/pull/1878)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix: updated some warning strings; properly refresh lua files embedded in falco [[#1864](https://github.com/falcosecurity/falco/pull/1864)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* style(userspace/engine): avoid creating multiple versions of methods only to assume default ruleset. Use a default argument instead. [[#1754](https://github.com/falcosecurity/falco/pull/1754)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* add raft in the adopters list [[#1776](https://github.com/falcosecurity/falco/pull/1776)] - [@teshsharma](https://github.com/teshsharma)
|
||||
* build: always populate partial version variables [[#1778](https://github.com/falcosecurity/falco/pull/1778)] - [@dnwe](https://github.com/dnwe)
|
||||
* build: updated cloudtrail plugin to latest version [[#1865](https://github.com/falcosecurity/falco/pull/1865)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* replace ".." concatenation with table.concat [[#1834](https://github.com/falcosecurity/falco/pull/1834)] - [@VadimZy](https://github.com/VadimZy)
|
||||
* fix(userspace/engine): actually make m_filter_all_event_types useful by properly using it as fallback when no filter event types is provided [[#1875](https://github.com/falcosecurity/falco/pull/1875)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): do not show plugin options in musl optimized builds [[#1871](https://github.com/falcosecurity/falco/pull/1871)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* fix(aws_cloudtrail_rules.yaml): correct required plugin versions [[#1867](https://github.com/falcosecurity/falco/pull/1867)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* docs: fix priority level "info" to "informational" [[#1858](https://github.com/falcosecurity/falco/pull/1858)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* Field properties changes [[#1838](https://github.com/falcosecurity/falco/pull/1838)] - [@mstemm](https://github.com/mstemm)
|
||||
* update(build): updated libs to latest master version; updated plugins versions [[#1856](https://github.com/falcosecurity/falco/pull/1856)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* Add Giant Swarm to Adopters list [[#1842](https://github.com/falcosecurity/falco/pull/1842)] - [@stone-z](https://github.com/stone-z)
|
||||
* update(tests): remove `token_bucket` unit tests [[#1798](https://github.com/falcosecurity/falco/pull/1798)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix(build): use consistent 7-character build abbrev sha [[#1830](https://github.com/falcosecurity/falco/pull/1830)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* add Phoenix to adopters list [[#1806](https://github.com/falcosecurity/falco/pull/1806)] - [@kaldyka](https://github.com/kaldyka)
|
||||
* remove unused files in test directory [[#1801](https://github.com/falcosecurity/falco/pull/1801)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* drop Falco luajit module, use the one provied by libs [[#1788](https://github.com/falcosecurity/falco/pull/1788)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* chore(build): update libs version to 7906f7e [[#1790](https://github.com/falcosecurity/falco/pull/1790)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* Add SysFlow to list of libs adopters [[#1747](https://github.com/falcosecurity/falco/pull/1747)] - [@araujof](https://github.com/araujof)
|
||||
* build: dropped centos8 circleci build because it is useless [[#1882](https://github.com/falcosecurity/falco/pull/1882)] - [@FedeDP](https://github.com/FedeDP)
|
||||
|
||||
|
||||
## v0.30.0
|
||||
|
||||
Released on 2021-10-01
|
||||
|
||||
@@ -58,6 +58,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "debug")
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE "release")
|
||||
set(KBUILD_FLAGS "${DRAIOS_FEATURE_FLAGS}")
|
||||
add_definitions(-DBUILD_TYPE_RELEASE)
|
||||
endif()
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
@@ -67,6 +68,7 @@ endif()
|
||||
|
||||
if(MUSL_OPTIMIZED_BUILD)
|
||||
set(MUSL_FLAGS "-static -Os -fPIE -pie")
|
||||
add_definitions(-DMUSL_OPTIMIZED)
|
||||
endif()
|
||||
|
||||
# explicitly set hardening flags
|
||||
@@ -97,8 +99,8 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
|
||||
include(GetFalcoVersion)
|
||||
|
||||
set(PACKAGE_NAME "falco")
|
||||
set(PROBE_NAME "falco")
|
||||
set(PROBE_DEVICE_NAME "falco")
|
||||
set(DRIVER_NAME "falco")
|
||||
set(DRIVER_DEVICE_NAME "falco")
|
||||
set(DRIVERS_REPO "https://download.falco.org/driver")
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX
|
||||
@@ -148,6 +150,8 @@ if(NOT MINIMAL_BUILD)
|
||||
include(civetweb)
|
||||
endif()
|
||||
|
||||
include(cxxopts)
|
||||
|
||||
# Lpeg
|
||||
include(lpeg)
|
||||
|
||||
@@ -206,7 +210,9 @@ add_subdirectory(userspace/engine)
|
||||
add_subdirectory(userspace/falco)
|
||||
add_subdirectory(tests)
|
||||
|
||||
include(plugins)
|
||||
if(NOT MUSL_OPTIMIZED_BUILD)
|
||||
include(plugins)
|
||||
endif()
|
||||
|
||||
# Packages configuration
|
||||
include(CPackConfig)
|
||||
|
||||
@@ -10,5 +10,4 @@ endif()
|
||||
|
||||
if(CPACK_GENERATOR MATCHES "TGZ")
|
||||
set(CPACK_SET_DESTDIR "ON")
|
||||
set(CPACK_STRIP_FILES "OFF")
|
||||
endif()
|
||||
|
||||
@@ -24,6 +24,7 @@ ExternalProject_Add(
|
||||
GIT_TAG "v1.4.0"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
INSTALL_COMMAND
|
||||
${CMAKE_COMMAND} -E copy ${STRING_VIEW_LITE_PREFIX}/src/string-view-lite/include/nonstd/string_view.hpp
|
||||
${STRING_VIEW_LITE_INCLUDE}/nonstd/string_view.hpp)
|
||||
|
||||
30
cmake/modules/copy_files_to_build_dir.cmake
Normal file
30
cmake/modules/copy_files_to_build_dir.cmake
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
function(copy_files_to_build_dir source_files targetsuffix)
|
||||
|
||||
set(build_files)
|
||||
|
||||
foreach(file_path ${source_files})
|
||||
get_filename_component(trace_file ${file_path} NAME)
|
||||
list(APPEND build_files ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(copy-files-${targetsuffix} ALL
|
||||
DEPENDS ${build_files})
|
||||
|
||||
add_custom_command(OUTPUT ${build_files}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${source_files} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${source_files})
|
||||
|
||||
endfunction()
|
||||
23
cmake/modules/cxxopts.cmake
Normal file
23
cmake/modules/cxxopts.cmake
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
set(CXXOPTS_SRC "${PROJECT_BINARY_DIR}/cxxopts-prefix/src/cxxopts/")
|
||||
set(CXXOPTS_INCLUDE_DIR "${CXXOPTS_SRC}/include")
|
||||
|
||||
ExternalProject_Add(
|
||||
cxxopts
|
||||
URL "https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.0.0.tar.gz"
|
||||
URL_HASH "SHA256=36f41fa2a46b3c1466613b63f3fa73dc24d912bc90d667147f1e43215a8c6d00"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
@@ -24,8 +24,8 @@ else()
|
||||
# default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake
|
||||
# -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||
set(FALCOSECURITY_LIBS_VERSION "bb9bee8e522fc953c2a79093d688d3d82b925e8b")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=ab2f18ff9c8d92dd06088ccfa73d4230fce3617613229f5afd839a37c13b0459")
|
||||
set(FALCOSECURITY_LIBS_VERSION "39e05ab79c77cfb05a3fa2309becc346d2b0fa2b")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=3f9a20e871d22333bfa34ea3f4a05d0697202895450dd3a7d519096c9e587b1e")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
@@ -47,8 +47,8 @@ if(MUSL_OPTIMIZED_BUILD)
|
||||
add_definitions(-DMUSL_OPTIMIZED)
|
||||
endif()
|
||||
|
||||
set(PROBE_VERSION "${FALCOSECURITY_LIBS_VERSION}")
|
||||
set(PROBE_NAME "falco")
|
||||
set(DRIVER_VERSION "${FALCOSECURITY_LIBS_VERSION}")
|
||||
set(DRIVER_NAME "falco")
|
||||
set(DRIVER_PACKAGE_NAME "falco")
|
||||
set(SCAP_BPF_PROBE_ENV_VAR_NAME "FALCO_BPF_PROBE")
|
||||
set(SCAP_HOST_ROOT_ENV_VAR_NAME "HOST_ROOT")
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
set(PLUGINS_VERSION "0.1.0-rc1-28-g019437e")
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME)
|
||||
|
||||
ExternalProject_Add(
|
||||
cloudtrail-plugin
|
||||
URL "https://download.falco.org/plugins/dev/cloudtrail-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=ad9692957c5435238e07d1625e1b247eabe98b85f54de9218367fdd73a6f3f0b"
|
||||
URL "https://download.falco.org/plugins/stable/cloudtrail-0.2.3-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=3dfce36f37a4f834b6078c6b78776414472a6ee775e8f262535313cc4031d0b7"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
@@ -27,8 +27,8 @@ install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plu
|
||||
|
||||
ExternalProject_Add(
|
||||
json-plugin
|
||||
URL "https://download.falco.org/plugins/dev/json-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=721ea5226b0f623915d0d5c34870589ad33a8ff795b0daa1af72f21a67430077"
|
||||
URL "https://download.falco.org/plugins/stable/json-0.2.2-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=83eb411c9f2125695875b229c6e7974e6a4cc7f028be146b79d26db30372af5e"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of rules is created at cmake time, not build time
|
||||
file(GLOB test_rule_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../test/rules/*.yaml")
|
||||
|
||||
foreach(rule_file_path ${test_rule_files})
|
||||
get_filename_component(rule_file ${rule_file_path} NAME)
|
||||
add_custom_target(docker-local-rule-${rule_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${rule_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${rule_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${rule_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${rule_file}
|
||||
DEPENDS ${rule_file_path})
|
||||
endforeach()
|
||||
|
||||
copy_files_to_build_dir("${test_rule_files}" docker-local-rules)
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of traces is created at cmake time, not build time
|
||||
file(GLOB test_trace_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../test/trace_files/*.scap")
|
||||
|
||||
foreach(trace_file_path ${test_trace_files})
|
||||
get_filename_component(trace_file ${trace_file_path} NAME)
|
||||
add_custom_target(docker-local-trace-${trace_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${trace_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
DEPENDS ${trace_file_path})
|
||||
endforeach()
|
||||
|
||||
copy_files_to_build_dir("${test_trace_files}" docker-local-traces)
|
||||
|
||||
@@ -20,7 +20,7 @@ RUN curl -L -o falco.tar.gz \
|
||||
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \
|
||||
&& mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml
|
||||
|
||||
FROM scratch
|
||||
FROM debian:11-slim
|
||||
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ log_level: info
|
||||
# Minimum rule priority level to load and run. All rules having a
|
||||
# priority more severe than this level will be loaded/run. Can be one
|
||||
# of "emergency", "alert", "critical", "error", "warning", "notice",
|
||||
# "info", "debug".
|
||||
# "informational", "debug".
|
||||
priority: debug
|
||||
|
||||
# Whether or not output to any of the output channels below is
|
||||
@@ -246,6 +246,7 @@ program_output:
|
||||
http_output:
|
||||
enabled: false
|
||||
url: http://some.url
|
||||
user_agent: "falcosecurity/falco"
|
||||
|
||||
# Falco supports running a gRPC server with two main binding types
|
||||
# 1. Over the network with mandatory mutual TLS authentication (mTLS)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2022 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -22,7 +22,9 @@
|
||||
# anything semver-compatible.
|
||||
- required_plugin_versions:
|
||||
- name: cloudtrail
|
||||
version: 0.1.0
|
||||
version: 0.2.3
|
||||
- name: json
|
||||
version: 0.2.2
|
||||
|
||||
# Note that this rule is disabled by default. It's useful only to
|
||||
# verify that the cloudtrail plugin is sending events properly. The
|
||||
@@ -339,7 +341,7 @@
|
||||
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicAcls]=false or
|
||||
json.value[/requestParameters/PublicAccessBlockConfiguration/IgnorePublicAcls]=false)
|
||||
output:
|
||||
A pulic access block for a bucket has been deleted
|
||||
A public access block for a bucket has been deleted
|
||||
(requesting user=%ct.user,
|
||||
requesting IP=%ct.srcip,
|
||||
AWS region=%ct.region,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
# Copyright (C) 2022 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -63,11 +63,14 @@
|
||||
condition: rename or remove
|
||||
|
||||
- macro: spawned_process
|
||||
condition: evt.type = execve and evt.dir=<
|
||||
condition: evt.type in (execve, execveat) and evt.dir=<
|
||||
|
||||
- macro: create_symlink
|
||||
condition: evt.type in (symlink, symlinkat) and evt.dir=<
|
||||
|
||||
- macro: create_hardlink
|
||||
condition: evt.type in (link, linkat) and evt.dir=<
|
||||
|
||||
- macro: chmod
|
||||
condition: (evt.type in (chmod, fchmod, fchmodat) and evt.dir=<)
|
||||
|
||||
@@ -216,13 +219,13 @@
|
||||
- list: deb_binaries
|
||||
items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude,
|
||||
frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key,
|
||||
apt-listchanges, unattended-upgr, apt-add-reposit, apt-config, apt-cache, apt.systemd.dai
|
||||
apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai
|
||||
]
|
||||
|
||||
# The truncated dpkg-preconfigu is intentional, process names are
|
||||
# truncated at the falcosecurity-libs level.
|
||||
- list: package_mgmt_binaries
|
||||
items: [rpm_binaries, deb_binaries, update-alternat, gem, pip, pip3, sane-utils.post, alternatives, chef-client, apk, snapd]
|
||||
items: [rpm_binaries, deb_binaries, update-alternat, gem, npm, pip, pip3, sane-utils.post, alternatives, chef-client, apk, snapd]
|
||||
|
||||
- macro: package_mgmt_procs
|
||||
condition: proc.name in (package_mgmt_binaries)
|
||||
@@ -772,6 +775,9 @@
|
||||
- macro: centrify_writing_krb
|
||||
condition: (proc.name in (adjoin,addns) and fd.name startswith /etc/krb5)
|
||||
|
||||
- macro: sssd_writing_krb
|
||||
condition: (proc.name=adcli and proc.aname[2]=sssd and fd.name startswith /etc/krb5)
|
||||
|
||||
- macro: cockpit_writing_conf
|
||||
condition: >
|
||||
((proc.pname=cockpit-kube-la or proc.aname[2]=cockpit-kube-la)
|
||||
@@ -1100,7 +1106,7 @@
|
||||
condition: (proc.name=oc and fd.name startswith /etc/origin/node)
|
||||
|
||||
- macro: keepalived_writing_conf
|
||||
condition: (proc.name=keepalived and fd.name=/etc/keepalived/keepalived.conf)
|
||||
condition: (proc.name in (keepalived, kube-keepalived) and fd.name=/etc/keepalived/keepalived.conf)
|
||||
|
||||
- macro: etcd_manager_updating_dns
|
||||
condition: (container and proc.name=etcd-manager and fd.name=/etc/hosts)
|
||||
@@ -1215,6 +1221,7 @@
|
||||
and not nginx_writing_certs
|
||||
and not chef_client_writing_conf
|
||||
and not centrify_writing_krb
|
||||
and not sssd_writing_krb
|
||||
and not cockpit_writing_conf
|
||||
and not ipsec_writing_conf
|
||||
and not httpd_writing_ssl_conf
|
||||
@@ -1871,19 +1878,6 @@
|
||||
container.image.repository in (falco_sensitive_mount_images) or
|
||||
container.image.repository startswith quay.io/sysdig/)
|
||||
|
||||
# These container images are allowed to run with hostnetwork=true
|
||||
- list: falco_hostnetwork_images
|
||||
items: [
|
||||
gcr.io/google-containers/prometheus-to-sd,
|
||||
gcr.io/projectcalico-org/typha,
|
||||
gcr.io/projectcalico-org/node,
|
||||
gke.gcr.io/gke-metadata-server,
|
||||
gke.gcr.io/kube-proxy,
|
||||
gke.gcr.io/netd-amd64,
|
||||
k8s.gcr.io/ip-masq-agent-amd64
|
||||
k8s.gcr.io/prometheus-to-sd,
|
||||
]
|
||||
|
||||
# Add conditions to this macro (probably in a separate file,
|
||||
# overwriting this macro) to specify additional containers that are
|
||||
# allowed to perform sensitive mounts.
|
||||
@@ -2574,15 +2568,15 @@
|
||||
condition: >
|
||||
(modify and (
|
||||
evt.arg.name contains "bash_history" or
|
||||
evt.arg.name contains "zsh_history" or
|
||||
evt.arg.name endswith "zsh_history" or
|
||||
evt.arg.name contains "fish_read_history" or
|
||||
evt.arg.name endswith "fish_history" or
|
||||
evt.arg.oldpath contains "bash_history" or
|
||||
evt.arg.oldpath contains "zsh_history" or
|
||||
evt.arg.oldpath endswith "zsh_history" or
|
||||
evt.arg.oldpath contains "fish_read_history" or
|
||||
evt.arg.oldpath endswith "fish_history" or
|
||||
evt.arg.path contains "bash_history" or
|
||||
evt.arg.path contains "zsh_history" or
|
||||
evt.arg.path endswith "zsh_history" or
|
||||
evt.arg.path contains "fish_read_history" or
|
||||
evt.arg.path endswith "fish_history"))
|
||||
|
||||
@@ -2590,7 +2584,7 @@
|
||||
condition: >
|
||||
(open_write and (
|
||||
fd.name contains "bash_history" or
|
||||
fd.name contains "zsh_history" or
|
||||
fd.name endswith "zsh_history" or
|
||||
fd.name contains "fish_read_history" or
|
||||
fd.name endswith "fish_history") and evt.arg.flags contains "O_TRUNC")
|
||||
|
||||
@@ -2709,7 +2703,17 @@
|
||||
(evt.arg.target in (sensitive_file_names) or evt.arg.target in (sensitive_directory_names))
|
||||
output: >
|
||||
Symlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.target linkpath=%evt.arg.linkpath parent_process=%proc.pname)
|
||||
priority: NOTICE
|
||||
priority: WARNING
|
||||
tags: [file, mitre_exfiltration]
|
||||
|
||||
- rule: Create Hardlink Over Sensitive Files
|
||||
desc: Detect hardlink created over sensitive files
|
||||
condition: >
|
||||
create_hardlink and
|
||||
(evt.arg.oldpath in (sensitive_file_names))
|
||||
output: >
|
||||
Hardlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.oldpath linkpath=%evt.arg.newpath parent_process=%proc.pname)
|
||||
priority: WARNING
|
||||
tags: [file, mitre_exfiltration]
|
||||
|
||||
- list: miner_ports
|
||||
@@ -2820,7 +2824,7 @@
|
||||
|
||||
- rule: Detect crypto miners using the Stratum protocol
|
||||
desc: Miners typically specify the mining pool to connect to with a URI that begins with 'stratum+tcp'
|
||||
condition: spawned_process and proc.cmdline contains "stratum+tcp"
|
||||
condition: spawned_process and (proc.cmdline contains "stratum+tcp" or proc.cmdline contains "stratum2+tcp" or proc.cmdline contains "stratum+ssl" or proc.cmdline contains "stratum2+ssl")
|
||||
output: Possible miner running (command=%proc.cmdline container=%container.info image=%container.image.repository)
|
||||
priority: CRITICAL
|
||||
tags: [process, mitre_execution]
|
||||
@@ -3039,7 +3043,7 @@
|
||||
# A privilege escalation to root through heap-based buffer overflow
|
||||
- rule: Sudo Potential Privilege Escalation
|
||||
desc: Privilege escalation vulnerability affecting sudo (<= 1.9.5p2). Executing sudo using sudoedit -s or sudoedit -i command with command-line argument that ends with a single backslash character from an unprivileged user it's possible to elevate the user privileges to root.
|
||||
condition: spawned_process and user.uid != 0 and proc.name=sudoedit and (proc.args contains -s or proc.args contains -i) and (proc.args contains "\ " or proc.args endswith \)
|
||||
condition: spawned_process and user.uid != 0 and (proc.name=sudoedit or proc.name = sudo) and (proc.args contains -s or proc.args contains -i or proc.args contains --login) and (proc.args contains "\ " or proc.args endswith \)
|
||||
output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)"
|
||||
priority: CRITICAL
|
||||
tags: [filesystem, mitre_privilege_escalation]
|
||||
@@ -3120,7 +3124,17 @@
|
||||
priority: NOTICE
|
||||
tags: [network, process, mitre_command_and_control]
|
||||
|
||||
# This rule helps detect CVE-2021-4034:
|
||||
# A privilege escalation to root through memory corruption
|
||||
- rule: Polkit Local Privilege Escalation Vulnerability (CVE-2021-4034)
|
||||
desc: "This rule detects an attempt to exploit a privilege escalation vulnerability in Polkit's pkexec. By running specially crafted code, a local user can leverage this flaw to gain root privileges on a compromised system"
|
||||
condition:
|
||||
spawned_process and user.uid != 0 and proc.name=pkexec and proc.args = ''
|
||||
output:
|
||||
"Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) (user=%user.loginname uid=%user.loginuid command=%proc.cmdline args=%proc.args)"
|
||||
priority: CRITICAL
|
||||
tags: [process, mitre_privilege_escalation]
|
||||
|
||||
# Application rules have moved to application_rules.yaml. Please look
|
||||
# there if you want to enable them by adding to
|
||||
# falco_rules.local.yaml.
|
||||
|
||||
|
||||
@@ -152,6 +152,19 @@
|
||||
source: k8s_audit
|
||||
tags: [k8s]
|
||||
|
||||
# These container images are allowed to run with hostnetwork=true
|
||||
- list: falco_hostnetwork_images
|
||||
items: [
|
||||
gcr.io/google-containers/prometheus-to-sd,
|
||||
gcr.io/projectcalico-org/typha,
|
||||
gcr.io/projectcalico-org/node,
|
||||
gke.gcr.io/gke-metadata-server,
|
||||
gke.gcr.io/kube-proxy,
|
||||
gke.gcr.io/netd-amd64,
|
||||
k8s.gcr.io/ip-masq-agent-amd64
|
||||
k8s.gcr.io/prometheus-to-sd,
|
||||
]
|
||||
|
||||
# Corresponds to K8s CIS Benchmark 1.7.4
|
||||
- rule: Create HostNetwork Pod
|
||||
desc: Detect an attempt to start a pod using the host network.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set -e
|
||||
|
||||
DKMS_PACKAGE_NAME="@PACKAGE_NAME@"
|
||||
DKMS_VERSION="@PROBE_VERSION@"
|
||||
DKMS_VERSION="@DRIVER_VERSION@"
|
||||
NAME="@PACKAGE_NAME@"
|
||||
|
||||
postinst_found=0
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set -e
|
||||
|
||||
DKMS_PACKAGE_NAME="@PACKAGE_NAME@"
|
||||
DKMS_VERSION="@PROBE_VERSION@"
|
||||
DKMS_VERSION="@DRIVER_VERSION@"
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|deconfigure)
|
||||
|
||||
@@ -160,15 +160,26 @@ load_kernel_module_compile() {
|
||||
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
|
||||
chmod +x /tmp/falco-dkms-make
|
||||
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
|
||||
echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod"
|
||||
chcon -t modules_object_t "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1 || true
|
||||
chcon -t modules_object_t "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1 || true
|
||||
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
|
||||
echo "* ${DRIVER_NAME} module installed in dkms"
|
||||
KO_FILE="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}"
|
||||
if [ -f "$KO_FILE.ko" ]; then
|
||||
KO_FILE="$KO_FILE.ko"
|
||||
elif [ -f "$KO_FILE.ko.gz" ]; then
|
||||
KO_FILE="$KO_FILE.ko.gz"
|
||||
elif [ -f "$KO_FILE.ko.xz" ]; then
|
||||
KO_FILE="$KO_FILE.ko.xz"
|
||||
elif [ -f "$KO_FILE.ko.zst" ]; then
|
||||
KO_FILE="$KO_FILE.ko.zst"
|
||||
else
|
||||
>&2 echo "${DRIVER_NAME} module file not found"
|
||||
return
|
||||
fi
|
||||
echo "* ${DRIVER_NAME} module found: ${KO_FILE}"
|
||||
echo "* Trying 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
|
||||
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)"
|
||||
exit 0
|
||||
else
|
||||
echo "* Unable to insmod ${DRIVER_NAME} module"
|
||||
fi
|
||||
@@ -196,8 +207,12 @@ load_kernel_module_download() {
|
||||
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
|
||||
echo "* Download succeeded"
|
||||
chcon -t modules_object_t "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
|
||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module found and inserted"
|
||||
exit $?
|
||||
if insmod "${HOME}/.falco/${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
|
||||
else
|
||||
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module"
|
||||
return
|
||||
@@ -241,11 +256,6 @@ load_kernel_module() {
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "* Trying to load a system ${DRIVER_NAME} module, if present"
|
||||
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "* Looking for a ${DRIVER_NAME} module locally (kernel ${KERNEL_RELEASE})"
|
||||
|
||||
@@ -268,6 +278,13 @@ load_kernel_module() {
|
||||
load_kernel_module_compile
|
||||
fi
|
||||
|
||||
# Last try (might load a previous driver version)
|
||||
echo "* Trying to load a system ${DRIVER_NAME} module, if present"
|
||||
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Not able to download a prebuilt module nor to compile one on-the-fly
|
||||
>&2 echo "Consider compiling your own ${DRIVER_NAME} driver and loading it or getting in touch with the Falco community"
|
||||
exit 1
|
||||
@@ -497,7 +514,7 @@ print_usage() {
|
||||
echo " --source-only skip execution and allow sourcing in another script"
|
||||
echo ""
|
||||
echo "Environment variables:"
|
||||
echo " DRIVER_REPO specify a different URL where to look for prebuilt Falco drivers"
|
||||
echo " DRIVERS_REPO specify a different URL where to look for prebuilt Falco drivers"
|
||||
echo " DRIVER_NAME specify a different name for the driver"
|
||||
echo " DRIVER_INSECURE_DOWNLOAD whether you want to allow insecure downloads or not"
|
||||
echo ""
|
||||
@@ -530,8 +547,8 @@ if [[ -z "$MAX_RMMOD_WAIT" ]]; then
|
||||
MAX_RMMOD_WAIT=60
|
||||
fi
|
||||
|
||||
DRIVER_VERSION="@PROBE_VERSION@"
|
||||
DRIVER_NAME=${DRIVER_NAME:-"@PROBE_NAME@"}
|
||||
DRIVER_VERSION="@DRIVER_VERSION@"
|
||||
DRIVER_NAME=${DRIVER_NAME:-"@DRIVER_NAME@"}
|
||||
FALCO_VERSION="@FALCO_VERSION@"
|
||||
|
||||
DRIVER="module"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
mod_version="@PROBE_VERSION@"
|
||||
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
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
mod_version="@PROBE_VERSION@"
|
||||
mod_version="@DRIVER_VERSION@"
|
||||
dkms remove -m falco -v $mod_version --all --rpm_safe_upgrade
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
add_subdirectory(trace_files)
|
||||
|
||||
add_custom_target(test-trace-files ALL)
|
||||
add_dependencies(test-trace-files trace-files-base-scap trace-files-psp trace-files-k8s-audit trace-files-plugins)
|
||||
|
||||
add_subdirectory(plugins)
|
||||
add_subdirectory(confs/plugins)
|
||||
|
||||
@@ -49,6 +49,7 @@ trace_files: !mux
|
||||
detect: False
|
||||
rules_file:
|
||||
- ../rules/falco_rules.yaml
|
||||
- ../rules/k8s_audit_rules.yaml
|
||||
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
|
||||
- ./rules/k8s_audit/trust_nginx_container.yaml
|
||||
trace_file: trace_files/k8s_audit/create_nginx_pod_privileged.json
|
||||
@@ -74,6 +75,7 @@ trace_files: !mux
|
||||
detect: False
|
||||
rules_file:
|
||||
- ../rules/falco_rules.yaml
|
||||
- ../rules/k8s_audit_rules.yaml
|
||||
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
|
||||
- ./rules/k8s_audit/trust_nginx_container.yaml
|
||||
trace_file: trace_files/k8s_audit/create_nginx_pod_hostnetwork.json
|
||||
|
||||
@@ -524,10 +524,10 @@ class FalcoTest(Test):
|
||||
["md5sum", "/boot/config-{}".format(kernel_release)]).rstrip()
|
||||
config_hash = md5_output.split(" ")[0]
|
||||
|
||||
probe_filename = "falco-{}-{}-{}-{}.ko".format(
|
||||
driver_filename = "falco-{}-{}-{}-{}.ko".format(
|
||||
falco_version, arch, kernel_release, config_hash)
|
||||
driver_path = os.path.join(self.falcodir, "driver", "falco.ko")
|
||||
module_path = os.path.join(self.module_dir, probe_filename)
|
||||
module_path = os.path.join(self.module_dir, driver_filename)
|
||||
self.log.debug("Copying {} to {}".format(driver_path, module_path))
|
||||
shutil.copyfile(driver_path, module_path)
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ trace_files: !mux
|
||||
|
||||
incompat_plugin_rules_version:
|
||||
exit_status: 1
|
||||
stderr_contains: "Runtime error: Plugin cloudtrail version 0.1.0 not compatible with required plugin version 100000.0.0. Exiting."
|
||||
stderr_contains: "Runtime error: Plugin cloudtrail version .* not compatible with required plugin version 100000.0.0. Exiting."
|
||||
conf_file: BUILD_DIR/test/confs/plugins/cloudtrail_json_create_instances.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_incompat_plugin_version.yaml
|
||||
|
||||
@@ -2,19 +2,11 @@ add_subdirectory(k8s_audit)
|
||||
add_subdirectory(psp)
|
||||
add_subdirectory(plugins)
|
||||
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of traces is created at cmake time, not build time
|
||||
file(GLOB test_trace_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*.scap")
|
||||
|
||||
foreach(trace_file_path ${test_trace_files})
|
||||
get_filename_component(trace_file ${trace_file_path} NAME)
|
||||
add_custom_target(test-trace-${trace_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${trace_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
DEPENDS ${trace_file_path})
|
||||
list(APPEND BASE_SCAP_TRACE_FILES_TARGETS test-trace-${trace_file})
|
||||
endforeach()
|
||||
copy_files_to_build_dir("${test_trace_files}" base-scap)
|
||||
|
||||
add_custom_target(trace-files-base-scap ALL)
|
||||
add_dependencies(trace-files-base-scap ${BASE_SCAP_TRACE_FILES_TARGETS})
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of traces is created at cmake time, not build time
|
||||
file(GLOB test_trace_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*.json")
|
||||
|
||||
foreach(trace_file_path ${test_trace_files})
|
||||
get_filename_component(trace_file ${trace_file_path} NAME)
|
||||
add_custom_target(test-trace-${trace_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${trace_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
DEPENDS ${trace_file_path})
|
||||
list(APPEND K8S_AUDIT_TRACE_FILES_TARGETS test-trace-${trace_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(trace-files-k8s-audit ALL)
|
||||
add_dependencies(trace-files-k8s-audit ${K8S_AUDIT_TRACE_FILES_TARGETS})
|
||||
copy_files_to_build_dir("${test_trace_files}" k8s-audit)
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of traces is created at cmake time, not build time
|
||||
file(GLOB test_trace_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*.json")
|
||||
|
||||
foreach(trace_file_path ${test_trace_files})
|
||||
get_filename_component(trace_file ${trace_file_path} NAME)
|
||||
add_custom_target(test-trace-${trace_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${trace_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
DEPENDS ${trace_file_path})
|
||||
list(APPEND PLUGINS_TRACE_FILES_TARGETS test-trace-${trace_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(trace-files-plugins ALL)
|
||||
add_dependencies(trace-files-plugins ${PLUGINS_TRACE_FILES_TARGETS})
|
||||
copy_files_to_build_dir("${test_trace_files}" plugins)
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
include(copy_files_to_build_dir)
|
||||
|
||||
# Note: list of traces is created at cmake time, not build time
|
||||
file(GLOB test_trace_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*.json"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*.scap")
|
||||
|
||||
foreach(trace_file_path ${test_trace_files})
|
||||
get_filename_component(trace_file ${trace_file_path} NAME)
|
||||
add_custom_target(test-trace-${trace_file} ALL
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${trace_file_path} ${CMAKE_CURRENT_BINARY_DIR}/${trace_file}
|
||||
DEPENDS ${trace_file_path})
|
||||
list(APPEND PSP_TRACE_FILES_TARGETS test-trace-${trace_file})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(trace-files-psp ALL)
|
||||
add_dependencies(trace-files-psp ${PSP_TRACE_FILES_TARGETS})
|
||||
copy_files_to_build_dir("${test_trace_files}" psp)
|
||||
|
||||
@@ -17,17 +17,25 @@
|
||||
if(MINIMAL_BUILD)
|
||||
set(
|
||||
FALCO_TESTS_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/app_runnable_action.cpp
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/app_action_manager.cpp
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/logger.cpp
|
||||
test_base.cpp
|
||||
engine/test_rulesets.cpp
|
||||
engine/test_falco_utils.cpp
|
||||
falco/test_actions.cpp
|
||||
falco/test_configuration.cpp
|
||||
)
|
||||
else()
|
||||
set(
|
||||
FALCO_TESTS_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/app_runnable_action.cpp
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/app_action_manager.cpp
|
||||
${PROJECT_SOURCE_DIR}/userspace/falco/logger.cpp
|
||||
test_base.cpp
|
||||
engine/test_rulesets.cpp
|
||||
engine/test_falco_utils.cpp
|
||||
falco/test_actions.cpp
|
||||
falco/test_configuration.cpp
|
||||
falco/test_webserver.cpp
|
||||
)
|
||||
|
||||
@@ -42,8 +42,9 @@ TEST_CASE("Should enable/disable for exact match w/ default ruleset", "[rulesets
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("one_rule", exact_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -57,8 +58,9 @@ TEST_CASE("Should enable/disable for exact match w/ specific ruleset", "[ruleset
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("one_rule", exact_match, enabled, non_default_ruleset);
|
||||
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
|
||||
@@ -76,8 +78,9 @@ TEST_CASE("Should not enable for exact match different rule name", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("some_other_rule", exact_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
|
||||
@@ -88,8 +91,9 @@ TEST_CASE("Should enable/disable for exact match w/ substring and default rulese
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("one_rule", substring_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -103,8 +107,9 @@ TEST_CASE("Should not enable for substring w/ exact_match", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("one_", exact_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
|
||||
@@ -115,8 +120,9 @@ TEST_CASE("Should enable/disable for prefix match w/ default ruleset", "[ruleset
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("one_", substring_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -130,8 +136,9 @@ TEST_CASE("Should enable/disable for suffix match w/ default ruleset", "[ruleset
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("_rule", substring_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -145,8 +152,9 @@ TEST_CASE("Should enable/disable for substring match w/ default ruleset", "[rule
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("ne_ru", substring_match, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -160,8 +168,9 @@ TEST_CASE("Should enable/disable for substring match w/ specific ruleset", "[rul
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable("ne_ru", substring_match, enabled, non_default_ruleset);
|
||||
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
|
||||
@@ -179,9 +188,10 @@ TEST_CASE("Should enable/disable for tags w/ default ruleset", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
std::set<std::string> want_tags = {"some_tag"};
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable_tags(want_tags, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -195,9 +205,10 @@ TEST_CASE("Should enable/disable for tags w/ specific ruleset", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
std::set<std::string> want_tags = {"some_tag"};
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable_tags(want_tags, enabled, non_default_ruleset);
|
||||
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
|
||||
@@ -215,9 +226,10 @@ TEST_CASE("Should not enable for different tags", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
std::set<std::string> want_tags = {"some_different_tag"};
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable_tags(want_tags, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 0);
|
||||
@@ -228,9 +240,10 @@ TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> filter = create_filter();
|
||||
string rule_name = "one_rule";
|
||||
string source = "syscall";
|
||||
std::set<std::string> want_tags = {"some_tag", "some_different_tag"};
|
||||
|
||||
r.add(rule_name, tags, filter);
|
||||
r.add(source, rule_name, tags, filter);
|
||||
|
||||
r.enable_tags(want_tags, enabled);
|
||||
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
|
||||
@@ -241,16 +254,17 @@ TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
|
||||
|
||||
TEST_CASE("Should enable/disable for incremental adding tags", "[rulesets]")
|
||||
{
|
||||
string source = "syscall";
|
||||
falco_ruleset r;
|
||||
std::shared_ptr<gen_event_filter> rule1_filter = create_filter();
|
||||
string rule1_name = "one_rule";
|
||||
std::set<std::string> rule1_tags = {"rule1_tag"};
|
||||
r.add(rule1_name, rule1_tags, rule1_filter);
|
||||
r.add(source, rule1_name, rule1_tags, rule1_filter);
|
||||
|
||||
std::shared_ptr<gen_event_filter> rule2_filter = create_filter();
|
||||
string rule2_name = "two_rule";
|
||||
std::set<std::string> rule2_tags = {"rule2_tag"};
|
||||
r.add(rule2_name, rule2_tags, rule2_filter);
|
||||
r.add(source, rule2_name, rule2_tags, rule2_filter);
|
||||
|
||||
std::set<std::string> want_tags;
|
||||
|
||||
|
||||
387
tests/falco/test_actions.cpp
Normal file
387
tests/falco/test_actions.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "app_action_manager.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
// Test actions just record the order they were run (or skipped)
|
||||
class test_action : public falco::app::runnable_action {
|
||||
public:
|
||||
|
||||
static std::vector<std::string> s_actions_run;
|
||||
|
||||
test_action(const std::string &name,
|
||||
const std::string &group,
|
||||
const std::list<std::string> &prerequsites,
|
||||
run_result res)
|
||||
: m_name(name),
|
||||
m_group(group),
|
||||
m_prerequsites(prerequsites),
|
||||
m_res(res)
|
||||
{
|
||||
}
|
||||
|
||||
~test_action()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::string &group()
|
||||
{
|
||||
return m_group;
|
||||
}
|
||||
|
||||
const std::list<std::string> &prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
run_result run()
|
||||
{
|
||||
s_actions_run.push_back(m_name);
|
||||
return m_res;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_group;
|
||||
std::list<std::string> m_prerequsites;
|
||||
run_result m_res;
|
||||
};
|
||||
|
||||
std::vector<std::string> test_action::s_actions_run;
|
||||
|
||||
static std::list<std::string> empty;
|
||||
static std::list<std::string> prereq_a = {"a"};
|
||||
static std::list<std::string> prereq_aa = {"aa"};
|
||||
static std::list<std::string> prereq_ab = {"ab"};
|
||||
static std::list<std::string> prereq_m = {"m"};
|
||||
static std::list<std::string> prereq_n = {"n"};
|
||||
|
||||
// The action names denote the dependency order e.g. "a", "b", "c" are
|
||||
// all independent, "aa" and "ab" depend on a but are independent of
|
||||
// each other, "aaa" "aab" depend on "aa" but are independent, etc.
|
||||
|
||||
static falco::app::runnable_action::run_result success_proceed{true, "", true};
|
||||
|
||||
static falco::app::runnable_action::run_result success_noproceed{true, "", false};
|
||||
|
||||
|
||||
static std::shared_ptr<test_action> a = std::make_shared<test_action>(std::string("a"),
|
||||
std::string("init"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> a_noproceed = std::make_shared<test_action>(std::string("a"),
|
||||
std::string("init"),
|
||||
empty,
|
||||
success_noproceed);
|
||||
|
||||
static std::shared_ptr<test_action> b = std::make_shared<test_action>(std::string("b"),
|
||||
std::string("init"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> c = std::make_shared<test_action>(std::string("c"),
|
||||
std::string("init"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> d = std::make_shared<test_action>(std::string("d"),
|
||||
std::string("init"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
std::shared_ptr<test_action> aa = std::make_shared<test_action>(std::string("aa"),
|
||||
std::string("init"),
|
||||
prereq_a,
|
||||
success_proceed);
|
||||
|
||||
std::shared_ptr<test_action> ab = std::make_shared<test_action>(std::string("ab"),
|
||||
std::string("init"),
|
||||
prereq_a,
|
||||
success_proceed);
|
||||
|
||||
std::shared_ptr<test_action> aa_noproceed = std::make_shared<test_action>(std::string("aa"),
|
||||
std::string("init"),
|
||||
prereq_a,
|
||||
success_noproceed);
|
||||
|
||||
std::shared_ptr<test_action> aaa = std::make_shared<test_action>(std::string("aaa"),
|
||||
std::string("init"),
|
||||
prereq_aa,
|
||||
success_proceed);
|
||||
|
||||
std::shared_ptr<test_action> aab = std::make_shared<test_action>(std::string("aab"),
|
||||
std::string("init"),
|
||||
prereq_aa,
|
||||
success_proceed);
|
||||
|
||||
std::shared_ptr<test_action> aba = std::make_shared<test_action>(std::string("aba"),
|
||||
std::string("init"),
|
||||
prereq_ab,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> m = std::make_shared<test_action>(std::string("m"),
|
||||
std::string("run"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> ma = std::make_shared<test_action>(std::string("ma"),
|
||||
std::string("run"),
|
||||
prereq_m,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> n = std::make_shared<test_action>(std::string("n"),
|
||||
std::string("run"),
|
||||
empty,
|
||||
success_proceed);
|
||||
|
||||
static std::shared_ptr<test_action> na = std::make_shared<test_action>(std::string("na"),
|
||||
std::string("run"),
|
||||
prereq_n,
|
||||
success_proceed);
|
||||
|
||||
static std::vector<std::string>::iterator find_action(const std::string &name,
|
||||
std::vector<std::string>::iterator begin = test_action::s_actions_run.begin())
|
||||
{
|
||||
return std::find(begin,
|
||||
test_action::s_actions_run.end(),
|
||||
name);
|
||||
}
|
||||
|
||||
static bool action_is_found(const std::string &name,
|
||||
std::vector<std::string>::iterator begin = test_action::s_actions_run.begin())
|
||||
{
|
||||
auto it = find_action(name, begin);
|
||||
|
||||
return (it != test_action::s_actions_run.end());
|
||||
}
|
||||
|
||||
TEST_CASE("action manager can add and run actions", "[actions]")
|
||||
{
|
||||
std::list<std::string> groups = {"init", "run"};
|
||||
|
||||
SECTION("Two independent")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(b);
|
||||
|
||||
amgr.run();
|
||||
|
||||
// Can't compare to any direct vector as order is not guaranteed
|
||||
REQUIRE(action_is_found(a->name()) == true);
|
||||
REQUIRE(action_is_found(b->name()) == true);
|
||||
}
|
||||
|
||||
SECTION("Two dependent")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(aa);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a", "aa"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("One independent, two dependent")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(aa);
|
||||
amgr.add(b);
|
||||
|
||||
amgr.run();
|
||||
|
||||
// Can't compare to any direct vector as order is not guaranteed
|
||||
REQUIRE(action_is_found(a->name()) == true);
|
||||
REQUIRE(action_is_found(aa->name()) == true);
|
||||
REQUIRE(action_is_found(b->name()) == true);
|
||||
|
||||
// Ensure that aa appears after a
|
||||
auto it = find_action(a->name());
|
||||
REQUIRE(action_is_found(aa->name(), it) == true);
|
||||
}
|
||||
|
||||
SECTION("Two dependent, first does not proceed")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a_noproceed);
|
||||
amgr.add(aa);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("Two dependent, second does not proceed")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(aa_noproceed);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a", "aa"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("Three dependent, first does not proceed")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a_noproceed);
|
||||
amgr.add(aa);
|
||||
amgr.add(aaa);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("Three dependent, second does not proceed")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(aa_noproceed);
|
||||
amgr.add(aaa);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a", "aa"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("Groups")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(ma);
|
||||
amgr.add(m);
|
||||
amgr.add(aa);
|
||||
amgr.add(a);
|
||||
|
||||
amgr.run();
|
||||
|
||||
std::vector<std::string> exp_actions_run = {"a", "aa", "m", "ma"};
|
||||
REQUIRE(test_action::s_actions_run == exp_actions_run);
|
||||
}
|
||||
|
||||
SECTION("Complex")
|
||||
{
|
||||
falco::app::action_manager amgr;
|
||||
amgr.set_groups(groups);
|
||||
|
||||
test_action::s_actions_run.clear();
|
||||
|
||||
amgr.add(a);
|
||||
amgr.add(b);
|
||||
amgr.add(c);
|
||||
amgr.add(d);
|
||||
amgr.add(aa);
|
||||
amgr.add(ab);
|
||||
amgr.add(aaa);
|
||||
amgr.add(aab);
|
||||
amgr.add(aba);
|
||||
amgr.add(m);
|
||||
amgr.add(ma);
|
||||
amgr.add(n);
|
||||
amgr.add(na);
|
||||
|
||||
amgr.run();
|
||||
|
||||
// a, b, c, d must be found. Order not specified.
|
||||
REQUIRE(action_is_found(a->name()) == true);
|
||||
REQUIRE(action_is_found(b->name()) == true);
|
||||
REQUIRE(action_is_found(c->name()) == true);
|
||||
REQUIRE(action_is_found(d->name()) == true);
|
||||
|
||||
// aa, ab must be after a.
|
||||
auto it = find_action(a->name());
|
||||
REQUIRE(action_is_found(aa->name(), it) == true);
|
||||
REQUIRE(action_is_found(ab->name(), it) == true);
|
||||
|
||||
// aaa, aab must be after aa
|
||||
it = find_action(aa->name());
|
||||
REQUIRE(action_is_found(aaa->name(), it) == true);
|
||||
REQUIRE(action_is_found(aab->name(), it) == true);
|
||||
|
||||
// aba must be after ab
|
||||
it = find_action(ab->name());
|
||||
REQUIRE(action_is_found(aba->name(), it) == true);
|
||||
|
||||
// The run actions must be the last four
|
||||
std::vector<std::string>::iterator last_four = test_action::s_actions_run.end() - 4;
|
||||
REQUIRE(action_is_found(m->name(), last_four) == true);
|
||||
REQUIRE(action_is_found(ma->name(), last_four) == true);
|
||||
REQUIRE(action_is_found(n->name(), last_four) == true);
|
||||
REQUIRE(action_is_found(na->name(), last_four) == true);
|
||||
|
||||
// ma must be after m
|
||||
it = find_action(m->name());
|
||||
REQUIRE(action_is_found(ma->name(), it) == true);
|
||||
|
||||
// na must be after n
|
||||
it = find_action(n->name());
|
||||
REQUIRE(action_is_found(na->name(), it) == true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,6 +56,3 @@ else()
|
||||
endif()
|
||||
|
||||
target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}" luafiles)
|
||||
|
||||
configure_file(config_falco_engine.h.in config_falco_engine.h)
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ limitations under the License.
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "config_falco_engine.h"
|
||||
#include "falco_common.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
#include "falco_engine_lua_files.hh"
|
||||
|
||||
@@ -25,7 +25,6 @@ limitations under the License.
|
||||
#include "falco_engine.h"
|
||||
#include "falco_utils.h"
|
||||
#include "falco_engine_version.h"
|
||||
#include "config_falco_engine.h"
|
||||
|
||||
#include "formats.h"
|
||||
|
||||
@@ -44,7 +43,7 @@ const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
|
||||
|
||||
using namespace std;
|
||||
|
||||
falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir)
|
||||
falco_engine::falco_engine(bool seed_rng)
|
||||
: m_next_ruleset_id(0),
|
||||
m_min_priority(falco_common::PRIORITY_DEBUG),
|
||||
m_sampling_ratio(1), m_sampling_multiplier(0),
|
||||
@@ -136,6 +135,12 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
|
||||
{
|
||||
for(auto &field : fld_class.fields)
|
||||
{
|
||||
// Skip fields with the EPF_TABLE_ONLY flag.
|
||||
if(field.tags.find("EPF_TABLE_ONLY") != field.tags.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%s\n", field.name.c_str());
|
||||
}
|
||||
}
|
||||
@@ -415,7 +420,7 @@ void falco_engine::add_filter(std::shared_ptr<gen_event_filter> filter,
|
||||
throw falco_exception(err);
|
||||
}
|
||||
|
||||
it->second->add(rule, tags, filter);
|
||||
it->second->add(source, rule, tags, filter);
|
||||
}
|
||||
|
||||
bool falco_engine::is_source_valid(const std::string &source)
|
||||
@@ -427,7 +432,7 @@ bool falco_engine::is_plugin_compatible(const std::string &name,
|
||||
const std::string &version,
|
||||
std::string &required_version)
|
||||
{
|
||||
sinsp_plugin::version plugin_version(version.c_str());
|
||||
sinsp_plugin::version plugin_version(version);
|
||||
|
||||
if(!plugin_version.m_valid)
|
||||
{
|
||||
@@ -442,13 +447,12 @@ bool falco_engine::is_plugin_compatible(const std::string &name,
|
||||
|
||||
for(auto &rversion : m_required_plugin_versions[name])
|
||||
{
|
||||
sinsp_plugin::version req_version(rversion.c_str());
|
||||
if(req_version.m_version_major > plugin_version.m_version_major)
|
||||
sinsp_plugin::version req_version(rversion);
|
||||
if (!plugin_version.check(req_version))
|
||||
{
|
||||
required_version = rversion;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -32,7 +32,6 @@ limitations under the License.
|
||||
#include "rules.h"
|
||||
#include "ruleset.h"
|
||||
|
||||
#include "config_falco_engine.h"
|
||||
#include "falco_common.h"
|
||||
|
||||
//
|
||||
@@ -44,7 +43,7 @@ limitations under the License.
|
||||
class falco_engine : public falco_common
|
||||
{
|
||||
public:
|
||||
falco_engine(bool seed_rng=true, const std::string& alternate_lua_dir=FALCO_ENGINE_SOURCE_LUA_DIR);
|
||||
falco_engine(bool seed_rng=true);
|
||||
virtual ~falco_engine();
|
||||
|
||||
// A given engine has a version which identifies the fields
|
||||
|
||||
@@ -22,4 +22,3 @@ limitations under the License.
|
||||
// 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 "4de812495f8529ac20bda2b9774462b15911a51df293d59fe9ccb6b922fdeb9d"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ limitations under the License.
|
||||
#include "falco_engine.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
falco_formats::falco_formats(falco_engine *engine,
|
||||
falco_formats::falco_formats(std::shared_ptr<falco_engine> engine,
|
||||
bool json_include_output_property,
|
||||
bool json_include_tags_property)
|
||||
: m_falco_engine(engine),
|
||||
|
||||
@@ -33,7 +33,7 @@ extern "C"
|
||||
class falco_formats
|
||||
{
|
||||
public:
|
||||
falco_formats(falco_engine *engine,
|
||||
falco_formats(std::shared_ptr<falco_engine> engine,
|
||||
bool json_include_output_property,
|
||||
bool json_include_tags_property);
|
||||
virtual ~falco_formats();
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
const std::string &format);
|
||||
|
||||
protected:
|
||||
falco_engine *m_falco_engine;
|
||||
std::shared_ptr<falco_engine> m_falco_engine;
|
||||
bool m_json_include_output_property;
|
||||
bool m_json_include_tags_property;
|
||||
};
|
||||
|
||||
@@ -1529,12 +1529,9 @@ void json_event_formatter::set_format(output_format of, const std::string &forma
|
||||
bool json_event_formatter::tostring_withformat(gen_event *gevt, std::string &output, gen_event_formatter::output_format of)
|
||||
{
|
||||
json_event *ev = static_cast<json_event *>(gevt);
|
||||
|
||||
std::string ret;
|
||||
|
||||
if(of == OF_JSON)
|
||||
{
|
||||
ret = tojson(ev);
|
||||
output = tojson(ev);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# "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.
|
||||
|
||||
file(GLOB_RECURSE lua_module_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua)
|
||||
file(GLOB_RECURSE lua_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/falco_engine_lua_files.cpp
|
||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh ${CMAKE_CURRENT_SOURCE_DIR} ${LYAML_LUA_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
||||
@@ -113,31 +113,6 @@ function expand_macros(ast, defs, changed)
|
||||
return true, changed
|
||||
end
|
||||
|
||||
function get_macros(ast, set)
|
||||
if (ast.type == "Macro") then
|
||||
set[ast.value] = true
|
||||
return set
|
||||
end
|
||||
|
||||
if ast.type == "Filter" then
|
||||
return get_macros(ast.value, set)
|
||||
end
|
||||
|
||||
if ast.type == "BinaryBoolOp" then
|
||||
local left = get_macros(ast.left, {})
|
||||
local right = get_macros(ast.right, {})
|
||||
|
||||
for m, _ in pairs(left) do set[m] = true end
|
||||
for m, _ in pairs(right) do set[m] = true end
|
||||
|
||||
return set
|
||||
end
|
||||
if ast.type == "UnaryBoolOp" then
|
||||
return get_macros(ast.argument, set)
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
function get_filters(ast)
|
||||
|
||||
local filters = {}
|
||||
|
||||
@@ -59,10 +59,10 @@ end
|
||||
|
||||
-- Permissive for case and for common abbreviations.
|
||||
priorities = {
|
||||
Emergency=0, Alert=1, Critical=2, Error=3, Warning=4, Notice=5, Informational=5, Debug=7,
|
||||
emergency=0, alert=1, critical=2, error=3, warning=4, notice=5, informational=5, debug=7,
|
||||
EMERGENCY=0, ALERT=1, CRITICAL=2, ERROR=3, WARNING=4, NOTICE=5, INFORMATIONAL=5, DEBUG=7,
|
||||
INFO=5, info=5
|
||||
Emergency=0, Alert=1, Critical=2, Error=3, Warning=4, Notice=5, Informational=6, Debug=7,
|
||||
emergency=0, alert=1, critical=2, error=3, warning=4, notice=5, informational=6, debug=7,
|
||||
EMERGENCY=0, ALERT=1, CRITICAL=2, ERROR=3, WARNING=4, NOTICE=5, INFORMATIONAL=6, DEBUG=7,
|
||||
INFO=6, info=6
|
||||
}
|
||||
|
||||
--[[
|
||||
@@ -157,17 +157,6 @@ local function create_filter_obj(node, lua_parser, parent_bool_op)
|
||||
return nil
|
||||
end
|
||||
|
||||
function set_output(output_format, state)
|
||||
|
||||
if(output_ast.type == "OutputFormat") then
|
||||
|
||||
local format
|
||||
|
||||
else
|
||||
error ("Unexpected type in set_output: ".. output_ast.type)
|
||||
end
|
||||
end
|
||||
|
||||
-- This should be keep in sync with parser.lua
|
||||
defined_comp_operators = {
|
||||
["="]=1,
|
||||
@@ -197,7 +186,7 @@ defined_list_comp_operators = {
|
||||
-- object. The by_name index is used for things like describing rules,
|
||||
-- and the by_idx index is used to map the relational node index back
|
||||
-- to a rule.
|
||||
local state = {macros={}, lists={}, filter_ast=nil, rules_by_name={},
|
||||
local state = {macros={}, lists={}, rules_by_name={},
|
||||
skipped_rules_by_name={}, macros_by_name={}, lists_by_name={},
|
||||
n_rules=0, rules_by_idx={}, ordered_rule_names={}, ordered_macro_names={}, ordered_list_names={}}
|
||||
|
||||
@@ -293,19 +282,20 @@ function split_lines(rules_content)
|
||||
end
|
||||
|
||||
function get_orig_yaml_obj(rules_lines, row)
|
||||
local ret = ""
|
||||
idx = row
|
||||
local t = {}
|
||||
while (idx <= #rules_lines) do
|
||||
t[#t + 1] = rules_lines[idx]
|
||||
idx = idx + 1
|
||||
|
||||
idx = row
|
||||
while (idx <= #rules_lines) do
|
||||
ret = ret..rules_lines[idx].."\n"
|
||||
idx = idx + 1
|
||||
|
||||
if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then
|
||||
break
|
||||
end
|
||||
end
|
||||
t[#t + 1] = ""
|
||||
local ret = ""
|
||||
ret = table.concat(t, "\n")
|
||||
return ret
|
||||
end
|
||||
|
||||
function get_lines(rules_lines, row, num_lines)
|
||||
@@ -754,65 +744,69 @@ end
|
||||
-- Populates exfields with all fields used
|
||||
function build_exception_condition_string_multi_fields(eitem, exfields)
|
||||
|
||||
local fields = eitem['fields']
|
||||
local comps = eitem['comps']
|
||||
local fields = eitem['fields']
|
||||
local comps = eitem['comps']
|
||||
|
||||
local icond = "("
|
||||
local icond = {}
|
||||
|
||||
for i, values in ipairs(eitem['values']) do
|
||||
icond[#icond + 1] = "("
|
||||
|
||||
if #fields ~= #values then
|
||||
return nil, "Exception item "..eitem['name']..": fields and values lists must have equal length"
|
||||
end
|
||||
local lcount = 0
|
||||
for i, values in ipairs(eitem['values']) do
|
||||
if #fields ~= #values then
|
||||
return nil, "Exception item " .. eitem['name'] .. ": fields and values lists must have equal length"
|
||||
end
|
||||
|
||||
if icond ~= "(" then
|
||||
icond=icond.." or "
|
||||
end
|
||||
if lcount ~= 0 then
|
||||
icond[#icond + 1] = " or "
|
||||
end
|
||||
lcount = lcount + 1
|
||||
|
||||
icond=icond.."("
|
||||
icond[#icond + 1] = "("
|
||||
|
||||
for k=1,#fields do
|
||||
if k > 1 then
|
||||
icond=icond.." and "
|
||||
end
|
||||
local ival = values[k]
|
||||
local istr = ""
|
||||
for k = 1, #fields do
|
||||
if k > 1 then
|
||||
icond[#icond + 1] = " and "
|
||||
end
|
||||
local ival = values[k]
|
||||
local istr = ""
|
||||
|
||||
-- If ival is a table, express it as (titem1, titem2, etc)
|
||||
if type(ival) == "table" then
|
||||
istr = "("
|
||||
for _, item in ipairs(ival) do
|
||||
if istr ~= "(" then
|
||||
istr = istr..", "
|
||||
end
|
||||
istr = istr..quote_item(item)
|
||||
end
|
||||
istr = istr..")"
|
||||
else
|
||||
-- If the corresponding operator is one that works on lists, possibly add surrounding parentheses.
|
||||
if defined_list_comp_operators[comps[k]] then
|
||||
istr = paren_item(ival)
|
||||
else
|
||||
-- Quote the value if not already quoted
|
||||
istr = quote_item(ival)
|
||||
end
|
||||
end
|
||||
-- If ival is a table, express it as (titem1, titem2, etc)
|
||||
if type(ival) == "table" then
|
||||
istr = "("
|
||||
for _, item in ipairs(ival) do
|
||||
if istr ~= "(" then
|
||||
istr = istr .. ", "
|
||||
end
|
||||
istr = istr .. quote_item(item)
|
||||
end
|
||||
istr = istr .. ")"
|
||||
else
|
||||
-- If the corresponding operator is one that works on lists, possibly add surrounding parentheses.
|
||||
if defined_list_comp_operators[comps[k]] then
|
||||
istr = paren_item(ival)
|
||||
else
|
||||
-- Quote the value if not already quoted
|
||||
istr = quote_item(ival)
|
||||
end
|
||||
end
|
||||
|
||||
icond = icond..fields[k].." "..comps[k].." "..istr
|
||||
exfields[fields[k]] = true
|
||||
end
|
||||
icond[#icond + 1] = fields[k] .. " " .. comps[k] .. " " .. istr
|
||||
exfields[fields[k]] = true
|
||||
end
|
||||
|
||||
icond=icond..")"
|
||||
end
|
||||
icond[#icond + 1] = ")"
|
||||
end
|
||||
|
||||
icond = icond..")"
|
||||
icond[#icond + 1] = ")"
|
||||
|
||||
-- Don't return a trivially empty condition string
|
||||
if icond == "()" then
|
||||
icond = ""
|
||||
end
|
||||
-- Don't return a trivially empty condition string
|
||||
local ret = table.concat(icond)
|
||||
if ret == "()" then
|
||||
return "", nil
|
||||
end
|
||||
|
||||
return icond, nil
|
||||
return ret, nil
|
||||
|
||||
end
|
||||
|
||||
@@ -1054,22 +1048,14 @@ function load_rules(rules_content,
|
||||
|
||||
else
|
||||
num_evttypes = falco_rules.add_filter(rules_mgr, lua_parser, v['rule'], v['source'], v['tags'])
|
||||
if num_evttypes == 0 or num_evttypes > 100 then
|
||||
if v['source'] == "syscall" and (num_evttypes == 0 or num_evttypes > 100) then
|
||||
if warn_evttypes == true then
|
||||
msg = "Rule "..v['rule']..": warning (no-evttype):"
|
||||
msg = "Rule "..v['rule']..": warning (no-evttype):\n".." matches too many evt.type values.\n".." This has a significant performance penalty."
|
||||
warnings[#warnings + 1] = msg
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Rule ASTs are merged together into one big AST, with "OR" between each
|
||||
-- rule.
|
||||
if (state.filter_ast == nil) then
|
||||
state.filter_ast = filter_ast.filter.value
|
||||
else
|
||||
state.filter_ast = { type = "BinaryBoolOp", operator = "or", left = state.filter_ast, right = filter_ast.filter.value }
|
||||
end
|
||||
|
||||
-- Enable/disable the rule
|
||||
if (v['enabled'] == nil) then
|
||||
v['enabled'] = true
|
||||
|
||||
@@ -145,11 +145,19 @@ int falco_rules::add_filter(lua_State *ls)
|
||||
lua_pop(ls, 1);
|
||||
}
|
||||
|
||||
size_t num_evttypes = lp->filter()->evttypes().size();
|
||||
// todo(jasondellaluce,leogr,fededp): temp workaround, remove when fixed in libs
|
||||
size_t num_evttypes = 1; // assume plugin
|
||||
if(source == "syscall" || source == "k8s_audit")
|
||||
{
|
||||
num_evttypes = lp->filter()->evttypes().size();
|
||||
}
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
rules->add_filter(lp->filter(), rule, source, tags);
|
||||
} catch (exception &e) {
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
std::string errstr = string("Could not add rule to falco engine: ") + e.what();
|
||||
lua_pushstring(ls, errstr.c_str());
|
||||
lua_error(ls);
|
||||
|
||||
@@ -66,7 +66,7 @@ void falco_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_lis
|
||||
|
||||
void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
std::set<uint16_t> fevttypes = wrap->filter->evttypes();
|
||||
std::set<uint16_t> fevttypes = wrap->evttypes();
|
||||
|
||||
if(fevttypes.empty())
|
||||
{
|
||||
@@ -91,7 +91,7 @@ void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper>
|
||||
|
||||
void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
std::set<uint16_t> fevttypes = wrap->filter->evttypes();
|
||||
std::set<uint16_t> fevttypes = wrap->evttypes();
|
||||
|
||||
if(fevttypes.empty())
|
||||
{
|
||||
@@ -118,18 +118,16 @@ uint64_t falco_ruleset::ruleset_filters::num_filters()
|
||||
|
||||
bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
||||
{
|
||||
if(evt->get_type() >= m_filter_by_event_type.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(auto &wrap : m_filter_by_event_type[evt->get_type()])
|
||||
{
|
||||
if(wrap->filter->run(evt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(evt->get_type() < m_filter_by_event_type.size())
|
||||
{
|
||||
for(auto &wrap : m_filter_by_event_type[evt->get_type()])
|
||||
{
|
||||
if(wrap->filter->run(evt))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, try filters that are not specific to an event type.
|
||||
for(auto &wrap : m_filter_all_event_types)
|
||||
@@ -149,16 +147,18 @@ void falco_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &ev
|
||||
|
||||
for(auto &wrap : m_filters)
|
||||
{
|
||||
auto fevttypes = wrap->filter->evttypes();
|
||||
auto fevttypes = wrap->evttypes();
|
||||
evttypes.insert(fevttypes.begin(), fevttypes.end());
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::add(string &name,
|
||||
void falco_ruleset::add(string &source,
|
||||
string &name,
|
||||
set<string> &tags,
|
||||
std::shared_ptr<gen_event_filter> filter)
|
||||
{
|
||||
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
|
||||
wrap->source = source;
|
||||
wrap->name = name;
|
||||
wrap->tags = tags;
|
||||
wrap->filter = filter;
|
||||
|
||||
@@ -34,7 +34,8 @@ public:
|
||||
falco_ruleset();
|
||||
virtual ~falco_ruleset();
|
||||
|
||||
void add(std::string &name,
|
||||
void add(string &source,
|
||||
std::string &name,
|
||||
std::set<std::string> &tags,
|
||||
std::shared_ptr<gen_event_filter> filter);
|
||||
|
||||
@@ -73,9 +74,21 @@ private:
|
||||
|
||||
class filter_wrapper {
|
||||
public:
|
||||
std::string source;
|
||||
std::string name;
|
||||
std::set<std::string> tags;
|
||||
std::shared_ptr<gen_event_filter> filter;
|
||||
std::set<uint16_t> evttypes()
|
||||
{
|
||||
// todo(jasondellaluce,leogr): temp workarond, remove when fixed in libs
|
||||
if(source == "syscall" || source == "k8s_audit")
|
||||
{
|
||||
return filter->evttypes();
|
||||
}
|
||||
// else assume plugins
|
||||
return {ppm_event_type::PPME_PLUGINEVENT_E};
|
||||
// workaround end
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::list<std::shared_ptr<filter_wrapper>> filter_wrapper_list;
|
||||
|
||||
@@ -15,6 +15,32 @@ configure_file(config_falco.h.in config_falco.h)
|
||||
|
||||
set(
|
||||
FALCO_SOURCES
|
||||
application.cpp
|
||||
app_cmdline_options.cpp
|
||||
app_action.cpp
|
||||
app_runnable_action.cpp
|
||||
app_actions/create_signal_handlers.cpp
|
||||
app_actions/init_action.cpp
|
||||
app_actions/run_action.cpp
|
||||
app_actions/init_falco_engine.cpp
|
||||
app_actions/init_inspector.cpp
|
||||
app_actions/init_outputs.cpp
|
||||
app_actions/list_fields.cpp
|
||||
app_actions/list_plugins.cpp
|
||||
app_actions/load_config.cpp
|
||||
app_actions/load_plugins.cpp
|
||||
app_actions/load_rules_files.cpp
|
||||
app_actions/print_help.cpp
|
||||
app_actions/print_ignored_events.cpp
|
||||
app_actions/print_support.cpp
|
||||
app_actions/print_version.cpp
|
||||
app_actions/start_grpc_server.cpp
|
||||
app_actions/start_webserver.cpp
|
||||
app_actions/validate_rules_files.cpp
|
||||
app_actions/daemonize.cpp
|
||||
app_actions/open_inspector.cpp
|
||||
app_actions/process_events.cpp
|
||||
app_action_manager.cpp
|
||||
configuration.cpp
|
||||
logger.cpp
|
||||
falco_outputs.cpp
|
||||
@@ -33,6 +59,7 @@ set(
|
||||
"${PROJECT_BINARY_DIR}/userspace/falco"
|
||||
"${PROJECT_BINARY_DIR}/driver/src"
|
||||
"${STRING_VIEW_LITE_INCLUDE}"
|
||||
"${CXXOPTS_INCLUDE_DIR}"
|
||||
"${YAMLCPP_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${DRAIOS_DEPENDENCIES_DIR}/yaml-${DRAIOS_YAML_VERSION}/target/include"
|
||||
@@ -46,6 +73,7 @@ set(
|
||||
luajit
|
||||
lpeg
|
||||
lyaml
|
||||
cxxopts
|
||||
)
|
||||
|
||||
set(
|
||||
@@ -127,6 +155,7 @@ target_include_directories(
|
||||
falco
|
||||
PUBLIC
|
||||
${FALCO_INCLUDE_DIRECTORIES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
if(NOT MINIMAL_BUILD)
|
||||
|
||||
48
userspace/falco/app_action.cpp
Normal file
48
userspace/falco/app_action.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "application.h"
|
||||
#include "app_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
action::action(application &app)
|
||||
: m_app(app)
|
||||
{
|
||||
}
|
||||
|
||||
action::~action()
|
||||
{
|
||||
}
|
||||
|
||||
application &action::app()
|
||||
{
|
||||
return m_app;
|
||||
}
|
||||
|
||||
cmdline_options &action::options()
|
||||
{
|
||||
return m_app.options();
|
||||
}
|
||||
|
||||
application::action_state &action::state()
|
||||
{
|
||||
return m_app.state();
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
59
userspace/falco/app_action.h
Normal file
59
userspace/falco/app_action.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
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 "application.h"
|
||||
#include "app_runnable_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// This class represents an "action" e.g. a chunk of code to execute
|
||||
// as a part of running the falco application. Examples of actions are:
|
||||
// - initializing/configuring the inspector
|
||||
// - loading/configuring plugins
|
||||
// - reading events from a trace file or live event source
|
||||
//
|
||||
// Actions also include "one off" actions for things like --help
|
||||
// output, --list fields, etc.
|
||||
//
|
||||
// There's no attempt to distribute state (e.g. inspectors, lists of
|
||||
// plugins, etc) across actions. The expectation is that all state
|
||||
// that needs to be used across actions is held in the provided
|
||||
// application object and actions know which state they should create
|
||||
// and destroy.
|
||||
|
||||
// The reason for a sublcass is to allow for building/running unit
|
||||
// tests for the action manager without bringing in all of the falco
|
||||
// application code (engine, outputs, grpc, etc).
|
||||
class action : public runnable_action {
|
||||
public:
|
||||
action(application &app);
|
||||
virtual ~action();
|
||||
|
||||
application &app();
|
||||
|
||||
cmdline_options &options();
|
||||
application::action_state &state();
|
||||
|
||||
private:
|
||||
application &m_app;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
148
userspace/falco/app_action_manager.cpp
Normal file
148
userspace/falco/app_action_manager.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "app_action_manager.h"
|
||||
#include "logger.h"
|
||||
#include "falco_common.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
action_manager::action_manager()
|
||||
{
|
||||
}
|
||||
|
||||
action_manager::~action_manager()
|
||||
{
|
||||
}
|
||||
|
||||
void action_manager::set_groups(std::list<std::string> &groups)
|
||||
{
|
||||
m_groups = groups;
|
||||
}
|
||||
|
||||
void action_manager::add(std::shared_ptr<runnable_action> act)
|
||||
{
|
||||
m_actions[act->name()] = act;
|
||||
}
|
||||
|
||||
bool action_manager::compare_actions(const std::shared_ptr<runnable_action> &a, const std::shared_ptr<runnable_action> &b)
|
||||
{
|
||||
// Check b's prerequsites. If a is found return true.
|
||||
for(auto &prereq_name : b->prerequsites())
|
||||
{
|
||||
if(prereq_name == a->name())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not a direct dependency. Check b's prerequsites recursively
|
||||
for(auto &prereq_name : b->prerequsites())
|
||||
{
|
||||
auto it = m_actions.find(prereq_name);
|
||||
if(it == m_actions.end())
|
||||
{
|
||||
throw falco_exception("No action with name " + prereq_name + " exists?");
|
||||
}
|
||||
|
||||
if(compare_actions(a, it->second))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void action_manager::run()
|
||||
{
|
||||
for(auto &group : m_groups)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Running group ") + group);
|
||||
bool proceed = run_group(group);
|
||||
|
||||
if(!proceed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool action_manager::run_group(std::string &group)
|
||||
{
|
||||
bool proceed = true;
|
||||
|
||||
std::vector<std::shared_ptr<runnable_action>> actions_ordered;
|
||||
|
||||
for(auto &pair : m_actions)
|
||||
{
|
||||
if(pair.second->group() == group)
|
||||
{
|
||||
actions_ordered.push_back(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
auto compare = [this](const std::shared_ptr<runnable_action> &a,
|
||||
const std::shared_ptr<runnable_action> &b) {
|
||||
return this->compare_actions(a, b);
|
||||
};
|
||||
|
||||
// Order the actions according to precedence
|
||||
std::sort(actions_ordered.begin(), actions_ordered.end(), compare);
|
||||
|
||||
for(auto &act : actions_ordered)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Initializing action ") + act->name());
|
||||
|
||||
act->init();
|
||||
}
|
||||
|
||||
for(auto &act : actions_ordered)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Running action ") + act->name());
|
||||
|
||||
runnable_action::run_result res = act->run();
|
||||
|
||||
if(!res.success)
|
||||
{
|
||||
fprintf(stderr, "Could not complete %s: %s\n", act->name().c_str(), res.errstr.c_str());
|
||||
}
|
||||
|
||||
if(!res.proceed)
|
||||
{
|
||||
proceed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &act : actions_ordered)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Deinitializing action ") + act->name());
|
||||
|
||||
act->deinit();
|
||||
}
|
||||
|
||||
return proceed;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
63
userspace/falco/app_action_manager.h
Normal file
63
userspace/falco/app_action_manager.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 "app_runnable_action.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// This class manages a set of actions, ensuring that they run in an
|
||||
// order that honors their dependencies and their run results.
|
||||
|
||||
class action_manager {
|
||||
public:
|
||||
action_manager();
|
||||
virtual ~action_manager();
|
||||
|
||||
// Actions are organized into groups. All actions from a
|
||||
// given group are run before actions from another group.
|
||||
//
|
||||
// Example groups are "init", "run", etc.
|
||||
//
|
||||
// This specifies the order of groups.
|
||||
void set_groups(std::list<std::string> &groups);
|
||||
|
||||
void add(std::shared_ptr<runnable_action> act);
|
||||
|
||||
void run();
|
||||
|
||||
private:
|
||||
|
||||
// Returns true if subsequent groups should run, false otherwise.
|
||||
bool run_group(std::string &group);
|
||||
|
||||
std::list<std::string> m_groups;
|
||||
|
||||
// Return true if a is less (e.g. a should run before b)
|
||||
bool compare_actions(const std::shared_ptr<runnable_action> &a, const std::shared_ptr<runnable_action> &b);
|
||||
|
||||
std::map<std::string, std::shared_ptr<runnable_action>> m_actions;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
94
userspace/falco/app_actions/create_signal_handlers.cpp
Normal file
94
userspace/falco/app_actions/create_signal_handlers.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "create_signal_handlers.h"
|
||||
|
||||
static void signal_callback(int signal)
|
||||
{
|
||||
falco::app::application::get().state().terminate = true;
|
||||
}
|
||||
|
||||
static void reopen_outputs(int signal)
|
||||
{
|
||||
falco::app::application::get().state().reopen_outputs = true;
|
||||
}
|
||||
|
||||
static void restart_falco(int signal)
|
||||
{
|
||||
falco::app::application::get().state().restart = true;
|
||||
}
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_create_signal_handlers::act_create_signal_handlers(application &app)
|
||||
: init_action(app), m_name("create signal handlers")
|
||||
{
|
||||
}
|
||||
|
||||
act_create_signal_handlers::~act_create_signal_handlers()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_create_signal_handlers::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_create_signal_handlers::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_create_signal_handlers::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(! create_handler(SIGINT, signal_callback, ret) ||
|
||||
! create_handler(SIGTERM, signal_callback, ret) ||
|
||||
! create_handler(SIGUSR1, reopen_outputs, ret) ||
|
||||
! create_handler(SIGHUP, restart_falco, ret))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool act_create_signal_handlers::create_handler(int sig, void (*func)(int), run_result &ret)
|
||||
{
|
||||
if(signal(sig, func) == SIG_ERR)
|
||||
{
|
||||
char errbuf[1024];
|
||||
|
||||
ret.success = false;
|
||||
ret.errstr = std::string("Could not create signal handler for ") +
|
||||
strsignal(sig) +
|
||||
": " +
|
||||
strerror_r(errno, errbuf, sizeof(errbuf));
|
||||
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret.success;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
47
userspace/falco/app_actions/create_signal_handlers.h
Normal file
47
userspace/falco/app_actions/create_signal_handlers.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_create_signal_handlers : public init_action {
|
||||
public:
|
||||
act_create_signal_handlers(application &app);
|
||||
virtual ~act_create_signal_handlers();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
|
||||
bool create_handler(int sig, void (*func)(int), run_result &ret);
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
115
userspace/falco/app_actions/daemonize.cpp
Normal file
115
userspace/falco/app_actions/daemonize.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "daemonize.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_daemonize::act_daemonize(application &app)
|
||||
: run_action(app), m_name("daemonize"), m_daemonized(false)
|
||||
{
|
||||
}
|
||||
|
||||
act_daemonize::~act_daemonize()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_daemonize::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_daemonize::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_daemonize::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
// If daemonizing, do it here so any init errors will
|
||||
// be returned in the foreground process.
|
||||
if (options().daemon && !m_daemonized) {
|
||||
pid_t pid, sid;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
// error
|
||||
ret.success = false;
|
||||
ret.errstr = "Could not fork.";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
} else if (pid > 0) {
|
||||
// parent. Write child pid to pidfile and exit
|
||||
std::ofstream pidfile;
|
||||
pidfile.open(options().pidfilename);
|
||||
|
||||
if (!pidfile.good())
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = string("Could not write pid to pid file ") + options().pidfilename + ".";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
pidfile << pid;
|
||||
pidfile.close();
|
||||
return ret;
|
||||
}
|
||||
// if here, child.
|
||||
|
||||
// Become own process group.
|
||||
sid = setsid();
|
||||
if (sid < 0) {
|
||||
ret.success = false;
|
||||
ret.errstr = string("Could not set session id.");
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set umask so no files are world anything or group writable.
|
||||
umask(027);
|
||||
|
||||
// Change working directory to '/'
|
||||
if ((chdir("/")) < 0) {
|
||||
ret.success = false;
|
||||
ret.errstr = string("Could not change working directory to '/'.");
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Close stdin, stdout, stderr and reopen to /dev/null
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
open("/dev/null", O_RDONLY);
|
||||
open("/dev/null", O_RDWR);
|
||||
open("/dev/null", O_RDWR);
|
||||
|
||||
m_daemonized = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
46
userspace/falco/app_actions/daemonize.h
Normal file
46
userspace/falco/app_actions/daemonize.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "run_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_daemonize : public run_action {
|
||||
public:
|
||||
act_daemonize(application &app);
|
||||
virtual ~act_daemonize();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
bool m_daemonized;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
40
userspace/falco/app_actions/init_action.cpp
Normal file
40
userspace/falco/app_actions/init_action.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "load_plugins.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
static std::string init_group = "init";
|
||||
|
||||
init_action::init_action(application &app)
|
||||
: action(app)
|
||||
{
|
||||
}
|
||||
|
||||
init_action::~init_action()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &init_action::group()
|
||||
{
|
||||
return init_group;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
37
userspace/falco/app_actions/init_action.h
Normal file
37
userspace/falco/app_actions/init_action.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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 "app_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// All actions in the "init" group derive from this class
|
||||
|
||||
class init_action : public action {
|
||||
public:
|
||||
init_action(application &app);
|
||||
virtual ~init_action();
|
||||
|
||||
const std::string &group() override;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
118
userspace/falco/app_actions/init_falco_engine.cpp
Normal file
118
userspace/falco/app_actions/init_falco_engine.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "init_falco_engine.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_init_falco_engine::act_init_falco_engine(application &app)
|
||||
: init_action(app), m_name("init falco engine"),
|
||||
m_prerequsites({"init inspector"})
|
||||
{
|
||||
}
|
||||
|
||||
act_init_falco_engine::~act_init_falco_engine()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_init_falco_engine::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_init_falco_engine::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_init_falco_engine::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
configure_output_format();
|
||||
|
||||
// Create "factories" that can create filters/formatters for
|
||||
// syscalls and k8s audit events.
|
||||
|
||||
// libs requires raw pointer, we should modify libs to use reference/shared_ptr
|
||||
std::shared_ptr<gen_event_filter_factory> syscall_filter_factory(new sinsp_filter_factory(state().inspector.get()));
|
||||
std::shared_ptr<gen_event_filter_factory> k8s_audit_filter_factory(new json_event_filter_factory());
|
||||
|
||||
// libs requires raw pointer, we should modify libs to use reference/shared_ptr
|
||||
std::shared_ptr<gen_event_formatter_factory> syscall_formatter_factory(new sinsp_evt_formatter_factory(state().inspector.get()));
|
||||
std::shared_ptr<gen_event_formatter_factory> k8s_audit_formatter_factory(new json_event_formatter_factory(k8s_audit_filter_factory));
|
||||
|
||||
state().engine->add_source(application::s_syscall_source, syscall_filter_factory, syscall_formatter_factory);
|
||||
state().engine->add_source(application::s_k8s_audit_source, k8s_audit_filter_factory, k8s_audit_formatter_factory);
|
||||
|
||||
if(state().config->m_json_output)
|
||||
{
|
||||
syscall_formatter_factory->set_output_format(gen_event_formatter::OF_JSON);
|
||||
k8s_audit_formatter_factory->set_output_format(gen_event_formatter::OF_JSON);
|
||||
}
|
||||
|
||||
for(const auto &src : options().disable_sources)
|
||||
{
|
||||
state().enabled_sources.erase(src);
|
||||
}
|
||||
|
||||
// XXX/mstemm technically this isn't right, you could disable syscall *and* k8s_audit and configure a plugin.
|
||||
if(state().enabled_sources.empty())
|
||||
{
|
||||
throw std::invalid_argument("The event source \"syscall\" and \"k8s_audit\" can not be disabled together");
|
||||
}
|
||||
|
||||
state().engine->set_min_priority(state().config->m_min_priority);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void act_init_falco_engine::configure_output_format()
|
||||
{
|
||||
std::string output_format;
|
||||
bool replace_container_info = false;
|
||||
|
||||
if(options().print_container)
|
||||
{
|
||||
output_format = "container=%container.name (id=%container.id)";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(options().print_kubernetes)
|
||||
{
|
||||
output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(options().print_mesos)
|
||||
{
|
||||
output_format = "task=%mesos.task.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(!options().print_additional.empty())
|
||||
{
|
||||
output_format = options().print_additional;
|
||||
replace_container_info = false;
|
||||
}
|
||||
|
||||
if(!output_format.empty())
|
||||
{
|
||||
state().engine->set_extra(output_format, replace_container_info);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
47
userspace/falco/app_actions/init_falco_engine.h
Normal file
47
userspace/falco/app_actions/init_falco_engine.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_init_falco_engine : public init_action {
|
||||
public:
|
||||
act_init_falco_engine(application &app);
|
||||
virtual ~act_init_falco_engine();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
void configure_output_format();
|
||||
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
137
userspace/falco/app_actions/init_inspector.cpp
Normal file
137
userspace/falco/app_actions/init_inspector.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "init_inspector.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_init_inspector::act_init_inspector(application &app)
|
||||
: init_action(app), m_name("init inspector")
|
||||
{
|
||||
}
|
||||
|
||||
act_init_inspector::~act_init_inspector()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_init_inspector::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_init_inspector::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_init_inspector::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
state().inspector->set_buffer_format(options().event_buffer_format);
|
||||
|
||||
// If required, set the CRI paths
|
||||
for (auto &p : options().cri_socket_paths)
|
||||
{
|
||||
if (!p.empty())
|
||||
{
|
||||
state().inspector->add_cri_socket_path(p);
|
||||
}
|
||||
}
|
||||
|
||||
// Decide wether to do sync or async for CRI metadata fetch
|
||||
state().inspector->set_cri_async(!options().disable_cri_async);
|
||||
|
||||
//
|
||||
// If required, set the snaplen
|
||||
//
|
||||
if(options().snaplen != 0)
|
||||
{
|
||||
state().inspector->set_snaplen(options().snaplen);
|
||||
}
|
||||
|
||||
if(!options().all_events)
|
||||
{
|
||||
// Drop EF_DROP_SIMPLE_CONS kernel side
|
||||
state().inspector->set_simple_consumer();
|
||||
// Eventually, drop any EF_DROP_SIMPLE_CONS event
|
||||
// that reached userspace (there are some events that are not syscall-based
|
||||
// like signaldeliver, that have the EF_DROP_SIMPLE_CONS flag)
|
||||
state().inspector->set_drop_event_flags(EF_DROP_SIMPLE_CONS);
|
||||
}
|
||||
|
||||
state().inspector->set_hostname_and_port_resolution_mode(false);
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
|
||||
falco_logger::log(LOG_DEBUG, "Setting metadata download max size to " + to_string(state().config->m_metadata_download_max_mb) + " MB\n");
|
||||
falco_logger::log(LOG_DEBUG, "Setting metadata download chunk wait time to " + to_string(state().config->m_metadata_download_chunk_wait_us) + " μs\n");
|
||||
falco_logger::log(LOG_DEBUG, "Setting metadata download watch frequency to " + to_string(state().config->m_metadata_download_watch_freq_sec) + " seconds\n");
|
||||
state().inspector->set_metadata_download_params(state().config->m_metadata_download_max_mb * 1024 * 1024, state().config->m_metadata_download_chunk_wait_us, state().config->m_metadata_download_watch_freq_sec);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
// Initializing k8s/mesos might have to move to open inspector
|
||||
//
|
||||
// Run k8s, if required
|
||||
//
|
||||
char *k8s_api_env = NULL;
|
||||
if(!options().k8s_api.empty() ||
|
||||
(k8s_api_env = getenv("FALCO_K8S_API")))
|
||||
{
|
||||
// Create string pointers for some config vars
|
||||
// and pass to inspector. The inspector then
|
||||
// owns the pointers.
|
||||
std::string *k8s_api_ptr = new string((!options().k8s_api.empty() ? options().k8s_api : k8s_api_env));
|
||||
std::string *k8s_api_cert_ptr = new string(options().k8s_api_cert);
|
||||
std::string *k8s_node_name_ptr = new string(options().k8s_node_name);
|
||||
|
||||
if(k8s_api_cert_ptr->empty())
|
||||
{
|
||||
if(char* k8s_cert_env = getenv("FALCO_K8S_API_CERT"))
|
||||
{
|
||||
*k8s_api_cert_ptr = k8s_cert_env;
|
||||
}
|
||||
}
|
||||
state().inspector->init_k8s_client(k8s_api_ptr, k8s_api_cert_ptr, k8s_node_name_ptr, options().verbose);
|
||||
}
|
||||
|
||||
//
|
||||
// Run mesos, if required
|
||||
//
|
||||
if(!options().mesos_api.empty())
|
||||
{
|
||||
// Differs from init_k8s_client in that it
|
||||
// passes a pointer but the inspector does
|
||||
// *not* own it and does not use it after
|
||||
// init_mesos_client() returns.
|
||||
state().inspector->init_mesos_client(&(options().mesos_api), options().verbose);
|
||||
}
|
||||
else if(char* mesos_api_env = getenv("FALCO_MESOS_API"))
|
||||
{
|
||||
std::string mesos_api_copy = mesos_api_env;
|
||||
state().inspector->init_mesos_client(&mesos_api_copy, options().verbose);
|
||||
}
|
||||
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/init_inspector.h
Normal file
45
userspace/falco/app_actions/init_inspector.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_init_inspector : public init_action {
|
||||
public:
|
||||
act_init_inspector(application &app);
|
||||
virtual ~act_init_inspector();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
88
userspace/falco/app_actions/init_outputs.cpp
Normal file
88
userspace/falco/app_actions/init_outputs.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "init_outputs.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_init_outputs::act_init_outputs(application &app)
|
||||
: init_action(app), m_name("init outputs"),
|
||||
m_prerequsites({"load config", "init falco engine"})
|
||||
{
|
||||
}
|
||||
|
||||
act_init_outputs::~act_init_outputs()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_init_outputs::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_init_outputs::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_init_outputs::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
// read hostname
|
||||
std::string hostname;
|
||||
if(char* env_hostname = getenv("FALCO_GRPC_HOSTNAME"))
|
||||
{
|
||||
hostname = env_hostname;
|
||||
}
|
||||
else
|
||||
{
|
||||
char c_hostname[256];
|
||||
int err = gethostname(c_hostname, 256);
|
||||
if(err != 0)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = "Failed to get hostname";
|
||||
ret.proceed = false;
|
||||
}
|
||||
hostname = c_hostname;
|
||||
}
|
||||
|
||||
state().outputs->init(state().engine,
|
||||
state().config->m_json_output,
|
||||
state().config->m_json_include_output_property,
|
||||
state().config->m_json_include_tags_property,
|
||||
state().config->m_output_timeout,
|
||||
state().config->m_notifications_rate, state().config->m_notifications_max_burst,
|
||||
state().config->m_buffered_outputs,
|
||||
state().config->m_time_format_iso_8601,
|
||||
hostname);
|
||||
|
||||
for(auto output : state().config->m_outputs)
|
||||
{
|
||||
state().outputs->add_output(output);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/init_outputs.h
Normal file
45
userspace/falco/app_actions/init_outputs.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_init_outputs : public init_action {
|
||||
public:
|
||||
act_init_outputs(application &app);
|
||||
virtual ~act_init_outputs();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
66
userspace/falco/app_actions/list_fields.cpp
Normal file
66
userspace/falco/app_actions/list_fields.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "list_fields.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_list_fields::act_list_fields(application &app)
|
||||
: init_action(app), m_name("list fields"),
|
||||
m_prerequsites({"load plugins"})
|
||||
{
|
||||
}
|
||||
|
||||
act_list_fields::~act_list_fields()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_list_fields::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_list_fields::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_list_fields::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().list_fields)
|
||||
{
|
||||
if(options().list_source_fields != "" &&
|
||||
!state().engine->is_source_valid(options().list_source_fields))
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = "Value for --list must be a valid source type";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
state().engine->list_fields(options().list_source_fields, options().verbose, options().names_only);
|
||||
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/list_fields.h
Normal file
45
userspace/falco/app_actions/list_fields.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_list_fields : public init_action {
|
||||
public:
|
||||
act_list_fields(application &app);
|
||||
virtual ~act_list_fields();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
78
userspace/falco/app_actions/list_plugins.cpp
Normal file
78
userspace/falco/app_actions/list_plugins.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "list_plugins.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_list_plugins::act_list_plugins(application &app)
|
||||
: init_action(app), m_name("list plugins"),
|
||||
m_prerequsites({"load plugins"})
|
||||
{
|
||||
}
|
||||
|
||||
act_list_plugins::~act_list_plugins()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_list_plugins::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_list_plugins::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_list_plugins::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().list_plugins)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
for(auto &info : state().plugin_infos)
|
||||
{
|
||||
os << "Name: " << info.name << std::endl;
|
||||
os << "Description: " << info.description << std::endl;
|
||||
os << "Contact: " << info.contact << std::endl;
|
||||
os << "Version: " << info.plugin_version.as_string() << std::endl;
|
||||
|
||||
if(info.type == TYPE_SOURCE_PLUGIN)
|
||||
{
|
||||
os << "Type: source plugin" << std::endl;
|
||||
os << "ID: " << info.id << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Type: extractor plugin" << std::endl;
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
printf("%lu Plugins Loaded:\n\n%s\n", state().plugin_infos.size(), os.str().c_str());
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/list_plugins.h
Normal file
45
userspace/falco/app_actions/list_plugins.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_list_plugins : public init_action {
|
||||
public:
|
||||
act_list_plugins(application &app);
|
||||
virtual ~act_list_plugins();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
73
userspace/falco/app_actions/load_config.cpp
Normal file
73
userspace/falco/app_actions/load_config.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "load_config.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_load_config::act_load_config(application &app)
|
||||
: init_action(app), m_name("load config")
|
||||
{
|
||||
}
|
||||
|
||||
act_load_config::~act_load_config()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_load_config::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_load_config::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_load_config::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if (options().conf_filename.size())
|
||||
{
|
||||
state().config->init(options().conf_filename, options().cmdline_config_options);
|
||||
falco_logger::set_time_format_iso_8601(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) + " (driver version " + std::string(DRIVER_VERSION) + ")\n");
|
||||
falco_logger::log(LOG_INFO, "Falco initialized with configuration file " + options().conf_filename + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.success = false;
|
||||
ret.proceed = false;
|
||||
|
||||
#ifndef BUILD_TYPE_RELEASE
|
||||
ret.errstr = std::string("You must create a config file at ") + FALCO_SOURCE_CONF_FILE + ", " + FALCO_INSTALL_CONF_FILE + " or by passing -c";
|
||||
#else
|
||||
ret.errstr = std::string("You must create a config file at ") + FALCO_INSTALL_CONF_FILE + " or by passing -c";
|
||||
#endif
|
||||
}
|
||||
|
||||
state().config->m_buffered_outputs = !options().unbuffered_outputs;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/load_config.h
Normal file
45
userspace/falco/app_actions/load_config.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_load_config : public init_action {
|
||||
public:
|
||||
act_load_config(application &app);
|
||||
virtual ~act_load_config();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
151
userspace/falco/app_actions/load_plugins.cpp
Normal file
151
userspace/falco/app_actions/load_plugins.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "load_plugins.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_load_plugins::act_load_plugins(application &app)
|
||||
: init_action(app), m_name("load plugins"),
|
||||
m_prerequsites({"init falco engine", "load config"})
|
||||
{
|
||||
}
|
||||
|
||||
act_load_plugins::~act_load_plugins()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_load_plugins::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_load_plugins::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_load_plugins::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
// All filterchecks created by plugins go in this
|
||||
// list. If we ever support multiple event sources at
|
||||
// the same time, this (and the below factories) will
|
||||
// have to be a map from event source to filtercheck
|
||||
// list.
|
||||
filter_check_list plugin_filter_checks;
|
||||
|
||||
// Factories that can create filters/formatters for
|
||||
// the (single) source supported by the (single) input plugin.
|
||||
// libs requires raw pointer, we should modify libs to use reference/shared_ptr
|
||||
std::shared_ptr<gen_event_filter_factory> plugin_filter_factory(new sinsp_filter_factory(state().inspector.get(), plugin_filter_checks));
|
||||
std::shared_ptr<gen_event_formatter_factory> plugin_formatter_factory(new sinsp_evt_formatter_factory(state().inspector.get(), plugin_filter_checks));
|
||||
|
||||
if(state().config->m_json_output)
|
||||
{
|
||||
plugin_formatter_factory->set_output_format(gen_event_formatter::OF_JSON);
|
||||
}
|
||||
|
||||
std::shared_ptr<sinsp_plugin> input_plugin;
|
||||
std::list<std::shared_ptr<sinsp_plugin>> extractor_plugins;
|
||||
for(auto &p : state().config->m_plugins)
|
||||
{
|
||||
std::shared_ptr<sinsp_plugin> plugin;
|
||||
#ifdef MUSL_OPTIMIZED
|
||||
ret.success = ret.proceed = false;
|
||||
ret.errstr = "Can not load/use plugins with musl optimized build";
|
||||
return ret;
|
||||
#else
|
||||
falco_logger::log(LOG_INFO, "Loading plugin (" + p.m_name + ") from file " + p.m_library_path + "\n");
|
||||
|
||||
// libs requires raw pointer, we should modify libs to use reference/shared_ptr
|
||||
plugin = sinsp_plugin::register_plugin(state().inspector.get(),
|
||||
p.m_library_path,
|
||||
(p.m_init_config.empty() ? NULL : (char *)p.m_init_config.c_str()),
|
||||
plugin_filter_checks);
|
||||
#endif
|
||||
|
||||
if(plugin->type() == TYPE_SOURCE_PLUGIN)
|
||||
{
|
||||
sinsp_source_plugin *splugin = static_cast<sinsp_source_plugin *>(plugin.get());
|
||||
|
||||
if(input_plugin)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = string("Can not load multiple source plugins. ") + input_plugin->name() + " already loaded";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_plugin = plugin;
|
||||
state().event_source = splugin->event_source();
|
||||
|
||||
state().inspector->set_input_plugin(p.m_name);
|
||||
if(!p.m_open_params.empty())
|
||||
{
|
||||
state().inspector->set_input_plugin_open_params(p.m_open_params.c_str());
|
||||
}
|
||||
|
||||
state().engine->add_source(state().event_source, plugin_filter_factory, plugin_formatter_factory);
|
||||
|
||||
} else {
|
||||
extractor_plugins.push_back(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that extractor plugins are compatible with the event source.
|
||||
// Also, ensure that extractor plugins don't have overlapping compatible event sources.
|
||||
std::set<std::string> compat_sources_seen;
|
||||
for(auto plugin : extractor_plugins)
|
||||
{
|
||||
// If the extractor plugin names compatible sources,
|
||||
// ensure that the input plugin's source is in the list
|
||||
// of compatible sources.
|
||||
sinsp_extractor_plugin *eplugin = static_cast<sinsp_extractor_plugin *>(plugin.get());
|
||||
const std::set<std::string> &compat_sources = eplugin->extract_event_sources();
|
||||
if(input_plugin &&
|
||||
!compat_sources.empty())
|
||||
{
|
||||
if (compat_sources.find(state().event_source) == compat_sources.end())
|
||||
{
|
||||
ret.success = ret.proceed = false;
|
||||
ret.errstr = string("Extractor plugin not compatible with event source ") + state().event_source;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(const auto &compat_source : compat_sources)
|
||||
{
|
||||
if(compat_sources_seen.find(compat_source) != compat_sources_seen.end())
|
||||
{
|
||||
ret.success = ret.proceed = false;
|
||||
ret.errstr = string("Extractor plugins have overlapping compatible event source ") + compat_source;
|
||||
return ret;
|
||||
}
|
||||
compat_sources_seen.insert(compat_source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state().plugin_infos = sinsp_plugin::plugin_infos(state().inspector.get());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/load_plugins.h
Normal file
45
userspace/falco/app_actions/load_plugins.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_load_plugins : public init_action {
|
||||
public:
|
||||
act_load_plugins(application &app);
|
||||
virtual ~act_load_plugins();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
200
userspace/falco/app_actions/load_rules_files.cpp
Normal file
200
userspace/falco/app_actions/load_rules_files.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "load_rules_files.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_load_rules_files::act_load_rules_files(application &app)
|
||||
: init_action(app), m_name("load rules files"),
|
||||
m_prerequsites({"load plugins"})
|
||||
{
|
||||
}
|
||||
|
||||
act_load_rules_files::~act_load_rules_files()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_load_rules_files::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_load_rules_files::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_load_rules_files::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
string all_rules;
|
||||
|
||||
if (options().rules_filenames.size())
|
||||
{
|
||||
state().config->m_rules_filenames = options().rules_filenames;
|
||||
}
|
||||
|
||||
if(state().config->m_rules_filenames.size() == 0)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = "You must specify at least one rules file/directory via -r or a rules_file entry in falco.yaml";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
falco_logger::log(LOG_DEBUG, "Configured rules filenames:\n");
|
||||
for (auto filename : state().config->m_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string(" ") + filename + "\n");
|
||||
}
|
||||
|
||||
for (auto filename : state().config->m_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
|
||||
uint64_t required_engine_version;
|
||||
|
||||
try {
|
||||
state().engine->load_rules_file(filename, options().verbose, options().all_events, required_engine_version);
|
||||
}
|
||||
catch(falco_exception &e)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = string("Could not load rules file ") + filename + ": " + e.what();
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
state().required_engine_versions[filename] = required_engine_version;
|
||||
}
|
||||
|
||||
// Ensure that all plugins are compatible with the loaded set of rules
|
||||
for(auto &info : state().plugin_infos)
|
||||
{
|
||||
std::string required_version;
|
||||
|
||||
if(!state().engine->is_plugin_compatible(info.name, info.plugin_version.as_string(), required_version))
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = std::string("Plugin ") + info.name + " version " + info.plugin_version.as_string() + " not compatible with required plugin version " + required_version;
|
||||
ret.proceed = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto substring : options().disabled_rule_substrings)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Disabling rules matching substring: " + substring + "\n");
|
||||
state().engine->enable_rule(substring, false);
|
||||
}
|
||||
|
||||
if(options().disabled_rule_tags.size() > 0)
|
||||
{
|
||||
for(auto &tag : options().disabled_rule_tags)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Disabling rules with tag: " + tag + "\n");
|
||||
}
|
||||
state().engine->enable_rule_by_tag(options().disabled_rule_tags, false);
|
||||
}
|
||||
|
||||
if(options().enabled_rule_tags.size() > 0)
|
||||
{
|
||||
// Since we only want to enable specific
|
||||
// rules, first disable all rules.
|
||||
state().engine->enable_rule(all_rules, false);
|
||||
for(auto &tag : options().enabled_rule_tags)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Enabling rules with tag: " + tag + "\n");
|
||||
}
|
||||
state().engine->enable_rule_by_tag(options().enabled_rule_tags, true);
|
||||
}
|
||||
|
||||
if(!options().all_events)
|
||||
{
|
||||
// For syscalls, see if any event types used by the
|
||||
// loaded rules are ones with the EF_DROP_SIMPLE_CONS
|
||||
// label.
|
||||
check_for_ignored_events();
|
||||
}
|
||||
|
||||
if (options().describe_all_rules)
|
||||
{
|
||||
state().engine->describe_rule(NULL);
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!options().describe_rule.empty())
|
||||
{
|
||||
state().engine->describe_rule(&(options().describe_rule));
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void act_load_rules_files::check_for_ignored_events()
|
||||
{
|
||||
std::set<uint16_t> evttypes;
|
||||
sinsp_evttables* einfo = state().inspector->get_event_info_tables();
|
||||
const struct ppm_event_info* etable = einfo->m_event_info;
|
||||
|
||||
state().engine->evttypes_for_ruleset(application::s_syscall_source, evttypes);
|
||||
|
||||
// Save event names so we don't warn for both the enter and exit event.
|
||||
std::set<std::string> warn_event_names;
|
||||
|
||||
for(auto evtnum : evttypes)
|
||||
{
|
||||
if(evtnum == PPME_GENERIC_E || evtnum == PPME_GENERIC_X)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!sinsp::simple_consumer_consider_evtnum(evtnum))
|
||||
{
|
||||
std::string name = etable[evtnum].name;
|
||||
if(warn_event_names.find(name) == warn_event_names.end())
|
||||
{
|
||||
warn_event_names.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print a single warning with the list of ignored events
|
||||
if (!warn_event_names.empty())
|
||||
{
|
||||
std::string skipped_events;
|
||||
bool first = true;
|
||||
for (const auto& evtname : warn_event_names)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
skipped_events += evtname;
|
||||
first = false;
|
||||
} else
|
||||
{
|
||||
skipped_events += "," + evtname;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"Rules match ignored syscall: warning (ignored-evttype):\n loaded rules match the following events: %s;\n but these events are not returned unless running falco with -A\n", skipped_events.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
47
userspace/falco/app_actions/load_rules_files.h
Normal file
47
userspace/falco/app_actions/load_rules_files.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_load_rules_files : public init_action {
|
||||
public:
|
||||
act_load_rules_files(application &app);
|
||||
virtual ~act_load_rules_files();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
void check_for_ignored_events();
|
||||
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
174
userspace/falco/app_actions/open_inspector.cpp
Normal file
174
userspace/falco/app_actions/open_inspector.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "open_inspector.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_open_inspector::act_open_inspector(application &app)
|
||||
: run_action(app), m_name("open_inspector"),
|
||||
m_prerequsites({"daemonize"})
|
||||
{
|
||||
}
|
||||
|
||||
act_open_inspector::~act_open_inspector()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_open_inspector::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_open_inspector::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_open_inspector::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().trace_filename.size())
|
||||
{
|
||||
// Try to open the trace file as a
|
||||
// capture file first.
|
||||
try {
|
||||
state().inspector->open(options().trace_filename);
|
||||
falco_logger::log(LOG_INFO, "Reading system call events from file: " + options().trace_filename + "\n");
|
||||
}
|
||||
catch(sinsp_exception &e)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, "Could not read trace file \"" + options().trace_filename + "\": " + string(e.what()));
|
||||
state().trace_is_scap=false;
|
||||
}
|
||||
|
||||
if(!state().trace_is_scap)
|
||||
{
|
||||
#ifdef MINIMAL_BUILD
|
||||
ret.success = false;
|
||||
ret.errstr = "Cannot use k8s audit events trace file with a minimal Falco build";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
#else
|
||||
try {
|
||||
string line;
|
||||
nlohmann::json j;
|
||||
|
||||
// Note we only temporarily open the file here.
|
||||
// The read file read loop will be later.
|
||||
ifstream ifs(options().trace_filename);
|
||||
getline(ifs, line);
|
||||
j = nlohmann::json::parse(line);
|
||||
|
||||
falco_logger::log(LOG_INFO, "Reading k8s audit events from file: " + options().trace_filename + "\n");
|
||||
}
|
||||
catch (nlohmann::json::parse_error& e)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = std::string("Trace filename ") + options().trace_filename + " not recognized as system call events or k8s audit events";
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = std::string("Could not open trace filename ") + options().trace_filename + " for reading: " + e.what();
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
open_t open_cb = [this](std::shared_ptr<sinsp> inspector)
|
||||
{
|
||||
if(options().userspace)
|
||||
{
|
||||
// open_udig() is the underlying method used in the capture code to parse userspace events from the kernel.
|
||||
//
|
||||
// Falco uses a ptrace(2) based userspace implementation.
|
||||
// Regardless of the implementation, the underlying method remains the same.
|
||||
inspector->open_udig();
|
||||
return;
|
||||
}
|
||||
inspector->open();
|
||||
};
|
||||
open_t open_nodriver_cb = [](std::shared_ptr<sinsp> inspector) {
|
||||
inspector->open_nodriver();
|
||||
};
|
||||
open_t open_f;
|
||||
|
||||
// Default mode: both event sources enabled
|
||||
if (state().enabled_sources.find(application::s_syscall_source) != state().enabled_sources.end() &&
|
||||
state().enabled_sources.find(application::s_k8s_audit_source) != state().enabled_sources.end())
|
||||
{
|
||||
open_f = open_cb;
|
||||
}
|
||||
if (state().enabled_sources.find(application::s_syscall_source) == state().enabled_sources.end())
|
||||
{
|
||||
open_f = open_nodriver_cb;
|
||||
}
|
||||
if (state().enabled_sources.find(application::s_k8s_audit_source) == state().enabled_sources.end())
|
||||
{
|
||||
open_f = open_cb;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
open_f(state().inspector);
|
||||
}
|
||||
catch(sinsp_exception &e)
|
||||
{
|
||||
// If syscall input source is enabled and not through userspace instrumentation
|
||||
if (state().enabled_sources.find(application::s_syscall_source) != state().enabled_sources.end() && !options().userspace)
|
||||
{
|
||||
// Try to insert the Falco kernel module
|
||||
if(system("modprobe " DRIVER_NAME " > /dev/null 2> /dev/null"))
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
|
||||
}
|
||||
open_f(state().inspector);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = e.what();
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This must be done after the open
|
||||
if(!options().all_events)
|
||||
{
|
||||
state().inspector->start_dropping_mode(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
47
userspace/falco/app_actions/open_inspector.h
Normal file
47
userspace/falco/app_actions/open_inspector.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "run_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_open_inspector : public run_action {
|
||||
public:
|
||||
typedef function<void(std::shared_ptr<sinsp> inspector)> open_t;
|
||||
|
||||
act_open_inspector(application &app);
|
||||
virtual ~act_open_inspector();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
56
userspace/falco/app_actions/print_help.cpp
Normal file
56
userspace/falco/app_actions/print_help.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "print_help.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_print_help::act_print_help(application &app)
|
||||
: init_action(app), m_name("print help")
|
||||
{
|
||||
}
|
||||
|
||||
act_print_help::~act_print_help()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_print_help::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_print_help::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_print_help::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().help)
|
||||
{
|
||||
printf("%s", options().usage().c_str());
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/print_help.h
Normal file
45
userspace/falco/app_actions/print_help.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_help : public init_action {
|
||||
public:
|
||||
act_print_help(application &app);
|
||||
virtual ~act_print_help();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
98
userspace/falco/app_actions/print_ignored_events.cpp
Normal file
98
userspace/falco/app_actions/print_ignored_events.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "print_ignored_events.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_print_ignored_events::act_print_ignored_events(application &app)
|
||||
: init_action(app), m_name("print ignored events"),
|
||||
m_prerequsites({"init inspector"})
|
||||
{
|
||||
}
|
||||
|
||||
act_print_ignored_events::~act_print_ignored_events()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_print_ignored_events::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_print_ignored_events::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_print_ignored_events::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().print_ignored_events)
|
||||
{
|
||||
print_all_ignored_events();
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void act_print_ignored_events::print_all_ignored_events()
|
||||
{
|
||||
sinsp_evttables* einfo = state().inspector->get_event_info_tables();
|
||||
const struct ppm_event_info* etable = einfo->m_event_info;
|
||||
const struct ppm_syscall_desc* stable = einfo->m_syscall_info_table;
|
||||
|
||||
std::set<string> ignored_event_names;
|
||||
for(uint32_t j = 0; j < PPM_EVENT_MAX; j++)
|
||||
{
|
||||
if(!sinsp::simple_consumer_consider_evtnum(j))
|
||||
{
|
||||
std::string name = etable[j].name;
|
||||
// Ignore event names NA*
|
||||
if(name.find("NA") != 0)
|
||||
{
|
||||
ignored_event_names.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t j = 0; j < PPM_SC_MAX; j++)
|
||||
{
|
||||
if(!sinsp::simple_consumer_consider_syscallid(j))
|
||||
{
|
||||
std::string name = stable[j].name;
|
||||
// Ignore event names NA*
|
||||
if(name.find("NA") != 0)
|
||||
{
|
||||
ignored_event_names.insert(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Ignored Event(s):");
|
||||
for(auto it : ignored_event_names)
|
||||
{
|
||||
printf(" %s", it.c_str());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
46
userspace/falco/app_actions/print_ignored_events.h
Normal file
46
userspace/falco/app_actions/print_ignored_events.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_ignored_events : public init_action {
|
||||
public:
|
||||
act_print_ignored_events(application &app);
|
||||
virtual ~act_print_ignored_events();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
void print_all_ignored_events();
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
100
userspace/falco/app_actions/print_support.cpp
Normal file
100
userspace/falco/app_actions/print_support.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include "falco_engine_version.h"
|
||||
#include "print_support.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_print_support::act_print_support(application &app)
|
||||
: init_action(app), m_name("print support"),
|
||||
m_prerequsites({"load rules files"})
|
||||
{
|
||||
}
|
||||
|
||||
act_print_support::~act_print_support()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_print_support::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_print_support::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_print_support::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().print_support)
|
||||
{
|
||||
nlohmann::json support;
|
||||
struct utsname sysinfo;
|
||||
std::string cmdline;
|
||||
|
||||
if(uname(&sysinfo) != 0)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = string("Could not uname() to find system info: ") + strerror(errno);
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
support["version"] = FALCO_VERSION;
|
||||
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"] = state().cmdline;
|
||||
support["engine_info"]["engine_version"] = FALCO_ENGINE_VERSION;
|
||||
support["config"] = read_file(options().conf_filename);
|
||||
support["rules_files"] = nlohmann::json::array();
|
||||
for(auto filename : state().config->m_rules_filenames)
|
||||
{
|
||||
nlohmann::json finfo;
|
||||
finfo["name"] = filename;
|
||||
nlohmann::json variant;
|
||||
variant["required_engine_version"] = state().required_engine_versions[filename];
|
||||
variant["content"] = read_file(filename);
|
||||
finfo["variants"].push_back(variant);
|
||||
support["rules_files"].push_back(finfo);
|
||||
}
|
||||
printf("%s\n", support.dump().c_str());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string act_print_support::read_file(std::string &filename)
|
||||
{
|
||||
std::ifstream t(filename);
|
||||
std::string str((std::istreambuf_iterator<char>(t)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
46
userspace/falco/app_actions/print_support.h
Normal file
46
userspace/falco/app_actions/print_support.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_support : public init_action {
|
||||
public:
|
||||
act_print_support(application &app);
|
||||
virtual ~act_print_support();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string read_file(std::string &filename);
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
58
userspace/falco/app_actions/print_version.cpp
Normal file
58
userspace/falco/app_actions/print_version.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "config_falco.h"
|
||||
#include "print_version.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_print_version::act_print_version(application &app)
|
||||
: init_action(app), m_name("print version")
|
||||
{
|
||||
}
|
||||
|
||||
act_print_version::~act_print_version()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_print_version::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_print_version::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_print_version::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().print_version_info)
|
||||
{
|
||||
printf("Falco version: %s\n", FALCO_VERSION);
|
||||
printf("Driver version: %s\n", DRIVER_VERSION);
|
||||
ret.proceed = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/print_version.h
Normal file
45
userspace/falco/app_actions/print_version.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_version : public init_action {
|
||||
public:
|
||||
act_print_version(application &app);
|
||||
virtual ~act_print_version();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
301
userspace/falco/app_actions/process_events.cpp
Normal file
301
userspace/falco/app_actions/process_events.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "falco_utils.h"
|
||||
#ifndef MINIMAL_BUILD
|
||||
#include "webserver.h"
|
||||
#endif
|
||||
#include "statsfilewriter.h"
|
||||
#include "process_events.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_process_events::act_process_events(application &app)
|
||||
: run_action(app), m_name("process_events"),
|
||||
m_prerequsites({"open inspector"})
|
||||
{
|
||||
}
|
||||
|
||||
act_process_events::~act_process_events()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_process_events::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_process_events::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_process_events::run()
|
||||
{
|
||||
syscall_evt_drop_mgr sdropmgr;
|
||||
// Used for stats
|
||||
double duration;
|
||||
scap_stats cstats;
|
||||
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
duration = ((double)clock()) / CLOCKS_PER_SEC;
|
||||
|
||||
if(!options().trace_filename.empty() && !state().trace_is_scap)
|
||||
{
|
||||
#ifndef MINIMAL_BUILD
|
||||
read_k8s_audit_trace_file(options().trace_filename);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t num_evts;
|
||||
|
||||
num_evts = do_inspect(state().engine,
|
||||
state().outputs,
|
||||
state().inspector,
|
||||
state().event_source,
|
||||
state().config,
|
||||
sdropmgr,
|
||||
uint64_t(options().duration_to_tot*ONE_SECOND_IN_NS),
|
||||
options().stats_filename,
|
||||
options().stats_interval,
|
||||
options().all_events,
|
||||
ret);
|
||||
|
||||
duration = ((double)clock()) / CLOCKS_PER_SEC - duration;
|
||||
|
||||
state().inspector->get_capture_stats(&cstats);
|
||||
|
||||
if(options().verbose)
|
||||
{
|
||||
fprintf(stderr, "Driver Events:%" PRIu64 "\nDriver Drops:%" PRIu64 "\n",
|
||||
cstats.n_evts,
|
||||
cstats.n_drops);
|
||||
|
||||
fprintf(stderr, "Elapsed time: %.3lf, Captured Events: %" PRIu64 ", %.2lf eps\n",
|
||||
duration,
|
||||
num_evts,
|
||||
num_evts / duration);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Honor -M also when using a trace file.
|
||||
// Since inspection stops as soon as all events have been consumed
|
||||
// just await the given duration is reached, if needed.
|
||||
if(!options().trace_filename.empty() && options().duration_to_tot>0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(options().duration_to_tot));
|
||||
}
|
||||
|
||||
state().inspector->close();
|
||||
state().engine->print_stats();
|
||||
sdropmgr.print_stats();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
// Read a jsonl file containing k8s audit events and pass each to the engine.
|
||||
void act_process_events::read_k8s_audit_trace_file(string &trace_filename)
|
||||
{
|
||||
ifstream ifs(trace_filename);
|
||||
|
||||
uint64_t line_num = 0;
|
||||
|
||||
while(ifs)
|
||||
{
|
||||
string line, errstr;
|
||||
|
||||
getline(ifs, line);
|
||||
line_num++;
|
||||
|
||||
if(line == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!k8s_audit_handler::accept_data(state().engine, state().outputs, line, errstr))
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "Could not read k8s audit event line #" + to_string(line_num) + ", \"" + line + "\": " + errstr + ", stopping");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Event processing loop
|
||||
//
|
||||
uint64_t act_process_events::do_inspect(std::shared_ptr<falco_engine> engine,
|
||||
std::shared_ptr<falco_outputs> outputs,
|
||||
std::shared_ptr<sinsp> inspector,
|
||||
std::string &event_source,
|
||||
std::shared_ptr<falco_configuration> config,
|
||||
syscall_evt_drop_mgr &sdropmgr,
|
||||
uint64_t duration_to_tot_ns,
|
||||
string &stats_filename,
|
||||
uint64_t stats_interval,
|
||||
bool all_events,
|
||||
run_result &result)
|
||||
{
|
||||
uint64_t num_evts = 0;
|
||||
int32_t rc;
|
||||
sinsp_evt* ev;
|
||||
StatsFileWriter writer;
|
||||
uint64_t duration_start = 0;
|
||||
uint32_t timeouts_since_last_success_or_msg = 0;
|
||||
|
||||
sdropmgr.init(inspector,
|
||||
outputs,
|
||||
config->m_syscall_evt_drop_actions,
|
||||
config->m_syscall_evt_drop_threshold,
|
||||
config->m_syscall_evt_drop_rate,
|
||||
config->m_syscall_evt_drop_max_burst,
|
||||
config->m_syscall_evt_simulate_drops);
|
||||
|
||||
if (stats_filename != "")
|
||||
{
|
||||
string errstr;
|
||||
|
||||
if (!writer.init(inspector, stats_filename, stats_interval, errstr))
|
||||
{
|
||||
throw falco_exception(errstr);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop through the events
|
||||
//
|
||||
while(1)
|
||||
{
|
||||
|
||||
rc = inspector->next(&ev);
|
||||
|
||||
writer.handle();
|
||||
|
||||
if(falco::app::application::get().state().reopen_outputs)
|
||||
{
|
||||
outputs->reopen_outputs();
|
||||
falco::app::application::get().state().reopen_outputs = false;
|
||||
}
|
||||
|
||||
if(falco::app::application::get().state().terminate)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "SIGINT received, exiting...\n");
|
||||
break;
|
||||
}
|
||||
else if (falco::app::application::get().state().restart)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "SIGHUP received, restarting...\n");
|
||||
break;
|
||||
}
|
||||
else if(rc == SCAP_TIMEOUT)
|
||||
{
|
||||
if(unlikely(ev == nullptr))
|
||||
{
|
||||
timeouts_since_last_success_or_msg++;
|
||||
if(event_source == application::s_syscall_source &&
|
||||
(timeouts_since_last_success_or_msg > config->m_syscall_evt_timeout_max_consecutives))
|
||||
{
|
||||
std::string rule = "Falco internal: timeouts notification";
|
||||
std::string msg = rule + ". " + std::to_string(config->m_syscall_evt_timeout_max_consecutives) + " consecutive timeouts without event.";
|
||||
std::string last_event_time_str = "none";
|
||||
if(duration_start > 0)
|
||||
{
|
||||
sinsp_utils::ts_to_string(duration_start, &last_event_time_str, false, true);
|
||||
}
|
||||
std::map<std::string, std::string> o = {
|
||||
{"last_event_time", last_event_time_str},
|
||||
};
|
||||
auto now = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
outputs->handle_msg(now, falco_common::PRIORITY_DEBUG, msg, rule, o);
|
||||
// Reset the timeouts counter, Falco alerted
|
||||
timeouts_since_last_success_or_msg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(rc == SCAP_EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(rc != SCAP_SUCCESS)
|
||||
{
|
||||
//
|
||||
// Event read error.
|
||||
//
|
||||
cerr << "rc = " << rc << endl;
|
||||
throw sinsp_exception(inspector->getlasterr().c_str());
|
||||
}
|
||||
|
||||
// Reset the timeouts counter, Falco succesfully got an event to process
|
||||
timeouts_since_last_success_or_msg = 0;
|
||||
if(duration_start == 0)
|
||||
{
|
||||
duration_start = ev->get_ts();
|
||||
}
|
||||
else if(duration_to_tot_ns > 0)
|
||||
{
|
||||
if(ev->get_ts() - duration_start >= duration_to_tot_ns)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!sdropmgr.process_event(inspector, ev))
|
||||
{
|
||||
result.success = false;
|
||||
result.errstr = "";
|
||||
result.proceed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!ev->simple_consumer_consider() && !all_events)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// As the inspector has no filter at its level, all
|
||||
// events are returned here. Pass them to the falco
|
||||
// engine, which will match the event against the set
|
||||
// of rules. If a match is found, pass the event to
|
||||
// the outputs.
|
||||
unique_ptr<falco_engine::rule_result> res = engine->process_event(event_source, ev);
|
||||
if(res)
|
||||
{
|
||||
outputs->handle_event(res->evt, res->rule, res->source, res->priority_num, res->format, res->tags);
|
||||
}
|
||||
|
||||
num_evts++;
|
||||
}
|
||||
|
||||
return num_evts;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
62
userspace/falco/app_actions/process_events.h
Normal file
62
userspace/falco/app_actions/process_events.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "run_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_process_events : public run_action {
|
||||
public:
|
||||
act_process_events(application &app);
|
||||
virtual ~act_process_events();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
void read_k8s_audit_trace_file(std::string &trace_filename);
|
||||
#endif
|
||||
|
||||
uint64_t do_inspect(std::shared_ptr<falco_engine> engine,
|
||||
std::shared_ptr<falco_outputs> outputs,
|
||||
std::shared_ptr<sinsp> inspector,
|
||||
std::string &event_source,
|
||||
std::shared_ptr<falco_configuration> config,
|
||||
syscall_evt_drop_mgr &sdropmgr,
|
||||
uint64_t duration_to_tot_ns,
|
||||
string &stats_filename,
|
||||
uint64_t stats_interval,
|
||||
bool all_events,
|
||||
run_result &result);
|
||||
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
40
userspace/falco/app_actions/run_action.cpp
Normal file
40
userspace/falco/app_actions/run_action.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "run_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
static std::string run_group = "run";
|
||||
|
||||
run_action::run_action(application &app)
|
||||
: action(app)
|
||||
{
|
||||
}
|
||||
|
||||
run_action::~run_action()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &run_action::group()
|
||||
{
|
||||
return run_group;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
37
userspace/falco/app_actions/run_action.h
Normal file
37
userspace/falco/app_actions/run_action.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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 "app_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// All actions in the "run" group derive from this class
|
||||
|
||||
class run_action : public action {
|
||||
public:
|
||||
run_action(application &app);
|
||||
virtual ~run_action();
|
||||
|
||||
const std::string &group() override;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
82
userspace/falco/app_actions/start_grpc_server.cpp
Normal file
82
userspace/falco/app_actions/start_grpc_server.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "start_grpc_server.h"
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_start_grpc_server::act_start_grpc_server(application &app)
|
||||
: init_action(app), m_name("start grpc server"),
|
||||
m_prerequsites({"init outputs"})
|
||||
{
|
||||
}
|
||||
|
||||
act_start_grpc_server::~act_start_grpc_server()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_start_grpc_server::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_start_grpc_server::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_start_grpc_server::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
// gRPC server
|
||||
if(state().config->m_grpc_enabled)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "gRPC server threadiness equals to " + to_string(state().config->m_grpc_threadiness) + "\n");
|
||||
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per thread, or implement
|
||||
// different queuing mechanisms, round robin, fanout? What we want to achieve?
|
||||
m_grpc_server.init(
|
||||
state().config->m_grpc_bind_address,
|
||||
state().config->m_grpc_threadiness,
|
||||
state().config->m_grpc_private_key,
|
||||
state().config->m_grpc_cert_chain,
|
||||
state().config->m_grpc_root_certs,
|
||||
state().config->m_log_level
|
||||
);
|
||||
m_grpc_server_thread = std::thread([this] {
|
||||
m_grpc_server.run();
|
||||
});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void act_start_grpc_server::deinit()
|
||||
{
|
||||
if(m_grpc_server_thread.joinable())
|
||||
{
|
||||
m_grpc_server.shutdown();
|
||||
m_grpc_server_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
56
userspace/falco/app_actions/start_grpc_server.h
Normal file
56
userspace/falco/app_actions/start_grpc_server.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
|
||||
#include "grpc_server.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_start_grpc_server : public init_action {
|
||||
public:
|
||||
act_start_grpc_server(application &app);
|
||||
virtual ~act_start_grpc_server();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
void deinit() override;
|
||||
|
||||
private:
|
||||
falco::grpc::server m_grpc_server;
|
||||
std::thread m_grpc_server_thread;
|
||||
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
68
userspace/falco/app_actions/start_webserver.cpp
Normal file
68
userspace/falco/app_actions/start_webserver.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "start_webserver.h"
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_start_webserver::act_start_webserver(application &app)
|
||||
: init_action(app), m_name("start webserver"),
|
||||
m_prerequsites({"init outputs"})
|
||||
{
|
||||
}
|
||||
|
||||
act_start_webserver::~act_start_webserver()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_start_webserver::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_start_webserver::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_start_webserver::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().trace_filename.empty() && state().config->m_webserver_enabled && state().enabled_sources.find(application::s_k8s_audit_source) != state().enabled_sources.end())
|
||||
{
|
||||
std::string ssl_option = (state().config->m_webserver_ssl_enabled ? " (SSL)" : "");
|
||||
falco_logger::log(LOG_INFO, "Starting internal webserver, listening on port " + to_string(state().config->m_webserver_listen_port) + ssl_option + "\n");
|
||||
m_webserver.init(state().config, state().engine, state().outputs);
|
||||
m_webserver.start();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void act_start_webserver::deinit()
|
||||
{
|
||||
m_webserver.stop();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
52
userspace/falco/app_actions/start_webserver.h
Normal file
52
userspace/falco/app_actions/start_webserver.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
#include "webserver.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_start_webserver : public init_action {
|
||||
public:
|
||||
act_start_webserver(application &app);
|
||||
virtual ~act_start_webserver();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
void deinit() override;
|
||||
|
||||
private:
|
||||
falco_webserver m_webserver;
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
#endif
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
77
userspace/falco/app_actions/validate_rules_files.cpp
Normal file
77
userspace/falco/app_actions/validate_rules_files.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "validate_rules_files.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
act_validate_rules_files::act_validate_rules_files(application &app)
|
||||
: init_action(app), m_name("validate rules files"),
|
||||
m_prerequsites({"load plugins"})
|
||||
{
|
||||
}
|
||||
|
||||
act_validate_rules_files::~act_validate_rules_files()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &act_validate_rules_files::name()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::list<std::string> &act_validate_rules_files::prerequsites()
|
||||
{
|
||||
return m_prerequsites;
|
||||
}
|
||||
|
||||
runnable_action::run_result act_validate_rules_files::run()
|
||||
{
|
||||
run_result ret = {true, "", true};
|
||||
|
||||
if(options().validate_rules_filenames.size() > 0)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Validating rules file(s):\n");
|
||||
for(auto file : options().validate_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, " " + file + "\n");
|
||||
}
|
||||
for(auto file : options().validate_rules_filenames)
|
||||
{
|
||||
// Only include the prefix if there is more than one file
|
||||
std::string prefix = (options().validate_rules_filenames.size() > 1 ? file + ": " : "");
|
||||
try {
|
||||
state().engine->load_rules_file(file, options().verbose, options().all_events);
|
||||
}
|
||||
catch(falco_exception &e)
|
||||
{
|
||||
ret.success = false;
|
||||
ret.errstr = prefix + e.what();
|
||||
ret.proceed = false;
|
||||
return ret;
|
||||
}
|
||||
printf("%sOk\n", prefix.c_str());
|
||||
}
|
||||
falco_logger::log(LOG_INFO, "Ok\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
45
userspace/falco/app_actions/validate_rules_files.h
Normal file
45
userspace/falco/app_actions/validate_rules_files.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <string>
|
||||
|
||||
#include "init_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_validate_rules_files : public init_action {
|
||||
public:
|
||||
act_validate_rules_files(application &app);
|
||||
virtual ~act_validate_rules_files();
|
||||
|
||||
const std::string &name() override;
|
||||
|
||||
const std::list<std::string> &prerequsites() override;
|
||||
|
||||
run_result run() override;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::list<std::string> m_prerequsites;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
209
userspace/falco/app_cmdline_options.cpp
Normal file
209
userspace/falco/app_cmdline_options.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "app_cmdline_options.h"
|
||||
#include "configuration.h"
|
||||
#include "config_falco.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// Most bool member variables do not need to be set explicitly, as
|
||||
// they are bound to command line options that have default
|
||||
// values. However, a few options can be ifdef'd out so explicitly
|
||||
// initialize their linked variables.
|
||||
cmdline_options::cmdline_options()
|
||||
: event_buffer_format(sinsp_evt::PF_NORMAL),
|
||||
list_plugins(false),
|
||||
m_cmdline_opts("falco", "Falco - Cloud Native Runtime Security")
|
||||
{
|
||||
define();
|
||||
}
|
||||
|
||||
cmdline_options::~cmdline_options()
|
||||
{
|
||||
}
|
||||
|
||||
bool cmdline_options::parse(int argc, char **argv, std::string &errstr)
|
||||
{
|
||||
try {
|
||||
m_cmdline_parsed = m_cmdline_opts.parse(argc, argv);
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
errstr = e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some options require additional processing/validation
|
||||
std::ifstream conf_stream;
|
||||
if (!conf_filename.empty())
|
||||
{
|
||||
conf_stream.open(conf_filename);
|
||||
if (!conf_stream.is_open())
|
||||
{
|
||||
errstr = std::string("Could not find configuration file at ") + conf_filename;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef BUILD_TYPE_RELEASE
|
||||
conf_stream.open(FALCO_SOURCE_CONF_FILE);
|
||||
if (conf_stream.is_open())
|
||||
{
|
||||
conf_filename = FALCO_SOURCE_CONF_FILE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
conf_stream.open(FALCO_INSTALL_CONF_FILE);
|
||||
if (conf_stream.is_open())
|
||||
{
|
||||
conf_filename = FALCO_INSTALL_CONF_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note we do not return false here. Although there is
|
||||
// no valid config file, some ways of running falco
|
||||
// (e.g. --help, --list) do not need a config file.
|
||||
//
|
||||
// Later, when it comes time to read a config file, if
|
||||
// the filename is empty we exit with an error.
|
||||
conf_filename = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_cmdline_parsed.count("b") > 0)
|
||||
{
|
||||
event_buffer_format = sinsp_evt::PF_BASE64;
|
||||
}
|
||||
|
||||
// Expand any paths provided via -r and fill in rules_filenames
|
||||
if(m_cmdline_parsed.count("r") > 0)
|
||||
{
|
||||
for(auto &path : m_cmdline_parsed["r"].as<std::vector<std::string>>())
|
||||
{
|
||||
falco_configuration::read_rules_file_directory(path, rules_filenames);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the vectors of enabled/disabled tags into sets to match falco engine API
|
||||
if(m_cmdline_parsed.count("T") > 0)
|
||||
{
|
||||
for(auto &tag : m_cmdline_parsed["T"].as<std::vector<std::string>>())
|
||||
{
|
||||
disabled_rule_tags.insert(tag);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_cmdline_parsed.count("t") > 0)
|
||||
{
|
||||
for(auto &tag : m_cmdline_parsed["t"].as<std::vector<std::string>>())
|
||||
{
|
||||
enabled_rule_tags.insert(tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Some combinations of arguments are not allowed.
|
||||
|
||||
// You can't both disable and enable rules
|
||||
if((disabled_rule_substrings.size() + disabled_rule_tags.size() > 0) &&
|
||||
enabled_rule_tags.size() > 0)
|
||||
{
|
||||
errstr = std::string("You can not specify both disabled (-D/-T) and enabled (-t) rules");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (daemon && pidfilename == "") {
|
||||
errstr = std::string("If -d is provided, a pid file must also be provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
list_fields = m_cmdline_parsed.count("list") > 0 ? true : false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string cmdline_options::usage()
|
||||
{
|
||||
return m_cmdline_opts.help();
|
||||
}
|
||||
|
||||
void cmdline_options::define()
|
||||
{
|
||||
m_cmdline_opts.add_options()
|
||||
("h,help", "Print this page", cxxopts::value(help)->default_value("false"))
|
||||
#ifdef BUILD_TYPE_RELEASE
|
||||
("c", "Configuration file. If not specified uses " FALCO_INSTALL_CONF_FILE ".", cxxopts::value(conf_filename), "<path>")
|
||||
#else
|
||||
("c", "Configuration file. If not specified tries " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ".", cxxopts::value(conf_filename), "<path>")
|
||||
#endif
|
||||
("A", "Monitor all events, including those with EF_DROP_SIMPLE_CONS flag.", cxxopts::value(all_events)->default_value("false"))
|
||||
("b,print-base64", "Print data buffers in base64. This is useful for encoding binary data that needs to be used over media designed to consume this format.")
|
||||
("cri", "Path to CRI socket for container metadata. Use the specified socket to fetch data from a CRI-compatible runtime. If not specified, uses libs default. It can be passed multiple times to specify socket to be tried until a successful one is found.", cxxopts::value(cri_socket_paths), "<path>")
|
||||
("d,daemon", "Run as a daemon.", cxxopts::value(daemon)->default_value("false"))
|
||||
("disable-cri-async", "Disable asynchronous CRI metadata fetching. This is useful to let the input event wait for the container metadata fetch to finish before moving forward. Async fetching, in some environments leads to empty fields for container metadata when the fetch is not fast enough to be completed asynchronously. This can have a performance penalty on your environment depending on the number of containers and the frequency at which they are created/started/stopped.", cxxopts::value(disable_cri_async)->default_value("false"))
|
||||
("disable-source", "Disable a specific event source. Available event sources are: syscall, k8s_audit, or any source from a configured source plugin. It can be passed multiple times. Can not disable all event sources.", cxxopts::value(disable_sources), "<event_source>")
|
||||
("D", "Disable any rules with names having the substring <substring>. Can be specified multiple times. Can not be specified with -t.", cxxopts::value(disabled_rule_substrings), "<substring>")
|
||||
("e", "Read the events from <events_file> (in .scap format for sinsp events, or jsonl for k8s audit events) instead of tapping into live.", cxxopts::value(trace_filename), "<events_file>")
|
||||
("i", "Print all events that are ignored by default (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false"))
|
||||
#ifndef MINIMAL_BUILD
|
||||
("k,k8s-api", "Enable Kubernetes support by connecting to the API server specified as argument. E.g. \"http://admin:password@127.0.0.1:8080\". The API server can also be specified via the environment variable FALCO_K8S_API.", cxxopts::value(k8s_api), "<url>")
|
||||
("K,k8s-api-cert", "Use the provided files names to authenticate user and (optionally) verify the K8S API server identity. Each entry must specify full (absolute, or relative to the current directory) path to the respective file. Private key password is optional (needed only if key is password protected). CA certificate is optional. For all files, only PEM file format is supported. Specifying CA certificate only is obsoleted - when single entry is provided for this option, it will be interpreted as the name of a file containing bearer token. Note that the format of this command-line option prohibits use of files whose names contain ':' or '#' characters in the file name.", cxxopts::value(k8s_api_cert), "(<bt_file> | <cert_file>:<key_file[#password]>[:<ca_cert_file>])")
|
||||
("k8s-node", "The node name will be used as a filter when requesting metadata of pods to the API server. Usually, it should be set to the current node on which Falco is running. If empty, no filter is set, which may have a performance penalty on large clusters.", cxxopts::value(k8s_node_name), "<node_name>")
|
||||
#endif
|
||||
("L", "Show the name and description of all rules and exit.", cxxopts::value(describe_all_rules)->default_value("false"))
|
||||
("l", "Show the name and description of the rule with name <rule> and exit.", cxxopts::value(describe_rule), "<rule>")
|
||||
("list", "List all defined fields. If <source> is provided, only list those fields for the source <source>. Current values for <source> are \"syscall\", \"k8s_audit\", or any source from a configured source plugin.", cxxopts::value(list_source_fields)->implicit_value(""), "<source>")
|
||||
#ifndef MUSL_OPTIMIZED
|
||||
("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]>")
|
||||
#endif
|
||||
("M", "Stop collecting after <num_seconds> reached.", cxxopts::value(duration_to_tot)->default_value("0"), "<num_seconds>")
|
||||
("N", "When used with --list/--list-source, 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>")
|
||||
("p,print", "Add additional information to each falco notification's output.", cxxopts::value(print_additional), "<output_format>")
|
||||
("pcontainer", "Add additional information to each falco notification's output, using a container-friendly format. Specifying -pc/-pcontainer will change the interpretation of %%container.info in rule output fields.", cxxopts::value(print_container)->default_value("false"))
|
||||
("pc", "Short for -pcontainer", cxxopts::value(print_container)->default_value("false"))
|
||||
("pkubernetes", "Add additional information to each falco notification's output, using a kubernetes-friendly format. Additionally, specifying -pk/-pkubernetes will change the interpretation of %%container.info in rule output fields.", cxxopts::value(print_kubernetes)->default_value("false"))
|
||||
("pk", "Short for -pkubernetes", cxxopts::value(print_kubernetes)->default_value("false"))
|
||||
("pmesos", "Add additional information to each falco notification's output, using a mesos-friendly format. Additionally, specifying -pm/-pmesos will change the interpretation of %%container.info in rule output fields.", cxxopts::value(print_mesos)->default_value("false"))
|
||||
("pm", "Short for -pmesos", cxxopts::value(print_mesos)->default_value("false"))
|
||||
("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). Can be specified 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>")
|
||||
("stats-interval", "When using -s <stats_file>, write statistics every <msec> ms. This uses signals, so don't recommend intervals below 200 ms. Defaults to 5000 (5 seconds).", cxxopts::value(stats_interval)->default_value("5000"), "<msec>")
|
||||
("S,snaplen", "Capture the first <len> bytes of each I/O buffer. By default, the first 80 bytes are captured. Use this option with caution, it can generate huge trace files.", cxxopts::value(snaplen)->default_value("0"), "<len>")
|
||||
("support", "Print support information including version, rules files used, etc. and exit.", cxxopts::value(print_support)->default_value("false"))
|
||||
("T", "Disable any rules with a tag=<tag>. Can be specified multiple times. Can not be specified with -t", cxxopts::value<std::vector<std::string>>(), "<tag>")
|
||||
("t", "Only run those rules with a tag=<tag>. Can be specified multiple times. Can not be specified with -T/-D.", cxxopts::value<std::vector<std::string>>(), "<tag>")
|
||||
("U,unbuffered", "Turn off output buffering to configured outputs. This causes every single line emitted by falco to be flushed which generates higher CPU usage but is useful when piping those outputs into another process or into a script.", cxxopts::value(unbuffered_outputs)->default_value("false"))
|
||||
("u,userspace", "Parse events from userspace. To be used in conjunction with the ptrace(2) based driver (pdig)", cxxopts::value(userspace)->default_value("false"))
|
||||
("V,validate", "Read the contents of the specified rules(s) file and exit. Can be specified multiple times to validate multiple files.", cxxopts::value(validate_rules_filenames), "<rules_file>")
|
||||
("v", "Verbose output.", cxxopts::value(verbose)->default_value("false"))
|
||||
("version", "Print version number.", cxxopts::value(print_version_info)->default_value("false"));
|
||||
|
||||
m_cmdline_opts.set_width(140);
|
||||
}
|
||||
|
||||
}; // namespace app
|
||||
}; // namespace falco
|
||||
88
userspace/falco/app_cmdline_options.h
Normal file
88
userspace/falco/app_cmdline_options.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 <event.h>
|
||||
|
||||
#include <cxxopts.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class cmdline_options {
|
||||
public:
|
||||
cmdline_options();
|
||||
~cmdline_options();
|
||||
|
||||
// Each of these maps directly to a command line option.
|
||||
bool help;
|
||||
std::string conf_filename;
|
||||
bool all_events;
|
||||
sinsp_evt::param_fmt event_buffer_format;
|
||||
std::vector<std::string> cri_socket_paths;
|
||||
bool daemon;
|
||||
bool disable_cri_async;
|
||||
std::vector<std::string> disable_sources;
|
||||
std::vector<std::string> disabled_rule_substrings;
|
||||
std::string trace_filename;
|
||||
std::string k8s_api;
|
||||
std::string k8s_api_cert;
|
||||
std::string k8s_node_name;
|
||||
bool describe_all_rules;
|
||||
std::string describe_rule;
|
||||
bool print_ignored_events;
|
||||
bool list_fields;
|
||||
std::string list_source_fields;
|
||||
bool list_plugins;
|
||||
std::string mesos_api;
|
||||
int duration_to_tot;
|
||||
bool names_only;
|
||||
std::vector<std::string> cmdline_config_options;
|
||||
std::string print_additional;
|
||||
bool print_container;
|
||||
bool print_kubernetes;
|
||||
bool print_mesos;
|
||||
std::string pidfilename;
|
||||
std::list<std::string> rules_filenames;
|
||||
std::string stats_filename;
|
||||
uint64_t stats_interval;
|
||||
uint64_t snaplen;
|
||||
bool print_support;
|
||||
std::set<std::string> disabled_rule_tags;
|
||||
std::set<std::string> enabled_rule_tags;
|
||||
bool unbuffered_outputs;
|
||||
bool userspace;
|
||||
std::vector<std::string> validate_rules_filenames;
|
||||
bool verbose;
|
||||
bool print_version_info;
|
||||
|
||||
bool parse(int argc, char **argv, std::string &errstr);
|
||||
|
||||
std::string usage();
|
||||
private:
|
||||
void define();
|
||||
|
||||
cxxopts::Options m_cmdline_opts;
|
||||
cxxopts::ParseResult m_cmdline_parsed;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2019 The Falco Authors.
|
||||
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.
|
||||
@@ -14,7 +14,26 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "app_runnable_action.h"
|
||||
|
||||
#define FALCO_ENGINE_LUA_DIR "${FALCO_ABSOLUTE_SHARE_DIR}/lua/"
|
||||
#define FALCO_ENGINE_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/engine/lua/"
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
runnable_action::runnable_action()
|
||||
{
|
||||
}
|
||||
|
||||
runnable_action::~runnable_action()
|
||||
{
|
||||
}
|
||||
|
||||
void runnable_action::init()
|
||||
{
|
||||
}
|
||||
|
||||
void runnable_action::deinit()
|
||||
{
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
82
userspace/falco/app_runnable_action.h
Normal file
82
userspace/falco/app_runnable_action.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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 <string>
|
||||
#include <list>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// Along with app_action.h, defines the interface for an application
|
||||
// action. The split implementation allows for building tests for the
|
||||
// action manager without bringing in all of the application related
|
||||
// code (falco engine, outputs, webserver, etc.).
|
||||
class runnable_action {
|
||||
public:
|
||||
|
||||
struct run_result {
|
||||
// If true, the action completed successfully.
|
||||
bool success;
|
||||
|
||||
// If success==false, details on the error.
|
||||
std::string errstr;
|
||||
|
||||
// If true, subsequent actions should be performed. If
|
||||
// false, subsequent actions should *not* be performed
|
||||
// and falco should tear down/exit.
|
||||
bool proceed;
|
||||
};
|
||||
|
||||
runnable_action();
|
||||
virtual ~runnable_action();
|
||||
|
||||
// Return the name of the action. Only used for logging
|
||||
// purposes and to use in prerequsites().
|
||||
virtual const std::string &name() = 0;
|
||||
|
||||
// Actions are organized into groups. All actions from a
|
||||
// given group are run before actions from another group.
|
||||
//
|
||||
// The order of groups is passed to the action manager in its
|
||||
// constructor.
|
||||
virtual const std::string &group() = 0;
|
||||
|
||||
// Return a list of action names that *must* run before this
|
||||
// action is run.
|
||||
virtual const std::list<std::string> &prerequsites() = 0;
|
||||
|
||||
// Initialize any state in the application that might be
|
||||
// shared with other components. This might include creating
|
||||
// inspectors, falco engines, etc.
|
||||
virtual void init();
|
||||
|
||||
// Destroy any state created in init()
|
||||
virtual void deinit();
|
||||
|
||||
// Perform the action. The returned run_result holds the
|
||||
// result of the action and whether later actions should
|
||||
// procceed.
|
||||
virtual run_result run() = 0;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
|
||||
|
||||
|
||||
133
userspace/falco/application.cpp
Normal file
133
userspace/falco/application.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// The falco "app" holds application-level configuration and contains
|
||||
// the implementation of any subcommand-like behaviors like --list, -i
|
||||
// (print_ignored_events), etc.
|
||||
|
||||
// It also contains the code to initialize components like the
|
||||
// inspector, falco engine, etc.
|
||||
|
||||
#include "application.h"
|
||||
#include "defined_app_actions.h"
|
||||
#include "falco_common.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
std::string application::s_syscall_source = "syscall";
|
||||
std::string application::s_k8s_audit_source = "k8s_audit";
|
||||
|
||||
application::action_state::action_state()
|
||||
: restart(false),
|
||||
terminate(false),
|
||||
reopen_outputs(false),
|
||||
enabled_sources({application::s_syscall_source, application::s_k8s_audit_source}),
|
||||
event_source(application::s_syscall_source)
|
||||
{
|
||||
config = std::make_shared<falco_configuration>();
|
||||
outputs = std::make_shared<falco_outputs>();
|
||||
inspector = std::make_shared<sinsp>();
|
||||
engine = std::make_shared<falco_engine>();
|
||||
}
|
||||
|
||||
application::action_state::~action_state()
|
||||
{
|
||||
}
|
||||
|
||||
application::application()
|
||||
: m_initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
application::~application()
|
||||
{
|
||||
}
|
||||
|
||||
application &application::get()
|
||||
{
|
||||
static application instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
cmdline_options &application::options()
|
||||
{
|
||||
if(!m_initialized)
|
||||
{
|
||||
throw falco_exception("App init() not called yet");
|
||||
}
|
||||
|
||||
return m_cmdline_options;
|
||||
}
|
||||
|
||||
application::action_state &application::state()
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
bool application::init(int argc, char **argv, std::string &errstr)
|
||||
{
|
||||
if(!m_cmdline_options.parse(argc, argv, errstr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(char **arg = argv; *arg; arg++)
|
||||
{
|
||||
if(state().cmdline.size() > 0)
|
||||
{
|
||||
state().cmdline += " ";
|
||||
}
|
||||
state().cmdline += *arg;
|
||||
}
|
||||
|
||||
|
||||
std::list<std::string> groups = {"init", "run"};
|
||||
m_action_manager.set_groups(groups);
|
||||
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_create_signal_handlers(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_init_falco_engine(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_init_inspector(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_init_outputs(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_list_fields(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_list_plugins(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_load_config(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_load_plugins(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_load_rules_files(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_print_help(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_print_ignored_events(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_print_support(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_print_version(*this)));
|
||||
#ifndef MINIMAL_BUILD
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_start_grpc_server(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_start_webserver(*this)));
|
||||
#endif
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_validate_rules_files(*this)));
|
||||
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_daemonize(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_open_inspector(*this)));
|
||||
m_action_manager.add(std::shared_ptr<runnable_action>(new act_process_events(*this)));
|
||||
m_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void application::run()
|
||||
{
|
||||
m_action_manager.run();
|
||||
}
|
||||
|
||||
}; // namespace app
|
||||
}; // namespace falco
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user