mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-30 16:42:34 +00:00
Compare commits
49 Commits
embed-lua-
...
fix-plugin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1df80fd94b | ||
|
|
6a42f4a133 | ||
|
|
8d9dd4440f | ||
|
|
c49093005d | ||
|
|
69767bb51b | ||
|
|
7750b6f209 | ||
|
|
8c705448cc | ||
|
|
6b9fafb75f | ||
|
|
fdcd7bffd0 | ||
|
|
d989e9c2d5 | ||
|
|
996ccf555c | ||
|
|
2f82a9baa1 | ||
|
|
dfb743838e | ||
|
|
c7609192c7 | ||
|
|
4d3fc354fa | ||
|
|
43bdfce6e5 | ||
|
|
a3976463d5 | ||
|
|
1a485c3447 | ||
|
|
96529300f6 | ||
|
|
27922faa27 | ||
|
|
8a1de131f4 | ||
|
|
e1e8715a0f | ||
|
|
9ae8d281f5 | ||
|
|
c705623f9e | ||
|
|
3640871725 | ||
|
|
6d507b054c | ||
|
|
f19a1d81c6 | ||
|
|
18c7b6500d | ||
|
|
8239fa41f4 | ||
|
|
a9e7512936 | ||
|
|
f67e8bdad7 | ||
|
|
a94e6de458 | ||
|
|
3e9f8c1ef1 | ||
|
|
d20a326e09 | ||
|
|
0c290d98f8 | ||
|
|
1befb053d0 | ||
|
|
ae57718bda | ||
|
|
55ce38cf3a | ||
|
|
18571eb20d | ||
|
|
9c449901f3 | ||
|
|
4ab8d6db98 | ||
|
|
5e354859a9 | ||
|
|
f4b79296fc | ||
|
|
6bf8f34d9f | ||
|
|
f8f053c7fa | ||
|
|
b88a1cbb09 | ||
|
|
c86615f68c | ||
|
|
08df1c63cf | ||
|
|
10512b9ef9 |
@@ -391,9 +391,15 @@ 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/"$//')
|
||||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
|
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||||
|
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin-dev -a x86_64
|
||||||
"publish/packages-deb-dev":
|
"publish/packages-deb-dev":
|
||||||
docker:
|
docker:
|
||||||
- image: docker.io/debian:stable
|
- image: docker.io/debian:stable
|
||||||
@@ -505,9 +511,15 @@ 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/"$//')
|
||||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
|
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||||
|
/source/falco/scripts/publish-bin -f /build/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
|
||||||
@@ -711,7 +723,6 @@ workflows:
|
|||||||
- falco
|
- falco
|
||||||
- test-infra
|
- test-infra
|
||||||
requires:
|
requires:
|
||||||
- "build/musl"
|
|
||||||
- "rpm/sign"
|
- "rpm/sign"
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -10,11 +10,8 @@ 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
|
||||||
|
|
||||||
*.idea*
|
*.idea*
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ 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
|
||||||
@@ -206,7 +207,9 @@ add_subdirectory(userspace/engine)
|
|||||||
add_subdirectory(userspace/falco)
|
add_subdirectory(userspace/falco)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
|
||||||
include(plugins)
|
if(NOT MUSL_OPTIMIZED_BUILD)
|
||||||
|
include(plugins)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Packages configuration
|
# Packages configuration
|
||||||
include(CPackConfig)
|
include(CPackConfig)
|
||||||
|
|||||||
@@ -10,5 +10,4 @@ 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()
|
||||||
|
|||||||
@@ -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 "bb9bee8e522fc953c2a79093d688d3d82b925e8b")
|
set(FALCOSECURITY_LIBS_VERSION "319368f1ad778691164d33d59945e00c5752cd27")
|
||||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=ab2f18ff9c8d92dd06088ccfa73d4230fce3617613229f5afd839a37c13b0459")
|
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=2cf44f06a282e8cee7aa1f775a08ea94c06e275faaf0636b21eb06af28cf4b3f")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# cd /path/to/build && cmake /path/to/source
|
# cd /path/to/build && cmake /path/to/source
|
||||||
|
|||||||
@@ -11,9 +11,10 @@
|
|||||||
# specific language governing permissions and limitations under the License.
|
# specific language governing permissions and limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
set(LYAML_SRC "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/ext/yaml")
|
set(LYAML_ROOT "${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml")
|
||||||
set(LYAML_LIB "${LYAML_SRC}/.libs/yaml.a")
|
set(LYAML_LIB "${LYAML_ROOT}/ext/yaml/.libs/yaml.a")
|
||||||
message(STATUS "Using bundled lyaml in '${LYAML_SRC}'")
|
set(LYAML_LUA_DIR "${LYAML_ROOT}/lib")
|
||||||
|
message(STATUS "Using bundled lyaml in '${LYAML_ROOT}'")
|
||||||
externalproject_add(
|
externalproject_add(
|
||||||
lyaml
|
lyaml
|
||||||
DEPENDS luajit libyaml
|
DEPENDS luajit libyaml
|
||||||
@@ -22,7 +23,6 @@ externalproject_add(
|
|||||||
BUILD_COMMAND ${CMD_MAKE}
|
BUILD_COMMAND ${CMD_MAKE}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_BYPRODUCTS ${LYAML_LIB}
|
BUILD_BYPRODUCTS ${LYAML_LIB}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
CONFIGURE_COMMAND ./configure --enable-static CFLAGS=-I${LIBYAML_INSTALL_DIR}/include CPPFLAGS=-I${LIBYAML_INSTALL_DIR}/include LDFLAGS=-L${LIBYAML_INSTALL_DIR}/lib LIBS=-lyaml LUA=${LUAJIT_SRC}/luajit LUA_INCLUDE=-I${LUAJIT_INCLUDE}
|
CONFIGURE_COMMAND ./configure --enable-static CFLAGS=-I${LIBYAML_INSTALL_DIR}/include CPPFLAGS=-I${LIBYAML_INSTALL_DIR}/include LDFLAGS=-L${LIBYAML_INSTALL_DIR}/lib LIBS=-lyaml LUA=${LUAJIT_SRC}/luajit LUA_INCLUDE=-I${LUAJIT_INCLUDE}
|
||||||
INSTALL_COMMAND sh -c
|
|
||||||
"cp -R ${PROJECT_BINARY_DIR}/lyaml-prefix/src/lyaml/lib/* ${PROJECT_SOURCE_DIR}/userspace/engine/lua"
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -13,12 +13,12 @@
|
|||||||
|
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
set(PLUGINS_VERSION "0.1.0-rc1-28-g019437e")
|
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME)
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
cloudtrail-plugin
|
cloudtrail-plugin
|
||||||
URL "https://download.falco.org/plugins/dev/cloudtrail-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
URL "https://download.falco.org/plugins/stable/cloudtrail-0.2.2-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||||
URL_HASH "SHA256=ad9692957c5435238e07d1625e1b247eabe98b85f54de9218367fdd73a6f3f0b"
|
URL_HASH "SHA256=1628717e48b2ba1b9c78c9081e2ec23e4d88bb1a7b68b12cf8dff7f247b5b9b1"
|
||||||
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/dev/json-${PLUGINS_VERSION}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
URL "https://download.falco.org/plugins/stable/json-0.2.1-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
|
||||||
URL_HASH "SHA256=721ea5226b0f623915d0d5c34870589ad33a8ff795b0daa1af72f21a67430077"
|
URL_HASH "SHA256=14d1cf4c3c651af0daec7a45162ef91172d6f0baba787f0eff0227b3cf2ca39c"
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
|
|||||||
@@ -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 scratch
|
FROM debian:11-slim
|
||||||
|
|
||||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ log_level: info
|
|||||||
# Minimum rule priority level to load and run. All rules having a
|
# 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",
|
||||||
# "info", "debug".
|
# "informational", "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,6 +246,7 @@ 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)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2019 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -22,7 +22,9 @@
|
|||||||
# anything semver-compatible.
|
# anything semver-compatible.
|
||||||
- required_plugin_versions:
|
- required_plugin_versions:
|
||||||
- name: cloudtrail
|
- name: cloudtrail
|
||||||
version: 0.1.0
|
version: 0.2.2
|
||||||
|
- name: json
|
||||||
|
version: 0.2.1
|
||||||
|
|
||||||
# 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
|
||||||
@@ -333,7 +335,7 @@
|
|||||||
desc: Detect deleting blocking public access to bucket.
|
desc: Detect deleting blocking public access to bucket.
|
||||||
condition:
|
condition:
|
||||||
ct.name="PutBucketPublicAccessBlock" and not ct.error exists and
|
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/RestrictPublicBuckets]=false or
|
||||||
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicPolicy]=false or
|
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicPolicy]=false or
|
||||||
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicAcls]=false or
|
json.value[/requestParameters/PublicAccessBlockConfiguration/BlockPublicAcls]=false or
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) 2020 The Falco Authors.
|
# Copyright (C) 2022 The Falco Authors.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -63,11 +63,14 @@
|
|||||||
condition: rename or remove
|
condition: rename or remove
|
||||||
|
|
||||||
- macro: spawned_process
|
- macro: spawned_process
|
||||||
condition: evt.type = execve and evt.dir=<
|
condition: evt.type in (execve, execveat) 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=<)
|
||||||
|
|
||||||
@@ -216,7 +219,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-config, apt-cache, apt.systemd.dai
|
apt-listchanges, unattended-upgr, apt-add-reposit, apt-cache, apt.systemd.dai
|
||||||
]
|
]
|
||||||
|
|
||||||
# The truncated dpkg-preconfigu is intentional, process names are
|
# The truncated dpkg-preconfigu is intentional, process names are
|
||||||
@@ -1871,19 +1874,6 @@
|
|||||||
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.
|
||||||
@@ -2709,7 +2699,17 @@
|
|||||||
(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: NOTICE
|
priority: WARNING
|
||||||
|
tags: [file, mitre_exfiltration]
|
||||||
|
|
||||||
|
- rule: Create Hardlink Over Sensitive Files
|
||||||
|
desc: Detect hardlink created over sensitive files
|
||||||
|
condition: >
|
||||||
|
create_hardlink and
|
||||||
|
(evt.arg.oldpath in (sensitive_file_names))
|
||||||
|
output: >
|
||||||
|
Hardlinks created over sensitive files (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline target=%evt.arg.oldpath linkpath=%evt.arg.newpath parent_process=%proc.pname)
|
||||||
|
priority: WARNING
|
||||||
tags: [file, mitre_exfiltration]
|
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"
|
condition: spawned_process and (proc.cmdline contains "stratum+tcp" or proc.cmdline contains "stratum2+tcp" or proc.cmdline contains "stratum+ssl" or proc.cmdline contains "stratum2+ssl")
|
||||||
output: Possible miner running (command=%proc.cmdline container=%container.info image=%container.image.repository)
|
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 and (proc.args contains -s or proc.args contains -i) and (proc.args contains "\ " or proc.args endswith \)
|
condition: spawned_process and user.uid != 0 and (proc.name=sudoedit or proc.name = sudo) and (proc.args contains -s or proc.args contains -i or proc.args contains --login) and (proc.args contains "\ " or proc.args endswith \)
|
||||||
output: "Detect Sudo Privilege Escalation Exploit (CVE-2021-3156) (user=%user.name parent=%proc.pname cmdline=%proc.cmdline %container.info)"
|
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]
|
||||||
|
|||||||
@@ -152,6 +152,19 @@
|
|||||||
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.
|
||||||
|
|||||||
@@ -160,15 +160,26 @@ 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, trying to insmod"
|
echo "* ${DRIVER_NAME} module installed in dkms"
|
||||||
chcon -t modules_object_t "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1 || true
|
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.xz" > /dev/null 2>&1 || true
|
if [ -f "$KO_FILE.ko" ]; then
|
||||||
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
|
KO_FILE="$KO_FILE.ko"
|
||||||
|
elif [ -f "$KO_FILE.ko.gz" ]; then
|
||||||
|
KO_FILE="$KO_FILE.ko.gz"
|
||||||
|
elif [ -f "$KO_FILE.ko.xz" ]; then
|
||||||
|
KO_FILE="$KO_FILE.ko.xz"
|
||||||
|
elif [ -f "$KO_FILE.ko.zst" ]; then
|
||||||
|
KO_FILE="$KO_FILE.ko.zst"
|
||||||
|
else
|
||||||
|
>&2 echo "${DRIVER_NAME} module file not found"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "* ${DRIVER_NAME} module found: ${KO_FILE}"
|
||||||
|
echo "* Trying insmod"
|
||||||
|
chcon -t modules_object_t "$KO_FILE" > /dev/null 2>&1 || true
|
||||||
|
if insmod "$KO_FILE" > /dev/null 2>&1; then
|
||||||
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
|
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
|
||||||
@@ -196,8 +207,12 @@ load_kernel_module_download() {
|
|||||||
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
|
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
|
||||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module found and inserted"
|
if insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"; then
|
||||||
exit $?
|
echo "* Success: ${DRIVER_NAME} module found and inserted"
|
||||||
|
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
|
||||||
@@ -241,11 +256,6 @@ 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})"
|
||||||
|
|
||||||
@@ -268,6 +278,13 @@ 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
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ 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
|
||||||
@@ -74,6 +75,7 @@ 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
|
||||||
|
|||||||
@@ -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 0.1.0 not compatible with required plugin version 100000.0.0. Exiting."
|
stderr_contains: "Runtime error: Plugin cloudtrail version .* not compatible with required plugin version 100000.0.0. Exiting."
|
||||||
conf_file: BUILD_DIR/test/confs/plugins/cloudtrail_json_create_instances.yaml
|
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
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
# "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.
|
||||||
|
|
||||||
|
add_subdirectory(lua)
|
||||||
|
|
||||||
set(FALCO_ENGINE_SOURCE_FILES
|
set(FALCO_ENGINE_SOURCE_FILES
|
||||||
rules.cpp
|
rules.cpp
|
||||||
falco_common.cpp
|
falco_common.cpp
|
||||||
@@ -36,7 +38,8 @@ if(MINIMAL_BUILD)
|
|||||||
"${STRING_VIEW_LITE_INCLUDE}"
|
"${STRING_VIEW_LITE_INCLUDE}"
|
||||||
"${LIBSCAP_INCLUDE_DIRS}"
|
"${LIBSCAP_INCLUDE_DIRS}"
|
||||||
"${LIBSINSP_INCLUDE_DIRS}"
|
"${LIBSINSP_INCLUDE_DIRS}"
|
||||||
"${PROJECT_BINARY_DIR}/userspace/engine")
|
"${PROJECT_BINARY_DIR}/userspace/engine"
|
||||||
|
"${PROJECT_BINARY_DIR}/userspace/engine/lua")
|
||||||
else()
|
else()
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
falco_engine
|
falco_engine
|
||||||
@@ -48,24 +51,8 @@ else()
|
|||||||
"${STRING_VIEW_LITE_INCLUDE}"
|
"${STRING_VIEW_LITE_INCLUDE}"
|
||||||
"${LIBSCAP_INCLUDE_DIRS}"
|
"${LIBSCAP_INCLUDE_DIRS}"
|
||||||
"${LIBSINSP_INCLUDE_DIRS}"
|
"${LIBSINSP_INCLUDE_DIRS}"
|
||||||
"${PROJECT_BINARY_DIR}/userspace/engine")
|
"${PROJECT_BINARY_DIR}/userspace/engine"
|
||||||
|
"${PROJECT_BINARY_DIR}/userspace/engine/lua")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" "${LPEG_LIB}" "${LYAML_LIB}" "${LIBYAML_LIB}")
|
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)
|
|
||||||
|
|
||||||
if(DEFINED FALCO_COMPONENT)
|
|
||||||
install(
|
|
||||||
DIRECTORY lua
|
|
||||||
DESTINATION "${FALCO_SHARE_DIR}"
|
|
||||||
COMPONENT "${FALCO_COMPONENT}"
|
|
||||||
FILES_MATCHING
|
|
||||||
PATTERN *.lua)
|
|
||||||
else()
|
|
||||||
install(
|
|
||||||
DIRECTORY lua
|
|
||||||
DESTINATION "${FALCO_SHARE_DIR}"
|
|
||||||
FILES_MATCHING
|
|
||||||
PATTERN *.lua)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (C) 2019 The Falco Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define FALCO_ENGINE_LUA_DIR "${FALCO_ABSOLUTE_SHARE_DIR}/lua/"
|
|
||||||
#define FALCO_ENGINE_SOURCE_LUA_DIR "${PROJECT_SOURCE_DIR}/userspace/engine/lua/"
|
|
||||||
@@ -16,9 +16,9 @@ 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"
|
||||||
|
|
||||||
std::vector<std::string> falco_common::priority_names = {
|
std::vector<std::string> falco_common::priority_names = {
|
||||||
"Emergency",
|
"Emergency",
|
||||||
@@ -48,68 +48,33 @@ falco_common::~falco_common()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void falco_common::init(const char *lua_main_filename, const char *alternate_lua_dir)
|
void falco_common::init()
|
||||||
{
|
{
|
||||||
ifstream is;
|
// Strings in the list lua_module_strings need to be loaded as
|
||||||
string lua_dir = FALCO_ENGINE_LUA_DIR;
|
// lua modules, which also involves adding them to the
|
||||||
string lua_main_path = lua_dir + lua_main_filename;
|
// package.module table.
|
||||||
|
for(const auto &pair : lua_module_strings)
|
||||||
is.open(lua_main_path);
|
|
||||||
if (!is.is_open())
|
|
||||||
{
|
{
|
||||||
lua_dir = alternate_lua_dir;
|
lua_getglobal(m_ls, "package");
|
||||||
lua_main_path = lua_dir + lua_main_filename;
|
lua_getfield(m_ls, -1, "preload");
|
||||||
|
|
||||||
is.open(lua_main_path);
|
if(luaL_loadstring(m_ls, pair.first))
|
||||||
if (!is.is_open())
|
|
||||||
{
|
{
|
||||||
throw falco_exception("Could not find Falco Lua entrypoint (tried " +
|
throw falco_exception("Failed to load embedded lua code " +
|
||||||
string(FALCO_ENGINE_LUA_DIR) + lua_main_filename + ", " +
|
string(pair.second) + ": " + lua_tostring(m_ls, -1));
|
||||||
string(alternate_lua_dir) + lua_main_filename + ")");
|
}
|
||||||
|
|
||||||
|
lua_setfield(m_ls, -2, pair.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strings in the list lua_code_strings need to be loaded and
|
||||||
|
// evaluated so any public functions can be directly called.
|
||||||
|
for(const auto &str : lua_code_strings)
|
||||||
|
{
|
||||||
|
if(luaL_loadstring(m_ls, str) || lua_pcall(m_ls, 0, 0, 0))
|
||||||
|
{
|
||||||
|
throw falco_exception("Failed to load + evaluate embedded lua code " +
|
||||||
|
string(str) + ": " + lua_tostring(m_ls, -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Lua interpreter
|
|
||||||
add_lua_path(lua_dir);
|
|
||||||
|
|
||||||
// Load the main program, which defines all the available functions.
|
|
||||||
string scriptstr((istreambuf_iterator<char>(is)),
|
|
||||||
istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
if(luaL_loadstring(m_ls, scriptstr.c_str()) || lua_pcall(m_ls, 0, 0, 0))
|
|
||||||
{
|
|
||||||
throw falco_exception("Failed to load script " +
|
|
||||||
lua_main_path + ": " + lua_tostring(m_ls, -1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void falco_common::add_lua_path(string &path)
|
|
||||||
{
|
|
||||||
string cpath = string(path);
|
|
||||||
path += "?.lua";
|
|
||||||
cpath += "?.so";
|
|
||||||
|
|
||||||
lua_getglobal(m_ls, "package");
|
|
||||||
|
|
||||||
lua_getfield(m_ls, -1, "path");
|
|
||||||
string cur_path = lua_tostring(m_ls, -1 );
|
|
||||||
cur_path += ';';
|
|
||||||
lua_pop(m_ls, 1);
|
|
||||||
|
|
||||||
cur_path.append(path.c_str());
|
|
||||||
|
|
||||||
lua_pushstring(m_ls, cur_path.c_str());
|
|
||||||
lua_setfield(m_ls, -2, "path");
|
|
||||||
|
|
||||||
lua_getfield(m_ls, -1, "cpath");
|
|
||||||
string cur_cpath = lua_tostring(m_ls, -1 );
|
|
||||||
cur_cpath += ';';
|
|
||||||
lua_pop(m_ls, 1);
|
|
||||||
|
|
||||||
cur_cpath.append(cpath.c_str());
|
|
||||||
|
|
||||||
lua_pushstring(m_ls, cur_cpath.c_str());
|
|
||||||
lua_setfield(m_ls, -2, "cpath");
|
|
||||||
|
|
||||||
lua_pop(m_ls, 1);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
falco_common();
|
falco_common();
|
||||||
virtual ~falco_common();
|
virtual ~falco_common();
|
||||||
|
|
||||||
void init(const char *lua_main_filename, const char *alternate_lua_dir);
|
void init();
|
||||||
|
|
||||||
// Priority levels, as a vector of strings
|
// Priority levels, as a vector of strings
|
||||||
static std::vector<std::string> priority_names;
|
static std::vector<std::string> priority_names;
|
||||||
@@ -91,7 +91,4 @@ protected:
|
|||||||
lua_State *m_ls;
|
lua_State *m_ls;
|
||||||
|
|
||||||
std::mutex m_ls_semaphore;
|
std::mutex m_ls_semaphore;
|
||||||
|
|
||||||
private:
|
|
||||||
void add_lua_path(std::string &path);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ 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"
|
||||||
|
|
||||||
@@ -44,7 +43,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, const std::string& alternate_lua_dir)
|
falco_engine::falco_engine(bool seed_rng)
|
||||||
: 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),
|
||||||
@@ -53,7 +52,7 @@ falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir)
|
|||||||
luaopen_lpeg(m_ls);
|
luaopen_lpeg(m_ls);
|
||||||
luaopen_yaml(m_ls);
|
luaopen_yaml(m_ls);
|
||||||
|
|
||||||
falco_common::init(m_lua_main_filename.c_str(), alternate_lua_dir.c_str());
|
falco_common::init();
|
||||||
falco_rules::init(m_ls);
|
falco_rules::init(m_ls);
|
||||||
|
|
||||||
m_required_plugin_versions.clear();
|
m_required_plugin_versions.clear();
|
||||||
@@ -136,6 +135,12 @@ 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ 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"
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -44,7 +43,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, const std::string& alternate_lua_dir=FALCO_ENGINE_SOURCE_LUA_DIR);
|
falco_engine(bool seed_rng=true);
|
||||||
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
|
||||||
@@ -265,7 +264,6 @@ private:
|
|||||||
uint32_t m_sampling_ratio;
|
uint32_t m_sampling_ratio;
|
||||||
double m_sampling_multiplier;
|
double m_sampling_multiplier;
|
||||||
|
|
||||||
std::string m_lua_main_filename = "rule_loader.lua";
|
|
||||||
static const std::string s_default_ruleset;
|
static const std::string s_default_ruleset;
|
||||||
uint32_t m_default_ruleset_id;
|
uint32_t m_default_ruleset_id;
|
||||||
|
|
||||||
|
|||||||
@@ -22,4 +22,3 @@ 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"
|
||||||
|
|
||||||
|
|||||||
@@ -1529,12 +1529,9 @@ void json_event_formatter::set_format(output_format of, const std::string &forma
|
|||||||
bool json_event_formatter::tostring_withformat(gen_event *gevt, std::string &output, gen_event_formatter::output_format of)
|
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)
|
||||||
{
|
{
|
||||||
ret = tojson(ev);
|
output = tojson(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
21
userspace/engine/lua/CMakeLists.txt
Normal file
21
userspace/engine/lua/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2021 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.
|
||||||
|
|
||||||
|
file(GLOB_RECURSE lua_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua)
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/falco_engine_lua_files.cpp
|
||||||
|
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh ${CMAKE_CURRENT_SOURCE_DIR} ${LYAML_LUA_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
DEPENDS ${lua_files} ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh lyaml)
|
||||||
|
|
||||||
|
add_library(luafiles falco_engine_lua_files.cpp)
|
||||||
|
|
||||||
|
target_include_directories(luafiles PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
84
userspace/engine/lua/lua-to-cpp.sh
Normal file
84
userspace/engine/lua/lua-to-cpp.sh
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
LUA_FILE_DIR=$1
|
||||||
|
LYAML_LUA_DIR=$2
|
||||||
|
OUTPUT_DIR=$3
|
||||||
|
|
||||||
|
MODULE_SYMS=()
|
||||||
|
CODE_SYMS=()
|
||||||
|
|
||||||
|
function add_lua_file {
|
||||||
|
filename=$1
|
||||||
|
is_module=$2
|
||||||
|
|
||||||
|
# Take the basename of the file
|
||||||
|
BASE_NAME=$(basename ${file} .lua)
|
||||||
|
SYMBOL_NAME="${BASE_NAME}_lua_file_contents"
|
||||||
|
FILE_CONTENTS=$(<${file})
|
||||||
|
|
||||||
|
# Add a symbol to the .cc file containing the contents of the file
|
||||||
|
echo "const char *${SYMBOL_NAME}=R\"LUAFILE(${FILE_CONTENTS})LUAFILE\";" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||||
|
|
||||||
|
# Add an extern reference to the .hh file
|
||||||
|
echo "extern const char *${SYMBOL_NAME};" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||||
|
|
||||||
|
if [[ "${is_module}" == "true" ]]; then
|
||||||
|
# Determine the module name for the file
|
||||||
|
if [[ "${file}" == *"/"* ]]; then
|
||||||
|
MODULE_NAME=$(echo ${file} | tr / . | sed -e 's/.lua//')
|
||||||
|
else
|
||||||
|
MODULE_NAME=$(basename ${file} .lua)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add the pair (string contents, module name) to MODULE_SYMS
|
||||||
|
PAIR=$(echo "{${SYMBOL_NAME},\"${MODULE_NAME}\"}")
|
||||||
|
MODULE_SYMS+=(${PAIR})
|
||||||
|
else
|
||||||
|
# Add the string to CODE_SYMS
|
||||||
|
CODE_SYMS+=(${SYMBOL_NAME})
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cat <<EOF > ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||||
|
// Automatically generated. Do not edit
|
||||||
|
#include "falco_engine_lua_files.hh"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF > ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||||
|
#pragma once
|
||||||
|
// Automatically generated. Do not edit
|
||||||
|
#include <list>
|
||||||
|
#include <utility>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# lyaml and any files in the "modules" subdirectory are treated as lua
|
||||||
|
# modules.
|
||||||
|
pushd ${LYAML_LUA_DIR}
|
||||||
|
for file in *.lua */*.lua; do
|
||||||
|
add_lua_file $file "true"
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd ${LUA_FILE_DIR}/modules
|
||||||
|
for file in *.lua; do
|
||||||
|
add_lua_file $file "true"
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Any .lua files in this directory are treated as code with functions
|
||||||
|
# to execute.
|
||||||
|
pushd ${LUA_FILE_DIR}
|
||||||
|
for file in ${LUA_FILE_DIR}/*.lua; do
|
||||||
|
add_lua_file $file "false"
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Create a list of lua module (string, module name) pairs from MODULE_SYMS
|
||||||
|
echo "extern std::list<std::pair<const char *,const char *>> lua_module_strings;" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||||
|
echo "std::list<std::pair<const char *,const char *>> lua_module_strings = {$(IFS=, ; echo "${MODULE_SYMS[*]}")};" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||||
|
|
||||||
|
# Create a list of lua code strings from CODE_SYMS
|
||||||
|
echo "extern std::list<const char *> lua_code_strings;" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||||
|
echo "std::list<const char *> lua_code_strings = {$(IFS=, ; echo "${CODE_SYMS[*]}")};" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||||
@@ -293,19 +293,20 @@ function split_lines(rules_content)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function get_orig_yaml_obj(rules_lines, row)
|
function get_orig_yaml_obj(rules_lines, row)
|
||||||
local ret = ""
|
idx = row
|
||||||
|
local t = {}
|
||||||
|
while (idx <= #rules_lines) do
|
||||||
|
t[#t + 1] = rules_lines[idx]
|
||||||
|
idx = idx + 1
|
||||||
|
|
||||||
idx = row
|
if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then
|
||||||
while (idx <= #rules_lines) do
|
break
|
||||||
ret = ret..rules_lines[idx].."\n"
|
end
|
||||||
idx = idx + 1
|
end
|
||||||
|
t[#t + 1] = ""
|
||||||
if idx > #rules_lines or rules_lines[idx] == "" or string.sub(rules_lines[idx], 1, 1) == '-' then
|
local ret = ""
|
||||||
break
|
ret = table.concat(t, "\n")
|
||||||
end
|
return ret
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_lines(rules_lines, row, num_lines)
|
function get_lines(rules_lines, row, num_lines)
|
||||||
@@ -754,65 +755,69 @@ 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 = {}
|
||||||
|
|
||||||
for i, values in ipairs(eitem['values']) do
|
icond[#icond + 1] = "("
|
||||||
|
|
||||||
if #fields ~= #values then
|
local lcount = 0
|
||||||
return nil, "Exception item "..eitem['name']..": fields and values lists must have equal length"
|
for i, values in ipairs(eitem['values']) do
|
||||||
end
|
if #fields ~= #values then
|
||||||
|
return nil, "Exception item " .. eitem['name'] .. ": fields and values lists must have equal length"
|
||||||
|
end
|
||||||
|
|
||||||
if icond ~= "(" then
|
if lcount ~= 0 then
|
||||||
icond=icond.." or "
|
icond[#icond + 1] = " or "
|
||||||
end
|
end
|
||||||
|
lcount = lcount + 1
|
||||||
|
|
||||||
icond=icond.."("
|
icond[#icond + 1] = "("
|
||||||
|
|
||||||
for k=1,#fields do
|
for k = 1, #fields do
|
||||||
if k > 1 then
|
if k > 1 then
|
||||||
icond=icond.." and "
|
icond[#icond + 1] = " 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..fields[k].." "..comps[k].." "..istr
|
icond[#icond + 1] = fields[k] .. " " .. comps[k] .. " " .. istr
|
||||||
exfields[fields[k]] = true
|
exfields[fields[k]] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
icond=icond..")"
|
icond[#icond + 1] = ")"
|
||||||
end
|
end
|
||||||
|
|
||||||
icond = icond..")"
|
icond[#icond + 1] = ")"
|
||||||
|
|
||||||
-- Don't return a trivially empty condition string
|
-- Don't return a trivially empty condition string
|
||||||
if icond == "()" then
|
local ret = table.concat(icond)
|
||||||
icond = ""
|
if ret == "()" then
|
||||||
end
|
return "", nil
|
||||||
|
end
|
||||||
|
|
||||||
return icond, nil
|
return ret, nil
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1054,9 +1059,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 num_evttypes == 0 or num_evttypes > 100 then
|
if v['source'] == "syscall" and (num_evttypes == 0 or num_evttypes > 100) then
|
||||||
if warn_evttypes == true then
|
if warn_evttypes == true then
|
||||||
msg = "Rule "..v['rule']..": warning (no-evttype):"
|
msg = "Rule "..v['rule']..": warning (no-evttype):\n".." matches too many evt.type values.\n".." This has a significant performance penalty."
|
||||||
warnings[#warnings + 1] = msg
|
warnings[#warnings + 1] = msg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper>
|
|||||||
{
|
{
|
||||||
std::set<uint16_t> fevttypes = wrap->filter->evttypes();
|
std::set<uint16_t> fevttypes = wrap->filter->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())
|
if(fevttypes.empty())
|
||||||
{
|
{
|
||||||
// Should run for all event types
|
// Should run for all event types
|
||||||
|
|||||||
@@ -148,6 +148,10 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,10 @@ 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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,49 +280,61 @@ 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> {
|
||||||
|
|
||||||
static bool read_file_from_key(const Node &node, const std::string &prefix, std::string &value)
|
// Note that this loses the distinction between init configs
|
||||||
{
|
// 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;
|
||||||
@@ -338,36 +354,44 @@ namespace YAML {
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
rhs.m_name = node["name"].as<std::string>();
|
||||||
{
|
|
||||||
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>();
|
||||||
|
if(rhs.m_library_path.at(0) != '/')
|
||||||
|
{
|
||||||
|
// prepend share dir if path is not absolute
|
||||||
|
rhs.m_library_path = string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!node["init_config"])
|
||||||
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
rhs.m_library_path = node["library_path"].as<std::string>();
|
rhs.m_init_config = node["init_config"].as<std::string>();
|
||||||
|
|
||||||
// prepend share dir if path is not absolute
|
|
||||||
if(rhs.m_library_path.at(0) != '/')
|
|
||||||
{
|
|
||||||
rhs.m_library_path = string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!read_file_from_key(node, string("init_config"), rhs.m_init_config))
|
if(node["open_params"])
|
||||||
{
|
{
|
||||||
return false;
|
rhs.m_open_params = node["open_params"].as<std::string>();
|
||||||
}
|
|
||||||
|
|
||||||
if(node["open_params"] &&
|
|
||||||
!read_file_from_key(node, string("open_params"), rhs.m_open_params))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ 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"
|
||||||
@@ -137,8 +136,12 @@ 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"
|
||||||
#ifndef MUSL_OPTIMIZED_BUILD
|
" --list-fields-markdown [<source>]\n"
|
||||||
|
" 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"
|
||||||
@@ -456,11 +459,29 @@ 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)
|
||||||
@@ -545,7 +566,6 @@ 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},
|
||||||
@@ -556,9 +576,7 @@ 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'},
|
||||||
@@ -578,8 +596,7 @@ 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;
|
||||||
|
|
||||||
@@ -751,7 +768,7 @@ int falco_init(int argc, char **argv)
|
|||||||
list_flds_source = optarg;
|
list_flds_source = optarg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef MUSL_OPTIMIZED_BUILD
|
#ifndef MUSL_OPTIMIZED
|
||||||
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;
|
||||||
@@ -772,16 +789,6 @@ 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:
|
||||||
@@ -817,7 +824,7 @@ int falco_init(int argc, char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine = new falco_engine(true, alternate_lua_dir);
|
engine = new falco_engine(true);
|
||||||
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
|
||||||
@@ -947,7 +954,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_BUILD
|
#ifdef MUSL_OPTIMIZED
|
||||||
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");
|
||||||
@@ -1041,6 +1048,7 @@ 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());
|
||||||
@@ -1138,11 +1146,6 @@ 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;
|
||||||
@@ -1206,6 +1209,10 @@ 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
|
||||||
|
|||||||
@@ -34,11 +34,14 @@ 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)
|
||||||
@@ -50,4 +53,4 @@ void falco::outputs::output_http::output(const message *msg)
|
|||||||
curl_slist_free_all(slist1);
|
curl_slist_free_all(slist1);
|
||||||
slist1 = NULL;
|
slist1 = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user