Compare commits

..

3 Commits

Author SHA1 Message Date
Mark Stemm
0e3121b17c Embed .lua files into falco executable
Instead of having .lua files external to the program responsible for
loading rules, embed the contents of those files into the executable
and load them as strings instead of as files:

Add a cmake custom command below userspace/engine/lua that calls a
bash script lua-to-cpp.sh to generate falco_engine_lua_files.{cpp,hh}
that are compiled into the falco engine library.

The script creates a .cpp file that has const char * symbols for each
file, as well as lists of files that should be loaded when the falco
engine is loaded. There are actually two lists:

- lua_module_strings: these are loaded and also added to the lua
  runtime package.preload table, so they are available when lua code
  require()s them.

- lua_code_strings: these are loaded *and* evaluated, so the functions
  in them are availble to be called from C++.

This simplifies some of the falco_common methods, as there's no need
to keep track of a "main" lua file to load or paths from which the lua
loader should find files for modules, and there's no need to keep
track of an "alternate" lua directory that occurs for debug builds.

Also, there's no need to include any .lua files in the installed
packages, as they're built into the falco binary.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-01-12 12:14:47 -08:00
Mark Stemm
b05b252100 Clean up lyaml build a bit
change LYAML_SRC to LYAML_ROOT, which points to the top source
directory now.

LYAML_LIB and (new) LYAML_LUA_DIR are based relative to that
directory.

There's no install step at all now--the static library and the .lua
files are now used directly from the source tree.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-01-12 12:13:06 -08:00
Mark Stemm
2df9a68140 Move compiler/parser lua files to a "modules" subdir
This will distinguish it from rule_loader.lua, which is *not* a module
but lua code with functions that can be called directly.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2022-01-12 09:59:42 -08:00
32 changed files with 304 additions and 464 deletions

View File

@@ -176,6 +176,38 @@ jobs:
pushd build pushd build
make tests make tests
popd 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 # Build using our own builder base image using centos 7
# This build is static, dependencies are bundled in the Falco binary # This build is static, dependencies are bundled in the Falco binary
"build/centos7": "build/centos7":
@@ -359,15 +391,9 @@ jobs:
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm-dev /source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm-dev
- run: - run:
name: Publish bin-dev name: Publish bin-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
- run:
name: Publish bin-static-dev
command: | command: |
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//') 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-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin-dev -a x86_64
"publish/packages-deb-dev": "publish/packages-deb-dev":
docker: docker:
- image: docker.io/debian:stable - image: docker.io/debian:stable
@@ -479,15 +505,9 @@ jobs:
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm /source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm
- run: - run:
name: Publish bin name: Publish bin
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
- run:
name: Publish bin-static
command: | command: |
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//') 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-static/release/falco-${FALCO_VERSION}-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": "publish/packages-deb":
docker: docker:
- image: docker.io/debian:stable - image: docker.io/debian:stable
@@ -598,6 +618,7 @@ workflows:
- "build/ubuntu-focal" - "build/ubuntu-focal"
- "build/ubuntu-focal-debug" - "build/ubuntu-focal-debug"
- "build/ubuntu-bionic" - "build/ubuntu-bionic"
- "build/centos8"
- "build/centos7" - "build/centos7"
- "build/centos7-debug" - "build/centos7-debug"
- "tests/integration": - "tests/integration":

3
.gitignore vendored
View File

