mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-22 04:32:21 +00:00
Compare commits
129 Commits
fix-plugin
...
add-app-ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98bc8703c9 | ||
|
|
b7a92cc154 | ||
|
|
9e4f0888e8 | ||
|
|
db2e2b19b3 | ||
|
|
481d25f8ee | ||
|
|
c07c327d87 | ||
|
|
149fc1e237 | ||
|
|
f9a9ed984c | ||
|
|
df219b5e1d | ||
|
|
3fbc90e99e | ||
|
|
ad42baed7a | ||
|
|
31111ab87b | ||
|
|
7d6b46218f | ||
|
|
fded42c203 | ||
|
|
5ff9101b95 | ||
|
|
36acd6dfbf | ||
|
|
4819748ab0 | ||
|
|
f7a5dd0d5b | ||
|
|
4705a92c49 | ||
|
|
a5d3663c75 | ||
|
|
58b6496f51 | ||
|
|
9dd85bf9db | ||
|
|
6c4b267109 | ||
|
|
7c005aa9dc | ||
|
|
2f2c5c4a9b | ||
|
|
aadb76f2e9 | ||
|
|
23f4f0eee0 | ||
|
|
97373a8b6e | ||
|
|
4ecb907223 | ||
|
|
db30d0e1c7 | ||
|
|
d173ab7a9e | ||
|
|
e4e8dcf06b | ||
|
|
e8aac31890 | ||
|
|
073339eff1 | ||
|
|
001e7557e6 | ||
|
|
73f98de005 | ||
|
|
3760155ec8 | ||
|
|
d8cfaee242 | ||
|
|
e173bf89a3 | ||
|
|
f12149dc87 | ||
|
|
19a6cf74f8 | ||
|
|
c62cc5e8c0 | ||
|
|
ead40f898a | ||
|
|
8eef71b801 | ||
|
|
97883e7535 | ||
|
|
4f897e0dc0 | ||
|
|
d0ee656dac | ||
|
|
49b88c14b2 | ||
|
|
9a314d9443 | ||
|
|
2b8a88c335 | ||
|
|
4a0c9d6ccb | ||
|
|
d55cd79ebd | ||
|
|
5e7346ccb0 | ||
|
|
35d0f0603f | ||
|
|
d685e0967a | ||
|
|
be35c45590 | ||
|
|
d700d2f768 | ||
|
|
4a215ced6c | ||
|
|
f5dab2eb5a | ||
|
|
53c77ea6b5 | ||
|
|
6e56ef77fd | ||
|
|
1306fd6ac1 | ||
|
|
530f999556 | ||
|
|
86cf80d05f | ||
|
|
ed11b8833f | ||
|
|
19ab9e5f35 | ||
|
|
4a8bec09d7 | ||
|
|
3646fb6e03 | ||
|
|
88a5404d1c | ||
|
|
5a19a1d3b0 | ||
|
|
3806e62c3a | ||
|
|
25b07e134c | ||
|
|
bda7d7bb11 | ||
|
|
ab05026065 | ||
|
|
cc30fcc0cf | ||
|
|
fa7fab525f | ||
|
|
ae56a10932 | ||
|
|
676fc9efa8 | ||
|
|
ff94383ed9 | ||
|
|
655ff76c3d | ||
|
|
cacbb3928d | ||
|
|
72725a7f87 | ||
|
|
00c3fa4908 | ||
|
|
eabd3ad24b | ||
|
|
a84adbd231 | ||
|
|
04ce76becc | ||
|
|
6dbccfcac5 | ||
|
|
bd725cb655 | ||
|
|
4d29b872ab | ||
|
|
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 |
@@ -13,7 +13,7 @@ jobs:
|
||||
command: apk update
|
||||
- run:
|
||||
name: Install build dependencies
|
||||
command: apk add g++ gcc cmake cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils
|
||||
command: apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils
|
||||
- run:
|
||||
name: Prepare project
|
||||
command: |
|
||||
@@ -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":
|
||||
@@ -519,7 +487,7 @@ jobs:
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
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/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin -a x86_64
|
||||
/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
|
||||
@@ -630,7 +598,6 @@ workflows:
|
||||
- "build/ubuntu-focal"
|
||||
- "build/ubuntu-focal-debug"
|
||||
- "build/ubuntu-bionic"
|
||||
- "build/centos8"
|
||||
- "build/centos7"
|
||||
- "build/centos7-debug"
|
||||
- "tests/integration":
|
||||
@@ -694,7 +661,7 @@ workflows:
|
||||
only: master
|
||||
requires:
|
||||
- publish/docker-dev
|
||||
# - "quality/static-analysis" # This is temporarly disabled: https://github.com/falcosecurity/falco/issues/1526
|
||||
# - "quality/static-analysis" # This is temporarily disabled: https://github.com/falcosecurity/falco/issues/1526
|
||||
release:
|
||||
jobs:
|
||||
- "build/musl":
|
||||
@@ -723,6 +690,7 @@ workflows:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build/musl"
|
||||
- "rpm/sign"
|
||||
filters:
|
||||
tags:
|
||||
|
||||
@@ -7,7 +7,7 @@ line_width = 120
|
||||
# How many spaces to tab for indent
|
||||
tab_size = 2
|
||||
|
||||
# If arglists are longer than this, break them always
|
||||
# If arg lists are longer than this, break them always
|
||||
max_subargs_per_line = 3
|
||||
|
||||
# If true, separate flow control names from their parentheses with a space
|
||||
@@ -21,7 +21,7 @@ separate_fn_name_with_space = False
|
||||
dangle_parens = False
|
||||
|
||||
# If the statement spelling length (including space and parenthesis is larger
|
||||
# than the tab width by more than this amoung, then force reject un-nested
|
||||
# than the tab width by more than this among, then force reject un-nested
|
||||
# layouts.
|
||||
max_prefix_chars = 2
|
||||
|
||||
@@ -54,7 +54,7 @@ always_wrap = []
|
||||
algorithm_order = [0, 1, 2, 3, 4]
|
||||
|
||||
# If true, the argument lists which are known to be sortable will be sorted
|
||||
# lexicographicall
|
||||
# lexicographically
|
||||
enable_sort = True
|
||||
|
||||
# If true, the parsers may infer whether or not an argument list is sortable
|
||||
|
||||
@@ -24,6 +24,8 @@ This is a list of production adopters of Falco (in alphabetical order):
|
||||
|
||||
* [Coveo](https://www.coveo.com/) - Coveo stitches together content and data, learning from every interaction, to tailor every experience using AI to drive growth, satisfy customers and develop employee proficiency. All Falco events are centralized in our SIEM for analysis. Understanding what is running on production servers, and the context around why things are running is even more tricky now that we have further abstractions with containers and orchestration systems. Falco is giving us a good visibility inside containers and complement other Host and Network Intrusion Detection Systems. In a near future, we expect to deploy serverless functions to take action when Falco identifies patterns worth taking action for.
|
||||
|
||||
* [Fairwinds](https://fairwinds.com/) - [Fairwinds Insights](https://fairwinds.com/insights), Kubernetes governance software, integrates Falco to offer a single pane of glass view into potential security incidents. Insights adds out-of-the-box integrations and rules filter to reduce alert fatigue and improve security response. The platform adds security prevention, detection, and response capabilities to your existing Kubernetes infrastructure. Security and DevOps teams benefit from a centralized view of container security vulnerability scanning and runtime container security.
|
||||
|
||||
* [Frame.io](https://frame.io/) - Frame.io is a cloud-based (SaaS) video review and collaboration platform that enables users to securely upload source media, work-in-progress edits, dailies, and more into private workspaces where they can invite their team and clients to collaborate on projects. Understanding what is running on production servers, and the context around why things are running is even more tricky now that we have further abstractions like Docker and Kubernetes. To get this needed visibility into our system, we rely on Falco. Falco's ability to collect raw system calls such as open, connect, exec, along with their arguments offer key insights on what is happening on the production system and became the foundation of our intrusion detection and alerting system.
|
||||
|
||||
* [Giant Swarm](https://www.giantswarm.io/) - Giant Swarm manages Kubernetes clusters and infrastructure for enterprises across multiple cloud providers as well as several flavors of on-premises data centers. Our platform provisions and monitors pure "vanilla" Kubernetes clusters which can be augmented with managed solutions to many common Kubernetes challenges, including security. We use Falco for anomaly detection as part of our collection of entirely open-source tools for securing our own clusters, and offer the same capabilities to our customers as part of our [managed security offering](https://docs.giantswarm.io/app-platform/apps/security/).
|
||||
@@ -39,10 +41,10 @@ This is a list of production adopters of Falco (in alphabetical order):
|
||||
|
||||
* [Pocteo](https://pocteo.co) - Pocteo helps with Kubernetes adoption in enterprises by providing a variety of services such as training, consulting, auditing and mentoring. We build CI/CD pipelines the GitOps way, as well as design and run k8s clusters. Pocteo uses Falco as a runtime monitoring system to secure clients' workloads against suspicious behavior and ensure k8s pods immutability. We also use Falco to collect, process and act on security events through a response engine and serverless functions.
|
||||
|
||||
* [Preferral](https://www.preferral.com) - Preferral is a HIPAA-compliant platform for Referral Management and Online Referral Forms. Preferral streamlines the referral process for patients, specialists and their referral partners. By automating the referral process, referring practices spend less time on the phone, manual efforts are eliminated, and patients get the right care from the right specialist. Preferral leverages Falco to provide a Host Intrusion Detection System to meet their HIPPA compliance requirements.
|
||||
* [Preferral](https://www.preferral.com) - Preferral is a HIPAA-compliant platform for Referral Management and Online Referral Forms. Preferral streamlines the referral process for patients, specialists and their referral partners. By automating the referral process, referring practices spend less time on the phone, manual efforts are eliminated, and patients get the right care from the right specialist. Preferral leverages Falco to provide a Host Intrusion Detection System to meet their HIPAA compliance requirements.
|
||||
* https://hipaa.preferral.com/01-preferral_hipaa_compliance/
|
||||
|
||||
* [Qonto](https://qonto.com) - Qonto is a modern banking for SMEs and freelancers. Qonto provides a fully featured business account with a simplified accounting flow. Falco is used by our SecOps team to detect suspicous behaviors in our clusters.
|
||||
* [Qonto](https://qonto.com) - Qonto is a modern banking for SMEs and freelancers. Qonto provides a fully featured business account with a simplified accounting flow. Falco is used by our SecOps team to detect suspicious behaviors in our clusters.
|
||||
|
||||
* [Raft](https://goraft.tech) - Raft is a government contractor that offers cloud-native solutions across many different agencies including DoD (Department of Defense), HHS (Health and Human Services), as well as within CFPB (Consumer Finance Protection Bureau). Raft leverages Falco to detect threats in our client's Kubernetes clusters and as a Host Intrusion Detection System. Raft proudly recommends Falco across all our different projects.
|
||||
|
||||
@@ -64,7 +66,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
|
||||
|
||||
|
||||
166
CHANGELOG.md
166
CHANGELOG.md
@@ -1,5 +1,153 @@
|
||||
# Change Log
|
||||
|
||||
## v0.31.1
|
||||
|
||||
Released on 2022-03-09
|
||||
|
||||
### Major Changes
|
||||
|
||||
|
||||
* new: add a new drop category `n_drops_scratch_map` [[#1916](https://github.com/falcosecurity/falco/pull/1916)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* new: allow to specify multiple --cri options [[#1893](https://github.com/falcosecurity/falco/pull/1893)] - [@FedeDP](https://github.com/FedeDP)
|
||||
|
||||
|
||||
### Minor Changes
|
||||
|
||||
* refactor(userspace/falco): replace direct getopt_long() cmdline option parsing with third-party cxxopts library. [[#1886](https://github.com/falcosecurity/falco/pull/1886)] - [@mstemm](https://github.com/mstemm)
|
||||
* update: driver version is b7eb0dd [[#1923](https://github.com/falcosecurity/falco/pull/1923)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix(userspace/falco): correct plugins init config conversion from YAML to JSON [[#1907](https://github.com/falcosecurity/falco/pull/1907)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix(userspace/engine): for rules at the informational level being loaded at the notice level [[#1885](https://github.com/falcosecurity/falco/pull/1885)] - [@mike-stewart](https://github.com/mike-stewart)
|
||||
* chore(userspace/falco): fixes truncated -b option description. [[#1915](https://github.com/falcosecurity/falco/pull/1915)] - [@andreabonanno](https://github.com/andreabonanno)
|
||||
* update(falco): updates usage description for -o, --option [[#1903](https://github.com/falcosecurity/falco/pull/1903)] - [@andreabonanno](https://github.com/andreabonanno)
|
||||
|
||||
### Security Fixes
|
||||
|
||||
* Fix for a TOCTOU issue that could lead to rule bypass (CVE-2022-26316). For more information, see the [advisory](https://github.com/falcosecurity/falco/security/advisories/GHSA-6v9j-2vm2-ghf7).
|
||||
|
||||
### Rule Changes
|
||||
|
||||
* rule(Detect outbound connections to common miner pool ports): fix url in rule output [[#1918](https://github.com/falcosecurity/falco/pull/1918)] - [@jsoref](https://github.com/jsoref)
|
||||
* rule(macro somebody_becoming_themself): renaming macro to somebody_becoming_themselves [[#1918](https://github.com/falcosecurity/falco/pull/1918)] - [@jsoref](https://github.com/jsoref)
|
||||
* rule(list package_mgmt_binaries): `npm` added [[#1866](https://github.com/falcosecurity/falco/pull/1866)] - [@rileydakota](https://github.com/rileydakota)
|
||||
* rule(Launch Package Management Process in Container): support for detecting `npm` usage [[#1866](https://github.com/falcosecurity/falco/pull/1866)] - [@rileydakota](https://github.com/rileydakota)
|
||||
* rule(Polkit Local Privilege Escalation Vulnerability): new rule created to detect CVE-2021-4034 [[#1877](https://github.com/falcosecurity/falco/pull/1877)] - [@darryk10](https://github.com/darryk10)
|
||||
* rule(macro: modify_shell_history): avoid false-positive alerts triggered by modifications to .zsh_history.new and .zsh_history.LOCK files [[#1832](https://github.com/falcosecurity/falco/pull/1832)] - [@m4wh6k](https://github.com/m4wh6k)
|
||||
* rule(macro: truncate_shell_history): avoid false-positive alerts triggered by modifications to .zsh_history.new and .zsh_history.LOCK files [[#1832](https://github.com/falcosecurity/falco/pull/1832)] - [@m4wh6k](https://github.com/m4wh6k)
|
||||
* rule(macro sssd_writing_krb): fixed a false-positive alert that was being generated when SSSD updates /etc/krb5.keytab [[#1825](https://github.com/falcosecurity/falco/pull/1825)] - [@mac-chaffee](https://github.com/mac-chaffee)
|
||||
* rule(macro write_etc_common): fixed a false-positive alert that was being generated when SSSD updates /etc/krb5.keytab [[#1825](https://github.com/falcosecurity/falco/pull/1825)] - [@mac-chaffee](https://github.com/mac-chaffee)
|
||||
* upgrade macro(keepalived_writing_conf) [[#1742](https://github.com/falcosecurity/falco/pull/1742)] - [@pabloopez](https://github.com/pabloopez)
|
||||
* rule_output(Delete Bucket Public Access Block) typo [[#1888](https://github.com/falcosecurity/falco/pull/1888)] - [@pabloopez](https://github.com/pabloopez)
|
||||
|
||||
|
||||
### Non user-facing changes
|
||||
|
||||
* fix(build): fix civetweb linking in cmake module [[#1919](https://github.com/falcosecurity/falco/pull/1919)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* chore(userspace/engine): remove unused lua functions and state vars [[#1908](https://github.com/falcosecurity/falco/pull/1908)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* fix(userspace/falco): applies FALCO_INSTALL_CONF_FILE as the default … [[#1900](https://github.com/falcosecurity/falco/pull/1900)] - [@andreabonanno](https://github.com/andreabonanno)
|
||||
* fix(scripts): correct typo in `falco-driver-loader` help message [[#1899](https://github.com/falcosecurity/falco/pull/1899)] - [@leogr](https://github.com/leogr)
|
||||
* update(build)!: replaced various `PROBE` with `DRIVER` where necessary. [[#1887](https://github.com/falcosecurity/falco/pull/1887)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* Add [Fairwinds](https://fairwinds.com) to the adopters list [[#1917](https://github.com/falcosecurity/falco/pull/1917)] - [@sudermanjr](https://github.com/sudermanjr)
|
||||
* build(cmake): several cmake changes to speed up/simplify builds for external projects and copying files from source-to-build directories [[#1905](https://github.com/falcosecurity/falco/pull/1905)] - [@mstemm](https://github.com/mstemm)
|
||||
|
||||
|
||||
## 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 'falcosecurity/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 content type 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 provided 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
|
||||
@@ -251,8 +399,8 @@ Released on 2021-01-18
|
||||
* docs(proposals): Exceptions handling proposal [[#1376](https://github.com/falcosecurity/falco/pull/1376)] - [@mstemm](https://github.com/mstemm)
|
||||
* docs: fix a broken link of README [[#1516](https://github.com/falcosecurity/falco/pull/1516)] - [@oke-py](https://github.com/oke-py)
|
||||
* docs: adding the kubernetes privileged use case to use cases [[#1484](https://github.com/falcosecurity/falco/pull/1484)] - [@fntlnz](https://github.com/fntlnz)
|
||||
* rules(Mkdir binary dirs): Adds exe_running_docker_save as an exception as this rules can be triggerred when a container is created. [[#1386](https://github.com/falcosecurity/falco/pull/1386)] - [@jhwbarlow](https://github.com/jhwbarlow)
|
||||
* rules(Create Hidden Files): Adds exe_running_docker_save as an exception as this rules can be triggerred when a container is created. [[#1386](https://github.com/falcosecurity/falco/pull/1386)] - [@jhwbarlow](https://github.com/jhwbarlow)
|
||||
* rules(Mkdir binary dirs): Adds exe_running_docker_save as an exception as this rules can be triggered when a container is created. [[#1386](https://github.com/falcosecurity/falco/pull/1386)] - [@jhwbarlow](https://github.com/jhwbarlow)
|
||||
* rules(Create Hidden Files): Adds exe_running_docker_save as an exception as this rules can be triggered when a container is created. [[#1386](https://github.com/falcosecurity/falco/pull/1386)] - [@jhwbarlow](https://github.com/jhwbarlow)
|
||||
* docs(.circleci): welcome Jonah (Amazon) as a new Falco CI maintainer [[#1518](https://github.com/falcosecurity/falco/pull/1518)] - [@leodido](https://github.com/leodido)
|
||||
* build: falcosecurity/falco:master also available on the AWS ECR Public registry [[#1512](https://github.com/falcosecurity/falco/pull/1512)] - [@leodido](https://github.com/leodido)
|
||||
* build: falcosecurity/falco:latest also available on the AWS ECR Public registry [[#1512](https://github.com/falcosecurity/falco/pull/1512)] - [@leodido](https://github.com/leodido)
|
||||
@@ -701,7 +849,7 @@ Released on 2020-01-23
|
||||
### Bug Fixes
|
||||
|
||||
* fix: providing clang into docker-builder [[#972](https://github.com/falcosecurity/falco/pull/972)]
|
||||
* fix: prevent throwing json type error c++ exceptions outside of the falco engine when procesing k8s audit events. [[#928](https://github.com/falcosecurity/falco/pull/928)]
|
||||
* fix: prevent throwing json type error c++ exceptions outside of the falco engine when processing k8s audit events. [[#928](https://github.com/falcosecurity/falco/pull/928)]
|
||||
* fix(docker/kernel/linuxkit): correct from for falco minimal image [[#913](https://github.com/falcosecurity/falco/pull/913)]
|
||||
|
||||
### Rule Changes
|
||||
@@ -816,7 +964,7 @@ Released 2019-07-31
|
||||
|
||||
* Fix a problem that would cause prevent container metadata lookups when falco was daemonized [[#731](https://github.com/falcosecurity/falco/pull/731)]
|
||||
|
||||
* Allow rule priorites to be expressed as lowercase and a mix of lower/uppercase [[#737](https://github.com/falcosecurity/falco/pull/737)]
|
||||
* Allow rule priorities to be expressed as lowercase and a mix of lower/uppercase [[#737](https://github.com/falcosecurity/falco/pull/737)]
|
||||
|
||||
### Rule Changes
|
||||
|
||||
@@ -1011,7 +1159,7 @@ Released 2019-05-13
|
||||
|
||||
* Docker-based builder/tester: You can now build Falco using the [falco-builder](https://falco.org/docs/source/#build-using-falco-builder-container) docker image, and run regression tests using the [falco-tester](https://falco.org/docs/source/#test-using-falco-tester-container) docker image. [[#522](https://github.com/falcosecurity/falco/pull/522)] [[#584](https://github.com/falcosecurity/falco/pull/584)]
|
||||
|
||||
* Several small docs changes to improve clarity and readibility [[#524](https://github.com/falcosecurity/falco/pull/524)] [[#540](https://github.com/falcosecurity/falco/pull/540)] [[#541](https://github.com/falcosecurity/falco/pull/541)] [[#542](https://github.com/falcosecurity/falco/pull/542)]
|
||||
* Several small docs changes to improve clarity and readability [[#524](https://github.com/falcosecurity/falco/pull/524)] [[#540](https://github.com/falcosecurity/falco/pull/540)] [[#541](https://github.com/falcosecurity/falco/pull/541)] [[#542](https://github.com/falcosecurity/falco/pull/542)]
|
||||
|
||||
* Add instructions on how to enable K8s Audit Logging for kops [[#535](https://github.com/falcosecurity/falco/pull/535)]
|
||||
|
||||
@@ -1126,7 +1274,7 @@ Released 2019-01-16
|
||||
|
||||
* Fix FPs related to `apt-config`/`apt-cache`, `apk` [[#490](https://github.com/falcosecurity/falco/pull/490)]
|
||||
|
||||
* New rules `Launch Package Management Process in Container`, `Netcat Remote Code Execution in Container`, `Lauch Suspicious Network Tool in Container` look for host-level network tools like `netcat`, package management tools like `apt-get`, or network tool binaries being run in a container. [[#490](https://github.com/falcosecurity/falco/pull/490)]
|
||||
* New rules `Launch Package Management Process in Container`, `Netcat Remote Code Execution in Container`, `Launch Suspicious Network Tool in Container` look for host-level network tools like `netcat`, package management tools like `apt-get`, or network tool binaries being run in a container. [[#490](https://github.com/falcosecurity/falco/pull/490)]
|
||||
|
||||
* Fix the `inbound` and `outbound` macros so they work with sendto/recvfrom/sendmsg/recvmsg. [[#470](https://github.com/falcosecurity/falco/pull/470)]
|
||||
|
||||
@@ -1159,7 +1307,7 @@ Released 2018-11-09
|
||||
|
||||
* Better coverage (e.g. reduced FPs) for critical stack, hids systems, ufw, cloud-init, etc. [[#445](https://github.com/falcosecurity/falco/pull/445)]
|
||||
|
||||
* New rules `Launch Package Management Process in Container`, `Netcat Remote Code Execution in Container`, and `Lauch Suspicious Network Tool in Container` look for running various suspicious programs in a container. [[#461](https://github.com/falcosecurity/falco/pull/461)]
|
||||
* New rules `Launch Package Management Process in Container`, `Netcat Remote Code Execution in Container`, and `Launch Suspicious Network Tool in Container` look for running various suspicious programs in a container. [[#461](https://github.com/falcosecurity/falco/pull/461)]
|
||||
|
||||
* Misc changes to address false positives in GKE, Istio, etc. [[#455](https://github.com/falcosecurity/falco/pull/455)] [[#439](https://github.com/falcosecurity/falco/issues/439)]
|
||||
|
||||
@@ -1214,7 +1362,7 @@ Released 2018-07-24
|
||||
|
||||
### Minor Changes
|
||||
|
||||
* Rules may now have an `skip-if-unknown-filter` property. If set to true, a rule will be skipped if its condition/output property refers to a filtercheck (e.g. `fd.some-new-attibute`) that is not present in the current falco version. [[#364](https://github.com/draios/falco/pull/364)] [[#345](https://github.com/draios/falco/issues/345)]
|
||||
* Rules may now have an `skip-if-unknown-filter` property. If set to true, a rule will be skipped if its condition/output property refers to a filtercheck (e.g. `fd.some-new-attribute`) that is not present in the current falco version. [[#364](https://github.com/draios/falco/pull/364)] [[#345](https://github.com/draios/falco/issues/345)]
|
||||
* Small changes to Falco `COPYING` file so github automatically recognizes license [[#380](https://github.com/draios/falco/pull/380)]
|
||||
* New example integration showing how to connect Falco with Anchore to dynamically create falco rules based on negative scan results [[#390](https://github.com/draios/falco/pull/390)]
|
||||
* New example integration showing how to connect Falco, [nats](https://nats.io/), and K8s to run flexible "playbooks" based on Falco events [[#389](https://github.com/draios/falco/pull/389)]
|
||||
@@ -1315,7 +1463,7 @@ Released 2017-10-10
|
||||
|
||||
Released 2017-10-10
|
||||
|
||||
**Important**: the location for falco's configuration file has moved from `/etc/falco.yaml` to `/etc/falco/falco.yaml`. The default rules file has moved from `/etc/falco_rules.yaml` to `/etc/falco/falco_rules.yaml`. In addition, 0.8.0 has added a _local_ ruls file to `/etc/falco/falco_rules.local.yaml`. See [the documentation](https://github.com/draios/falco/wiki/Falco-Default-and-Local-Rules-Files) for more details.
|
||||
**Important**: the location for falco's configuration file has moved from `/etc/falco.yaml` to `/etc/falco/falco.yaml`. The default rules file has moved from `/etc/falco_rules.yaml` to `/etc/falco/falco_rules.yaml`. In addition, 0.8.0 has added a _local_ rules file to `/etc/falco/falco_rules.local.yaml`. See [the documentation](https://github.com/draios/falco/wiki/Falco-Default-and-Local-Rules-Files) for more details.
|
||||
|
||||
### Major Changes
|
||||
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -98,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
|
||||
@@ -149,6 +150,8 @@ if(NOT MINIMAL_BUILD)
|
||||
include(civetweb)
|
||||
endif()
|
||||
|
||||
include(cxxopts)
|
||||
|
||||
# Lpeg
|
||||
include(lpeg)
|
||||
|
||||
|
||||
45
README.md
45
README.md
@@ -5,7 +5,7 @@
|
||||
|
||||
[](https://circleci.com/gh/falcosecurity/falco) [](https://bestpractices.coreinfrastructure.org/projects/2317) [](COPYING)
|
||||
|
||||
Want to talk? Join us on the [#falco](https://kubernetes.slack.com/archives/CMWH3EH32) channel in the [Kubernetes Slack](https://slack.k8s.io).
|
||||
Want to talk? Join us on the [#falco](https://kubernetes.slack.com/messages/falco) channel in the [Kubernetes Slack](https://slack.k8s.io).
|
||||
|
||||
### Latest releases
|
||||
|
||||
@@ -58,10 +58,25 @@ Notes:
|
||||
---
|
||||
|
||||
The Falco Project, originally created by [Sysdig](https://sysdig.com), is an incubating [CNCF](https://cncf.io) open source cloud native runtime security tool.
|
||||
Falco makes it easy to consume kernel events, and enrich those events with information from Kubernetes and the rest of the cloud native stack.
|
||||
Falco makes it easy to consume kernel events, and enrich those events with information from Kubernetes and the rest of the cloud native stack.
|
||||
Falco can also be extended to other data sources by using plugins.
|
||||
Falco has a rich set of security rules specifically built for Kubernetes, Linux, and cloud-native.
|
||||
If a rule is violated in a system, Falco will send an alert notifying the user of the violation and its severity.
|
||||
|
||||
### What can Falco detect?
|
||||
|
||||
Falco can detect and alert on any behavior that involves making Linux system calls.
|
||||
Falco alerts can be triggered by the use of specific system calls, their arguments, and by properties of the calling process.
|
||||
For example, Falco can easily detect incidents including but not limited to:
|
||||
|
||||
- A shell is running inside a container or pod in Kubernetes.
|
||||
- A container is running in privileged mode, or is mounting a sensitive path, such as `/proc`, from the host.
|
||||
- A server process is spawning a child process of an unexpected type.
|
||||
- Unexpected read of a sensitive file, such as `/etc/shadow`.
|
||||
- A non-device file is written to `/dev`.
|
||||
- A standard system binary, such as `ls`, is making an outbound network connection.
|
||||
- A privileged pod is started in a Kubernetes cluster.
|
||||
|
||||
### Installing Falco
|
||||
|
||||
If you would like to run Falco in **production** please adhere to the [official installation guide](https://falco.org/docs/getting-started/installation/).
|
||||
@@ -90,20 +105,22 @@ The Falco Project supports various SDKs for this endpoint.
|
||||
| Rust | [client-rs](https://github.com/falcosecurity/client-rs) |
|
||||
| Python | [client-py](https://github.com/falcosecurity/client-py) |
|
||||
|
||||
### Plugins
|
||||
|
||||
### What can Falco detect?
|
||||
Falco comes with a [plugin framework](https://falco.org/docs/plugins/) that extends it to potentially any cloud detection scenario. Plugins are shared libraries that conform to a documented API and allow for:
|
||||
|
||||
Falco can detect and alert on any behavior that involves making Linux system calls.
|
||||
Falco alerts can be triggered by the use of specific system calls, their arguments, and by properties of the calling process.
|
||||
For example, Falco can easily detect incidents including but not limited to:
|
||||
- Adding new event sources that can be used in rules;
|
||||
- Adding the ability to define new fields and extract information from events.
|
||||
|
||||
The Falco Project maintains [various plugins](https://github.com/falcosecurity/plugins) and provides SDKs for plugin development.
|
||||
|
||||
|
||||
##### SDKs
|
||||
|
||||
| Language | Repository |
|
||||
|----------|-------------------------------------------------------------------------------|
|
||||
| Go | [falcosecurity/plugin-sdk-go](https://github.com/falcosecurity/plugin-sdk-go) |
|
||||
|
||||
- A shell is running inside a container or pod in Kubernetes.
|
||||
- A container is running in privileged mode, or is mounting a sensitive path, such as `/proc`, from the host.
|
||||
- A server process is spawning a child process of an unexpected type.
|
||||
- Unexpected read of a sensitive file, such as `/etc/shadow`.
|
||||
- A non-device file is written to `/dev`.
|
||||
- A standard system binary, such as `ls`, is making an outbound network connection.
|
||||
- A privileged pod is started in a Kubernetes cluster.
|
||||
|
||||
### Documentation
|
||||
|
||||
@@ -115,7 +132,7 @@ To get involved with The Falco Project please visit [the community repository](h
|
||||
|
||||
How to reach out?
|
||||
|
||||
- Join the #falco channel on the [Kubernetes Slack](https://slack.k8s.io)
|
||||
- Join the [#falco](https://kubernetes.slack.com/messages/falco) channel on the [Kubernetes Slack](https://slack.k8s.io)
|
||||
- [Join the Falco mailing list](https://lists.cncf.io/g/cncf-falco-dev)
|
||||
- [Read the Falco documentation](https://falco.org/docs/)
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ Now assume `x.y.z` is the new version.
|
||||
|
||||
#### Release Manager <github handle>
|
||||
|
||||
<!-- Substitute Github handle with the release manager's one -->
|
||||
<!-- Substitute GitHub handle with the release manager's one -->
|
||||
```
|
||||
|
||||
- Finally, publish the release!
|
||||
|
||||
@@ -56,7 +56,7 @@ If a rule has been violated, Falco triggers an alert.
|
||||
### How does Falco work?
|
||||
|
||||
Falco traces kernel events and reports information about the system calls being executed at runtime.
|
||||
Falco leverages the extended berkley packet filter (eBPF) which is a kernel feature implemented for dynamic crash-resilient and secure code execution in the kernel.
|
||||
Falco leverages the extended berkeley packet filter (eBPF) which is a kernel feature implemented for dynamic crash-resilient and secure code execution in the kernel.
|
||||
Falco enriches these kernel events with information about containers running on the system.
|
||||
Falco also can consume signals from other input streams such as the containerd socket, the Kubernetes API server and the Kubernetes audit log.
|
||||
At runtime, Falco will reason about these events and assert them against configured security rules.
|
||||
@@ -113,7 +113,7 @@ Falco ultimately is a security engine. It reasons about signals coming from a sy
|
||||
|
||||
##### Anomaly detection
|
||||
|
||||
This refers to an event that occurs with something unsual, concerning, or odd occurs.
|
||||
This refers to an event that occurs with something unusual, concerning, or odd occurs.
|
||||
We can associate anomalies with unwanted behavior, and alert in their presence.
|
||||
|
||||
##### Detection tooling
|
||||
@@ -143,6 +143,10 @@ Sometimes this word is incorrectly used to refer to a `probe`.
|
||||
|
||||
The global term for the software that sends events from the kernel. Such as the eBPF `probe` or the `kernel module`.
|
||||
|
||||
#### Plugin
|
||||
|
||||
Used to describe a dynamic shared library (`.so` files in Unix, `.dll` files in Windows) that conforms to a documented API and allows to extend Falco's capabilities.
|
||||
|
||||
#### Falco
|
||||
|
||||
The name of the project, and also the name of [the main engine](https://github.com/falcosecurity/falco) that the rest of the project is built on.
|
||||
|
||||
@@ -45,7 +45,7 @@ string(REPLACE "\n" ";" output "${output}")
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
set(test ${line})
|
||||
# use escape commas to handle properly test cases with commans inside the name
|
||||
# use escape commas to handle properly test cases with commands inside the name
|
||||
string(REPLACE "," "\\," test_name ${test})
|
||||
# ...and add to script
|
||||
add_command(add_test "${prefix}${test}${suffix}" ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" "${test_name}" ${extra_args})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#
|
||||
|
||||
set(CIVETWEB_SRC "${PROJECT_BINARY_DIR}/civetweb-prefix/src/civetweb/")
|
||||
set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/${CMAKE_INSTALL_LIBDIR}/libcivetweb.a")
|
||||
SET(CIVETWEB_CPP_LIB "${CIVETWEB_SRC}/install/${CMAKE_INSTALL_LIBDIR}/libcivetweb-cpp.a")
|
||||
set(CIVETWEB_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb.a")
|
||||
SET(CIVETWEB_CPP_LIB "${CIVETWEB_SRC}/install/lib/libcivetweb-cpp.a")
|
||||
set(CIVETWEB_INCLUDE_DIR "${CIVETWEB_SRC}/install/include")
|
||||
message(STATUS "Using bundled civetweb in '${CIVETWEB_SRC}'")
|
||||
if (USE_BUNDLED_OPENSSL)
|
||||
@@ -25,6 +25,7 @@ if (USE_BUNDLED_OPENSSL)
|
||||
INSTALL_DIR ${CIVETWEB_SRC}/install
|
||||
CMAKE_ARGS
|
||||
-DBUILD_TESTING=off
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
-DCIVETWEB_BUILD_TESTING=off
|
||||
-DCIVETWEB_ENABLE_CXX=on
|
||||
-DCIVETWEB_ENABLE_SERVER_EXECUTABLE=off
|
||||
|
||||
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 "319368f1ad778691164d33d59945e00c5752cd27")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=2cf44f06a282e8cee7aa1f775a08ea94c06e275faaf0636b21eb06af28cf4b3f")
|
||||
set(FALCOSECURITY_LIBS_VERSION "b7eb0dd65226a8dc254d228c8d950d07bf3521d2")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=0f6dcdc3b94243c91294698ee343806539af81c5b33c60c6acf83fc1aa455e85")
|
||||
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")
|
||||
|
||||
@@ -17,8 +17,8 @@ string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME)
|
||||
|
||||
ExternalProject_Add(
|
||||
cloudtrail-plugin
|
||||
URL "https://download.falco.org/plugins/stable/cloudtrail-0.2.2-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=1628717e48b2ba1b9c78c9081e2ec23e4d88bb1a7b68b12cf8dff7f247b5b9b1"
|
||||
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/stable/json-0.2.1-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||
URL_HASH "SHA256=14d1cf4c3c651af0daec7a45162ef91172d6f0baba787f0eff0227b3cf2ca39c"
|
||||
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)
|
||||
|
||||
@@ -27,7 +27,7 @@ That's where Falco comes in. We want to make it possible for Falco to perform a
|
||||
|
||||
Transparently read a candidate PSP into an equivalent set of Falco rules that can look for the conditions in the PSP.
|
||||
|
||||
The PSP is converted into a set of Falco rules which can be either saved as a file for later use/inspection, or loaded directly so they they can monitor system calls and k8s audit activity.
|
||||
The PSP is converted into a set of Falco rules which can be either saved as a file for later use/inspection, or loaded directly so that they can monitor system calls and k8s audit activity.
|
||||
|
||||
### Non-Goals
|
||||
|
||||
@@ -51,6 +51,6 @@ No diagrams yet.
|
||||
|
||||
* We'll use [inja](https://github.com/pantor/inja) as the templating engine.
|
||||
|
||||
* For the most part, we can rely on the existing framework of rules, filter expressions, and output expressions that already exist in Falco. One significant change will be that filter fields can extract more than one "value" per event, and we'll need to define new operators to perform set comparisions betweeen values in an event and values in the comparison right-hand-side.
|
||||
* For the most part, we can rely on the existing framework of rules, filter expressions, and output expressions that already exist in Falco. One significant change will be that filter fields can extract more than one "value" per event, and we'll need to define new operators to perform set comparisons between values in an event and values in the comparison right-hand-side.
|
||||
|
||||
* This will rely heavily on existing support for [K8s Audit Events](https://falco.org/docs/event-sources/kubernetes-audit/) in Falco.
|
||||
|
||||
@@ -6,13 +6,13 @@ This is a proposal to better structure the Falco API.
|
||||
|
||||
The Falco API is a set of contracts describing how users can interacts with Falco.
|
||||
|
||||
By definiing a set of interfaces the Falco Authors intend to decouple Falco from other softwares and data (eg., from the input sources) and, at the same time, make it more extensible.
|
||||
By defining a set of interfaces the Falco Authors intend to decouple Falco from other softwares and data (eg., from the input sources) and, at the same time, make it more extensible.
|
||||
|
||||
Thus, this document intent is to propose a list of services that contistute the Falco API (targeting the first stable version of Falco, v1.0.0).
|
||||
Thus, this document intent is to propose a list of services that constitute the Falco API (targeting the first stable version of Falco, v1.0.0).
|
||||
|
||||
## Motivation
|
||||
|
||||
We want to enable users to use thirdy-party clients to interface with Falco outputs, inputs, rules, and configurations.
|
||||
We want to enable users to use third-party clients to interface with Falco outputs, inputs, rules, and configurations.
|
||||
|
||||
Such ability would enable the community to create a whole set of OSS tools, built on top of Falco.
|
||||
|
||||
@@ -94,7 +94,7 @@ This translates in having the following set of `proto` files.
|
||||
}
|
||||
```
|
||||
|
||||
- one or more `.proto` containing the commond models - ie., the already existing `schema.proto` containing source enum, etc.
|
||||
- one or more `.proto` containing the command models - ie., the already existing `schema.proto` containing source enum, etc.
|
||||
|
||||
```proto3
|
||||
# schema.proto
|
||||
|
||||
@@ -36,7 +36,7 @@ There will be no intention to cover Falco rule syntax in this proposal.
|
||||
|
||||
### Use cases
|
||||
|
||||
When new PRs are created in the area of rules, reviewers need to examine whether there are new rules, macros or lists are introduced. If yes, check wether follow the naming convention.
|
||||
When new PRs are created in the area of rules, reviewers need to examine whether there are new rules, macros or lists are introduced. If yes, check whether follow the naming convention.
|
||||
|
||||
### Diagrams
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ This is done as needed, and can best be measured by the need to cut a release an
|
||||
|
||||
### official support
|
||||
|
||||
As the need for a project grows, it can ultimately achieve the highest and most coveted status within The Falco Project. "_Offical support_."
|
||||
As the need for a project grows, it can ultimately achieve the highest and most coveted status within The Falco Project. "_Official support_."
|
||||
|
||||
The artifacts listed above are part of the official Falco release process. These artifact will be refined and amended by the [Part 2](./20200506-artifacts-scope-part-2.md).
|
||||
|
||||
@@ -111,4 +111,4 @@ Update documentation in [falco-website#184](https://github.com/falcosecurity/fal
|
||||
### Adjusting projects
|
||||
|
||||
- YAML manifest documentation to be moved to `contrib`
|
||||
- Minkube, Kind, Puppet, Ansible, etc documentation to be moved to `contrib`
|
||||
- Minikube, Kind, Puppet, Ansible, etc documentation to be moved to `contrib`
|
||||
|
||||
@@ -196,13 +196,13 @@ Exception values will most commonly be defined in rules with append: true. Here'
|
||||
|
||||
A rule exception applies if for a given event, the fields in a rule.exception match all of the values in some exception.item. For example, if a program `apk` writes to a file below `/usr/lib/alpine`, the rule will not trigger, even if the condition is met.
|
||||
|
||||
Notice that an item in a values list can be a list. This allows building exceptions with operators like "in", "pmatch", etc. that work on a list of items. The item can also be a name of an existing list. If not present surrounding parantheses will be added.
|
||||
Notice that an item in a values list can be a list. This allows building exceptions with operators like "in", "pmatch", etc. that work on a list of items. The item can also be a name of an existing list. If not present surrounding parentheses will be added.
|
||||
|
||||
Finally, note that the structure of the values property differs between the items where fields is a list of fields (proc_writer/container_writer/proc_filenames) and when it is a single field (procs_only). This changes how the condition snippet is constructed.
|
||||
|
||||
### Implementation
|
||||
|
||||
For exception items where the fields property is a list of field names, each exception can be thought of as an implicit "and not (field1 cmp1 val1 and field2 cmp2 val2 and...)" appended to the rule's condition. For exception items where the fields property is a single field name, the exception can be thought of as an implict "and not field cmp (val1, val2, ...)". In practice, that's how exceptions will be implemented.
|
||||
For exception items where the fields property is a list of field names, each exception can be thought of as an implicit "and not (field1 cmp1 val1 and field2 cmp2 val2 and...)" appended to the rule's condition. For exception items where the fields property is a single field name, the exception can be thought of as an implicit "and not field cmp (val1, val2, ...)". In practice, that's how exceptions will be implemented.
|
||||
|
||||
When a rule is parsed, the original condition will be wrapped in an extra layer of parentheses and all exception values will be appended to the condition. For example, using the example above, the resulting condition will be:
|
||||
|
||||
@@ -214,7 +214,7 @@ When a rule is parsed, the original condition will be wrapped in an extra layer
|
||||
(fd.filename in (python, go))))
|
||||
```
|
||||
|
||||
The exceptions are effectively syntatic sugar that allows expressing sets of exceptions in a concise way.
|
||||
The exceptions are effectively syntactic sugar that allows expressing sets of exceptions in a concise way.
|
||||
|
||||
### Advantages
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document reflects when and how we clean up the Falco artifacts from their storage location.
|
||||
|
||||
**Superseeded by**: [drivers-storage-s3 proposal](https://github.com/falcosecurity/falco/blob/master/proposals/20201025-drivers-storage-s3.md).
|
||||
**Superseded by**: [drivers-storage-s3 proposal](https://github.com/falcosecurity/falco/blob/master/proposals/20201025-drivers-storage-s3.md).
|
||||
|
||||
## Motivation
|
||||
|
||||
@@ -90,7 +90,7 @@ This way, assuming the number of prebuilt drivers does not skyrocket, we can rea
|
||||
|
||||
Notice that, in case a Falco stable release will not depend on a new driver version, this means the last two driver versions will, in this case, cover more than the two Falco stable releases.
|
||||
|
||||
### Archivation
|
||||
### Archiving
|
||||
|
||||
Since the process of building drivers is time and resource consuming, this document also proposes to move the driver versions in other storage facilities.
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ Source plugins also provide an "id", which is globally unique and is used in cap
|
||||
|
||||
An extractor plugin focuses only on field extraction from events generated by other plugins, or by the core libraries. It does *not* provide an event source, but can extract fields from other event sources. An example is json field extraction, where a plugin might be able to extract fields from arbitrary json payloads.
|
||||
|
||||
An extractor plugin provides an optional set of event sources. When the framework receives an event with an event source in the plugin's set of event sources, fields in expressions/Falco outputs will be extracted from events using the plugin. An extractor plugin can also *not* name a set of event sources. In this case, fields will be extracted from *all* events, regardless of source. In this case, the exctractor plugin must detect the format of arbitrary payloads and be able to return NULL/no value when the payload is not supported.
|
||||
An extractor plugin provides an optional set of event sources. When the framework receives an event with an event source in the plugin's set of event sources, fields in expressions/Falco outputs will be extracted from events using the plugin. An extractor plugin can also *not* name a set of event sources. In this case, fields will be extracted from *all* events, regardless of source. In this case, the extractor plugin must detect the format of arbitrary payloads and be able to return NULL/no value when the payload is not supported.
|
||||
|
||||
### Support for Plugin Events in Capture Files.
|
||||
|
||||
@@ -91,7 +91,7 @@ The libraries will do everything possible to validate the data coming from the p
|
||||
|
||||
### Plugin/Event Source registries
|
||||
|
||||
Every source plugin requires its own, unique plugin ID to interoperate with Falco and the other plugins. The plugin ID will be used by the libs to properly process incoming events (for example, when saving events to file and loading them back), and by plugins to unuambiguosly recognize their dependencies.
|
||||
Every source plugin requires its own, unique plugin ID to interoperate with Falco and the other plugins. The plugin ID will be used by the libs to properly process incoming events (for example, when saving events to file and loading them back), and by plugins to unambiguously recognize their dependencies.
|
||||
|
||||
To facilitate the allocation and distribution of plugin IDs, we will require that plugin developers request IDs for their plugins to the Falco organization. The mechanism used for plugin allocation is not determined yet and will be discussed in the future.
|
||||
|
||||
@@ -474,7 +474,7 @@ typedef struct
|
||||
// Return value: a json array of strings containing event
|
||||
// sources returned by a source plugin's get_event_source()
|
||||
// function.
|
||||
// This function is optional--if NULL then the exctractor
|
||||
// This function is optional--if NULL then the extractor
|
||||
// plugin will receive every event.
|
||||
//
|
||||
char* (*get_extract_event_sources)();
|
||||
@@ -526,7 +526,7 @@ We will also make a change to compile rules/macros/lists selectively based on th
|
||||
|
||||
### Handling Duplicate/Overlapping Fields in Plugins/Libraries Core
|
||||
|
||||
At an initial glance, adding plugins introduces the possibility of tens/hundreds of new filtercheck fields that could potentially overlap/conflict. For example, what happens if a plugin defines a "proc.name" field? However, the notion of "event source" makes these potential conflicts managable.
|
||||
At an initial glance, adding plugins introduces the possibility of tens/hundreds of new filtercheck fields that could potentially overlap/conflict. For example, what happens if a plugin defines a "proc.name" field? However, the notion of "event source" makes these potential conflicts manageable.
|
||||
|
||||
Remember that field extraction is always done in the context of an event, and each event can be mapped back to an event source. So we only need to ensure that filtercheck fields are distinct for a given event source. For example, it's perfectly valid for an AWS Cloudtrail plugin to define a proc.name field, as the events generated by that plugin are wholly separate from syscall events. For syscall events, the AWS Cloudtrail plugin is not involved and the core libraries extract the process name for the tid performing a syscall. For AWS Cloudtrail events, the core libraries are not involved in field extraction and is performed by the AWS Cloudtrail plugin instead.
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
# anything semver-compatible.
|
||||
- required_plugin_versions:
|
||||
- name: cloudtrail
|
||||
version: 0.2.2
|
||||
version: 0.2.3
|
||||
- name: json
|
||||
version: 0.2.1
|
||||
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
|
||||
@@ -335,13 +335,13 @@
|
||||
desc: Detect deleting blocking public access to bucket.
|
||||
condition:
|
||||
ct.name="PutBucketPublicAccessBlock" and not ct.error exists and
|
||||
json.value[/requestParameters/publicAccessBlock]='""' and
|
||||
json.value[/requestParameters/publicAccessBlock]="" and
|
||||
(json.value[/requestParameters/PublicAccessBlockConfiguration/RestrictPublicBuckets]=false or
|
||||
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicPolicy]=false or
|
||||
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,
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
# 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)
|
||||
@@ -443,6 +443,9 @@
|
||||
- list: shell_config_directories
|
||||
items: [/etc/zsh]
|
||||
|
||||
- macro: user_known_shell_config_modifiers
|
||||
condition: (never_true)
|
||||
|
||||
- rule: Modify Shell Configuration File
|
||||
desc: Detect attempt to modify shell configuration files
|
||||
condition: >
|
||||
@@ -452,6 +455,7 @@
|
||||
fd.directory in (shell_config_directories))
|
||||
and not proc.name in (shell_binaries)
|
||||
and not exe_running_docker_save
|
||||
and not user_known_shell_config_modifiers
|
||||
output: >
|
||||
a shell configuration file has been modified (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline pcmdline=%proc.pcmdline file=%fd.name container_id=%container.id image=%container.image.repository)
|
||||
priority:
|
||||
@@ -564,7 +568,7 @@
|
||||
|
||||
# Qualys seems to run a variety of shell subprocesses, at various
|
||||
# levels. This checks at a few levels without the cost of a full
|
||||
# proc.aname, which traverses the full parent heirarchy.
|
||||
# proc.aname, which traverses the full parent hierarchy.
|
||||
- macro: run_by_qualys
|
||||
condition: >
|
||||
(proc.pname=qualys-cloud-ag or
|
||||
@@ -775,6 +779,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)
|
||||
@@ -1103,7 +1110,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)
|
||||
@@ -1218,6 +1225,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
|
||||
@@ -2189,7 +2197,7 @@
|
||||
# output: "sshd sent error message to syslog (error=%evt.buffer)"
|
||||
# priority: WARNING
|
||||
|
||||
- macro: somebody_becoming_themself
|
||||
- macro: somebody_becoming_themselves
|
||||
condition: ((user.name=nobody and evt.arg.uid=nobody) or
|
||||
(user.name=www-data and evt.arg.uid=www-data) or
|
||||
(user.name=_apt and evt.arg.uid=_apt) or
|
||||
@@ -2227,7 +2235,7 @@
|
||||
evt.type=setuid and evt.dir=>
|
||||
and (known_user_in_container or not container)
|
||||
and not (user.name=root or user.uid=0)
|
||||
and not somebody_becoming_themself
|
||||
and not somebody_becoming_themselves
|
||||
and not proc.name in (known_setuid_binaries, userexec_binaries, mail_binaries, docker_binaries,
|
||||
nomachine_binaries)
|
||||
and not proc.name startswith "runc:"
|
||||
@@ -2251,7 +2259,7 @@
|
||||
activity by any programs that can manage users, passwords, or permissions. sudo and su are excluded.
|
||||
Activity in containers is also excluded--some containers create custom users on top
|
||||
of a base linux distribution at startup.
|
||||
Some innocuous commandlines that don't actually change anything are excluded.
|
||||
Some innocuous command lines that don't actually change anything are excluded.
|
||||
condition: >
|
||||
spawned_process and proc.name in (user_mgmt_binaries) and
|
||||
not proc.name in (su, sudo, lastlog, nologin, unix_chkpwd) and not container and
|
||||
@@ -2301,7 +2309,7 @@
|
||||
# explicitly enumerate the container images that you want to allow
|
||||
# access to EC2 metadata. In this main falco rules file, there isn't
|
||||
# any way to know all the containers that should have access, so any
|
||||
# container is alllowed, by repeating the "container" macro. In the
|
||||
# container is allowed, by repeating the "container" macro. In the
|
||||
# overridden macro, the condition would look something like
|
||||
# (container.image.repository = vendor/container-1 or
|
||||
# container.image.repository = vendor/container-2 or ...)
|
||||
@@ -2564,15 +2572,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"))
|
||||
|
||||
@@ -2580,7 +2588,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")
|
||||
|
||||
@@ -2619,7 +2627,7 @@
|
||||
items: [hyperkube, kubelet, k3s-agent]
|
||||
|
||||
# This macro should be overridden in user rules as needed. This is useful if a given application
|
||||
# should not be ignored alltogether with the user_known_chmod_applications list, but only in
|
||||
# should not be ignored altogether with the user_known_chmod_applications list, but only in
|
||||
# specific conditions.
|
||||
- macro: user_known_set_setuid_or_setgid_bit_conditions
|
||||
condition: (never_true)
|
||||
@@ -2814,7 +2822,7 @@
|
||||
desc: Miners typically connect to miner pools on common ports.
|
||||
condition: net_miner_pool and not trusted_images_query_miner_domain_dns
|
||||
enabled: false
|
||||
output: Outbound connection to IP/Port flagged by cryptoioc.ch (command=%proc.cmdline port=%fd.rport ip=%fd.rip container=%container.info image=%container.image.repository)
|
||||
output: Outbound connection to IP/Port flagged by https://cryptoioc.ch (command=%proc.cmdline port=%fd.rport ip=%fd.rip container=%container.info image=%container.image.repository)
|
||||
priority: CRITICAL
|
||||
tags: [network, mitre_execution]
|
||||
|
||||
@@ -3057,13 +3065,17 @@
|
||||
- macro: mount_info
|
||||
condition: (proc.args="" or proc.args intersects ("-V", "-l", "-h"))
|
||||
|
||||
- macro: user_known_mount_in_privileged_containers
|
||||
condition: (never_true)
|
||||
|
||||
- rule: Mount Launched in Privileged Container
|
||||
desc: Detect file system mount happened inside a privilegd container which might lead to container escape.
|
||||
desc: Detect file system mount happened inside a privileged container which might lead to container escape.
|
||||
condition: >
|
||||
spawned_process and container
|
||||
and container.privileged=true
|
||||
and proc.name=mount
|
||||
and not mount_info
|
||||
and not user_known_mount_in_privileged_containers
|
||||
output: Mount was executed inside a privileged container (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag)
|
||||
priority: WARNING
|
||||
tags: [container, cis, mitre_lateral_movement]
|
||||
@@ -3120,7 +3132,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.
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@
|
||||
tags: [k8s]
|
||||
|
||||
# Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
|
||||
# (exapand this to any built-in cluster role that does "sensitive" things)
|
||||
# (expand this to any built-in cluster role that does "sensitive" things)
|
||||
- rule: Attach to cluster-admin Role
|
||||
desc: Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
|
||||
condition: kevt and clusterrolebinding and kcreate and ka.req.binding.role=cluster-admin
|
||||
@@ -572,7 +572,7 @@
|
||||
# cluster creation. This may signify a permission setting too broader.
|
||||
# As we can't check for role of the user on a general ka.* event, this
|
||||
# may or may not be an administrator. Customize the full_admin_k8s_users
|
||||
# list to your needs, and activate at your discrection.
|
||||
# list to your needs, and activate at your discretion.
|
||||
|
||||
# # How to test:
|
||||
# # Execute any kubectl command connected using default cluster user, as:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -514,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 ""
|
||||
@@ -547,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)
|
||||
|
||||
@@ -71,7 +71,7 @@ The `falco_traces.yaml` test suite gets generated through the `falco_traces.yaml
|
||||
|
||||
### falco_tests_package
|
||||
|
||||
The `falco_tests_package.yaml` test suite requires some additional setup steps to be succesfully run on your local machine.
|
||||
The `falco_tests_package.yaml` test suite requires some additional setup steps to be successfully run on your local machine.
|
||||
|
||||
In particular, it requires some runners (ie., docker images) to be already built and present into your local machine.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ trace_files: !mux
|
||||
- not_equals_after_evttype: [execve]
|
||||
- not_after_evttype: [execve]
|
||||
- leading_trailing_evttypes: [execve,open]
|
||||
- leading_multtrailing_evttypes: [connect,execve,open]
|
||||
- leading_multtrailing_evttypes_using_in: [connect,execve,open]
|
||||
- leading_multitrailing_evttypes: [connect,execve,open]
|
||||
- leading_multitrailing_evttypes_using_in: [connect,execve,open]
|
||||
- not_equals_at_end: [all]
|
||||
- not_at_end: [all]
|
||||
- not_before_trailing_evttype: [all]
|
||||
|
||||
@@ -54,21 +54,21 @@ trace_files: !mux
|
||||
|
||||
multiple_source_plugins:
|
||||
exit_status: 1
|
||||
stderr_contains: "Runtime error: Can not load multiple source plugins. cloudtrail already loaded. Exiting."
|
||||
stderr_contains: "Can not load multiple source plugins. cloudtrail already loaded."
|
||||
conf_file: BUILD_DIR/test/confs/plugins/multiple_source_plugins.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances.yaml
|
||||
|
||||
incompatible_extract_sources:
|
||||
exit_status: 1
|
||||
stderr_contains: "Runtime error: Extractor plugin not compatible with event source aws_cloudtrail. Exiting."
|
||||
stderr_contains: "Extractor plugin not compatible with event source aws_cloudtrail."
|
||||
conf_file: BUILD_DIR/test/confs/plugins/incompatible_extract_sources.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances.yaml
|
||||
|
||||
overlap_extract_sources:
|
||||
exit_status: 1
|
||||
stderr_contains: "Runtime error: Extractor plugins have overlapping compatible event source test_source. Exiting."
|
||||
stderr_contains: "Extractor plugins have overlapping compatible event source test_source."
|
||||
conf_file: BUILD_DIR/test/confs/plugins/overlap_extract_sources.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances.yaml
|
||||
@@ -82,7 +82,7 @@ trace_files: !mux
|
||||
|
||||
incompat_plugin_rules_version:
|
||||
exit_status: 1
|
||||
stderr_contains: "Runtime error: Plugin cloudtrail version .* not compatible with required plugin version 100000.0.0. Exiting."
|
||||
stderr_contains: "Plugin cloudtrail version .* not compatible with required plugin version 100000.0.0."
|
||||
conf_file: BUILD_DIR/test/confs/plugins/cloudtrail_json_create_instances.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_incompat_plugin_version.yaml
|
||||
@@ -103,4 +103,20 @@ trace_files: !mux
|
||||
- Cloudtrail Create Instance
|
||||
stderr_contains: "Rule Cloudtrail Create Instance: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
no_plugins_unknown_source_macro:
|
||||
detect: False
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_macro.yaml
|
||||
trace_file: trace_files/empty.scap
|
||||
stderr_contains: "Macro Some Cloudtrail Macro: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
no_plugins_unknown_source_rule_exception:
|
||||
detect: False
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances_exceptions.yaml
|
||||
trace_file: trace_files/empty.scap
|
||||
rules_warning:
|
||||
- Cloudtrail Create Instance
|
||||
stderr_contains: "Rule Cloudtrail Create Instance: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
output: "None"
|
||||
priority: WARNING
|
||||
|
||||
- rule: leading_multtrailing_evttypes
|
||||
- rule: leading_multitrailing_evttypes
|
||||
desc: one evttype at beginning, multiple at end
|
||||
condition: evt.type=execve and proc.name=foo or evt.type=open or evt.type=connect
|
||||
output: "None"
|
||||
priority: WARNING
|
||||
|
||||
- rule: leading_multtrailing_evttypes_using_in
|
||||
- rule: leading_multitrailing_evttypes_using_in
|
||||
desc: one evttype at beginning, multiple at end, using in
|
||||
condition: evt.type=execve and proc.name=foo or evt.type in (open, connect)
|
||||
output: "None"
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
tags: [k8s]
|
||||
|
||||
# Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
|
||||
# (exapand this to any built-in cluster role that does "sensitive" things)
|
||||
# (expand this to any built-in cluster role that does "sensitive" things)
|
||||
- rule: Attach to cluster-admin Role
|
||||
desc: Detect any attempt to create a ClusterRoleBinding to the cluster-admin user
|
||||
condition: kevt and clusterrolebinding and kcreate and ka.req.binding.role=cluster-admin
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
- rule: Cloudtrail Create Instance
|
||||
desc: Detect Creating an EC2 Instance
|
||||
condition: evt.num > 0 and ct.name="StartInstances"
|
||||
output: EC2 Instance Created (evtnum=%evt.num info=%evt.plugininfo id=%ct.id user name=%json.value[/userIdentity/userName])
|
||||
exceptions:
|
||||
- name: user_secreid
|
||||
fields: [aws.user, aws.region]
|
||||
priority: INFO
|
||||
source: aws_cloudtrail
|
||||
4
test/rules/plugins/cloudtrail_macro.yaml
Normal file
4
test/rules/plugins/cloudtrail_macro.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
- macro: Some Cloudtrail Macro
|
||||
condition: aws.user=bob
|
||||
source: aws_cloudtrail
|
||||
|
||||
@@ -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 <algorithm>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ static std::string fieldclass_key(const gen_event_filter_factory::filter_fieldcl
|
||||
return fld_info.name + fld_info.shortdesc;
|
||||
}
|
||||
|
||||
void falco_engine::list_fields(std::string &source, bool verbose, bool names_only)
|
||||
void falco_engine::list_fields(std::string &source, bool verbose, bool names_only, bool markdown)
|
||||
{
|
||||
// Maps from field class name + short desc to list of event
|
||||
// sources for which this field class can be used.
|
||||
@@ -126,12 +126,7 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
|
||||
|
||||
seen_fieldclasses.insert(key);
|
||||
|
||||
if(!names_only)
|
||||
{
|
||||
printf("%s\n", fld_class.as_string(verbose,
|
||||
fieldclass_event_sources[fieldclass_key(fld_class)]).c_str());
|
||||
}
|
||||
else
|
||||
if(names_only)
|
||||
{
|
||||
for(auto &field : fld_class.fields)
|
||||
{
|
||||
@@ -144,6 +139,16 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
|
||||
printf("%s\n", field.name.c_str());
|
||||
}
|
||||
}
|
||||
else if (markdown)
|
||||
{
|
||||
printf("%s\n", fld_class.as_markdown(
|
||||
fieldclass_event_sources[fieldclass_key(fld_class)]).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s\n", fld_class.as_string(verbose,
|
||||
fieldclass_event_sources[fieldclass_key(fld_class)]).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,7 +392,7 @@ void falco_engine::describe_rule(string *rule)
|
||||
return m_rules->describe_rule(rule);
|
||||
}
|
||||
|
||||
// Print statistics on the the rules that triggered
|
||||
// Print statistics on the rules that triggered
|
||||
void falco_engine::print_stats()
|
||||
{
|
||||
lua_getglobal(m_ls, lua_print_stats.c_str());
|
||||
@@ -420,7 +425,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)
|
||||
@@ -432,7 +437,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)
|
||||
{
|
||||
@@ -447,13 +452,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;
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
// Print to stdout (using printf) a description of each field supported by this engine.
|
||||
// If source is non-empty, only fields for the provided source are printed.
|
||||
void list_fields(std::string &source, bool verbose, bool names_only);
|
||||
void list_fields(std::string &source, bool verbose, bool names_only, bool markdown);
|
||||
|
||||
//
|
||||
// Load rules either directly or from a filename.
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -278,7 +278,7 @@ private:
|
||||
// events. See alias struct for usage.
|
||||
std::list<nlohmann::json::json_pointer> m_jptrs;
|
||||
|
||||
// Theextraction function to use. May not be defined, in which
|
||||
// The extraction function to use. May not be defined, in which
|
||||
// case the default function is used.
|
||||
extract_t m_extract;
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ end
|
||||
The AST is changed in-place.
|
||||
|
||||
The return value is a boolean which is true if any macro was
|
||||
substitued. This allows a caller to re-traverse until no more macros are
|
||||
found, a simple strategy for recursive resoltuions (e.g. when a macro
|
||||
substituted. This allows a caller to re-traverse until no more macros are
|
||||
found, a simple strategy for recursive resolutions (e.g. when a macro
|
||||
definition uses another macro).
|
||||
|
||||
--]]
|
||||
@@ -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 = {}
|
||||
|
||||
@@ -57,7 +57,7 @@ local function geterrorinfo()
|
||||
end
|
||||
end
|
||||
|
||||
-- creates an errror message using the farthest failure position
|
||||
-- creates an error message using the farthest failure position
|
||||
local function errormsg()
|
||||
return geterrorinfo() / function(t)
|
||||
local p = t.ffp or 1
|
||||
|
||||
@@ -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={}}
|
||||
|
||||
@@ -471,6 +460,14 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
||||
v['source'] = "syscall"
|
||||
end
|
||||
|
||||
valid = falco_rules.is_source_valid(rules_mgr, v['source'])
|
||||
|
||||
if valid == false then
|
||||
msg = "Macro "..v['macro']..": warning (unknown-source): unknown source "..v['source']..", skipping"
|
||||
warnings[#warnings + 1] = msg
|
||||
goto next_object
|
||||
end
|
||||
|
||||
if state.macros_by_name[v['macro']] == nil then
|
||||
state.ordered_macro_names[#state.ordered_macro_names+1] = v['macro']
|
||||
end
|
||||
@@ -553,6 +550,14 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
||||
v['source'] = "syscall"
|
||||
end
|
||||
|
||||
valid = falco_rules.is_source_valid(rules_mgr, v['source'])
|
||||
|
||||
if valid == false then
|
||||
msg = "Rule "..v['rule']..": warning (unknown-source): unknown source "..v['source']..", skipping"
|
||||
warnings[#warnings + 1] = msg
|
||||
goto next_object
|
||||
end
|
||||
|
||||
-- Add an empty exceptions property to the rule if not defined
|
||||
if v['exceptions'] == nil then
|
||||
v['exceptions'] = {}
|
||||
@@ -620,7 +625,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
||||
return false, build_error_with_context(v['context'], "Rule exception item must have name property"), warnings
|
||||
end
|
||||
|
||||
-- Seperate case when a exception name is not found
|
||||
-- Separate case when a exception name is not found
|
||||
-- This means that a new exception is being appended
|
||||
|
||||
local new_exception = true
|
||||
@@ -746,6 +751,8 @@ function load_rules_doc(rules_mgr, doc, load_state)
|
||||
arr = build_error_with_context(context, "Unknown top level object: "..table.tostring(v))
|
||||
warnings[#warnings + 1] = arr[1]
|
||||
end
|
||||
|
||||
::next_object::
|
||||
end
|
||||
|
||||
return true, {}, warnings
|
||||
@@ -1019,14 +1026,6 @@ function load_rules(rules_content,
|
||||
|
||||
if (filter_ast.type == "Rule") then
|
||||
|
||||
valid = falco_rules.is_source_valid(rules_mgr, v['source'])
|
||||
|
||||
if valid == false then
|
||||
msg = "Rule "..v['rule']..": warning (unknown-source): unknown source "..v['source']..", skipping"
|
||||
warnings[#warnings + 1] = msg
|
||||
goto next_rule
|
||||
end
|
||||
|
||||
state.n_rules = state.n_rules + 1
|
||||
|
||||
state.rules_by_idx[state.n_rules] = v
|
||||
@@ -1067,14 +1066,6 @@ function load_rules(rules_content,
|
||||
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,11 +66,8 @@ 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();
|
||||
|
||||
// TODO: who fills this one for rules without evt.type specified?
|
||||
// Can this be actually empty?
|
||||
// Is m_filter_all_event_types useful?
|
||||
if(fevttypes.empty())
|
||||
{
|
||||
// Should run for all event types
|
||||
@@ -94,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())
|
||||
{
|
||||
@@ -121,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)
|
||||
@@ -152,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 workaround, 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,33 @@ 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/easyopts_action.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 +60,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 +74,7 @@ set(
|
||||
luajit
|
||||
lpeg
|
||||
lyaml
|
||||
cxxopts
|
||||
)
|
||||
|
||||
set(
|
||||
@@ -127,6 +156,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_cmdline_options.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 or have ways to advertise what state
|
||||
// an action manages. 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
|
||||
163
userspace/falco/app_action_manager.cpp
Normal file
163
userspace/falco/app_action_manager.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
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>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
runnable_action::run_result action_manager::run()
|
||||
{
|
||||
runnable_action::run_result res;
|
||||
|
||||
sort_groups();
|
||||
res = run_groups();
|
||||
deinit_groups();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void action_manager::sort_groups()
|
||||
{
|
||||
for(auto &group : m_groups)
|
||||
{
|
||||
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);
|
||||
|
||||
m_actions_ordered[group] = std::move(actions_ordered);
|
||||
}
|
||||
}
|
||||
|
||||
runnable_action::run_result action_manager::run_groups()
|
||||
{
|
||||
runnable_action::run_result res;
|
||||
|
||||
for(auto &group : m_groups)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Running group ") + group);
|
||||
|
||||
for(auto &act : m_actions_ordered[group])
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Running action ") + act->name());
|
||||
|
||||
res = act->run();
|
||||
|
||||
if(!res.success)
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Could not complete ") + act->name() + " : " + res.errstr);
|
||||
}
|
||||
|
||||
if(!res.proceed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!res.proceed)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void action_manager::deinit_groups()
|
||||
{
|
||||
for(auto &group : m_groups)
|
||||
{
|
||||
for(auto &act : m_actions_ordered[group])
|
||||
{
|
||||
falco_logger::log(LOG_DEBUG, string("Deinitializing action ") + act->name());
|
||||
|
||||
act->deinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
67
userspace/falco/app_action_manager.h
Normal file
67
userspace/falco/app_action_manager.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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 <list>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
// This class manages a set of actions, ensuring that they run in an
|
||||
// order that honors their dependencies, groups 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);
|
||||
|
||||
runnable_action::run_result run();
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<std::shared_ptr<runnable_action>> ordered_actions_t;
|
||||
|
||||
void sort_groups();
|
||||
runnable_action::run_result run_groups();
|
||||
void deinit_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::list<std::string> m_groups;
|
||||
std::map<std::string, std::shared_ptr<runnable_action>> m_actions;
|
||||
std::map<std::string, ordered_actions_t> m_actions_ordered;
|
||||
};
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
99
userspace/falco/app_actions/create_signal_handlers.cpp
Normal file
99
userspace/falco/app_actions/create_signal_handlers.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
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];
|
||||
|
||||
if (strerror_r(errno, errbuf, sizeof(errbuf)) != 0)
|
||||
{
|
||||
snprintf(errbuf, sizeof(errbuf)-1, "Errno %d", errno);
|
||||
}
|
||||
|
||||
ret.success = false;
|
||||
ret.errstr = std::string("Could not create signal handler for ") +
|
||||
strsignal(sig) +
|
||||
": " +
|
||||
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/easyopts_action.cpp
Normal file
40
userspace/falco/app_actions/easyopts_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 "easyopts_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
static std::string easyopts_group = "easyopts";
|
||||
|
||||
easyopts_action::easyopts_action(application &app)
|
||||
: action(app)
|
||||
{
|
||||
}
|
||||
|
||||
easyopts_action::~easyopts_action()
|
||||
{
|
||||
}
|
||||
|
||||
const std::string &easyopts_action::group()
|
||||
{
|
||||
return easyopts_group;
|
||||
}
|
||||
|
||||
}; // namespace application
|
||||
}; // namespace falco
|
||||
|
||||
37
userspace/falco/app_actions/easyopts_action.h
Normal file
37
userspace/falco/app_actions/easyopts_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 "easyopts" group derive from this class
|
||||
|
||||
class easyopts_action : public action {
|
||||
public:
|
||||
easyopts_action(application &app);
|
||||
virtual ~easyopts_action();
|
||||
|
||||
const std::string &group() override;
|
||||
};
|
||||
|
||||
}; // 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 "init_action.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", "load config"})
|
||||
{
|
||||
}
|
||||
|
||||
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_additional == "c" || options().print_additional == "container")
|
||||
{
|
||||
output_format = "container=%container.name (id=%container.id)";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(options().print_additional == "k" || options().print_additional == "kubernetes")
|
||||
{
|
||||
output_format = "k8s.ns=%k8s.ns.name k8s.pod=%k8s.pod.name container=%container.id";
|
||||
replace_container_info = true;
|
||||
}
|
||||
else if(options().print_additional == "m" || options().print_additional == "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
|
||||
|
||||
138
userspace/falco/app_actions/init_inspector.cpp
Normal file
138
userspace/falco/app_actions/init_inspector.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
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"),
|
||||
m_prerequsites({"load config"})
|
||||
{
|
||||
}
|
||||
|
||||
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 whether 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
|
||||
|
||||
74
userspace/falco/app_actions/list_fields.cpp
Normal file
74
userspace/falco/app_actions/list_fields.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
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 <fields_info.h>
|
||||
|
||||
#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, options().markdown);
|
||||
|
||||
ret.proceed = false;
|
||||
}
|
||||
else if(app().options().list_syscall_events)
|
||||
{
|
||||
list_events(app().state().inspector.get(), app().options().markdown);
|
||||
|
||||
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
|
||||
|
||||
144
userspace/falco/app_actions/load_plugins.cpp
Normal file
144
userspace/falco/app_actions/load_plugins.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
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};
|
||||
|
||||
// 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(), m_plugin_filter_checks));
|
||||
std::shared_ptr<gen_event_formatter_factory> plugin_formatter_factory(new sinsp_evt_formatter_factory(state().inspector.get(), m_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()),
|
||||
m_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
|
||||
|
||||
52
userspace/falco/app_actions/load_plugins.h
Normal file
52
userspace/falco/app_actions/load_plugins.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"
|
||||
|
||||
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:
|
||||
// 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 m_plugin_filter_checks;
|
||||
|
||||
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)
|
||||
: easyopts_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 "easyopts_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_help : public easyopts_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)
|
||||
: easyopts_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 "easyopts_action.h"
|
||||
|
||||
namespace falco {
|
||||
namespace app {
|
||||
|
||||
class act_print_version : public easyopts_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
|
||||
|
||||
302
userspace/falco/app_actions/process_events.cpp
Normal file
302
userspace/falco/app_actions/process_events.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
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(state().reopen_outputs)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "SIGUSR1 received, reopening outputs...\n");
|
||||
outputs->reopen_outputs();
|
||||
app().state().reopen_outputs = false;
|
||||
}
|
||||
|
||||
if(state().terminate)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "SIGINT received, exiting...\n");
|
||||
break;
|
||||
}
|
||||
else if (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 successfully 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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user