@@ -10,6 +10,9 @@ test/.phoronix-test-suite
test/results*.json.* test/results*.json.*
test/build test/build
userspace/engine/lua/lyaml
userspace/engine/lua/lyaml.lua
.vscode/* .vscode/*
.luacheckcache .luacheckcache

View File

@@ -1,99 +1,5 @@
# Change Log # Change Log
## v0.31.0
Released on 2022-01-31
### Major Changes
* new: add support for plugins to extend Falco functionality to new event sources and custom fields [[#1753](https://github.com/falcosecurity/falco/pull/1753)] - [@mstemm](https://github.com/mstemm)
* new: add ability to set User-Agent http header when sending http output. Provide default value of 'falcosecurit/falco'. [[#1850](https://github.com/falcosecurity/falco/pull/1850)] - [@yoshi314](https://github.com/yoshi314)
* new(configuration): support defining plugin init config as a YAML [[#1852](https://github.com/falcosecurity/falco/pull/1852)] - [@jasondellaluce](https://github.com/jasondellaluce)
### Minor Changes
* rules: add the official Falco ECR repository to rules [[#1817](https://github.com/falcosecurity/falco/pull/1817)] - [@calvinbui](https://github.com/calvinbui)
* build: update CircleCI machine image for eBPF tests to a newer version of ubuntu [[#1764](https://github.com/falcosecurity/falco/pull/1764)] - [@mstemm](https://github.com/mstemm)
* update(engine): refactor Falco engine to be agnostic to specific event sources [[#1715](https://github.com/falcosecurity/falco/pull/1715)] - [@mstemm](https://github.com/mstemm)
* build: upgrade civetweb to v1.15 [[#1782](https://github.com/falcosecurity/falco/pull/1782)] - [@FedeDP](https://github.com/FedeDP)
* update: driver version is 319368f1ad778691164d33d59945e00c5752cd27 now [[#1861](https://github.com/falcosecurity/falco/pull/1861)] - [@FedeDP](https://github.com/FedeDP)
* build: allow using local libs source dir by setting `FALCOSECURITY_LIBS_SOURCE_DIR` in cmake [[#1791](https://github.com/falcosecurity/falco/pull/1791)] - [@jasondellaluce](https://github.com/jasondellaluce)
* build: the statically linked binary package is now published with the `-static` suffix [[#1873](https://github.com/falcosecurity/falco/pull/1873)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update!: removed "--alternate-lua-dir" cmdline option as lua scripts are now embedded in Falco executable. [[#1872](https://github.com/falcosecurity/falco/pull/1872)] - [@FedeDP](https://github.com/FedeDP)
* build: switch to dynamic build for the binary package (`.tar.gz`) [[#1853](https://github.com/falcosecurity/falco/pull/1853)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update: simpleconsumer filtering is now being done at kernel level [[#1846](https://github.com/falcosecurity/falco/pull/1846)] - [@FedeDP](https://github.com/FedeDP)
* update(scripts/falco-driver-loader): first try to load the latest kmod version, then fallback to an already installed if any [[#1863](https://github.com/falcosecurity/falco/pull/1863)] - [@leogr](https://github.com/leogr)
* refactor: clean up --list output with better formatting and no duplicate sections across event sources. [[#1816](https://github.com/falcosecurity/falco/pull/1816)] - [@mstemm](https://github.com/mstemm)
* update: embed .lua files used to load/compile rules into the main falco executable, for simplicity and to avoid tampering. [[#1843](https://github.com/falcosecurity/falco/pull/1843)] - [@mstemm](https://github.com/mstemm)
* update: support non-enumerable event sources in gRPC outputs service [[#1840](https://github.com/falcosecurity/falco/pull/1840)] - [@jasondellaluce](https://github.com/jasondellaluce)
* docs: add jasondellaluce to OWNERS [[#1818](https://github.com/falcosecurity/falco/pull/1818)] - [@jasondellaluce](https://github.com/jasondellaluce)
* chore: --list option can be used to selectively list fields related to new sources that are introduced by plugins [[#1839](https://github.com/falcosecurity/falco/pull/1839)] - [@loresuso](https://github.com/loresuso)
* update(userspace/falco): support arbitrary-depth nested values in YAML configuration [[#1792](https://github.com/falcosecurity/falco/pull/1792)] - [@jasondellaluce](https://github.com/jasondellaluce)
* build: bump FakeIt version to 2.0.9 [[#1797](https://github.com/falcosecurity/falco/pull/1797)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update: allow append of new exceptions to rules [[#1780](https://github.com/falcosecurity/falco/pull/1780)] - [@sai-arigeli](https://github.com/sai-arigeli)
* update: Linux packages are now signed with SHA256 [[#1758](https://github.com/falcosecurity/falco/pull/1758)] - [@twa16](https://github.com/twa16)
### Bug Fixes
* fix(scripts/falco-driver-loader): fix for SELinux insmod denials [[#1756](https://github.com/falcosecurity/falco/pull/1756)] - [@dwindsor](https://github.com/dwindsor)
* fix(scripts/falco-driver-loader): correctly clean loaded drivers when using `--clean` [[#1795](https://github.com/falcosecurity/falco/pull/1795)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(userspace/falco): in case output_file cannot be opened, throw a falco exception [[#1773](https://github.com/falcosecurity/falco/pull/1773)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/engine): support jsonpointer escaping in rule parser [[#1777](https://github.com/falcosecurity/falco/pull/1777)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(scripts/falco-driver-loader): support kernel object files in `.zst` and `.gz` compression formats [[#1863](https://github.com/falcosecurity/falco/pull/1863)] - [@leogr](https://github.com/leogr)
* fix(engine): correctly format json output in json_event [[#1847](https://github.com/falcosecurity/falco/pull/1847)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix: set http output contenttype to text/plain when json output is disabled [[#1829](https://github.com/falcosecurity/falco/pull/1829)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/falco): accept 'Content-Type' header that contains "application/json", but it is not strictly equal to it [[#1800](https://github.com/falcosecurity/falco/pull/1800)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/engine): supporting enabled-only overwritten rules [[#1775](https://github.com/falcosecurity/falco/pull/1775)] - [@jasondellaluce](https://github.com/jasondellaluce)
### Rule Changes
* rule(Create Symlink Over Sensitive File): corrected typo in rule output [[#1820](https://github.com/falcosecurity/falco/pull/1820)] - [@deepskyblue86](https://github.com/deepskyblue86)
* rule(macro open_write): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
* rule(macro open_read): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
* rule(macro open_directory): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
* rule(Create files below dev): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
* rule(Container Drift Detected (open+create)): add support to openat2 [[#1796](https://github.com/falcosecurity/falco/pull/1796)] - [@jasondellaluce](https://github.com/jasondellaluce)
* rule(macro sensitive_mount): add containerd socket [[#1815](https://github.com/falcosecurity/falco/pull/1815)] - [@loresuso](https://github.com/loresuso)
* rule(macro spawned_process): monitor also processes spawned by `execveat` [[#1868](https://github.com/falcosecurity/falco/pull/1868)] - [@Andreagit97](https://github.com/Andreagit97)
* rule(Create Hardlink Over Sensitive Files): new rule to detect hard links created over sensitive files [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
* rule(Detect crypto miners using the Stratum protocol): add `stratum2+tcp` and `stratum+ssl` protocols detection [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
* rule(Sudo Potential Privilege Escalation): correct special case for the CVE-2021-3156 exploit [[#1810](https://github.com/falcosecurity/falco/pull/1810)] - [@sberkovich](https://github.com/sberkovich)
* rule(list falco_hostnetwork_images): moved to k8s_audit_rules.yaml to avoid a warning when usng falco_rules.yaml only [[#1681](https://github.com/falcosecurity/falco/pull/1681)] - [@leodido](https://github.com/leodido)
* rule(list deb_binaries): remove `apt-config` [[#1860](https://github.com/falcosecurity/falco/pull/1860)] - [@Andreagit97](https://github.com/Andreagit97)
* rule(Launch Remote File Copy Tools in Container): add additional binaries: curl and wget. [[#1771](https://github.com/falcosecurity/falco/pull/1771)] - [@ec4n6](https://github.com/ec4n6)
* rule(list known_sa_list): add coredns, coredns-autoscaler, endpointslicemirroring-controller, horizontal-pod-autoscaler, job-controller, node-controller (nodelifecycle), persistent-volume-binder, pv-protection-controller, pvc-protection-controller, root-ca-cert-publisher and service-account-controller as allowed service accounts in the kube-system namespace [[#1760](https://github.com/falcosecurity/falco/pull/1760)] - [@sboschman](https://github.com/sboschman)
### Non user-facing changes
* fix: force-set evt.type for plugin source events [[#1878](https://github.com/falcosecurity/falco/pull/1878)] - [@FedeDP](https://github.com/FedeDP)
* fix: updated some warning strings; properly refresh lua files embedded in falco [[#1864](https://github.com/falcosecurity/falco/pull/1864)] - [@FedeDP](https://github.com/FedeDP)
* style(userspace/engine): avoid creating multiple versions of methods only to assume default ruleset. Use a default argument instead. [[#1754](https://github.com/falcosecurity/falco/pull/1754)] - [@FedeDP](https://github.com/FedeDP)
* add raft in the adopters list [[#1776](https://github.com/falcosecurity/falco/pull/1776)] - [@teshsharma](https://github.com/teshsharma)
* build: always populate partial version variables [[#1778](https://github.com/falcosecurity/falco/pull/1778)] - [@dnwe](https://github.com/dnwe)
* build: updated cloudtrail plugin to latest version [[#1865](https://github.com/falcosecurity/falco/pull/1865)] - [@FedeDP](https://github.com/FedeDP)
* replace ".." concatenation with table.concat [[#1834](https://github.com/falcosecurity/falco/pull/1834)] - [@VadimZy](https://github.com/VadimZy)
* fix(userspace/engine): actually make m_filter_all_event_types useful by properly using it as fallback when no filter event types is provided [[#1875](https://github.com/falcosecurity/falco/pull/1875)] - [@FedeDP](https://github.com/FedeDP)
* fix(build): do not show plugin options in musl optimized builds [[#1871](https://github.com/falcosecurity/falco/pull/1871)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(aws_cloudtrail_rules.yaml): correct required plugin versions [[#1867](https://github.com/falcosecurity/falco/pull/1867)] - [@FedeDP](https://github.com/FedeDP)
* docs: fix priority level "info" to "informational" [[#1858](https://github.com/falcosecurity/falco/pull/1858)] - [@Andreagit97](https://github.com/Andreagit97)
* Field properties changes [[#1838](https://github.com/falcosecurity/falco/pull/1838)] - [@mstemm](https://github.com/mstemm)
* update(build): updated libs to latest master version; updated plugins versions [[#1856](https://github.com/falcosecurity/falco/pull/1856)] - [@FedeDP](https://github.com/FedeDP)
* Add Giant Swarm to Adopters list [[#1842](https://github.com/falcosecurity/falco/pull/1842)] - [@stone-z](https://github.com/stone-z)
* update(tests): remove `token_bucket` unit tests [[#1798](https://github.com/falcosecurity/falco/pull/1798)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(build): use consistent 7-character build abbrev sha [[#1830](https://github.com/falcosecurity/falco/pull/1830)] - [@LucaGuerra](https://github.com/LucaGuerra)
* add Phoenix to adopters list [[#1806](https://github.com/falcosecurity/falco/pull/1806)] - [@kaldyka](https://github.com/kaldyka)
* remove unused files in test directory [[#1801](https://github.com/falcosecurity/falco/pull/1801)] - [@jasondellaluce](https://github.com/jasondellaluce)
* drop Falco luajit module, use the one provied by libs [[#1788](https://github.com/falcosecurity/falco/pull/1788)] - [@FedeDP](https://github.com/FedeDP)
* chore(build): update libs version to 7906f7e [[#1790](https://github.com/falcosecurity/falco/pull/1790)] - [@LucaGuerra](https://github.com/LucaGuerra)
* Add SysFlow to list of libs adopters [[#1747](https://github.com/falcosecurity/falco/pull/1747)] - [@araujof](https://github.com/araujof)
* build: dropped centos8 circleci build because it is useless [[#1882](https://github.com/falcosecurity/falco/pull/1882)] - [@FedeDP](https://github.com/FedeDP)
## v0.30.0 ## v0.30.0
Released on 2021-10-01 Released on 2021-10-01

View File

@@ -67,7 +67,6 @@ endif()
if(MUSL_OPTIMIZED_BUILD) if(MUSL_OPTIMIZED_BUILD)
set(MUSL_FLAGS "-static -Os -fPIE -pie") set(MUSL_FLAGS "-static -Os -fPIE -pie")
add_definitions(-DMUSL_OPTIMIZED)
endif() endif()
# explicitly set hardening flags # explicitly set hardening flags
@@ -207,9 +206,7 @@ add_subdirectory(userspace/engine)
add_subdirectory(userspace/falco) add_subdirectory(userspace/falco)
add_subdirectory(tests) add_subdirectory(tests)
if(NOT MUSL_OPTIMIZED_BUILD) include(plugins)
include(plugins)
endif()
# Packages configuration # Packages configuration
include(CPackConfig) include(CPackConfig)

View File

@@ -10,4 +10,5 @@ endif()
if(CPACK_GENERATOR MATCHES "TGZ") if(CPACK_GENERATOR MATCHES "TGZ")
set(CPACK_SET_DESTDIR "ON") set(CPACK_SET_DESTDIR "ON")
set(CPACK_STRIP_FILES "OFF")
endif() endif()

View File

@@ -24,8 +24,8 @@ else()
# default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake # default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake
# -DFALCOSECURITY_LIBS_VERSION=dev ..` # -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION) if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "319368f1ad778691164d33d59945e00c5752cd27") set(FALCOSECURITY_LIBS_VERSION "bb9bee8e522fc953c2a79093d688d3d82b925e8b")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=2cf44f06a282e8cee7aa1f775a08ea94c06e275faaf0636b21eb06af28cf4b3f") set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=ab2f18ff9c8d92dd06088ccfa73d4230fce3617613229f5afd839a37c13b0459")
endif() endif()
# cd /path/to/build && cmake /path/to/source # cd /path/to/build && cmake /path/to/source

View File

@@ -13,12 +13,12 @@
include(ExternalProject) include(ExternalProject)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME) set(PLUGINS_VERSION "0.1.0-rc1-28-g019437e")
ExternalProject_Add( ExternalProject_Add(
cloudtrail-plugin cloudtrail-plugin
URL "https://download.falco.org/plugins/stable/cloudtrail-0.2.3-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz" URL "https://download.falco.org/plugins/dev/cloudtrail-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=3dfce36f37a4f834b6078c6b78776414472a6ee775e8f262535313cc4031d0b7" URL_HASH "SHA256=ad9692957c5435238e07d1625e1b247eabe98b85f54de9218367fdd73a6f3f0b"
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "") INSTALL_COMMAND "")
@@ -27,8 +27,8 @@ install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plu
ExternalProject_Add( ExternalProject_Add(
json-plugin json-plugin
URL "https://download.falco.org/plugins/stable/json-0.2.2-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz" URL "https://download.falco.org/plugins/dev/json-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=83eb411c9f2125695875b229c6e7974e6a4cc7f028be146b79d26db30372af5e" URL_HASH "SHA256=721ea5226b0f623915d0d5c34870589ad33a8ff795b0daa1af72f21a67430077"
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
BUILD_COMMAND "" BUILD_COMMAND ""
INSTALL_COMMAND "") INSTALL_COMMAND "")

View File

@@ -20,7 +20,7 @@ RUN curl -L -o falco.tar.gz \
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \ RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \
&& mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml && mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml
FROM debian:11-slim FROM scratch
LABEL maintainer="cncf-falco-dev@lists.cncf.io" LABEL maintainer="cncf-falco-dev@lists.cncf.io"

View File

@@ -92,7 +92,7 @@ log_level: info
# Minimum rule priority level to load and run. All rules having a # Minimum rule priority level to load and run. All rules having a
# priority more severe than this level will be loaded/run. Can be one # priority more severe than this level will be loaded/run. Can be one
# of "emergency", "alert", "critical", "error", "warning", "notice", # of "emergency", "alert", "critical", "error", "warning", "notice",
# "informational", "debug". # "info", "debug".
priority: debug priority: debug
# Whether or not output to any of the output channels below is # Whether or not output to any of the output channels below is
@@ -246,7 +246,6 @@ program_output:
http_output: http_output:
enabled: false enabled: false
url: http://some.url url: http://some.url
user_agent: "falcosecurity/falco"
# Falco supports running a gRPC server with two main binding types # Falco supports running a gRPC server with two main binding types
# 1. Over the network with mandatory mutual TLS authentication (mTLS) # 1. Over the network with mandatory mutual TLS authentication (mTLS)

View File

@@ -1,5 +1,5 @@
# #
# Copyright (C) 2022 The Falco Authors. # Copyright (C) 2019 The Falco Authors.
# #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,9 +22,7 @@
# anything semver-compatible. # anything semver-compatible.
- required_plugin_versions: - required_plugin_versions:
- name: cloudtrail - name: cloudtrail
version: 0.2.3 version: 0.1.0
- name: json
version: 0.2.2
# Note that this rule is disabled by default. It's useful only to # Note that this rule is disabled by default. It's useful only to
# verify that the cloudtrail plugin is sending events properly. The # verify that the cloudtrail plugin is sending events properly. The

View File

@@ -1,5 +1,5 @@
# #
# Copyright (C) 2022 The Falco Authors. # Copyright (C) 2020 The Falco Authors.
# #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@@ -63,14 +63,11 @@
condition: rename or remove condition: rename or remove
- macro: spawned_process - macro: spawned_process
condition: evt.type in (execve, execveat) and evt.dir=< condition: evt.type = execve and evt.dir=<
- macro: create_symlink - macro: create_symlink
condition: evt.type in (symlink, symlinkat) and evt.dir=< condition: evt.type in (symlink, symlinkat) and evt.dir=<
- macro: create_hardlink
condition: evt.type in (link, linkat) and evt.dir=<
- macro: chmod - macro: chmod
condition: (evt.type in (chmod, fchmod, fchmodat) and evt.dir=<) condition: (evt.type in (chmod, fchmod, fchmodat) and evt.dir=<)
@@ -219,7 +216,7 @@
- list: deb_binaries - list: deb_binaries
items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude, items: [dpkg, dpkg-preconfigu, dpkg-reconfigur, dpkg-divert, apt, apt-get, aptitude,
frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key, frontend, preinst, add-apt-reposit, apt-auto-remova, apt-key,
apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai apt-listchanges, unattended-upgr, apt-add-reposit, apt-config, apt-cache, apt.systemd.dai
] ]
# The truncated dpkg-preconfigu is intentional, process names are # The truncated dpkg-preconfigu is intentional, process names are
@@ -1874,6 +1871,19 @@
container.image.repository in (falco_sensitive_mount_images) or container.image.repository in (falco_sensitive_mount_images) or
container.image.repository startswith quay.io/sysdig/) container.image.repository startswith quay.io/sysdig/)
# These container images are allowed to run with hostnetwork=true
- list: falco_hostnetwork_images
items: [
gcr.io/google-containers/prometheus-to-sd,
gcr.io/projectcalico-org/typha,
gcr.io/projectcalico-org/node,
gke.gcr.io/gke-metadata-server,
gke.gcr.io/kube-proxy,
gke.gcr.io/netd-amd64,
k8s.gcr.io/ip-masq-agent-amd64
k8s.gcr.io/prometheus-to-sd,
]
# Add conditions to this macro (probably in a separate file, # Add conditions to this macro (probably in a separate file,
# overwriting this macro) to specify additional containers that are # overwriting this macro) to specify additional containers that are
# allowed to perform sensitive mounts. # allowed to perform sensitive mounts.
@@ -2699,17 +2709,7 @@
(evt.arg.target in (sensitive_file_names) or evt.arg.target in (sensitive_directory_names)) (evt.arg.target in (sensitive_file_names) or evt.arg.target in (sensitive_directory_names))
output: > output: >
Symlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.target linkpath=%evt.arg.linkpath parent_process=%proc.pname) Symlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.target linkpath=%evt.arg.linkpath parent_process=%proc.pname)
priority: WARNING priority: NOTICE
tags: [file, mitre_exfiltration]
- rule: Create Hardlink Over Sensitive Files
desc: Detect hardlink created over sensitive files
condition: >
create_hardlink and
(evt.arg.oldpath in (sensitive_file_names))
output: >
Hardlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.oldpath linkpath=%evt.arg.newpath parent_process=%proc.pname)
priority: WARNING
tags: [file, mitre_exfiltration] tags: [file, mitre_exfiltration]
- list: miner_ports - list: miner_ports
@@ -2820,7 +2820,7 @@
- rule: Detect crypto miners using the Stratum protocol - rule: Detect crypto miners using the Stratum protocol
desc: Miners typically specify the mining pool to connect to with a URI that begins with 'stratum+tcp' desc: Miners typically specify the mining pool to connect to with a URI that begins with 'stratum+tcp'
condition: spawned_process and (proc.cmdline contains "stratum+tcp" or proc.cmdline contains "stratum2+tcp" or proc.cmdline contains "stratum+ssl" or proc.cmdline contains "stratum2+ssl") condition: spawned_process and proc.cmdline contains "stratum+tcp"
output: Possible miner running (command=%proc.cmdline container=%container.info image=%container.image.repository) output: Possible miner running (command=%proc.cmdline container=%container.info image=%container.image.repository)
priority: CRITICAL priority: CRITICAL
tags: [process, mitre_execution] tags: [process, mitre_execution]
@@ -3039,7 +3039,7 @@
# A privilege escalation to root through heap-based buffer overflow # A privilege escalation to root through heap-based buffer overflow
- rule: Sudo Potential Privilege Escalation - rule: Sudo Potential Privilege Escalation
desc: Privilege escalation vulnerability affecting sudo (<= 1.9.5p2). Executing sudo using sudoedit -s or sudoedit -i command with command-line argument that ends with a single backslash character from an unprivileged user it's possible to elevate the user privileges to root. desc: Privilege escalation vulnerability affecting sudo (<= 1.9.5p2). Executing sudo using sudoedit -s or sudoedit -i command with command-line argument that ends with a single backslash character from an unprivileged user it's possible to elevate the user privileges to root.
condition: spawned_process and user.uid != 0 and (proc.name=sudoedit or proc.name = sudo) and (proc.args contains -s or proc.args contains -i or proc.args contains --login) and (proc.args contains "\ " or proc.args endswith \) condition: spawned_process and user.uid != 0 and proc.name=sudoedit and (proc.args contains -s or proc.args contains -i) and (proc.args contains "\ " or proc.args endswith \)
output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)" output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)"
priority: CRITICAL priority: CRITICAL
tags: [filesystem, mitre_privilege_escalation] tags: [filesystem, mitre_privilege_escalation]

View File

@@ -152,19 +152,6 @@
source: k8s_audit source: k8s_audit
tags: [k8s] tags: [k8s]
# These container images are allowed to run with hostnetwork=true
- list: falco_hostnetwork_images
items: [
gcr.io/google-containers/prometheus-to-sd,
gcr.io/projectcalico-org/typha,
gcr.io/projectcalico-org/node,
gke.gcr.io/gke-metadata-server,
gke.gcr.io/kube-proxy,
gke.gcr.io/netd-amd64,
k8s.gcr.io/ip-masq-agent-amd64
k8s.gcr.io/prometheus-to-sd,
]
# Corresponds to K8s CIS Benchmark 1.7.4 # Corresponds to K8s CIS Benchmark 1.7.4
- rule: Create HostNetwork Pod - rule: Create HostNetwork Pod
desc: Detect an attempt to start a pod using the host network. desc: Detect an attempt to start a pod using the host network.

View File

@@ -160,26 +160,15 @@ load_kernel_module_compile() {
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
chmod +x /tmp/falco-dkms-make chmod +x /tmp/falco-dkms-make
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* ${DRIVER_NAME} module installed in dkms" echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod"
KO_FILE="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}" chcon -t modules_object_t "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1 || true
if [ -f "$KO_FILE.ko" ]; then chcon -t modules_object_t "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1 || true
KO_FILE="$KO_FILE.ko" if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
elif [ -f "$KO_FILE.ko.gz" ]; then
KO_FILE="$KO_FILE.ko.gz"
elif [ -f "$KO_FILE.ko.xz" ]; then
KO_FILE="$KO_FILE.ko.xz"
elif [ -f "$KO_FILE.ko.zst" ]; then
KO_FILE="$KO_FILE.ko.zst"
else
>&2 echo "${DRIVER_NAME} module file not found"
return
fi
echo "* ${DRIVER_NAME} module found: ${KO_FILE}"
echo "* Trying insmod"
chcon -t modules_object_t "$KO_FILE" > /dev/null 2>&1 || true
if insmod "$KO_FILE" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms" echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
exit 0 exit 0
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)"
exit 0
else else
echo "* Unable to insmod ${DRIVER_NAME} module" echo "* Unable to insmod ${DRIVER_NAME} module"
fi fi
@@ -207,12 +196,8 @@ load_kernel_module_download() {
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
echo "* Download succeeded" echo "* Download succeeded"
chcon -t modules_object_t "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true chcon -t modules_object_t "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
if insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"; then insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module found and inserted"
echo "* Success: ${DRIVER_NAME} module found and inserted" exit $?
exit 0
else
>&2 echo "Unable to insmod the prebuilt ${DRIVER_NAME} module"
fi
else else
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module" >&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module"
return return
@@ -256,6 +241,11 @@ load_kernel_module() {
exit 0 exit 0
fi fi
echo "* Trying to load a system ${DRIVER_NAME} module, if present"
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
exit 0
fi
echo "* Looking for a ${DRIVER_NAME} module locally (kernel ${KERNEL_RELEASE})" echo "* Looking for a ${DRIVER_NAME} module locally (kernel ${KERNEL_RELEASE})"
@@ -278,13 +268,6 @@ load_kernel_module() {
load_kernel_module_compile load_kernel_module_compile
fi fi
# Last try (might load a previous driver version)
echo "* Trying to load a system ${DRIVER_NAME} module, if present"
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
exit 0
fi
# Not able to download a prebuilt module nor to compile one on-the-fly # Not able to download a prebuilt module nor to compile one on-the-fly
>&2 echo "Consider compiling your own ${DRIVER_NAME} driver and loading it or getting in touch with the Falco community" >&2 echo "Consider compiling your own ${DRIVER_NAME} driver and loading it or getting in touch with the Falco community"
exit 1 exit 1

View File

@@ -49,7 +49,6 @@ trace_files: !mux
detect: False detect: False
rules_file: rules_file:
- ../rules/falco_rules.yaml - ../rules/falco_rules.yaml
- ../rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml - ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml - ./rules/k8s_audit/trust_nginx_container.yaml
trace_file: trace_files/k8s_audit/create_nginx_pod_privileged.json trace_file: trace_files/k8s_audit/create_nginx_pod_privileged.json
@@ -75,7 +74,6 @@ trace_files: !mux
detect: False detect: False
rules_file: rules_file:
- ../rules/falco_rules.yaml - ../rules/falco_rules.yaml
- ../rules/k8s_audit_rules.yaml
- ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml - ./rules/k8s_audit/engine_v4_k8s_audit_rules.yaml
- ./rules/k8s_audit/trust_nginx_container.yaml - ./rules/k8s_audit/trust_nginx_container.yaml
trace_file: trace_files/k8s_audit/create_nginx_pod_hostnetwork.json trace_file: trace_files/k8s_audit/create_nginx_pod_hostnetwork.json

View File

@@ -82,7 +82,7 @@ trace_files: !mux
incompat_plugin_rules_version: incompat_plugin_rules_version:
exit_status: 1 exit_status: 1
stderr_contains: "Runtime error: Plugin cloudtrail version .* not compatible with required plugin version 100000.0.0. Exiting." stderr_contains: "Runtime error: Plugin cloudtrail version 0.1.0 not compatible with required plugin version 100000.0.0. Exiting."
conf_file: BUILD_DIR/test/confs/plugins/cloudtrail_json_create_instances.yaml conf_file: BUILD_DIR/test/confs/plugins/cloudtrail_json_create_instances.yaml
rules_file: rules_file:
- rules/plugins/cloudtrail_incompat_plugin_version.yaml - rules/plugins/cloudtrail_incompat_plugin_version.yaml

View File

@@ -42,9 +42,8 @@ TEST_CASE("Should enable/disable for exact match w/ default ruleset", "[rulesets
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("one_rule", exact_match, enabled); r.enable("one_rule", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -58,9 +57,8 @@ TEST_CASE("Should enable/disable for exact match w/ specific ruleset", "[ruleset
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("one_rule", exact_match, enabled, non_default_ruleset); r.enable("one_rule", exact_match, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@@ -78,9 +76,8 @@ TEST_CASE("Should not enable for exact match different rule name", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("some_other_rule", exact_match, enabled); r.enable("some_other_rule", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
@@ -91,9 +88,8 @@ TEST_CASE("Should enable/disable for exact match w/ substring and default rulese
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("one_rule", substring_match, enabled); r.enable("one_rule", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -107,9 +103,8 @@ TEST_CASE("Should not enable for substring w/ exact_match", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("one_", exact_match, enabled); r.enable("one_", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
@@ -120,9 +115,8 @@ TEST_CASE("Should enable/disable for prefix match w/ default ruleset", "[ruleset
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("one_", substring_match, enabled); r.enable("one_", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -136,9 +130,8 @@ TEST_CASE("Should enable/disable for suffix match w/ default ruleset", "[ruleset
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("_rule", substring_match, enabled); r.enable("_rule", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -152,9 +145,8 @@ TEST_CASE("Should enable/disable for substring match w/ default ruleset", "[rule
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("ne_ru", substring_match, enabled); r.enable("ne_ru", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -168,9 +160,8 @@ TEST_CASE("Should enable/disable for substring match w/ specific ruleset", "[rul
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable("ne_ru", substring_match, enabled, non_default_ruleset); r.enable("ne_ru", substring_match, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@@ -188,10 +179,9 @@ TEST_CASE("Should enable/disable for tags w/ default ruleset", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
std::set<std::string> want_tags = {"some_tag"}; std::set<std::string> want_tags = {"some_tag"};
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled); r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -205,10 +195,9 @@ TEST_CASE("Should enable/disable for tags w/ specific ruleset", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
std::set<std::string> want_tags = {"some_tag"}; std::set<std::string> want_tags = {"some_tag"};
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled, non_default_ruleset); r.enable_tags(want_tags, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@@ -226,10 +215,9 @@ TEST_CASE("Should not enable for different tags", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
std::set<std::string> want_tags = {"some_different_tag"}; std::set<std::string> want_tags = {"some_different_tag"};
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled); r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 0); REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 0);
@@ -240,10 +228,9 @@ TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> filter = create_filter(); std::shared_ptr<gen_event_filter> filter = create_filter();
string rule_name = "one_rule"; string rule_name = "one_rule";
string source = "syscall";
std::set<std::string> want_tags = {"some_tag", "some_different_tag"}; std::set<std::string> want_tags = {"some_tag", "some_different_tag"};
r.add(source, rule_name, tags, filter); r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled); r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1); REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@@ -254,17 +241,16 @@ TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
TEST_CASE("Should enable/disable for incremental adding tags", "[rulesets]") TEST_CASE("Should enable/disable for incremental adding tags", "[rulesets]")
{ {
string source = "syscall";
falco_ruleset r; falco_ruleset r;
std::shared_ptr<gen_event_filter> rule1_filter = create_filter(); std::shared_ptr<gen_event_filter> rule1_filter = create_filter();
string rule1_name = "one_rule"; string rule1_name = "one_rule";
std::set<std::string> rule1_tags = {"rule1_tag"}; std::set<std::string> rule1_tags = {"rule1_tag"};
r.add(source, rule1_name, rule1_tags, rule1_filter); r.add(rule1_name, rule1_tags, rule1_filter);
std::shared_ptr<gen_event_filter> rule2_filter = create_filter(); std::shared_ptr<gen_event_filter> rule2_filter = create_filter();
string rule2_name = "two_rule"; string rule2_name = "two_rule";
std::set<std::string> rule2_tags = {"rule2_tag"}; std::set<std::string> rule2_tags = {"rule2_tag"};
r.add(source, rule2_name, rule2_tags, rule2_filter); r.add(rule2_name, rule2_tags, rule2_filter);
std::set<std::string> want_tags; std::set<std::string> want_tags;

View File

@@ -56,3 +56,6 @@ else()
endif() endif()
target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}" luafiles) target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}" luafiles)
configure_file(config_falco_engine.h.in config_falco_engine.h)

View File

@@ -0,0 +1,20 @@
/*
Copyright (C) 2019 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#define FALCO_ENGINE_LUA_DIR "${FALCO_ABSOLUTE_SHARE_DIR}/lua/"
#define FALCO_ENGINE_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/engine/lua/"

View File

@@ -16,6 +16,7 @@ limitations under the License.
#include <fstream> #include <fstream>
#include "config_falco_engine.h"
#include "falco_common.h" #include "falco_common.h"
#include "banned.h" // This raises a compilation error when certain functions are used #include "banned.h" // This raises a compilation error when certain functions are used
#include "falco_engine_lua_files.hh" #include "falco_engine_lua_files.hh"

View File

@@ -25,6 +25,7 @@ limitations under the License.
#include "falco_engine.h" #include "falco_engine.h"
#include "falco_utils.h" #include "falco_utils.h"
#include "falco_engine_version.h" #include "falco_engine_version.h"
#include "config_falco_engine.h"
#include "formats.h" #include "formats.h"
@@ -43,7 +44,7 @@ const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
using namespace std; using namespace std;
falco_engine::falco_engine(bool seed_rng) falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir)
: m_next_ruleset_id(0), : m_next_ruleset_id(0),
m_min_priority(falco_common::PRIORITY_DEBUG), m_min_priority(falco_common::PRIORITY_DEBUG),
m_sampling_ratio(1), m_sampling_multiplier(0), m_sampling_ratio(1), m_sampling_multiplier(0),
@@ -135,12 +136,6 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
{ {
for(auto &field : fld_class.fields) for(auto &field : fld_class.fields)
{ {
// Skip fields with the EPF_TABLE_ONLY flag.
if(field.tags.find("EPF_TABLE_ONLY") != field.tags.end())
{
continue;
}
printf("%s\n", field.name.c_str()); printf("%s\n", field.name.c_str());
} }
} }
@@ -420,7 +415,7 @@ void falco_engine::add_filter(std::shared_ptr<gen_event_filter> filter,
throw falco_exception(err); throw falco_exception(err);
} }
it->second->add(source, rule, tags, filter); it->second->add(rule, tags, filter);
} }
bool falco_engine::is_source_valid(const std::string &source) bool falco_engine::is_source_valid(const std::string &source)
@@ -432,7 +427,7 @@ bool falco_engine::is_plugin_compatible(const std::string &name,
const std::string &version, const std::string &version,
std::string &required_version) std::string &required_version)
{ {
sinsp_plugin::version plugin_version(version); sinsp_plugin::version plugin_version(version.c_str());
if(!plugin_version.m_valid) if(!plugin_version.m_valid)
{ {
@@ -447,12 +442,13 @@ bool falco_engine::is_plugin_compatible(const std::string &name,
for(auto &rversion : m_required_plugin_versions[name]) for(auto &rversion : m_required_plugin_versions[name])
{ {
sinsp_plugin::version req_version(rversion); sinsp_plugin::version req_version(rversion.c_str());
if (!plugin_version.check(req_version)) if(req_version.m_version_major > plugin_version.m_version_major)
{ {
required_version = rversion; required_version = rversion;
return false; return false;
} }
} }
return true; return true;

View File

@@ -32,6 +32,7 @@ limitations under the License.
#include "rules.h" #include "rules.h"
#include "ruleset.h" #include "ruleset.h"
#include "config_falco_engine.h"
#include "falco_common.h" #include "falco_common.h"
// //
@@ -43,7 +44,7 @@ limitations under the License.
class falco_engine : public falco_common class falco_engine : public falco_common
{ {
public: public:
falco_engine(bool seed_rng=true); falco_engine(bool seed_rng=true, const std::string& alternate_lua_dir=FALCO_ENGINE_SOURCE_LUA_DIR);
virtual ~falco_engine(); virtual ~falco_engine();
// A given engine has a version which identifies the fields // A given engine has a version which identifies the fields

View File

@@ -22,3 +22,4 @@ limitations under the License.
// represents the fields supported by this version of Falco. It's used // represents the fields supported by this version of Falco. It's used
// at build time to detect a changed set of fields. // at build time to detect a changed set of fields.
#define FALCO_FIELDS_CHECKSUM "4de812495f8529ac20bda2b9774462b15911a51df293d59fe9ccb6b922fdeb9d" #define FALCO_FIELDS_CHECKSUM "4de812495f8529ac20bda2b9774462b15911a51df293d59fe9ccb6b922fdeb9d"

View File

@@ -1529,9 +1529,12 @@ void json_event_formatter::set_format(output_format of, const std::string &forma
bool json_event_formatter::tostring_withformat(gen_event *gevt, std::string &output, gen_event_formatter::output_format of) bool json_event_formatter::tostring_withformat(gen_event *gevt, std::string &output, gen_event_formatter::output_format of)
{ {
json_event *ev = static_cast<json_event *>(gevt); json_event *ev = static_cast<json_event *>(gevt);
std::string ret;
if(of == OF_JSON) if(of == OF_JSON)
{ {
output = tojson(ev); ret = tojson(ev);
return true; return true;
} }
else else

View File

@@ -10,7 +10,7 @@
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the # "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. # specific language governing permissions and limitations under the License.
file(GLOB_RECURSE lua_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua) file(GLOB_RECURSE lua_module_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/falco_engine_lua_files.cpp add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/falco_engine_lua_files.cpp
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh ${CMAKE_CURRENT_SOURCE_DIR} ${LYAML_LUA_DIR} ${CMAKE_CURRENT_BINARY_DIR} COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh ${CMAKE_CURRENT_SOURCE_DIR} ${LYAML_LUA_DIR} ${CMAKE_CURRENT_BINARY_DIR}

View File

@@ -293,20 +293,19 @@ function split_lines(rules_content)
end end
function get_orig_yaml_obj(rules_lines, row) function get_orig_yaml_obj(rules_lines, row)
idx = row local ret = ""
local t = {}
while (idx <= #rules_lines) do
t[#t + 1] = rules_lines[idx]
idx = idx + 1
if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then idx = row
break while (idx <= #rules_lines) do
end ret = ret..rules_lines[idx].."\n"
end idx = idx + 1
t[#t + 1] = ""
local ret = "" if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then
ret = table.concat(t, "\n") break
return ret end
end
return ret
end end
function get_lines(rules_lines, row, num_lines) function get_lines(rules_lines, row, num_lines)
@@ -755,69 +754,65 @@ end
-- Populates exfields with all fields used -- Populates exfields with all fields used
function build_exception_condition_string_multi_fields(eitem, exfields) function build_exception_condition_string_multi_fields(eitem, exfields)
local fields = eitem['fields'] local fields = eitem['fields']
local comps = eitem['comps'] local comps = eitem['comps']
local icond = {} local icond = "("
icond[#icond + 1] = "(" for i, values in ipairs(eitem['values']) do
local lcount = 0 if #fields ~= #values then
for i, values in ipairs(eitem['values']) do return nil, "Exception item "..eitem['name']..": fields and values lists must have equal length"
if #fields ~= #values then end
return nil, "Exception item " .. eitem['name'] .. ": fields and values lists must have equal length"
end
if lcount ~= 0 then if icond ~= "(" then
icond[#icond + 1] = " or " icond=icond.." or "
end end
lcount = lcount + 1
icond[#icond + 1] = "(" icond=icond.."("
for k = 1, #fields do for k=1,#fields do
if k > 1 then if k > 1 then
icond[#icond + 1] = " and " icond=icond.." and "
end end
local ival = values[k] local ival = values[k]
local istr = "" local istr = ""
-- If ival is a table, express it as (titem1, titem2, etc) -- If ival is a table, express it as (titem1, titem2, etc)
if type(ival) == "table" then if type(ival) == "table" then
istr = "(" istr = "("
for _, item in ipairs(ival) do for _, item in ipairs(ival) do
if istr ~= "(" then if istr ~= "(" then
istr = istr .. ", " istr = istr..", "
end end
istr = istr .. quote_item(item) istr = istr..quote_item(item)
end end
istr = istr .. ")" istr = istr..")"
else else
-- If the corresponding operator is one that works on lists, possibly add surrounding parentheses. -- If the corresponding operator is one that works on lists, possibly add surrounding parentheses.
if defined_list_comp_operators[comps[k]] then if defined_list_comp_operators[comps[k]] then
istr = paren_item(ival) istr = paren_item(ival)
else else
-- Quote the value if not already quoted -- Quote the value if not already quoted
istr = quote_item(ival) istr = quote_item(ival)
end end
end end
icond[#icond + 1] = fields[k] .. " " .. comps[k] .. " " .. istr icond = icond..fields[k].." "..comps[k].." "..istr
exfields[fields[k]] = true exfields[fields[k]] = true
end end
icond[#icond + 1] = ")" icond=icond..")"
end end
icond[#icond + 1] = ")" icond = icond..")"
-- Don't return a trivially empty condition string -- Don't return a trivially empty condition string
local ret = table.concat(icond) if icond == "()" then
if ret == "()" then icond = ""
return "", nil end
end
return ret, nil return icond, nil
end end
@@ -1059,9 +1054,9 @@ function load_rules(rules_content,
else else
num_evttypes = falco_rules.add_filter(rules_mgr, lua_parser, v['rule'], v['source'], v['tags']) num_evttypes = falco_rules.add_filter(rules_mgr, lua_parser, v['rule'], v['source'], v['tags'])
if v['source'] == "syscall" and (num_evttypes == 0 or num_evttypes > 100) then if num_evttypes == 0 or num_evttypes > 100 then
if warn_evttypes == true then if warn_evttypes == true then
msg = "Rule "..v['rule']..": warning (no-evttype):\n".." matches too many evt.type values.\n".." This has a significant performance penalty." msg = "Rule "..v['rule']..": warning (no-evttype):"
warnings[#warnings + 1] = msg warnings[#warnings + 1] = msg
end end
end end

View File

@@ -145,19 +145,11 @@ int falco_rules::add_filter(lua_State *ls)
lua_pop(ls, 1); lua_pop(ls, 1);
} }
// todo(jasondellaluce,leogr,fededp): temp workaround, remove when fixed in libs size_t num_evttypes = lp->filter()->evttypes().size();
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); 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(); std::string errstr = string("Could not add rule to falco engine: ") + e.what();
lua_pushstring(ls, errstr.c_str()); lua_pushstring(ls, errstr.c_str());
lua_error(ls); lua_error(ls);

View File

@@ -66,7 +66,7 @@ void falco_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_lis
void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap) void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
{ {
std::set<uint16_t> fevttypes = wrap->evttypes(); std::set<uint16_t> fevttypes = wrap->filter->evttypes();
if(fevttypes.empty()) if(fevttypes.empty())
{ {
@@ -91,7 +91,7 @@ void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper>
void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap) void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
{ {
std::set<uint16_t> fevttypes = wrap->evttypes(); std::set<uint16_t> fevttypes = wrap->filter->evttypes();
if(fevttypes.empty()) if(fevttypes.empty())
{ {
@@ -118,16 +118,18 @@ uint64_t falco_ruleset::ruleset_filters::num_filters()
bool falco_ruleset::ruleset_filters::run(gen_event *evt) bool falco_ruleset::ruleset_filters::run(gen_event *evt)
{ {
if(evt->get_type() < m_filter_by_event_type.size()) if(evt->get_type() >= m_filter_by_event_type.size())
{ {
for(auto &wrap : m_filter_by_event_type[evt->get_type()]) return false;
{ }
if(wrap->filter->run(evt))
{ for(auto &wrap : m_filter_by_event_type[evt->get_type()])
return true; {
} if(wrap->filter->run(evt))
} {
} return true;
}
}
// Finally, try filters that are not specific to an event type. // Finally, try filters that are not specific to an event type.
for(auto &wrap : m_filter_all_event_types) for(auto &wrap : m_filter_all_event_types)
@@ -147,18 +149,16 @@ void falco_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &ev
for(auto &wrap : m_filters) for(auto &wrap : m_filters)
{ {
auto fevttypes = wrap->evttypes(); auto fevttypes = wrap->filter->evttypes();
evttypes.insert(fevttypes.begin(), fevttypes.end()); evttypes.insert(fevttypes.begin(), fevttypes.end());
} }
} }
void falco_ruleset::add(string &source, void falco_ruleset::add(string &name,
string &name,
set<string> &tags, set<string> &tags,
std::shared_ptr<gen_event_filter> filter) std::shared_ptr<gen_event_filter> filter)
{ {
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper()); std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
wrap->source = source;
wrap->name = name; wrap->name = name;
wrap->tags = tags; wrap->tags = tags;
wrap->filter = filter; wrap->filter = filter;

View File

@@ -34,8 +34,7 @@ public:
falco_ruleset(); falco_ruleset();
virtual ~falco_ruleset(); virtual ~falco_ruleset();
void add(string &source, void add(std::string &name,
std::string &name,
std::set<std::string> &tags, std::set<std::string> &tags,
std::shared_ptr<gen_event_filter> filter); std::shared_ptr<gen_event_filter> filter);
@@ -74,21 +73,9 @@ private:
class filter_wrapper { class filter_wrapper {
public: public:
std::string source;
std::string name; std::string name;
std::set<std::string> tags; std::set<std::string> tags;
std::shared_ptr<gen_event_filter> filter; std::shared_ptr<gen_event_filter> filter;
std::set<uint16_t> evttypes()
{
// todo(jasondellaluce,leogr): temp workarond, remove when fixed in libs
if(source == "syscall" || source == "k8s_audit")
{
return filter->evttypes();
}
// else assume plugins
return {ppm_event_type::PPME_PLUGINEVENT_E};
// workaround end
}
}; };
typedef std::list<std::shared_ptr<filter_wrapper>> filter_wrapper_list; typedef std::list<std::shared_ptr<filter_wrapper>> filter_wrapper_list;

View File

@@ -148,10 +148,6 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
} }
http_output.options["url"] = url; http_output.options["url"] = url;
string user_agent;
user_agent = m_config->get_scalar<string>("http_output.user_agent","falcosecurity/falco");
http_output.options["user_agent"] = user_agent;
m_outputs.push_back(http_output); m_outputs.push_back(http_output);
} }

View File

@@ -168,10 +168,6 @@ private:
int nodeIdx = std::stoi(key.substr(i + 1, close_param_idx - i - 1)); int nodeIdx = std::stoi(key.substr(i + 1, close_param_idx - i - 1));
ret.reset(ret[nodeIdx]); ret.reset(ret[nodeIdx]);
i = close_param_idx; i = close_param_idx;
if (i < key.size() - 1 && key[i + 1] == '.')
{
i++;
}
} }
} }
} }
@@ -280,61 +276,49 @@ private:
}; };
namespace YAML { namespace YAML {
template<>
struct convert<nlohmann::json> {
static bool decode(const Node& node, nlohmann::json& res)
{
int int_val;
double double_val;
bool bool_val;
std::string str_val;
nlohmann::json sub{};
switch (node.Type()) {
case YAML::NodeType::Map:
for (auto &&it: node)
{
YAML::convert<nlohmann::json>::decode(it.second, sub);
res[it.first.as<std::string>()] = sub;
}
break;
case YAML::NodeType::Sequence:
for (auto &&it : node)
{
YAML::convert<nlohmann::json>::decode(it, sub);
res.emplace_back(sub);
}
break;
case YAML::NodeType::Scalar:
if (YAML::convert<int>::decode(node, int_val))
{
res = int_val;
}
else if (YAML::convert<double>::decode(node, double_val))
{
res = double_val;
}
else if (YAML::convert<bool>::decode(node, bool_val))
{
res = bool_val;
}
else if (YAML::convert<std::string>::decode(node, str_val))
{
res = str_val;
}
default:
break;
}
return true;
}
};
template<> template<>
struct convert<falco_configuration::plugin_config> { struct convert<falco_configuration::plugin_config> {
// Note that this loses the distinction between init configs static bool read_file_from_key(const Node &node, const std::string &prefix, std::string &value)
// defined as YAML maps or as opaque strings. {
std::string key = prefix;
if(node[key])
{
value = node[key].as<std::string>();
return true;
}
key += "_file";
if(node[key])
{
std::string path = node[key].as<std::string>();
// prepend share dir if path is not absolute
if(path.at(0) != '/')
{
path = string(FALCO_ENGINE_PLUGINS_DIR) + path;
}
// Intentionally letting potential
// exception be thrown, will get
// caught when reading config.
std::ifstream f(path);
std::string str((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());
value = str;
return true;
}
return false;
}
// Note that the distinction between
// init_config/init_config_file and
// open_params/open_params_file is lost. But also,
// this class doesn't write yaml config anyway.
static Node encode(const falco_configuration::plugin_config & rhs) { static Node encode(const falco_configuration::plugin_config & rhs) {
Node node; Node node;
node["name"] = rhs.m_name; node["name"] = rhs.m_name;
@@ -354,44 +338,36 @@ namespace YAML {
{ {
return false; return false;
} }
rhs.m_name = node["name"].as<std::string>(); else
{
rhs.m_name = node["name"].as<std::string>();
}
if(!node["library_path"]) if(!node["library_path"])
{ {
return false; return false;
} }
rhs.m_library_path = node["library_path"].as<std::string>(); else
if(rhs.m_library_path.at(0) != '/')
{ {
rhs.m_library_path = node["library_path"].as<std::string>();
// prepend share dir if path is not absolute // prepend share dir if path is not absolute
rhs.m_library_path = string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path; if(rhs.m_library_path.at(0) != '/')
{
rhs.m_library_path = string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path;
}
} }
if(!node["init_config"]) if(!read_file_from_key(node, string("init_config"), rhs.m_init_config))
{ {
return false; return false;
} }
// By convention, if the init config is a YAML map we convert it
// in a JSON object string. This is useful for plugins implementing
// the `get_init_schema` API symbol, which right now support the
// JSON Schema specific. If we ever support other schema/data types,
// we may want to bundle the conversion logic in an ad-hoc class.
// The benefit of this is being able of parsing/editing the config as
// a YAML map instead of having an opaque string.
if (node["init_config"].IsMap())
{
nlohmann::json json;
YAML::convert<nlohmann::json>::decode(node["init_config"], json);
rhs.m_init_config = json.dump();
}
else
{
rhs.m_init_config = node["init_config"].as<std::string>();
}
if(node["open_params"]) if(node["open_params"] &&
!read_file_from_key(node, string("open_params"), rhs.m_open_params))
{ {
rhs.m_open_params = node["open_params"].as<std::string>(); return false;
} }
return true; return true;

View File

@@ -94,6 +94,7 @@ static void usage()
" -h, --help Print this page\n" " -h, --help Print this page\n"
" -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n" " -c Configuration file (default " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ")\n"
" -A Monitor all events, including those with EF_DROP_SIMPLE_CONS flag.\n" " -A Monitor all events, including those with EF_DROP_SIMPLE_CONS flag.\n"
" --alternate-lua-dir <path> Specify an alternate path for loading Falco lua files\n"
" -b, --print-base64 Print data buffers in base64.\n" " -b, --print-base64 Print data buffers in base64.\n"
" This is useful for encoding binary data that needs to be used over media designed to.\n" " This is useful for encoding binary data that needs to be used over media designed to.\n"
" --cri <path> Path to CRI socket for container metadata.\n" " --cri <path> Path to CRI socket for container metadata.\n"
@@ -136,12 +137,8 @@ static void usage()
" -l <rule> Show the name and description of the rule with name <rule> and exit.\n" " -l <rule> Show the name and description of the rule with name <rule> and exit.\n"
" --list [<source>] List all defined fields. If <source> is provided, only list those fields for\n" " --list [<source>] List all defined fields. If <source> is provided, only list those fields for\n"
" the source <source>. Current values for <source> are \"syscall\", \"k8s_audit\"\n" " the source <source>. Current values for <source> are \"syscall\", \"k8s_audit\"\n"
" --list-fields-markdown [<source>]\n" #ifndef MUSL_OPTIMIZED_BUILD
" List fields in md\n"
#ifndef MUSL_OPTIMIZED
" --list-plugins Print info on all loaded plugins and exit.\n" " --list-plugins Print info on all loaded plugins and exit.\n"
#endif
#ifndef MINIMAL_BUILD
" -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\n" " -m <url[,marathon_url]>, --mesos-api <url[,marathon_url]>\n"
" Enable Mesos support by connecting to the API server\n" " Enable Mesos support by connecting to the API server\n"
" specified as argument. E.g. \"http://admin:password@127.0.0.1:5050\".\n" " specified as argument. E.g. \"http://admin:password@127.0.0.1:5050\".\n"
@@ -459,29 +456,11 @@ static void check_for_ignored_events(sinsp &inspector, falco_engine &engine)
std::string name = etable[evtnum].name; std::string name = etable[evtnum].name;
if(warn_event_names.find(name) == warn_event_names.end()) if(warn_event_names.find(name) == warn_event_names.end())
{ {
printf("Loaded rules use event %s, but this event is not returned unless running falco with -A\n", name.c_str());
warn_event_names.insert(name); 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());
}
} }
static void list_source_fields(falco_engine *engine, bool verbose, bool names_only, std::string &source) static void list_source_fields(falco_engine *engine, bool verbose, bool names_only, std::string &source)
@@ -566,6 +545,7 @@ int falco_init(int argc, char **argv)
static struct option long_options[] = static struct option long_options[] =
{ {
{"alternate-lua-dir", required_argument, 0},
{"cri", required_argument, 0}, {"cri", required_argument, 0},
{"daemon", no_argument, 0, 'd'}, {"daemon", no_argument, 0, 'd'},
{"disable-cri-async", no_argument, 0, 0}, {"disable-cri-async", no_argument, 0, 0},
@@ -576,7 +556,9 @@ int falco_init(int argc, char **argv)
{"k8s-api", required_argument, 0, 'k'}, {"k8s-api", required_argument, 0, 'k'},
{"k8s-node", required_argument, 0}, {"k8s-node", required_argument, 0},
{"list", optional_argument, 0}, {"list", optional_argument, 0},
#ifndef MUSL_OPTIMIZED_BUILD
{"list-plugins", no_argument, 0}, {"list-plugins", no_argument, 0},
#endif
{"mesos-api", required_argument, 0, 'm'}, {"mesos-api", required_argument, 0, 'm'},
{"option", required_argument, 0, 'o'}, {"option", required_argument, 0, 'o'},
{"pidfile", required_argument, 0, 'P'}, {"pidfile", required_argument, 0, 'P'},
@@ -596,7 +578,8 @@ int falco_init(int argc, char **argv)
{ {
set<string> disabled_rule_substrings; set<string> disabled_rule_substrings;
string substring; string substring;
string all_rules; string all_rules = "";
string alternate_lua_dir = FALCO_ENGINE_SOURCE_LUA_DIR;
set<string> disabled_rule_tags; set<string> disabled_rule_tags;
set<string> enabled_rule_tags; set<string> enabled_rule_tags;
@@ -768,7 +751,7 @@ int falco_init(int argc, char **argv)
list_flds_source = optarg; list_flds_source = optarg;
} }
} }
#ifndef MUSL_OPTIMIZED #ifndef MUSL_OPTIMIZED_BUILD
else if (string(long_options[long_index].name) == "list-plugins") else if (string(long_options[long_index].name) == "list-plugins")
{ {
list_plugins = true; list_plugins = true;
@@ -789,6 +772,16 @@ int falco_init(int argc, char **argv)
disable_sources.insert(optarg); disable_sources.insert(optarg);
} }
} }
else if (string(long_options[long_index].name)== "alternate-lua-dir")
{
if(optarg != NULL)
{
alternate_lua_dir = optarg;
if (alternate_lua_dir.back() != '/') {
alternate_lua_dir += '/';
}
}
}
break; break;
default: default:
@@ -824,7 +817,7 @@ int falco_init(int argc, char **argv)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
engine = new falco_engine(true); engine = new falco_engine(true, alternate_lua_dir);
engine->set_extra(output_format, replace_container_info); engine->set_extra(output_format, replace_container_info);
// Create "factories" that can create filters/formatters for // Create "factories" that can create filters/formatters for
@@ -954,7 +947,7 @@ int falco_init(int argc, char **argv)
for(auto &p : config.m_plugins) for(auto &p : config.m_plugins)
{ {
std::shared_ptr<sinsp_plugin> plugin; std::shared_ptr<sinsp_plugin> plugin;
#ifdef MUSL_OPTIMIZED #ifdef MUSL_OPTIMIZED_BUILD
throw std::invalid_argument(string("Can not load/use plugins with musl optimized build")); throw std::invalid_argument(string("Can not load/use plugins with musl optimized build"));
#else #else
falco_logger::log(LOG_INFO, "Loading plugin (" + p.m_name + ") from file " + p.m_library_path + "\n"); falco_logger::log(LOG_INFO, "Loading plugin (" + p.m_name + ") from file " + p.m_library_path + "\n");
@@ -1048,7 +1041,6 @@ int falco_init(int argc, char **argv)
{ {
os << "Type: extractor plugin" << std::endl; os << "Type: extractor plugin" << std::endl;
} }
os << std::endl;
} }
printf("%lu Plugins Loaded:\n\n%s\n", infos.size(), os.str().c_str()); printf("%lu Plugins Loaded:\n\n%s\n", infos.size(), os.str().c_str());
@@ -1146,6 +1138,11 @@ int falco_init(int argc, char **argv)
engine->enable_rule_by_tag(enabled_rule_tags, true); engine->enable_rule_by_tag(enabled_rule_tags, true);
} }
// 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(*inspector, *engine);
if(print_support) if(print_support)
{ {
nlohmann::json support; nlohmann::json support;
@@ -1209,10 +1206,6 @@ int falco_init(int argc, char **argv)
if(!all_events) if(!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(*inspector, *engine);
// Drop EF_DROP_SIMPLE_CONS kernel side // Drop EF_DROP_SIMPLE_CONS kernel side
inspector->set_simple_consumer(); inspector->set_simple_consumer();
// Eventually, drop any EF_DROP_SIMPLE_CONS event // Eventually, drop any EF_DROP_SIMPLE_CONS event

View File

@@ -34,14 +34,11 @@ void falco::outputs::output_http::output(const message *msg)
} else { } else {
slist1 = curl_slist_append(slist1, "Content-Type: text/plain"); slist1 = curl_slist_append(slist1, "Content-Type: text/plain");
} }
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1);
curl_easy_setopt(curl, CURLOPT_URL, m_oc.options["url"].c_str()); curl_easy_setopt(curl, CURLOPT_URL, m_oc.options["url"].c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg->msg.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg->msg.c_str());
curl_easy_setopt(curl, CURLOPT_USERAGENT, m_oc.options["user_agent"].c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(res != CURLE_OK) if(res != CURLE_OK)