mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-23 13:12:25 +00:00
Compare commits
59 Commits
new/profil
...
proposal/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc875db899 | ||
|
|
0b60fb90a4 | ||
|
|
b69bde6bd4 | ||
|
|
d2f0ad7c07 | ||
|
|
70b9bfe1d6 | ||
|
|
17f6da7885 | ||
|
|
dee0cc67f3 | ||
|
|
8429256e37 | ||
|
|
00884ef581 | ||
|
|
578ef7f64d | ||
|
|
a5ce61f03f | ||
|
|
74ca02d199 | ||
|
|
3bfd94fefd | ||
|
|
6eb9b1add1 | ||
|
|
81e29c55ec | ||
|
|
f186e5f41f | ||
|
|
ade64b0ce8 | ||
|
|
d808c0aeaf | ||
|
|
65e069a020 | ||
|
|
75c2275dac | ||
|
|
258f73ede2 | ||
|
|
3386671452 | ||
|
|
2680a459ec | ||
|
|
da9278f061 | ||
|
|
dc0670c718 | ||
|
|
05ce5b7f0b | ||
|
|
de8bade2bf | ||
|
|
e245fe460f | ||
|
|
d7de45acb2 | ||
|
|
86b473e224 | ||
|
|
d1c9aae881 | ||
|
|
986ea28279 | ||
|
|
5266618689 | ||
|
|
fa3d2eb473 | ||
|
|
acb3f94786 | ||
|
|
d1af7e139f | ||
|
|
434a5abc8b | ||
|
|
fd97f99b9f | ||
|
|
555bf1f10d | ||
|
|
f3f512c6dd | ||
|
|
8d79c11953 | ||
|
|
439152c8d8 | ||
|
|
3d3d537d85 | ||
|
|
88dbc78a44 | ||
|
|
59c2e6b421 | ||
|
|
33c93e6c29 | ||
|
|
46483339a3 | ||
|
|
762ef015b8 | ||
|
|
b887c92c91 | ||
|
|
efd0bf1967 | ||
|
|
5c69639a69 | ||
|
|
b8875df48f | ||
|
|
368817a95d | ||
|
|
622a6c1e44 | ||
|
|
95e7242d13 | ||
|
|
c42cb1858c | ||
|
|
935d9f5378 | ||
|
|
2345ea2770 | ||
|
|
901239c3c8 |
@@ -2,9 +2,9 @@ version: 2
|
||||
jobs:
|
||||
# Build using ubuntu LTS
|
||||
# This build is dynamic, most dependencies are taken from the OS
|
||||
"build/ubuntu-bionic":
|
||||
"build/ubuntu-focal":
|
||||
docker:
|
||||
- image: ubuntu:bionic
|
||||
- image: ubuntu:focal
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -12,19 +12,19 @@ jobs:
|
||||
command: apt update -y
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm linux-headers-$(uname -r) libelf-dev cmake build-essential libcurl4-openssl-dev -y
|
||||
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
||||
- run:
|
||||
name: Prepare project
|
||||
command: |
|
||||
mkdir build
|
||||
pushd build
|
||||
cmake ..
|
||||
cmake -DBUILD_BPF=On ..
|
||||
popd
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
pushd build
|
||||
make -j4 all
|
||||
KERNELDIR=/lib/modules/$(ls /lib/modules)/build make -j4 all
|
||||
popd
|
||||
- run:
|
||||
name: Run unit tests
|
||||
@@ -34,9 +34,9 @@ jobs:
|
||||
popd
|
||||
# Debug build using ubuntu LTS
|
||||
# This build is dynamic, most dependencies are taken from the OS
|
||||
"build/ubuntu-bionic-debug":
|
||||
"build/ubuntu-focal-debug":
|
||||
docker:
|
||||
- image: ubuntu:bionic
|
||||
- image: ubuntu:focal
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -44,19 +44,19 @@ jobs:
|
||||
command: apt update -y
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm linux-headers-$(uname -r) libelf-dev cmake build-essential libcurl4-openssl-dev -y
|
||||
command: DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libncurses-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-generic clang llvm git -y
|
||||
- run:
|
||||
name: Prepare project
|
||||
command: |
|
||||
mkdir build
|
||||
pushd build
|
||||
cmake -DCMAKE_BUILD_TYPE=debug ..
|
||||
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_BPF=On ..
|
||||
popd
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
pushd build
|
||||
make -j4 all
|
||||
KERNELDIR=/lib/modules/$(ls /lib/modules)/build make -j4 all
|
||||
popd
|
||||
- run:
|
||||
name: Run unit tests
|
||||
@@ -138,6 +138,15 @@ jobs:
|
||||
- run:
|
||||
name: Execute integration tests
|
||||
command: /usr/bin/entrypoint test
|
||||
"tests/driver-loader/integration":
|
||||
machine:
|
||||
image: ubuntu-1604:202004-01
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/ws
|
||||
- run:
|
||||
name: Execute driver-loader integration tests
|
||||
command: /tmp/ws/source/falco/test/driver-loader/run_test.sh /tmp/ws/build/release/
|
||||
# Sign rpm packages
|
||||
"rpm/sign":
|
||||
docker:
|
||||
@@ -208,17 +217,19 @@ jobs:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run:
|
||||
name: Build and publish slim-dev
|
||||
name: Build and publish no-driver-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
docker build --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} -t falcosecurity/falco:master-slim docker/slim
|
||||
docker build --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} -t falcosecurity/falco-no-driver:master docker/no-driver
|
||||
docker tag falcosecurity/falco-no-driver:master falcosecurity/falco:master-slim
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push falcosecurity/falco-no-driver:master
|
||||
docker push falcosecurity/falco:master-slim
|
||||
- run:
|
||||
name: Build and publish dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
docker build --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} -t falcosecurity/falco:master docker/stable
|
||||
docker build --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} -t falcosecurity/falco:master docker/falco
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push falcosecurity/falco:master
|
||||
- run:
|
||||
@@ -266,17 +277,21 @@ jobs:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run:
|
||||
name: Build and publish slim
|
||||
name: Build and publish no-driver
|
||||
command: |
|
||||
docker build --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "falcosecurity/falco:${CIRCLE_TAG}-slim" docker/slim
|
||||
docker tag "falcosecurity/falco:${CIRCLE_TAG}-slim" falcosecurity/falco:latest-slim
|
||||
docker build --build-arg VERSION_BUCKET=bin --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "falcosecurity/falco-no-driver:${CIRCLE_TAG}" docker/no-driver
|
||||
docker tag "falcosecurity/falco-no-driver:${CIRCLE_TAG}" falcosecurity/falco-no-driver:latest
|
||||
docker tag "falcosecurity/falco-no-driver:${CIRCLE_TAG}" "falcosecurity/falco:${CIRCLE_TAG}-slim"
|
||||
docker tag "falcosecurity/falco-no-driver:${CIRCLE_TAG}" "falcosecurity/falco:latest-slim"
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push "falcosecurity/falco-no-driver:${CIRCLE_TAG}"
|
||||
docker push "falcosecurity/falco-no-driver:latest"
|
||||
docker push "falcosecurity/falco:${CIRCLE_TAG}-slim"
|
||||
docker push "falcosecurity/falco:latest-slim"
|
||||
- run:
|
||||
name: Build and publish stable
|
||||
name: Build and publish falco
|
||||
command: |
|
||||
docker build --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "falcosecurity/falco:${CIRCLE_TAG}" docker/stable
|
||||
docker build --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "falcosecurity/falco:${CIRCLE_TAG}" docker/falco
|
||||
docker tag "falcosecurity/falco:${CIRCLE_TAG}" falcosecurity/falco:latest
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push "falcosecurity/falco:${CIRCLE_TAG}"
|
||||
@@ -293,13 +308,16 @@ workflows:
|
||||
version: 2
|
||||
build_and_test:
|
||||
jobs:
|
||||
- "build/ubuntu-bionic"
|
||||
- "build/ubuntu-bionic-debug"
|
||||
- "build/ubuntu-focal"
|
||||
- "build/ubuntu-focal-debug"
|
||||
- "build/centos7"
|
||||
- "build/centos7-debug"
|
||||
- "tests/integration":
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "tests/driver-loader/integration":
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "rpm/sign":
|
||||
context: falco
|
||||
filters:
|
||||
@@ -327,6 +345,7 @@ workflows:
|
||||
only: master
|
||||
requires:
|
||||
- "publish/packages-dev"
|
||||
- "tests/driver-loader/integration"
|
||||
release:
|
||||
jobs:
|
||||
- "build/centos7":
|
||||
|
||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -40,12 +40,8 @@ Please remove the leading whitespace before the `/kind <>` you uncommented.
|
||||
|
||||
> /area engine
|
||||
|
||||
> /area examples
|
||||
|
||||
> /area rules
|
||||
|
||||
> /area integrations
|
||||
|
||||
> /area tests
|
||||
|
||||
> /area proposals
|
||||
|
||||
@@ -10,6 +10,9 @@ This is a list of production adopters of Falco (in alphabetical order):
|
||||
|
||||
* [League](https://league.com/ca/) - League provides health benefits management services to help employees understand and get the most from their benefits, and employers to provide effective, efficient plans. Falco is used to monitor our deployed services on Kubernetes, protecting against malicious access to containerswhich could lead to leaks of PHI or other sensitive data. The Falco alerts are logged in Stackdriver for grouping and further analysis. In the future, we're hoping for integrations with Prometheus and AlertManager as well.
|
||||
|
||||
* [Logz.io](https://logz.io/) - Logz.io is a cloud observability platform for modern engineering teams. The Logz.io platform consists of three products — Log Management, Infrastructure Monitoring, and Cloud SIEM — that work together to unify the jobs of monitoring, troubleshooting, and security. We empower engineers to deliver better software by offering the world's most popular open source observability tools — the ELK Stack, Grafana, and Jaeger — in a single, easy to use, and powerful platform purpose-built for monitoring distributed cloud environments. Cloud SIEM supports data from multiple sources, including Falco's alerts, and offers useful rules and dashboards content to visualize and manage incidents across your systems in a unified UI.
|
||||
* https://logz.io/blog/k8s-security-with-falco-and-cloud-siem/
|
||||
|
||||
* [Preferral](https://www.preferral.com) - Preferral is a HIPAA-compliant platform for Referral Management and Online Referral Forms. Preferral streamlines the referral process for patients, specialists and their referral partners. By automating the referral process, referring practices spend less time on the phone, manual efforts are eliminated, and patients get the right care from the right specialist. Preferral leverages Falco to provide a Host Intrusion Detection System to meet their HIPPA compliance requirements.
|
||||
* https://hipaa.preferral.com/01-preferral_hipaa_compliance/
|
||||
|
||||
|
||||
42
CHANGELOG.md
42
CHANGELOG.md
@@ -2,6 +2,48 @@
|
||||
|
||||
This file documents all notable changes to Falco. The release numbering uses [semantic versioning](http://semver.org).
|
||||
|
||||
## v0.23.0
|
||||
|
||||
Released on 2020-18-05
|
||||
|
||||
### Major Changes
|
||||
|
||||
* BREAKING CHANGE: the falco-driver-loader script now references `falco-probe.o` and `falco-probe.ko` as `falco.o` and `falco.ko` [[#1158](https://github.com/falcosecurity/falco/pull/1158)]
|
||||
* BREAKING CHANGE: the `falco-driver-loader` script environment variable to use a custom repository to download drivers now uses the `DRIVERS_REPO` environment variable instead of `DRIVER_LOOKUP_URL`. This variable must contain the parent URI containing the following directory structure `/$driver_version$/falco_$target$_$kernelrelease$_$kernelversion$.[ko|o]`. e.g: [[#1160](https://github.com/falcosecurity/falco/pull/1160)]
|
||||
* new(scripts): options and command-line usage for `falco-driver-loader` [[#1200](https://github.com/falcosecurity/falco/pull/1200)]
|
||||
* new: ability to specify exact matches when adding rules to Falco engine (only API) [[#1185](https://github.com/falcosecurity/falco/pull/1185)]
|
||||
* new(docker): add an image that wraps the `falco-driver-loader` with the toolchain [[#1192](https://github.com/falcosecurity/falco/pull/1192)]
|
||||
* new(docker): add `falcosecurity/falco-no-driver` image [[#1205](https://github.com/falcosecurity/falco/pull/1205)]
|
||||
|
||||
|
||||
### Minor Changes
|
||||
|
||||
* update(scripts): improve `falco-driver-loader` output messages [[#1200](https://github.com/falcosecurity/falco/pull/1200)]
|
||||
* update: containers look for prebuilt drivers on the Drivers Build Grid [[#1158](https://github.com/falcosecurity/falco/pull/1158)]
|
||||
* update: driver version bump to 96bd9bc560f67742738eb7255aeb4d03046b8045 [[#1190](https://github.com/falcosecurity/falco/pull/1190)]
|
||||
* update(docker): now `falcosecurity/falco:slim-*` alias to `falcosecurity/falco-no-driver:*` [[#1205](https://github.com/falcosecurity/falco/pull/1205)]
|
||||
* docs: instructions to run unit tests [[#1199](https://github.com/falcosecurity/falco/pull/1199)]
|
||||
* docs(examples): move `/examples` to `contrib` repo [[#1191](https://github.com/falcosecurity/falco/pull/1191)]
|
||||
* update(docker): remove `minimal` image [[#1196](https://github.com/falcosecurity/falco/pull/1196)]
|
||||
* update(integration): move `/integrations` to `contrib` repo [[#1157](https://github.com/falcosecurity/falco/pull/1157)]
|
||||
* https://dl.bintray.com/driver/$driver_version$/falco_$target$_$kernelrelease$_$kernelversion$.[ko|o]` [[#1160](https://github.com/falcosecurity/falco/pull/1160)]
|
||||
* update(docker/event-generator): remove the event-generator from Falco repository [[#1156](https://github.com/falcosecurity/falco/pull/1156)]
|
||||
* docs(examples): set audit level to metadata for object secrets [[#1153](https://github.com/falcosecurity/falco/pull/1153)]
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix(scripts): upstream files (prebuilt drivers) for the generic Ubuntu kernel contains "ubuntu-generic" [[#1212](https://github.com/falcosecurity/falco/pull/1212)]
|
||||
* fix: support Falco driver on Linux kernels 5.6.y [[#1174](https://github.com/falcosecurity/falco/pull/1174)]
|
||||
|
||||
|
||||
### Rule Changes
|
||||
|
||||
* rule(Redirect STDOUT/STDIN to Network Connection in Container): correct rule name as per rules naming convention [[#1164](https://github.com/falcosecurity/falco/pull/1164)]
|
||||
* rule(Redirect STDOUT/STDIN to Network Connection in Container): new rule to detect Redirect stdout/stdin to network connection in container [[#1152](https://github.com/falcosecurity/falco/pull/1152)]
|
||||
* rule(K8s Secret Created): new rule to track the creation of Kubernetes secrets (excluding kube-system and service account secrets) [[#1151](https://github.com/falcosecurity/falco/pull/1151)]
|
||||
* rule(K8s Secret Deleted): new rule to track the deletion of Kubernetes secrets (excluding kube-system and service account secrets) [[#1151](https://github.com/falcosecurity/falco/pull/1151)]
|
||||
|
||||
## v0.22.1
|
||||
|
||||
Released on 2020-17-04
|
||||
|
||||
@@ -17,8 +17,8 @@ project(falco)
|
||||
option(USE_BUNDLED_DEPS "Bundle hard to find dependencies into the Falco binary" OFF)
|
||||
option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags" OFF)
|
||||
|
||||
# Elapsed time set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") # TODO(fntlnz, leodido): add
|
||||
# a flag to enable this
|
||||
# Elapsed time
|
||||
# set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") # TODO(fntlnz, leodido): add a flag to enable this
|
||||
|
||||
# Make flag for parallel processing
|
||||
include(ProcessorCount)
|
||||
@@ -99,7 +99,8 @@ ExternalProject_Add(
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
# curses We pull this in because libsinsp won't build without it
|
||||
# curses
|
||||
# We pull this in because libsinsp won't build without it
|
||||
set(CURSES_NEED_NCURSES TRUE)
|
||||
find_package(Curses REQUIRED)
|
||||
message(STATUS "Found ncurses: include: ${CURSES_INCLUDE_DIR}, lib: ${CURSES_LIBRARIES}")
|
||||
@@ -214,11 +215,8 @@ ExternalProject_Add(
|
||||
BUILD_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" WITH_CPP=1
|
||||
INSTALL_COMMAND ${CMD_MAKE} COPT="-DNO_FILES" install-lib install-headers PREFIX=${CIVETWEB_SRC}/install "WITH_CPP=1")
|
||||
|
||||
# Hedley
|
||||
include(DownloadHedley)
|
||||
|
||||
# FlatBuffers
|
||||
include(FlatBuffers)
|
||||
#string-view-lite
|
||||
include(DownloadStringViewLite)
|
||||
|
||||
# gRPC
|
||||
include(gRPC)
|
||||
@@ -241,8 +239,8 @@ add_subdirectory(rules)
|
||||
# Dockerfiles
|
||||
add_subdirectory(docker)
|
||||
|
||||
# Clang format add_custom_target(format COMMAND clang-format --style=file -i $<TARGET_PROPERTY:falco,SOURCES> COMMENT
|
||||
# "Formatting ..." VERBATIM)
|
||||
# Clang format
|
||||
# add_custom_target(format COMMAND clang-format --style=file -i $<TARGET_PROPERTY:falco,SOURCES> COMMENT "Formatting ..." VERBATIM)
|
||||
|
||||
# Shared build variables
|
||||
set(FALCO_SINSP_LIBRARY sinsp)
|
||||
@@ -251,7 +249,6 @@ set(FALCO_ABSOLUTE_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/${FALCO_SHARE_DIR}")
|
||||
set(FALCO_BIN_DIR bin)
|
||||
|
||||
add_subdirectory(scripts)
|
||||
add_subdirectory(userspace/profiler)
|
||||
add_subdirectory(userspace/engine)
|
||||
add_subdirectory(userspace/falco)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -81,7 +81,7 @@ Some examples:
|
||||
|
||||
### Slack
|
||||
|
||||
Other discussion, and **support requests** should go through the `#falco` channel in the open source slack, please join [here](https://slack.sysdig.com).
|
||||
Other discussion, and **support requests** should go through the `#falco` channel in the Kubernetes slack, please join [here](https://slack.k8s.io/).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Finally, on the proposed due date the assignees for the upcoming release proceed
|
||||
|
||||
### 1. Release notes
|
||||
- Let `YYYY-MM-DD` the day before of the [latest release](https://github.com/falcosecurity/falco/releases)
|
||||
- Check the release note block of every PR matching the `is:pr is:merged closed:>YYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+closed%3A%3EYYYY-MM-DD)
|
||||
- Check the release note block of every PR matching the `is:pr is:merged closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+closed%3A%3EYYYY-MM-DD)
|
||||
- Ensure the release note block follows the [commit convention](https://github.com/falcosecurity/falco/blob/master/CONTRIBUTING.md#commit-convention), otherwise fix its content
|
||||
- If the PR has no milestone, assign it to the milestone currently undergoing release
|
||||
- Check issues without a milestone (using [is:pr is:merged no:milestone closed:>YYYT-MM-DD](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+no%3Amilestone+closed%3A%3EYYYT-MM-DD) filter) and add them to the milestone currently undergoing release
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
#
|
||||
|
||||
set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}")
|
||||
set(CPACK_PACKAGE_VENDOR "Cloud Native Computing Foundation (CNCF) cncf.io.")
|
||||
set(CPACK_PACKAGE_CONTACT "cncf-falco-dev@lists.cncf.io") # todo: change this once we've got @falco.org addresses
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
@@ -12,17 +12,16 @@
|
||||
#
|
||||
include(ExternalProject)
|
||||
|
||||
set(CATCH2_PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix)
|
||||
set(CATCH2_INCLUDE ${CATCH2_PREFIX}/include)
|
||||
set(CATCH2_INCLUDE ${CMAKE_BINARY_DIR}/catch2-prefix/include)
|
||||
|
||||
set(CATCH_EXTERNAL_URL URL https://github.com/catchorg/catch2/archive/v2.12.1.tar.gz URL_HASH
|
||||
SHA256=e5635c082282ea518a8dd7ee89796c8026af8ea9068cd7402fb1615deacd91c3)
|
||||
|
||||
ExternalProject_Add(
|
||||
catch2
|
||||
PREFIX ${CATCH2_PREFIX}
|
||||
PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix
|
||||
${CATCH_EXTERNAL_URL}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CATCH2_PREFIX}/src/catch2/single_include/catch2/catch.hpp
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp
|
||||
${CATCH2_INCLUDE}/catch.hpp)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
@@ -10,17 +10,20 @@
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
#
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
set(HEDLEY_PREFIX ${CMAKE_BINARY_DIR}/hedley-prefix)
|
||||
set(HEDLEY_INCLUDE ${HEDLEY_PREFIX}/include)
|
||||
message(STATUS "Found hedley: include: ${HEDLEY_INCLUDE}")
|
||||
set(STRING_VIEW_LITE_PREFIX ${CMAKE_BINARY_DIR}/string-view-lite-prefix)
|
||||
set(STRING_VIEW_LITE_INCLUDE ${STRING_VIEW_LITE_PREFIX}/include)
|
||||
message(STATUS "Found string-view-lite: include: ${STRING_VIEW_LITE_INCLUDE}")
|
||||
|
||||
ExternalProject_Add(
|
||||
hedley
|
||||
PREFIX ${HEDLEY_PREFIX}
|
||||
GIT_REPOSITORY "https://github.com/nemequ/hedley.git"
|
||||
GIT_TAG "v13"
|
||||
string-view-lite
|
||||
PREFIX ${STRING_VIEW_LITE_PREFIX}
|
||||
GIT_REPOSITORY "https://github.com/martinmoene/string-view-lite.git"
|
||||
GIT_TAG "v1.4.0"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${HEDLEY_PREFIX}/src/hedley/hedley.h ${HEDLEY_INCLUDE}/hedley.h)
|
||||
INSTALL_COMMAND
|
||||
${CMAKE_COMMAND} -E copy ${STRING_VIEW_LITE_PREFIX}/src/string-view-lite/include/nonstd/string_view.hpp
|
||||
${STRING_VIEW_LITE_INCLUDE}/nonstd/string_view.hpp)
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 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.
|
||||
#
|
||||
|
||||
if(NOT USE_BUNDLED_DEPS)
|
||||
find_program(FLATBUFFERS_FLATC_EXECUTABLE NAMES flatc)
|
||||
find_path(FLATBUFFERS_INCLUDE_DIR NAMES flatbuffers/flatbuffers.h)
|
||||
|
||||
if(FLATBUFFERS_FLATC_EXECUTABLE AND FLATBUFFERS_INCLUDE_DIR)
|
||||
message(STATUS "Found flatbuffers: include: ${FLATBUFFERS_INCLUDE_DIR}, flatc: ${FLATBUFFERS_FLATC_EXECUTABLE}")
|
||||
else()
|
||||
message(FATAL_ERROR "Couldn't find system flatbuffers")
|
||||
endif()
|
||||
else()
|
||||
include(ExternalProject)
|
||||
|
||||
set(FLATBUFFERS_PREFIX ${CMAKE_BINARY_DIR}/flatbuffers-prefix)
|
||||
set(FLATBUFFERS_FLATC_EXECUTABLE
|
||||
${FLATBUFFERS_PREFIX}/bin/flatc
|
||||
CACHE INTERNAL "FlatBuffer compiler")
|
||||
set(FLATBUFFERS_INCLUDE_DIR
|
||||
${FLATBUFFERS_PREFIX}/include
|
||||
CACHE INTERNAL "FlatBuffer include directory")
|
||||
|
||||
ExternalProject_Add(
|
||||
flatbuffers
|
||||
PREFIX ${FLATBUFFERS_PREFIX}
|
||||
GIT_REPOSITORY "https://github.com/google/flatbuffers.git"
|
||||
GIT_TAG "v1.12.0"
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_INSTALL_PREFIX=${FLATBUFFERS_PREFIX}
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DFLATBUFFERS_CODE_COVERAGE=OFF
|
||||
-DFLATBUFFERS_BUILD_TESTS=OFF
|
||||
-DFLATBUFFERS_INSTALL=ON
|
||||
-DFLATBUFFERS_BUILD_FLATLIB=OFF
|
||||
-DFLATBUFFERS_BUILD_FLATC=ON
|
||||
-DFLATBUFFERS_BUILD_FLATHASH=OFF
|
||||
-DFLATBUFFERS_BUILD_GRPCTEST=OFF
|
||||
-DFLATBUFFERS_BUILD_SHAREDLIB=OFF
|
||||
BUILD_BYPRODUCTS ${FLATBUFFERS_FLATC_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
# From FindFlatBuffer.cmake
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FlatBuffers DEFAULT_MSG FLATBUFFERS_FLATC_EXECUTABLE FLATBUFFERS_INCLUDE_DIR)
|
||||
|
||||
if(FLATBUFFERS_FOUND)
|
||||
function(FLATBUFFERS_GENERATE_C_HEADERS Name)
|
||||
set(FLATC_OUTPUTS)
|
||||
foreach(FILE ${ARGN})
|
||||
get_filename_component(FLATC_OUTPUT ${FILE} NAME_WE)
|
||||
set(FLATC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FLATC_OUTPUT}_generated.h")
|
||||
|
||||
list(APPEND FLATC_OUTPUTS ${FLATC_OUTPUT})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${FLATC_OUTPUT}
|
||||
COMMAND ${FLATBUFFERS_FLATC_EXECUTABLE} ARGS -c -o "${CMAKE_CURRENT_BINARY_DIR}/" ${FILE}
|
||||
DEPENDS ${FILE}
|
||||
COMMENT "Building C++ header for ${FILE}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endforeach()
|
||||
set(${Name}_OUTPUTS
|
||||
${FLATC_OUTPUTS}
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
set(FLATBUFFERS_INCLUDE_DIRS ${FLATBUFFERS_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
else()
|
||||
set(FLATBUFFERS_INCLUDE_DIR)
|
||||
endif()
|
||||
@@ -1,3 +1,16 @@
|
||||
#
|
||||
# Copyright (C) 2020 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.
|
||||
#
|
||||
|
||||
# Retrieve git ref and commit hash
|
||||
include(GetGitRevisionDescription)
|
||||
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#
|
||||
# Copyright (C) 2020 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.
|
||||
#
|
||||
if(NOT USE_BUNDLED_DEPS)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
message(STATUS "Found openssl: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
@@ -16,7 +16,7 @@ set(SYSDIG_CMAKE_WORKING_DIR "${CMAKE_BINARY_DIR}/sysdig-repo")
|
||||
|
||||
# this needs to be here at the top
|
||||
if(USE_BUNDLED_DEPS)
|
||||
# explicitly force this dependency to use the system OpenSSL
|
||||
# explicitly force this dependency to use the bundled OpenSSL
|
||||
set(USE_BUNDLED_OPENSSL ON)
|
||||
endif()
|
||||
|
||||
@@ -26,8 +26,8 @@ file(MAKE_DIRECTORY ${SYSDIG_CMAKE_WORKING_DIR})
|
||||
# To update sysdig version for the next release, change the default below
|
||||
# In case you want to test against another sysdig version just pass the variable - ie., `cmake -DSYSDIG_VERSION=dev ..`
|
||||
if(NOT SYSDIG_VERSION)
|
||||
set(SYSDIG_VERSION "96bd9bc560f67742738eb7255aeb4d03046b8045")
|
||||
set(SYSDIG_CHECKSUM "SHA256=766e8952a36a4198fd976b9d848523e6abe4336612188e4fc911e217d8e8a00d")
|
||||
set(SYSDIG_VERSION "422ab408c5706fbdd45432646cc197eb79459169")
|
||||
set(SYSDIG_CHECKSUM "SHA256=367db2a480bca327a46f901bcc8384f151231bcddba88c719a06cf13971f4ab5")
|
||||
endif()
|
||||
set(PROBE_VERSION "${SYSDIG_VERSION}")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 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
|
||||
|
||||
@@ -6,9 +6,9 @@ This directory contains various ways to package Falco as a container and related
|
||||
|
||||
| Name | Directory | Description |
|
||||
|---|---|---|
|
||||
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/stable | Falco (DEB built from git tag or from the master) with all the building toolchain. |
|
||||
| [falcosecurity/falco:latest-slim](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_-slim](https://hub.docker.com/repository/docker/falcosecurity/falco),[falcosecurity/falco:master-slim](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/slim | Falco (DEB build from git tag or from the master) without the building toolchain. |
|
||||
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/falco | Falco (DEB built from git tag or from the master) with all the building toolchain. |
|
||||
| [falcosecurity/falco-driver-loader:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:master](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader) | docker/driver-loader | `falco-driver-loader` as entrypoint with the building toolchain. |
|
||||
| [falcosecurity/falco-no-driver:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver), [falcosecurity/falco-no-driver:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver),[falcosecurity/falco-no-driver:master](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver) | docker/no-driver | Falco (TGZ built from git tag or from the master) without the building toolchain. |
|
||||
| [falcosecurity/falco-builder:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-builder) | docker/builder | The complete build tool chain for compiling Falco from source. See [the documentation](https://falco.org/docs/source/) for more details on building from source. Used to build Falco (CI). |
|
||||
| [falcosecurity/falco-tester:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-tester) | docker/tester | Container image for running the Falco test suite. Used to run Falco integration tests (CI). |
|
||||
| _to not be published_ | docker/local | Built on-the-fly and used by falco-tester. |
|
||||
|
||||
@@ -25,4 +25,4 @@ do
|
||||
ln -s "$i" "/usr/src/$base"
|
||||
done
|
||||
|
||||
/usr/bin/falco-driver-loader $1
|
||||
/usr/bin/falco-driver-loader "$@"
|
||||
61
docker/no-driver/Dockerfile
Normal file
61
docker/no-driver/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
||||
FROM ubuntu:18.04 as ubuntu
|
||||
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
ARG FALCO_VERSION
|
||||
ARG VERSION_BUCKET=bin
|
||||
|
||||
ENV FALCO_VERSION=${FALCO_VERSION}
|
||||
ENV VERSION_BUCKET=${VERSION_BUCKET}
|
||||
|
||||
WORKDIR /
|
||||
|
||||
ADD https://bintray.com/api/ui/download/falcosecurity/${VERSION_BUCKET}/x86_64/falco-${FALCO_VERSION}-x86_64.tar.gz /
|
||||
|
||||
RUN apt-get update -y && \
|
||||
apt-get install -y libyaml-0-2 binutils && \
|
||||
tar -xvf falco-${FALCO_VERSION}-x86_64.tar.gz && \
|
||||
rm -f falco-${FALCO_VERSION}-x86_64.tar.gz && \
|
||||
mv falco-${FALCO_VERSION}-x86_64 falco && \
|
||||
strip falco/usr/bin/falco && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \
|
||||
&& mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=ubuntu /lib/x86_64-linux-gnu/libanl.so.1 \
|
||||
/lib/x86_64-linux-gnu/libc.so.6 \
|
||||
/lib/x86_64-linux-gnu/libdl.so.2 \
|
||||
/lib/x86_64-linux-gnu/libgcc_s.so.1 \
|
||||
/lib/x86_64-linux-gnu/libm.so.6 \
|
||||
/lib/x86_64-linux-gnu/libnsl.so.1 \
|
||||
/lib/x86_64-linux-gnu/libnss_compat.so.2 \
|
||||
/lib/x86_64-linux-gnu/libnss_files.so.2 \
|
||||
/lib/x86_64-linux-gnu/libnss_nis.so.2 \
|
||||
/lib/x86_64-linux-gnu/libpthread.so.0 \
|
||||
/lib/x86_64-linux-gnu/librt.so.1 \
|
||||
/lib/x86_64-linux-gnu/libz.so.1 \
|
||||
/lib/x86_64-linux-gnu/
|
||||
|
||||
COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libstdc++.so.6 \
|
||||
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
|
||||
|
||||
COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libyaml-0.so.2.0.5 \
|
||||
/usr/lib/x86_64-linux-gnu/libyaml-0.so.2
|
||||
|
||||
COPY --from=ubuntu /etc/ld.so.cache \
|
||||
/etc/nsswitch.conf \
|
||||
/etc/ld.so.cache \
|
||||
/etc/passwd \
|
||||
/etc/group \
|
||||
/etc/
|
||||
|
||||
COPY --from=ubuntu /etc/default/nss /etc/default/nss
|
||||
COPY --from=ubuntu /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
|
||||
|
||||
COPY --from=ubuntu /falco /
|
||||
|
||||
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]
|
||||
@@ -1,48 +0,0 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
LABEL RUN="docker run -i -t -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro --name <name> <image>"
|
||||
|
||||
ARG FALCO_VERSION=latest
|
||||
ARG VERSION_BUCKET=deb
|
||||
|
||||
ENV FALCO_VERSION=${FALCO_VERSION}
|
||||
ENV VERSION_BUCKET=${VERSION_BUCKET}
|
||||
|
||||
ENV HOST_ROOT /host
|
||||
ENV HOME /root
|
||||
|
||||
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
# bash-completion \
|
||||
# bc \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg2 \
|
||||
jq \
|
||||
# netcat \
|
||||
# xz-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add - \
|
||||
&& echo "deb https://dl.bintray.com/falcosecurity/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
|
||||
&& apt-get update -y \
|
||||
&& if [ "$FALCO_VERSION" = "latest" ]; then apt-get install -y --no-install-recommends falco; else apt-get install -y --no-install-recommends falco=${FALCO_VERSION}; fi \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Change the falco config within the container to enable ISO 8601
|
||||
# output.
|
||||
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /etc/falco/falco.yaml > /etc/falco/falco.yaml.new \
|
||||
&& mv /etc/falco/falco.yaml.new /etc/falco/falco.yaml
|
||||
|
||||
# Some base images have an empty /lib/modules by default
|
||||
# If it's not empty, docker build will fail instead of
|
||||
# silently overwriting the existing directory
|
||||
RUN rm -df /lib/modules \
|
||||
&& ln -s $HOST_ROOT/lib/modules /lib/modules
|
||||
|
||||
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]
|
||||
@@ -30,7 +30,7 @@ How to use.
|
||||
|
||||
How to build.
|
||||
|
||||
* cd docker/builder && DOCKER_BUILDKIT=1 docker build -t falcosecurity/falco-tester .
|
||||
* cd docker/tester && DOCKER_BUILDKIT=1 docker build -t falcosecurity/falco-tester .
|
||||
|
||||
Environment.
|
||||
|
||||
|
||||
28
falco.yaml
28
falco.yaml
@@ -139,7 +139,7 @@ stdout_output:
|
||||
webserver:
|
||||
enabled: true
|
||||
listen_port: 8765
|
||||
k8s_audit_endpoint: /k8s_audit
|
||||
k8s_audit_endpoint: /k8s-audit
|
||||
ssl_enabled: false
|
||||
ssl_certificate: /etc/falco/falco.pem
|
||||
|
||||
@@ -167,21 +167,35 @@ http_output:
|
||||
enabled: false
|
||||
url: http://some.url
|
||||
|
||||
# gRPC server configuration.
|
||||
# The gRPC server is secure by default (mutual TLS) so you need to generate certificates and update their paths here.
|
||||
# Falco supports running a gRPC server with two main binding types
|
||||
# 1. Over the network with mandatory mutual TLS authentication (mTLS)
|
||||
# 2. Over a local unix socket with no authentication
|
||||
# By default, the gRPC server is disabled, with no enabled services (see grpc_output)
|
||||
# please comment/uncomment and change accordingly the options below to configure it.
|
||||
# Important note: if Falco has any troubles creating the gRPC server
|
||||
# this information will be logged, however the main Falco daemon will not be stopped.
|
||||
# gRPC server over network with (mandatory) mutual TLS configuration.
|
||||
# This gRPC server is secure by default so you need to generate certificates and update their paths here.
|
||||
# By default the gRPC server is off.
|
||||
# You can configure the address to bind and expose it.
|
||||
# By modifying the threadiness configuration you can fine-tune the number of threads (and context) it will use.
|
||||
# grpc:
|
||||
# enabled: true
|
||||
# bind_address: "0.0.0.0:5060"
|
||||
# threadiness: 8
|
||||
# private_key: "/etc/falco/certs/server.key"
|
||||
# cert_chain: "/etc/falco/certs/server.crt"
|
||||
# root_certs: "/etc/falco/certs/ca.crt"
|
||||
|
||||
# gRPC server using an unix socket
|
||||
grpc:
|
||||
enabled: false
|
||||
bind_address: "0.0.0.0:5060"
|
||||
bind_address: "unix:///var/run/falco.sock"
|
||||
threadiness: 8
|
||||
private_key: "/etc/falco/certs/server.key"
|
||||
cert_chain: "/etc/falco/certs/server.crt"
|
||||
root_certs: "/etc/falco/certs/ca.crt"
|
||||
|
||||
# gRPC output service.
|
||||
# By default it is off.
|
||||
# By enabling this all the output events will be kept in memory until you read them with a gRPC client.
|
||||
# Make sure to have a consumer for them or leave this disabled.
|
||||
grpc_output:
|
||||
enabled: false
|
||||
|
||||
72
proposals/20200623-rules-required-engine-version-scope.md
Normal file
72
proposals/20200623-rules-required-engine-version-scope.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Required engine version scoping for rules
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Summary](#summary)
|
||||
- [Motivation](#motivation)
|
||||
* [Goals](#goals)
|
||||
* [Non-Goals](#non-goals)
|
||||
* [Use cases](#use-cases)
|
||||
* [Example of rules file](#example-of-rules-file)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Summary
|
||||
|
||||
We want to be able to scope the `required_engine_version` field also for the specific rule/macro
|
||||
other than just for the currently rules file.
|
||||
|
||||
## Motivation
|
||||
|
||||
While the Falco engine and drivers evolve, new fields are added. While new fields are added,
|
||||
the upstream rules evolve too. This menas that we need a mechanism to be able to tell the users
|
||||
and the engine at load time "Hey, this rule is compatible". We currently do that at file level
|
||||
using the `required_engine_version` field.
|
||||
|
||||
While this is very handy, this also does not help users to understand what are the rules that require,
|
||||
let's say engine verison `6` instead of `5`. It's very likely that 99% of a file is compatible with engine `2` while
|
||||
in reality only one rule is not.
|
||||
|
||||
This is particularly useful for rules sharing. Users with different Falco versions can share rules containing this field
|
||||
and instead of getting `<NA>` they can be informed immediatelly about the incompatibility.
|
||||
|
||||
### Goals
|
||||
|
||||
- To add a new field `required_engine_version` scoped to the `rule` and `macro` sections.
|
||||
- The new fields take priority over the file global `required_engine_version` field.
|
||||
|
||||
### Non-Goals
|
||||
|
||||
- NONE
|
||||
|
||||
### Use cases
|
||||
|
||||
- Better understanding of what are the specific rules that need a specific engine version
|
||||
- Helps for when we want to make an API to create/delete/modify rules at runtime. In such a dynamic scenarios it's very useful for users to just know in advance if that rule is compatible
|
||||
- Makes easier to spot `<NA>` fields happening for `required_engine_version` mismatches since the incompatibility is immediately reported by the engine.
|
||||
|
||||
|
||||
### Example of rules file
|
||||
|
||||
```yaml
|
||||
- required_engine_version: 2
|
||||
|
||||
- list: cat_binaries
|
||||
items: [cat]
|
||||
|
||||
- list: cat_capable_binaries
|
||||
items: [cat_binaries]
|
||||
|
||||
- macro: is_cat
|
||||
condition: proc.name in (cat_capable_binaries)
|
||||
|
||||
- rule: open_from_cat
|
||||
required_engine_version: 4
|
||||
desc: A process named cat does an open
|
||||
condition: evt.type=open and is_cat
|
||||
output: "An open was seen (command=%proc.cmdline)"
|
||||
priority: WARNING
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
@@ -55,6 +55,7 @@
|
||||
- macro: proc_name_exists
|
||||
condition: (proc.name!="<NA>")
|
||||
|
||||
# todo(leogr): we miss "renameat2", but it's not yet supported by sinsp
|
||||
- macro: rename
|
||||
condition: evt.type in (rename, renameat)
|
||||
- macro: mkdir
|
||||
@@ -80,17 +81,29 @@
|
||||
|
||||
- macro: bin_dir_mkdir
|
||||
condition: >
|
||||
(evt.arg[1] startswith /bin/ or
|
||||
evt.arg[1] startswith /sbin/ or
|
||||
evt.arg[1] startswith /usr/bin/ or
|
||||
evt.arg[1] startswith /usr/sbin/)
|
||||
(evt.arg.path startswith /bin/ or
|
||||
evt.arg.path startswith /sbin/ or
|
||||
evt.arg.path startswith /usr/bin/ or
|
||||
evt.arg.path startswith /usr/sbin/)
|
||||
|
||||
- macro: bin_dir_rename
|
||||
condition: >
|
||||
evt.arg[1] startswith /bin/ or
|
||||
evt.arg[1] startswith /sbin/ or
|
||||
evt.arg[1] startswith /usr/bin/ or
|
||||
evt.arg[1] startswith /usr/sbin/
|
||||
(evt.arg.path startswith /bin/ or
|
||||
evt.arg.path startswith /sbin/ or
|
||||
evt.arg.path startswith /usr/bin/ or
|
||||
evt.arg.path startswith /usr/sbin/ or
|
||||
evt.arg.name startswith /bin/ or
|
||||
evt.arg.name startswith /sbin/ or
|
||||
evt.arg.name startswith /usr/bin/ or
|
||||
evt.arg.name startswith /usr/sbin/ or
|
||||
evt.arg.oldpath startswith /bin/ or
|
||||
evt.arg.oldpath startswith /sbin/ or
|
||||
evt.arg.oldpath startswith /usr/bin/ or
|
||||
evt.arg.oldpath startswith /usr/sbin/ or
|
||||
evt.arg.newpath startswith /bin/ or
|
||||
evt.arg.newpath startswith /sbin/ or
|
||||
evt.arg.newpath startswith /usr/bin/ or
|
||||
evt.arg.newpath startswith /usr/sbin/)
|
||||
|
||||
- macro: etc_dir
|
||||
condition: fd.name startswith /etc/
|
||||
@@ -707,7 +720,7 @@
|
||||
|
||||
- macro: lvprogs_writing_conf
|
||||
condition: >
|
||||
(proc.name in (dmeventd,lvcreate,pvscan) and
|
||||
(proc.name in (dmeventd,lvcreate,pvscan,lvs) and
|
||||
(fd.name startswith /etc/lvm/archive or
|
||||
fd.name startswith /etc/lvm/backup or
|
||||
fd.name startswith /etc/lvm/cache))
|
||||
@@ -929,6 +942,12 @@
|
||||
NOTICE
|
||||
tags: [filesystem, mitre_persistence]
|
||||
|
||||
# Users should overwrite this macro to specify conditions under which a
|
||||
# write under the binary dir is ignored. For example, it may be okay to
|
||||
# install a binary in the context of a ci/cd build.
|
||||
- macro: user_known_write_below_binary_dir_activities
|
||||
condition: (never_true)
|
||||
|
||||
- rule: Write below binary dir
|
||||
desc: an attempt to write to any file below a set of binary directories
|
||||
condition: >
|
||||
@@ -937,6 +956,7 @@
|
||||
and not exe_running_docker_save
|
||||
and not python_running_get_pip
|
||||
and not python_running_ms_oms
|
||||
and not user_known_write_below_binary_dir_activities
|
||||
output: >
|
||||
File below a known binary directory opened for writing (user=%user.name
|
||||
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository)
|
||||
@@ -1356,6 +1376,9 @@
|
||||
- macro: runc_writing_exec_fifo
|
||||
condition: (proc.cmdline="runc:[1:CHILD] init" and fd.name=/exec.fifo)
|
||||
|
||||
- macro: runc_writing_var_lib_docker
|
||||
condition: (proc.cmdline="runc:[1:CHILD] init" and evt.arg.filename startswith /var/lib/docker)
|
||||
|
||||
- rule: Write below root
|
||||
desc: an attempt to write to any file directly below / or /root
|
||||
condition: >
|
||||
@@ -1505,7 +1528,7 @@
|
||||
|
||||
- rule: Modify binary dirs
|
||||
desc: an attempt to modify any file below a set of binary directories.
|
||||
condition: (bin_dir_rename) and modify and not package_mgmt_procs and not exe_running_docker_save
|
||||
condition: bin_dir_rename and modify and not package_mgmt_procs and not exe_running_docker_save
|
||||
output: >
|
||||
File below known binary directory renamed/removed (user=%user.name command=%proc.cmdline
|
||||
pcmdline=%proc.pcmdline operation=%evt.type file=%fd.name %evt.args container_id=%container.id image=%container.image.repository)
|
||||
@@ -2225,7 +2248,7 @@
|
||||
desc: creating any files below /dev other than known programs that manage devices. Some rootkits hide files in /dev.
|
||||
condition: >
|
||||
fd.directory = /dev and
|
||||
(evt.type = creat or (evt.type = open and evt.arg.flags contains O_CREAT))
|
||||
(evt.type = creat or ((evt.type = open or evt.type = openat) and evt.arg.flags contains O_CREAT))
|
||||
and not proc.name in (dev_creation_binaries)
|
||||
and not fd.name in (allowed_dev_files)
|
||||
and not fd.name startswith /dev/tty
|
||||
@@ -2437,7 +2460,9 @@
|
||||
|
||||
- macro: trusted_logging_images
|
||||
condition: (container.image.repository endswith "splunk/fluentd-hec" or
|
||||
container.image.repository endswith "fluent/fluentd-kubernetes-daemonset")
|
||||
container.image.repository endswith "fluent/fluentd-kubernetes-daemonset" or
|
||||
container.image.repository endswith "openshift3/ose-logging-fluentd" or
|
||||
container.image.repository endswith "containernetworking/azure-npm")
|
||||
|
||||
- rule: Clear Log Activities
|
||||
desc: Detect clearing of critical log files
|
||||
@@ -2500,7 +2525,7 @@
|
||||
- rule: Delete Bash History
|
||||
desc: Detect bash history deletion
|
||||
condition: >
|
||||
((spawned_process and proc.name in (shred, rm, mv) and proc.args contains "bash_history") or
|
||||
((spawned_process and proc.name in (shred, rm, mv) and proc.args contains "bash_history") or
|
||||
(open_write and fd.name contains "bash_history" and evt.arg.flags contains "O_TRUNC"))
|
||||
output: >
|
||||
Shell history had been deleted or renamed (user=%user.name type=%evt.type command=%proc.cmdline fd.name=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath %container.info)
|
||||
@@ -2514,6 +2539,12 @@
|
||||
- list: user_known_chmod_applications
|
||||
items: [hyperkube, kubelet]
|
||||
|
||||
# This macro should be overridden in user rules as needed. This is useful if a given application
|
||||
# should not be ignored alltogether with the user_known_chmod_applications list, but only in
|
||||
# specific conditions.
|
||||
- macro: user_known_set_setuid_or_setgid_bit_conditions
|
||||
condition: (never_true)
|
||||
|
||||
- rule: Set Setuid or Setgid bit
|
||||
desc: >
|
||||
When the setuid or setgid bits are set for an application,
|
||||
@@ -2523,6 +2554,7 @@
|
||||
consider_all_chmods and chmod and (evt.arg.mode contains "S_ISUID" or evt.arg.mode contains "S_ISGID")
|
||||
and not proc.name in (user_known_chmod_applications)
|
||||
and not exe_running_docker_save
|
||||
and not user_known_set_setuid_or_setgid_bit_conditions
|
||||
output: >
|
||||
Setuid or setgid bit is set via chmod (fd=%evt.arg.fd filename=%evt.arg.filename mode=%evt.arg.mode user=%user.name process=%proc.name
|
||||
command=%proc.cmdline container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||
@@ -2556,7 +2588,7 @@
|
||||
items: [rsync, scp, sftp, dcp]
|
||||
|
||||
- macro: remote_file_copy_procs
|
||||
condition: (proc.name in (remote_File_copy_binaries))
|
||||
condition: (proc.name in (remote_file_copy_binaries))
|
||||
|
||||
- rule: Launch Remote File Copy Tools in Container
|
||||
desc: Detect remote file copy tools launched in container
|
||||
@@ -2687,11 +2719,16 @@
|
||||
# Whitelist for known docker client binaries run inside container
|
||||
# - k8s.gcr.io/fluentd-gcp-scaler in GCP/GKE
|
||||
- macro: user_known_k8s_client_container
|
||||
condition: (k8s.ns.name="kube-system" and container.image.repository=k8s.gcr.io/fluentd-gcp-scaler)
|
||||
|
||||
condition: >
|
||||
(k8s.ns.name="kube-system" and container.image.repository=k8s.gcr.io/fluentd-gcp-scaler) or
|
||||
container.image.repository=mcr.microsoft.com/aks/hcp/hcp-tunnel-front
|
||||
|
||||
- macro: user_known_k8s_client_container_parens
|
||||
condition: (user_known_k8s_client_container)
|
||||
|
||||
- rule: The docker client is executed in a container
|
||||
desc: Detect a k8s client tool executed inside a container
|
||||
condition: spawned_process and container and not user_known_k8s_client_container and proc.name in (k8s_client_binaries)
|
||||
condition: spawned_process and container and not user_known_k8s_client_container_parens and proc.name in (k8s_client_binaries)
|
||||
output: "Docker or kubernetes client executed in container (user=%user.name %container.info parent=%proc.pname cmdline=%proc.cmdline image=%container.image.repository:%container.image.tag)"
|
||||
priority: WARNING
|
||||
tags: [container, mitre_execution]
|
||||
@@ -2712,7 +2749,7 @@
|
||||
output: Packet socket was created in a container (user=%user.name command=%proc.cmdline socket_info=%evt.args container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||
priority: NOTICE
|
||||
tags: [network, mitre_discovery]
|
||||
|
||||
|
||||
# Change to (always_true) to enable rule 'Network connection outside local subnet'
|
||||
- macro: enabled_rule_network_only_subnet
|
||||
condition: (never_true)
|
||||
@@ -2728,7 +2765,7 @@
|
||||
- macro: network_local_subnet
|
||||
condition: >
|
||||
fd.rnet in (rfc_1918_addresses) or
|
||||
fd.ip = "0.0.0.0" or
|
||||
fd.ip = "0.0.0.0" or
|
||||
fd.net = "127.0.0.0/8"
|
||||
|
||||
# # How to test:
|
||||
@@ -2788,7 +2825,7 @@
|
||||
not fd.sport in (authorized_server_port)
|
||||
output: >
|
||||
Network connection outside authorized port and binary
|
||||
(command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id
|
||||
(command=%proc.cmdline connection=%fd.name user=%user.name container_id=%container.id
|
||||
image=%container.image.repository)
|
||||
priority: WARNING
|
||||
tags: [network]
|
||||
@@ -2800,6 +2837,46 @@
|
||||
Redirect stdout/stdin to network connection (user=%user.name %container.info process=%proc.name parent=%proc.pname cmdline=%proc.cmdline terminal=%proc.tty container_id=%container.id image=%container.image.repository fd.name=%fd.name fd.num=%fd.num fd.type=%fd.type fd.sip=%fd.sip)
|
||||
priority: WARNING
|
||||
|
||||
# The two Container Drift rules below will fire when a new executable is created in a container.
|
||||
# There are two ways to create executables - file is created with execution permissions or permissions change of existing file.
|
||||
# We will use a new sysdig filter, is_open_exec, to find all files creations with execution permission, and will trace all chmods in a container.
|
||||
# The use case we are targeting here is an attempt to execute code that was not shipped as part of a container (drift) -
|
||||
# an activity that might be malicious or non-compliant.
|
||||
# Two things to pay attention to:
|
||||
# 1) In most cases, 'docker cp' will not be identified, but the assumption is that if an attacker gained access to the container runtime daemon, they are already privileged
|
||||
# 2) Drift rules will be noisy in environments in which containers are built (e.g. docker build)
|
||||
|
||||
- rule: Container Drift Detected (chmod)
|
||||
desc: New executable created in a container due to chmod
|
||||
condition: >
|
||||
chmod and
|
||||
consider_all_chmods and
|
||||
container and
|
||||
not runc_writing_exec_fifo and
|
||||
not runc_writing_var_lib_docker and
|
||||
evt.rawres>=0 and
|
||||
((evt.arg.mode contains "S_IXUSR") or
|
||||
(evt.arg.mode contains "S_IXGRP") or
|
||||
(evt.arg.mode contains "S_IXOTH"))
|
||||
output: Drift detected (chmod), new executable created in a container (user=%user.name command=%proc.cmdline filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode event=%evt.type)
|
||||
priority: ERROR
|
||||
|
||||
# ****************************************************************************
|
||||
# * "Container Drift Detected (open+create)" requires FALCO_ENGINE_VERSION 6 *
|
||||
# ****************************************************************************
|
||||
- rule: Container Drift Detected (open+create)
|
||||
desc: New executable created in a container due to open+create
|
||||
condition: >
|
||||
evt.type in (open,openat,creat) and
|
||||
evt.is_open_exec=true and
|
||||
container and
|
||||
not runc_writing_exec_fifo and
|
||||
not runc_writing_var_lib_docker and
|
||||
evt.rawres>=0
|
||||
output: Drift detected (open+create), new executable created in a container (user=%user.name command=%proc.cmdline filename=%evt.arg.filename name=%evt.arg.name mode=%evt.arg.mode event=%evt.type)
|
||||
priority: ERROR
|
||||
|
||||
|
||||
# Application rules have moved to application_rules.yaml. Please look
|
||||
# there if you want to enable them by adding to
|
||||
# falco_rules.local.yaml.
|
||||
|
||||
@@ -40,8 +40,14 @@
|
||||
|
||||
# If you wish to restrict activity to a specific set of users, override/append to this list.
|
||||
# users created by kops are included
|
||||
- list: vertical_pod_autoscaler_users
|
||||
items: ["vpa-recommender", "vpa-updater"]
|
||||
|
||||
- list: allowed_k8s_users
|
||||
items: ["minikube", "minikube-user", "kubelet", "kops", "admin", "kube", "kube-proxy"]
|
||||
items: [
|
||||
"minikube", "minikube-user", "kubelet", "kops", "admin", "kube", "kube-proxy",
|
||||
vertical_pod_autoscaler_users,
|
||||
]
|
||||
|
||||
- rule: Disallowed K8s User
|
||||
desc: Detect any k8s operation by users outside of an allowed set of users.
|
||||
@@ -180,7 +186,7 @@
|
||||
- rule: Anonymous Request Allowed
|
||||
desc: >
|
||||
Detect any request made by the anonymous user that was allowed
|
||||
condition: kevt and ka.user.name=system:anonymous and ka.auth.decision!=reject and not health_endpoint
|
||||
condition: kevt and ka.user.name=system:anonymous and ka.auth.decision="allow" and not health_endpoint
|
||||
output: Request by anonymous user allowed (user=%ka.user.name verb=%ka.verb uri=%ka.uri reason=%ka.auth.reason))
|
||||
priority: WARNING
|
||||
source: k8s_audit
|
||||
|
||||
@@ -64,8 +64,8 @@ do_start()
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
if [ ! -d /sys/module/falco_probe ]; then
|
||||
/sbin/modprobe falco-probe || exit 1
|
||||
if [ ! -d /sys/module/falco ]; then
|
||||
/sbin/modprobe falco || exit 1
|
||||
fi
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
@@ -96,7 +96,7 @@ do_stop()
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
/sbin/rmmod falco-probe
|
||||
/sbin/rmmod falco
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#
|
||||
# Returns 1 if $cos_ver > $base_ver, 0 otherwise
|
||||
#
|
||||
cos_version_greater()
|
||||
{
|
||||
cos_version_greater() {
|
||||
if [[ $cos_ver == "${base_ver}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -68,29 +67,29 @@ cos_version_greater()
|
||||
|
||||
get_kernel_config() {
|
||||
if [ -f /proc/config.gz ]; then
|
||||
echo "Found kernel config at /proc/config.gz"
|
||||
echo "* Found kernel config at /proc/config.gz"
|
||||
KERNEL_CONFIG_PATH=/proc/config.gz
|
||||
elif [ -f "/boot/config-${KERNEL_RELEASE}" ]; then
|
||||
echo "Found kernel config at /boot/config-${KERNEL_RELEASE}"
|
||||
echo "* Found kernel config at /boot/config-${KERNEL_RELEASE}"
|
||||
KERNEL_CONFIG_PATH=/boot/config-${KERNEL_RELEASE}
|
||||
elif [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/boot/config-${KERNEL_RELEASE}" ]; then
|
||||
echo "Found kernel config at ${HOST_ROOT}/boot/config-${KERNEL_RELEASE}"
|
||||
echo "* Found kernel config at ${HOST_ROOT}/boot/config-${KERNEL_RELEASE}"
|
||||
KERNEL_CONFIG_PATH="${HOST_ROOT}/boot/config-${KERNEL_RELEASE}"
|
||||
elif [ -f "/usr/lib/ostree-boot/config-${KERNEL_RELEASE}" ]; then
|
||||
echo "Found kernel config at /usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
echo "* Found kernel config at /usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
KERNEL_CONFIG_PATH="/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
elif [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}" ]; then
|
||||
echo "Found kernel config at ${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
echo "* Found kernel config at ${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
KERNEL_CONFIG_PATH="${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
|
||||
elif [ -f "/lib/modules/${KERNEL_RELEASE}/config" ]; then
|
||||
# this code works both for native host and agent container assuming that
|
||||
# Dockerfile sets up the desired symlink /lib/modules -> $HOST_ROOT/lib/modules
|
||||
echo "Found kernel config at /lib/modules/${KERNEL_RELEASE}/config"
|
||||
echo "* Found kernel config at /lib/modules/${KERNEL_RELEASE}/config"
|
||||
KERNEL_CONFIG_PATH="/lib/modules/${KERNEL_RELEASE}/config"
|
||||
fi
|
||||
|
||||
if [ -z "${KERNEL_CONFIG_PATH}" ]; then
|
||||
echo "Cannot find kernel config"
|
||||
>&2 echo "Cannot find kernel config"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -131,7 +130,7 @@ get_target_id() {
|
||||
if [[ $KERNEL_RELEASE == *"aws"* ]]; then
|
||||
TARGET_ID="ubuntu-aws"
|
||||
else
|
||||
TARGET_ID="ubuntu"
|
||||
TARGET_ID="ubuntu-generic"
|
||||
fi
|
||||
;;
|
||||
(*)
|
||||
@@ -140,6 +139,59 @@ get_target_id() {
|
||||
esac
|
||||
}
|
||||
|
||||
load_kernel_module_compile() {
|
||||
# skip dkms on UEK hosts because it will always fail
|
||||
if [[ $(uname -r) == *uek* ]]; then
|
||||
echo "* Skipping dkms install for UEK host"
|
||||
else
|
||||
if hash dkms &>/dev/null; then
|
||||
echo "* Trying to dkms install ${DRIVER_NAME} module"
|
||||
if dkms install -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
|
||||
echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod"
|
||||
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
|
||||
exit 0
|
||||
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)"
|
||||
exit 0
|
||||
else
|
||||
echo "* Unable to insmod ${DRIVER_NAME} module"
|
||||
fi
|
||||
else
|
||||
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
|
||||
if [ -f "${DKMS_LOG}" ]; then
|
||||
echo "* Running dkms build failed, dumping ${DKMS_LOG}"
|
||||
cat "${DKMS_LOG}"
|
||||
else
|
||||
echo "* Running dkms build failed, couldn't find ${DKMS_LOG}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "* Skipping dkms install (dkms not found)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
load_kernel_module_download() {
|
||||
|
||||
get_target_id
|
||||
|
||||
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
|
||||
|
||||
local URL
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)
|
||||
|
||||
echo "* Trying to download prebuilt module from ${URL}"
|
||||
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
|
||||
echo "* Download succeeded"
|
||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module loaded"
|
||||
exit $?
|
||||
else
|
||||
>&2 echo "Download failed, consider compiling your own ${DRIVER_NAME} module and loading it or getting in touch with the Falco community"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
load_kernel_module() {
|
||||
if ! hash lsmod > /dev/null 2>&1; then
|
||||
>&2 echo "This program requires lsmod"
|
||||
@@ -177,67 +229,160 @@ load_kernel_module() {
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# skip dkms on UEK hosts because it will always fail`
|
||||
if [[ $(uname -r) == *uek* ]]; then
|
||||
echo "* Skipping dkms install for UEK host"
|
||||
else
|
||||
if hash dkms &>/dev/null && dkms install -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
|
||||
echo "* Trying to load a dkms ${DRIVER_NAME} module, if present"
|
||||
|
||||
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
|
||||
echo "${DRIVER_NAME} module found and loaded in dkms"
|
||||
exit 0
|
||||
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
|
||||
echo "${DRIVER_NAME} module found and loaded in dkms (xz)"
|
||||
exit 0
|
||||
else
|
||||
echo "* Unable to insmod"
|
||||
fi
|
||||
else
|
||||
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
|
||||
if [ -f "${DKMS_LOG}" ]; then
|
||||
echo "* Running dkms build failed, dumping ${DKMS_LOG}"
|
||||
cat "${DKMS_LOG}"
|
||||
else
|
||||
echo "* Running dkms build failed, couldn't find ${DKMS_LOG}"
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ENABLE_COMPILE" ]; then
|
||||
load_kernel_module_compile
|
||||
fi
|
||||
|
||||
|
||||
echo "* Trying to load a system ${DRIVER_NAME} driver, if present"
|
||||
|
||||
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
|
||||
echo "${DRIVER_NAME} module found and loaded with modprobe"
|
||||
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "* Trying to find a prebuilt ${DRIVER_NAME} module for kernel ${KERNEL_RELEASE}"
|
||||
|
||||
echo "* Trying to find locally a prebuilt ${DRIVER_NAME} module for kernel ${KERNEL_RELEASE}, if present"
|
||||
|
||||
get_target_id
|
||||
|
||||
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
|
||||
|
||||
if [ -f "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" ]; then
|
||||
echo "Found a prebuilt module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
|
||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"
|
||||
echo "* Found a prebuilt module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
|
||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module loaded"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
local URL
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)
|
||||
if [ -n "$ENABLE_DOWNLOAD" ]; then
|
||||
load_kernel_module_download
|
||||
fi
|
||||
}
|
||||
|
||||
echo "* Trying to download prebuilt module from ${URL}"
|
||||
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
|
||||
echo "Download succeeded, loading module"
|
||||
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"
|
||||
exit $?
|
||||
else
|
||||
>&2 echo "Download failed, consider compiling your own ${DRIVER_NAME} module and loading it or getting in touch with the Falco community"
|
||||
exit 1
|
||||
load_bpf_probe_compile() {
|
||||
local BPF_KERNEL_SOURCES_URL=""
|
||||
local STRIP_COMPONENTS=1
|
||||
|
||||
customize_kernel_build() {
|
||||
if [ -n "${KERNEL_EXTRA_VERSION}" ]; then
|
||||
sed -i "s/LOCALVERSION=\"\"/LOCALVERSION=\"${KERNEL_EXTRA_VERSION}\"/" .config
|
||||
fi
|
||||
make olddefconfig > /dev/null
|
||||
make modules_prepare > /dev/null
|
||||
}
|
||||
|
||||
if [ -n "${COS}" ]; then
|
||||
echo "* COS detected (build ${BUILD_ID}), using cos kernel headers"
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="https://storage.googleapis.com/cos-tools/${BUILD_ID}/kernel-headers.tgz"
|
||||
KERNEL_EXTRA_VERSION="+"
|
||||
STRIP_COMPONENTS=0
|
||||
|
||||
customize_kernel_build() {
|
||||
pushd usr/src/* > /dev/null || exit
|
||||
|
||||
# Note: this overrides the KERNELDIR set while untarring the tarball
|
||||
KERNELDIR=$(pwd)
|
||||
export KERNELDIR
|
||||
|
||||
sed -i '/^#define randomized_struct_fields_start struct {$/d' include/linux/compiler-clang.h
|
||||
sed -i '/^#define randomized_struct_fields_end };$/d' include/linux/compiler-clang.h
|
||||
|
||||
popd > /dev/null || exit
|
||||
|
||||
# Might need to configure our own sources depending on COS version
|
||||
cos_ver=${BUILD_ID}
|
||||
base_ver=11553.0.0
|
||||
|
||||
cos_version_greater
|
||||
greater_ret=$?
|
||||
|
||||
if [[ greater_ret -eq 1 ]]; then
|
||||
export KBUILD_EXTRA_CPPFLAGS=-DCOS_73_WORKAROUND
|
||||
fi
|
||||
}
|
||||
fi
|
||||
|
||||
if [ -n "${MINIKUBE}" ]; then
|
||||
echo "* Minikube detected (${MINIKUBE_VERSION}), using linux kernel sources for minikube kernel"
|
||||
local kernel_version
|
||||
kernel_version=$(uname -r)
|
||||
local -r kernel_version_major=$(echo "${kernel_version}" | cut -d. -f1)
|
||||
local -r kernel_version_minor=$(echo "${kernel_version}" | cut -d. -f2)
|
||||
local -r kernel_version_patch=$(echo "${kernel_version}" | cut -d. -f3)
|
||||
|
||||
if [ "${kernel_version_patch}" == "0" ]; then
|
||||
kernel_version="${kernel_version_major}.${kernel_version_minor}"
|
||||
fi
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ -n "${BPF_USE_LOCAL_KERNEL_SOURCES}" ]; then
|
||||
local -r kernel_version_major=$(uname -r | cut -d. -f1)
|
||||
local -r kernel_version=$(uname -r | cut -d- -f1)
|
||||
KERNEL_EXTRA_VERSION="-$(uname -r | cut -d- -f2)"
|
||||
|
||||
echo "* Using downloaded kernel sources for kernel version ${kernel_version}..."
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
|
||||
echo "* Downloading ${BPF_KERNEL_SOURCES_URL}"
|
||||
|
||||
mkdir -p /tmp/kernel
|
||||
cd /tmp/kernel || exit
|
||||
cd "$(mktemp -d -p /tmp/kernel)" || exit
|
||||
if ! curl -L -o kernel-sources.tgz --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then
|
||||
>&2 echo "Download failed"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
echo "* Extracting kernel sources"
|
||||
|
||||
mkdir kernel-sources && tar xf kernel-sources.tgz -C kernel-sources --strip-components "${STRIP_COMPONENTS}"
|
||||
|
||||
cd kernel-sources || exit
|
||||
KERNELDIR=$(pwd)
|
||||
export KERNELDIR
|
||||
|
||||
if [[ "${KERNEL_CONFIG_PATH}" == *.gz ]]; then
|
||||
zcat "${KERNEL_CONFIG_PATH}" > .config
|
||||
else
|
||||
cat "${KERNEL_CONFIG_PATH}" > .config
|
||||
fi
|
||||
|
||||
echo "* Configuring kernel"
|
||||
customize_kernel_build
|
||||
fi
|
||||
|
||||
echo "* Trying to compile the eBPF probe (${BPF_PROBE_FILENAME})"
|
||||
|
||||
make -C "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf" > /dev/null
|
||||
|
||||
mkdir -p "${HOME}/.falco"
|
||||
mv "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${BPF_PROBE_FILENAME}"
|
||||
|
||||
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
|
||||
rm -r /tmp/kernel
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
load_bpf_probe_download() {
|
||||
local URL
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
|
||||
|
||||
echo "* Trying to download a prebuilt eBPF probe from ${URL}"
|
||||
|
||||
if ! curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${URL}"; then
|
||||
>&2 echo "Download failed"
|
||||
exit 1;
|
||||
fi
|
||||
}
|
||||
|
||||
load_bpf_probe() {
|
||||
|
||||
echo "* Mounting debugfs"
|
||||
|
||||
if [ ! -d /sys/kernel/debug/tracing ]; then
|
||||
@@ -262,128 +407,27 @@ load_bpf_probe() {
|
||||
|
||||
get_target_id
|
||||
|
||||
local BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
|
||||
BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
|
||||
|
||||
if [ ! -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
|
||||
local BPF_KERNEL_SOURCES_URL=""
|
||||
local STRIP_COMPONENTS=1
|
||||
|
||||
customize_kernel_build() {
|
||||
if [ -n "${KERNEL_EXTRA_VERSION}" ]; then
|
||||
sed -i "s/LOCALVERSION=\"\"/LOCALVERSION=\"${KERNEL_EXTRA_VERSION}\"/" .config
|
||||
fi
|
||||
make olddefconfig > /dev/null
|
||||
make modules_prepare > /dev/null
|
||||
}
|
||||
|
||||
if [ -n "${COS}" ]; then
|
||||
echo "* COS detected (build ${BUILD_ID}), using cos kernel headers..."
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="https://storage.googleapis.com/cos-tools/${BUILD_ID}/kernel-headers.tgz"
|
||||
KERNEL_EXTRA_VERSION="+"
|
||||
STRIP_COMPONENTS=0
|
||||
|
||||
customize_kernel_build() {
|
||||
pushd usr/src/* > /dev/null || exit
|
||||
|
||||
# Note: this overrides the KERNELDIR set while untarring the tarball
|
||||
KERNELDIR=$(pwd)
|
||||
export KERNELDIR
|
||||
|
||||
sed -i '/^#define randomized_struct_fields_start struct {$/d' include/linux/compiler-clang.h
|
||||
sed -i '/^#define randomized_struct_fields_end };$/d' include/linux/compiler-clang.h
|
||||
|
||||
popd > /dev/null || exit
|
||||
|
||||
# Might need to configure our own sources depending on COS version
|
||||
cos_ver=${BUILD_ID}
|
||||
base_ver=11553.0.0
|
||||
|
||||
cos_version_greater
|
||||
greater_ret=$?
|
||||
|
||||
if [[ greater_ret -eq 1 ]]; then
|
||||
export KBUILD_EXTRA_CPPFLAGS=-DCOS_73_WORKAROUND
|
||||
fi
|
||||
}
|
||||
fi
|
||||
|
||||
if [ -n "${MINIKUBE}" ]; then
|
||||
echo "* Minikube detected (${MINIKUBE_VERSION}), using linux kernel sources for minikube kernel"
|
||||
local kernel_version
|
||||
kernel_version=$(uname -r)
|
||||
local -r kernel_version_major=$(echo "${kernel_version}" | cut -d. -f1)
|
||||
local -r kernel_version_minor=$(echo "${kernel_version}" | cut -d. -f2)
|
||||
local -r kernel_version_patch=$(echo "${kernel_version}" | cut -d. -f3)
|
||||
|
||||
if [ "${kernel_version_patch}" == "0" ]; then
|
||||
kernel_version="${kernel_version_major}.${kernel_version_minor}"
|
||||
fi
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ -n "${BPF_USE_LOCAL_KERNEL_SOURCES}" ]; then
|
||||
local -r kernel_version_major=$(uname -r | cut -d. -f1)
|
||||
local -r kernel_version=$(uname -r | cut -d- -f1)
|
||||
KERNEL_EXTRA_VERSION="-$(uname -r | cut -d- -f2)"
|
||||
|
||||
echo "* Using downloaded kernel sources for kernel version ${kernel_version}..."
|
||||
|
||||
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
|
||||
echo "* Downloading ${BPF_KERNEL_SOURCES_URL}"
|
||||
|
||||
mkdir -p /tmp/kernel
|
||||
cd /tmp/kernel || exit
|
||||
cd "$(mktemp -d -p /tmp/kernel)" || exit
|
||||
if ! curl -L -o kernel-sources.tgz --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
echo "* Extracting kernel sources"
|
||||
|
||||
mkdir kernel-sources && tar xf kernel-sources.tgz -C kernel-sources --strip-components "${STRIP_COMPONENTS}"
|
||||
|
||||
cd kernel-sources || exit
|
||||
KERNELDIR=$(pwd)
|
||||
export KERNELDIR
|
||||
|
||||
if [[ "${KERNEL_CONFIG_PATH}" == *.gz ]]; then
|
||||
zcat "${KERNEL_CONFIG_PATH}" > .config
|
||||
else
|
||||
cat "${KERNEL_CONFIG_PATH}" > .config
|
||||
fi
|
||||
|
||||
echo "* Configuring kernel"
|
||||
customize_kernel_build
|
||||
fi
|
||||
|
||||
echo "* Trying to compile the eBPF probe (${BPF_PROBE_FILENAME})"
|
||||
|
||||
make -C "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf" > /dev/null
|
||||
|
||||
mkdir -p "${HOME}/.falco"
|
||||
mv "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${BPF_PROBE_FILENAME}"
|
||||
|
||||
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
|
||||
rm -r /tmp/kernel
|
||||
if [ -n "$ENABLE_COMPILE" ]; then
|
||||
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
echo "* Skipping compile, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
|
||||
else
|
||||
load_bpf_probe_compile
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
local URL
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
|
||||
|
||||
echo "* Trying to download a prebuilt eBPF probe from ${URL}"
|
||||
|
||||
curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${URL}"
|
||||
if [ -n "$ENABLE_DOWNLOAD" ]; then
|
||||
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
echo "* Skipping download, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
|
||||
else
|
||||
load_bpf_probe_download
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
echo "* eBPF probe located in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
|
||||
|
||||
if [ ! -f /proc/sys/net/core/bpf_jit_enable ]; then
|
||||
echo "******************************************************************"
|
||||
echo "** BPF doesn't have JIT enabled, performance might be degraded. **"
|
||||
@@ -391,20 +435,37 @@ load_bpf_probe() {
|
||||
echo "******************************************************************"
|
||||
fi
|
||||
|
||||
echo "* eBPF probe located, it's now possible to start Falco"
|
||||
|
||||
ln -sf "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${HOME}/.falco/${DRIVER_NAME}-bpf.o"
|
||||
ln -sf "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${HOME}/.falco/${DRIVER_NAME}-bpf.o" \
|
||||
&& echo "* Success: eBPF probe symlinked to ${HOME}/.falco/${DRIVER_NAME}-bpf.o"
|
||||
exit $?
|
||||
else
|
||||
echo "* Failure to find an eBPF probe"
|
||||
>&2 echo "Failure to find an eBPF probe"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " falco-driver-loader [driver] [options]"
|
||||
echo ""
|
||||
echo "Available drivers:"
|
||||
echo " module kernel module (default)"
|
||||
echo " bpf eBPF probe"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --help show brief help"
|
||||
echo " --compile try to compile the driver locally"
|
||||
echo " --download try to download a prebuilt driver"
|
||||
echo " --source-only skip execution and allow sourcing in another script"
|
||||
echo ""
|
||||
}
|
||||
|
||||
ARCH=$(uname -m)
|
||||
KERNEL_RELEASE=$(uname -r)
|
||||
KERNEL_VERSION=$(uname -v | sed 's/#\([[:digit:]]\+\).*/\1/')
|
||||
DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"}
|
||||
|
||||
if [ -n "$DRIVER_INSECURE_DOWNLOAD" ]
|
||||
then
|
||||
FALCO_DRIVER_CURL_OPTIONS=-fsSk
|
||||
@@ -420,18 +481,84 @@ fi
|
||||
DRIVER_VERSION="@PROBE_VERSION@"
|
||||
DRIVER_NAME="@PROBE_NAME@"
|
||||
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
echo "Installer must be run as root (or with sudo)."
|
||||
exit 1
|
||||
DRIVER="module"
|
||||
if [ -v FALCO_BPF_PROBE ]; then
|
||||
DRIVER="bpf"
|
||||
fi
|
||||
|
||||
if ! hash curl > /dev/null 2>&1; then
|
||||
echo "This program requires curl"
|
||||
exit 1
|
||||
ENABLE_COMPILE=
|
||||
ENABLE_DOWNLOAD=
|
||||
|
||||
has_args=
|
||||
has_opts=
|
||||
source_only=
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
module|bpf)
|
||||
if [ -n "$has_args" ]; then
|
||||
>&2 echo "Only one driver can be passed"
|
||||
print_usage
|
||||
exit 1
|
||||
else
|
||||
DRIVER="$1"
|
||||
has_args="true"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
--compile)
|
||||
ENABLE_COMPILE="yes"
|
||||
has_opts="true"
|
||||
shift
|
||||
;;
|
||||
--download)
|
||||
ENABLE_DOWNLOAD="yes"
|
||||
has_opts="true"
|
||||
shift
|
||||
;;
|
||||
--source-only)
|
||||
source_only="true"
|
||||
shift
|
||||
;;
|
||||
--*)
|
||||
>&2 echo "Unknown option: $1"
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
>&2 echo "Unknown driver: $1"
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$has_opts" ]; then
|
||||
ENABLE_COMPILE="yes"
|
||||
ENABLE_DOWNLOAD="yes"
|
||||
fi
|
||||
|
||||
if [ -v FALCO_BPF_PROBE ] || [ "${1}" = "bpf" ]; then
|
||||
load_bpf_probe
|
||||
else
|
||||
load_kernel_module
|
||||
fi
|
||||
if [ -z "$source_only" ]; then
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
>&2 echo "This program must be run as root (or with sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! hash curl > /dev/null 2>&1; then
|
||||
>&2 echo "This program requires curl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "* Running falco-driver-loader with: driver=$DRIVER, compile=${ENABLE_COMPILE:-"no"}, download=${ENABLE_DOWNLOAD:-"no"}"
|
||||
case $DRIVER in
|
||||
module)
|
||||
load_kernel_module
|
||||
;;
|
||||
bpf)
|
||||
load_bpf_probe
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -53,8 +53,8 @@ start() {
|
||||
# [ -f $config ] || exit 6
|
||||
echo -n $"Starting $prog: "
|
||||
daemon $exec --daemon --pidfile=$pidfile
|
||||
if [ ! -d /sys/module/falco_probe ]; then
|
||||
/sbin/modprobe falco-probe || return $?
|
||||
if [ ! -d /sys/module/falco ]; then
|
||||
/sbin/modprobe falco || return $?
|
||||
fi
|
||||
retval=$?
|
||||
echo
|
||||
@@ -67,7 +67,7 @@ stop() {
|
||||
killproc -p $pidfile
|
||||
retval=$?
|
||||
echo
|
||||
/sbin/rmmod falco-probe
|
||||
/sbin/rmmod falco
|
||||
[ $retval -eq 0 ] && rm -f $lockfile
|
||||
return $retval
|
||||
}
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
# Falco Regression tests
|
||||
# Falco regression tests
|
||||
|
||||
This folder contains the Regression tests suite for Falco.
|
||||
|
||||
You can find instructions on how to run this test suite on the Falco website [here](https://falco.org/docs/source/#run-regression-tests).
|
||||
|
||||
## Test suites
|
||||
|
||||
- [falco_tests](./falco_tests.yaml)
|
||||
- [falco_traces](./falco_traces.yaml)
|
||||
- [falco_tests_package](./falco_tests_package.yaml)
|
||||
- [falco_k8s_audit_tests](./falco_k8s_audit_tests.yaml)
|
||||
- [falco_tests_psp](./falco_tests_psp.yaml)
|
||||
|
||||
## Running locally
|
||||
|
||||
Using `virtualenv` the steps to locally run a specific test suite are the following ones (from this directory):
|
||||
|
||||
```console
|
||||
virtualenv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
BUILD_DIR="../build" avocado run --mux-yaml falco_tests.yaml --job-results-dir /tmp/job-results -- falco_test.py
|
||||
deactivate
|
||||
```
|
||||
|
||||
The name of the specific test suite to run is `falco_tests.yaml` in this case. Change it to run others test suites.
|
||||
|
||||
In case you want to only execute a specific test case, use the `--mux-filter-only` parameter as follows:
|
||||
|
||||
```console
|
||||
BUILD_DIR="../build" avocado run --mux-yaml falco_tests.yaml --job-results-dir /tmp/job-results --mux-filter-only /run/trace_files/program_output -- falco_test.py
|
||||
```
|
||||
|
||||
To obtain the path of all the available variants, execute:
|
||||
|
||||
```console
|
||||
avocado variants --mux-yaml falco_test.yaml
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -21,14 +21,14 @@ rules_file: /etc/falco_rules.yaml
|
||||
# Whether to output events in json or text
|
||||
json_output: false
|
||||
|
||||
# Send information logs to stderr and/or syslog Note these are *not* security
|
||||
# notification logs! These are just Falco lifecycle (and possibly error) logs.
|
||||
# Send information logs to stderr and/or syslog
|
||||
# Note these are *not* security notification logs!
|
||||
# These are just Falco lifecycle (and possibly error) logs.
|
||||
log_stderr: false
|
||||
log_syslog: false
|
||||
|
||||
# Where security notifications should go.
|
||||
# Multiple outputs can be enabled.
|
||||
|
||||
syslog_output:
|
||||
enabled: false
|
||||
|
||||
|
||||
48
test/driver-loader/run_test.sh
Executable file
48
test/driver-loader/run_test.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
BUILD_DIR=$1
|
||||
|
||||
SCRIPT=$(readlink -f $0)
|
||||
SCRIPTDIR=$(dirname $SCRIPT)
|
||||
RUNNERDIR="${SCRIPTDIR}/runner"
|
||||
FALCO_VERSION=$(cat ${BUILD_DIR}/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
DRIVER_VERSION=$(cat ${BUILD_DIR}/userspace/falco/config_falco.h | grep 'DRIVER_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
FALCO_PACKAGE="falco-${FALCO_VERSION}-x86_64.tar.gz"
|
||||
|
||||
cp "${BUILD_DIR}/${FALCO_PACKAGE}" "${RUNNERDIR}"
|
||||
pushd ${RUNNERDIR}
|
||||
docker build --build-arg FALCO_VERSION="$FALCO_VERSION" \
|
||||
-t falcosecurity/falco:test-driver-loader \
|
||||
-f "${RUNNERDIR}/Dockerfile" ${RUNNERDIR}
|
||||
popd
|
||||
rm -f "${RUNNERDIR}/${FALCO_PACKAGE}"
|
||||
|
||||
docker run --rm --privileged \
|
||||
-e FALCO_VERSION="$FALCO_VERSION" \
|
||||
-e DRIVER_VERSION="$DRIVER_VERSION" \
|
||||
-v /dev:/host/dev \
|
||||
-v /proc:/host/proc:ro \
|
||||
-v /boot:/host/boot:ro \
|
||||
-v /lib/modules:/host/lib/modules:ro \
|
||||
-v /usr:/host/usr:ro \
|
||||
-v /etc:/host/etc:ro \
|
||||
falcosecurity/falco:test-driver-loader
|
||||
|
||||
docker rmi -f falcosecurity/falco:test-driver-loader
|
||||
33
test/driver-loader/runner/Dockerfile
Normal file
33
test/driver-loader/runner/Dockerfile
Normal file
@@ -0,0 +1,33 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
ARG FALCO_VERSION=
|
||||
RUN test -n FALCO_VERSION
|
||||
ENV FALCO_VERSION ${FALCO_VERSION}
|
||||
ENV DRIVER_VERSION=
|
||||
ENV HOST_ROOT=/host
|
||||
|
||||
# Minimal set of deps required to run falco-driver-loader and falco
|
||||
RUN apt-get update -y
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
libyaml-0-2 \
|
||||
dkms \
|
||||
curl \
|
||||
gcc \
|
||||
clang-7 \
|
||||
llvm-7 \
|
||||
libelf-dev
|
||||
|
||||
RUN rm -rf /usr/bin/clang \
|
||||
&& rm -rf /usr/bin/llc \
|
||||
&& ln -s /usr/bin/clang-7 /usr/bin/clang \
|
||||
&& ln -s /usr/bin/llc-7 /usr/bin/llc
|
||||
|
||||
RUN rm -rf /lib/modules \
|
||||
&& ln -s $HOST_ROOT/lib/modules /lib/modules
|
||||
|
||||
ADD falco-${FALCO_VERSION}-x86_64.tar.gz /
|
||||
RUN cp -R /falco-${FALCO_VERSION}-x86_64/* /
|
||||
|
||||
COPY test.sh /
|
||||
CMD /test.sh
|
||||
136
test/driver-loader/runner/test.sh
Executable file
136
test/driver-loader/runner/test.sh
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
FALCO="falco -M 1"
|
||||
FALCO_DRIVER_LOADER=falco-driver-loader
|
||||
|
||||
|
||||
function init() {
|
||||
|
||||
# We need this here since is not part of the falco-driver-loader script
|
||||
#
|
||||
# todo(leogr): maybe this can be moved into falco-driver-loader directly
|
||||
# since it depends on HOST_ROOT
|
||||
if [ -n "${HOST_ROOT}" ]; then
|
||||
echo "INIT: Setting up /usr/src links from host"
|
||||
for i in "$HOST_ROOT/usr/src"/*
|
||||
do
|
||||
base=$(basename "$i")
|
||||
ln -s "$i" "/usr/src/$base"
|
||||
done
|
||||
fi
|
||||
|
||||
local EXPECTED_DRIVER_VERSION=${DRIVER_VERSION}
|
||||
|
||||
# We need some env vars to be populated
|
||||
# Just source falco-driver-loader, and call get_target_id
|
||||
# Loaded driver will be cleaned up later, if any.
|
||||
echo "INIT: Sourcing ${FALCO_DRIVER_LOADER} to get env vars populated"
|
||||
set +eu
|
||||
source $FALCO_DRIVER_LOADER --source-only
|
||||
get_target_id
|
||||
set -eu
|
||||
|
||||
if [ ! "${EXPECTED_DRIVER_VERSION}" = "${DRIVER_VERSION}" ]; then
|
||||
echo "INIT: Unexpected DRIVER_VERSION in falco-driver-loader"
|
||||
echo "Expected: ${EXPECTED_DRIVER_VERSION}"
|
||||
echo "Found: ${DRIVER_VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FALCO_KERNEL_MODULE_PATH="${HOME}/.falco/${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
|
||||
FALCO_BPF_PROBE_PATH="${HOME}/.falco/${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
|
||||
cleanup_drivers
|
||||
}
|
||||
|
||||
function cleanup_drivers() {
|
||||
echo "CLEANUP: remove drivers, if any"
|
||||
|
||||
# kernel module
|
||||
rmmod "$DRIVER_NAME" > /dev/null 2>&1 || true
|
||||
dkms uninstall "$DRIVER_NAME/$DRIVER_VERSION" > /dev/null 2>&1 || true
|
||||
rm -f "$FALCO_KERNEL_MODULE_PATH"
|
||||
|
||||
# bpf probe
|
||||
local PROBE_INSTALL_PATH="${HOME}/.falco/${DRIVER_NAME}-bpf.o"
|
||||
rm -f "$FALCO_BPF_PROBE_PATH"
|
||||
rm -f "$PROBE_INSTALL_PATH"
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
echo ""
|
||||
echo "TEST: $1"
|
||||
echo ""
|
||||
$1
|
||||
echo ""
|
||||
echo "PASS: $1"
|
||||
echo ""
|
||||
cleanup_drivers
|
||||
}
|
||||
|
||||
function assert_kernel_module() {
|
||||
echo "ASSERT: module loaded"
|
||||
local KMOD_NAME=$(echo "${DRIVER_NAME}" | tr "-" "_")
|
||||
if ! lsmod | grep "${KMOD_NAME}" > /dev/null 2>&1; then
|
||||
echo "FAIL: module not loaded"
|
||||
exit 1
|
||||
fi
|
||||
echo "ASSERT: falco works with module"
|
||||
if ! $FALCO; then
|
||||
echo "FAIL: falco does not work with module"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function assert_bpf_probe() {
|
||||
local PROBE_INSTALL_PATH="${HOME}/.falco/${DRIVER_NAME}-bpf.o"
|
||||
echo "ASSERT: eBPF probe at $PROBE_INSTALL_PATH"
|
||||
if ! test -f "$PROBE_INSTALL_PATH"; then
|
||||
echo "FAIL: eBPF probe not found"
|
||||
exit 1
|
||||
fi
|
||||
echo "ASSERT: falco works with bpf"
|
||||
if ! FALCO_BPF_PROBE="" $FALCO; then
|
||||
echo "FAIL: falco does not work with bpf"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function test_kernel_module() {
|
||||
$FALCO_DRIVER_LOADER
|
||||
assert_kernel_module
|
||||
}
|
||||
|
||||
|
||||
function test_bpf_probe() {
|
||||
$FALCO_DRIVER_LOADER bpf
|
||||
assert_bpf_probe
|
||||
}
|
||||
|
||||
echo "falco-driver-loader tester"
|
||||
echo ""
|
||||
echo "Falco version: $FALCO_VERSION"
|
||||
echo "Driver version: $DRIVER_VERSION"
|
||||
echo "HOST_ROOT: ${HOST_ROOT}"
|
||||
echo ""
|
||||
|
||||
init
|
||||
|
||||
run_test "test_kernel_module"
|
||||
run_test "test_bpf_probe"
|
||||
@@ -411,8 +411,8 @@ class FalcoTest(Test):
|
||||
md5_output = subprocess.check_output(["md5sum", "/boot/config-{}".format(kernel_release)]).rstrip()
|
||||
config_hash = md5_output.split(" ")[0]
|
||||
|
||||
probe_filename = "falco-probe-{}-{}-{}-{}.ko".format(falco_version, arch, kernel_release, config_hash)
|
||||
driver_path = os.path.join(self.falcodir, "driver", "falco-probe.ko")
|
||||
probe_filename = "falco-{}-{}-{}-{}.ko".format(falco_version, arch, kernel_release, config_hash)
|
||||
driver_path = os.path.join(self.falcodir, "driver", "falco.ko")
|
||||
module_path = os.path.join(self.module_dir, probe_filename)
|
||||
self.log.debug("Copying {} to {}".format(driver_path, module_path))
|
||||
shutil.copyfile(driver_path, module_path)
|
||||
|
||||
11
test/requirements.txt
Normal file
11
test/requirements.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
avocado-framework==69.0
|
||||
avocado-framework-plugin-varianter-yaml-to-mux==69.0
|
||||
certifi==2020.4.5.1
|
||||
chardet==3.0.4
|
||||
idna==2.9
|
||||
pbr==5.4.5
|
||||
PyYAML==5.3.1
|
||||
requests==2.23.0
|
||||
six==1.14.0
|
||||
stevedore==1.32.0
|
||||
urllib3==1.25.9
|
||||
@@ -14,9 +14,9 @@
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
set(FALCO_TESTS_SOURCES test_base.cpp engine/test_token_bucket.cpp falco/test_webserver.cpp engine/test_rulesets.cpp profiler/test_profiler.cpp)
|
||||
set(FALCO_TESTS_SOURCES test_base.cpp engine/test_token_bucket.cpp engine/test_rulesets.cpp engine/test_falco_utils.cpp falco/test_webserver.cpp)
|
||||
|
||||
set(FALCO_TESTED_LIBRARIES falco_engine falco_profiler)
|
||||
set(FALCO_TESTED_LIBRARIES falco_engine)
|
||||
|
||||
SET(FALCO_TESTS_ARGUMENTS "" CACHE STRING "Test arguments to pass to the Falco test suite")
|
||||
|
||||
@@ -43,12 +43,12 @@ if(FALCO_BUILD_TESTS)
|
||||
"${YAMLCPP_INCLUDE_DIR}"
|
||||
"${CIVETWEB_INCLUDE_DIR}"
|
||||
"${PROJECT_SOURCE_DIR}/userspace/falco")
|
||||
add_dependencies(falco_test catch2 hedley)
|
||||
add_dependencies(falco_test catch2)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
catch_discover_tests(falco_test)
|
||||
separate_arguments(FALCO_TESTS_ARGUMENTS)
|
||||
add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} ${FALCO_TESTS_ARGUMENTS} DEPENDS falco_test flatbuffer_profiler)
|
||||
add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} ${FALCO_TESTS_ARGUMENTS} DEPENDS falco_test)
|
||||
endif()
|
||||
|
||||
53
tests/engine/test_falco_utils.cpp
Normal file
53
tests/engine/test_falco_utils.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (C) 2020 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#include "falco_utils.h"
|
||||
#include <nonstd/string_view.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("is_unix_scheme matches", "[utils]")
|
||||
{
|
||||
SECTION("rvalue")
|
||||
{
|
||||
bool res = falco::utils::network::is_unix_scheme("unix:///var/run/falco.sock");
|
||||
REQUIRE(res);
|
||||
}
|
||||
|
||||
SECTION("std::string")
|
||||
{
|
||||
std::string url("unix:///var/run/falco.sock");
|
||||
bool res = falco::utils::network::is_unix_scheme(url);
|
||||
REQUIRE(res);
|
||||
}
|
||||
|
||||
SECTION("char[]")
|
||||
{
|
||||
char url[] = "unix:///var/run/falco.sock";
|
||||
bool res = falco::utils::network::is_unix_scheme(url);
|
||||
REQUIRE(res);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("is_unix_scheme does not match", "[utils]")
|
||||
{
|
||||
bool res = falco::utils::network::is_unix_scheme("something:///var/run/falco.sock");
|
||||
REQUIRE_FALSE(res);
|
||||
}
|
||||
|
||||
TEST_CASE("is_unix_scheme only matches scheme at the start of the string", "[utils]")
|
||||
{
|
||||
bool res = falco::utils::network::is_unix_scheme("/var/run/unix:///falco.sock");
|
||||
REQUIRE_FALSE(res);
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2020 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#include "profiler.h"
|
||||
#include <catch.hpp>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
#include <hedley.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include <flatbuffers/flatbuffers.h>
|
||||
#include "profile_generated.h"
|
||||
|
||||
// void profile_recurse(int times)
|
||||
// {
|
||||
// PROFILEME();
|
||||
// for(int i = 1; i < times; i++)
|
||||
// {
|
||||
// profile_recurse(1);
|
||||
// }
|
||||
// }
|
||||
|
||||
void profiler_sleep_1sec()
|
||||
{
|
||||
PROFILEME();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
|
||||
void profiler_sleep_2sec()
|
||||
{
|
||||
PROFILEME();
|
||||
profiler_sleep_1sec();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
||||
|
||||
TEST_CASE("profiler stores labels and chunks", "[profiler]")
|
||||
{
|
||||
SECTION("profiler needs to be allocated before usage")
|
||||
{
|
||||
profiler::alloc_chunk();
|
||||
REQUIRE(profiler::chunks.size() == 1);
|
||||
REQUIRE(profiler::labels.empty());
|
||||
}
|
||||
|
||||
SECTION("calling a profiled function results in labels and chunks increase")
|
||||
{
|
||||
profiler_sleep_1sec();
|
||||
REQUIRE(profiler::labels.size() == 1);
|
||||
REQUIRE(profiler::chunks.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("calling just another profiled function that calls the one previously called should only increase labels by one")
|
||||
{
|
||||
profiler_sleep_2sec();
|
||||
REQUIRE(profiler::labels.size() == 2);
|
||||
REQUIRE(profiler::chunks.size() == 1);
|
||||
}
|
||||
|
||||
SECTION("clean")
|
||||
{
|
||||
profiler::labels.clear();
|
||||
profiler::chunks.clear();
|
||||
REQUIRE(profiler::labels.empty());
|
||||
REQUIRE(profiler::chunks.empty());
|
||||
}
|
||||
}
|
||||
|
||||
void bb()
|
||||
{
|
||||
PROFILEME();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
}
|
||||
|
||||
void aa()
|
||||
{
|
||||
PROFILEME();
|
||||
bb();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
}
|
||||
|
||||
void aa_threaded()
|
||||
{
|
||||
profiler::alloc_chunk();
|
||||
PROFILEME();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
}
|
||||
|
||||
void cc()
|
||||
{
|
||||
PROFILEME();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
}
|
||||
|
||||
void profiler_fake_root_func()
|
||||
{
|
||||
PROFILEME();
|
||||
aa();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
bb();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
cc();
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
aa();
|
||||
}
|
||||
|
||||
TEST_CASE("profiler computes parents (single chunk)", "[profiler]")
|
||||
{
|
||||
profiler::alloc_chunk();
|
||||
profiler_fake_root_func();
|
||||
|
||||
REQUIRE(profiler::labels.size() == 4);
|
||||
REQUIRE(profiler::chunks.size() == 1);
|
||||
REQUIRE(profiler::chunks[0].begin[5] == 0); // profiler_fake_root_func is root (parent = 0)
|
||||
|
||||
auto predicate = [](int x) {
|
||||
return [=](const profiler::label &l) {
|
||||
return l.label == profiler::chunks[0].begin[x];
|
||||
};
|
||||
};
|
||||
|
||||
// Ctor ordering:
|
||||
// profile_fake_root
|
||||
// AA1
|
||||
// BB1
|
||||
// BB2
|
||||
// CC1
|
||||
// AA2
|
||||
// BB3
|
||||
|
||||
// Dtor ordering:
|
||||
// BB1
|
||||
// AA1
|
||||
// BB2
|
||||
// CC1
|
||||
// BB3
|
||||
// AA2
|
||||
// profile_fake_root
|
||||
|
||||
auto root = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(0));
|
||||
REQUIRE(root->func == "profiler_fake_root_func"); // function name is "profiler_fake_root_func"
|
||||
REQUIRE(profiler::chunks[0].begin[5 + CHUNK_ELEMENTS] == root->label); // aa (call aa1) has parent "profiler_fake_root_func"
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "aa"); // function name is "aa" (call aa1)
|
||||
REQUIRE(profiler::chunks[0].begin[5 + (2 * CHUNK_ELEMENTS)] == it->label); // bb (call bb1) has parent "aa" (call aa1)
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(2 * CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "bb"); // function name is "bb" (call bb1)
|
||||
REQUIRE(profiler::chunks[0].begin[5 + (3 * CHUNK_ELEMENTS)] == root->label); // bb (call bb2) has parent "profiler_fake_root_func"
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(3 * CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "bb"); // function name is "bb" (call bb2)
|
||||
REQUIRE(profiler::chunks[0].begin[5 + (4 * CHUNK_ELEMENTS)] == root->label); // cc (call cc1) has parent "profiler_fake_root_func"
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(4 * CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "cc"); // function name is "cc" (call cc1)
|
||||
REQUIRE(profiler::chunks[0].begin[5 + (5 * CHUNK_ELEMENTS)] == root->label); // aa (call aa2) has parent "profiler_fake_root_func"
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(5 * CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "aa"); // function name is "aa" (call aa2)
|
||||
REQUIRE(profiler::chunks[0].begin[5 + (6 * CHUNK_ELEMENTS)] == it->label); // bb (call bb3) has parent "aa" (call aa2)
|
||||
}
|
||||
|
||||
{
|
||||
auto it = std::find_if(std::begin(profiler::labels), std::end(profiler::labels), predicate(6 * CHUNK_ELEMENTS));
|
||||
REQUIRE(it->func == "bb"); // function name is "bb" (call bb3)
|
||||
}
|
||||
|
||||
for(std::vector<int>::size_type j = 0; j != profiler::chunks.size(); j++)
|
||||
{
|
||||
auto *c = profiler::chunks[j].begin;
|
||||
for(int i = 0; i < CHUNK_SIZE; i += CHUNK_ELEMENTS)
|
||||
{
|
||||
if(c[i] == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
auto parent = c[i + 5];
|
||||
auto e = ((unsigned long long)c[i + 4]) | (((unsigned long long)c[i + 3]) << 32);
|
||||
auto s = ((unsigned long long)c[i + 2]) | (((unsigned long long)c[i + 1]) << 32);
|
||||
char b[1024];
|
||||
if(i == 0)
|
||||
{
|
||||
sprintf(b, "#;idx;parent ;function ;clocks");
|
||||
std::cout << std::string(b) << std::endl;
|
||||
}
|
||||
sprintf(b, "%ld;%03d;%010u;%u;%lld", j, i, parent, c[i], e - s);
|
||||
std::cout << std::string(b) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
profiler::labels.clear();
|
||||
profiler::chunks.clear();
|
||||
REQUIRE(profiler::labels.empty());
|
||||
REQUIRE(profiler::chunks.empty());
|
||||
}
|
||||
// TEST_CASE("profile computes recursive parents (more chunks)", "[profiler]")
|
||||
// {
|
||||
// alloc_chunk();
|
||||
// REQUIRE(chunks.size() == 1);
|
||||
|
||||
// size_t expected_chunks = 2;
|
||||
// int how_many_times = (CHUNK_SIZE / CHUNK_ELEMENTS) * HEDLEY_STATIC_CAST(int, expected_chunks);
|
||||
|
||||
// profile_recurse(how_many_times);
|
||||
|
||||
// REQUIRE(labels.size() == 1);
|
||||
// REQUIRE(chunks.size() == expected_chunks + 1);
|
||||
|
||||
// for(std::vector<int>::size_type j = 0; j != chunks.size(); j++)
|
||||
// {
|
||||
// auto *c = chunks[j].begin;
|
||||
// for(int i = 0; i < CHUNK_SIZE; i++)
|
||||
// {
|
||||
// char b[1024];
|
||||
// sprintf(b, "%ld - %03d: %u", j, i, c[i]);
|
||||
// std::cout << std::string(b) << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
// labels.clear();
|
||||
// chunks.clear();
|
||||
// REQUIRE(labels.empty());
|
||||
// REQUIRE(chunks.empty());
|
||||
// }
|
||||
|
||||
TEST_CASE("profiler flatbuffer serialization deserialization", "[profiler]")
|
||||
{
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
|
||||
auto node_one = profiler::CreateNodeDirect(
|
||||
builder,
|
||||
"do_init",
|
||||
"falco_engine.cpp",
|
||||
345,
|
||||
500);
|
||||
|
||||
auto node_two_one = profiler::CreateNodeDirect(
|
||||
builder,
|
||||
"do_match2",
|
||||
"ruleset.cpp",
|
||||
690,
|
||||
100);
|
||||
|
||||
std::vector<flatbuffers::Offset<profiler::Node>> third_level;
|
||||
third_level.push_back(node_two_one);
|
||||
|
||||
auto node_two = profiler::CreateNodeDirect(
|
||||
builder,
|
||||
"do_match",
|
||||
"ruleset.cpp",
|
||||
678,
|
||||
250,
|
||||
&third_level);
|
||||
|
||||
std::vector<flatbuffers::Offset<profiler::Node>> second_level;
|
||||
second_level.push_back(node_one);
|
||||
second_level.push_back(node_two);
|
||||
|
||||
auto root = profiler::CreateNodeDirect(
|
||||
builder,
|
||||
"main",
|
||||
"falco.cpp",
|
||||
123,
|
||||
750,
|
||||
&second_level);
|
||||
|
||||
profiler::FinishNodeBuffer(builder, root);
|
||||
|
||||
SECTION("binary output has identifier")
|
||||
{
|
||||
REQUIRE(profiler::NodeBufferHasIdentifier(builder.GetBufferPointer()) == true);
|
||||
}
|
||||
|
||||
SECTION("deserialization")
|
||||
{
|
||||
auto node = profiler::GetNode(builder.GetBufferPointer());
|
||||
|
||||
REQUIRE(node->cycles() == 750);
|
||||
REQUIRE(node->line() == 123);
|
||||
REQUIRE(node->func()->str() == "main");
|
||||
REQUIRE(node->file()->str() == "falco.cpp");
|
||||
REQUIRE(node->childs() != nullptr);
|
||||
REQUIRE(node->childs()->size() == 2);
|
||||
REQUIRE(node->childs()->Get(0) == flatbuffers::GetTemporaryPointer(builder, node_one));
|
||||
REQUIRE(node->childs()->Get(1) == flatbuffers::GetTemporaryPointer(builder, node_two));
|
||||
|
||||
auto expect_one = node->childs()->Get(0);
|
||||
REQUIRE(expect_one->cycles() == 500);
|
||||
REQUIRE(expect_one->line() == 345);
|
||||
REQUIRE(expect_one->func()->str() == "do_init");
|
||||
REQUIRE(expect_one->file()->str() == "falco_engine.cpp");
|
||||
REQUIRE(expect_one->childs() == nullptr);
|
||||
|
||||
auto expect_two = node->childs()->Get(1);
|
||||
REQUIRE(expect_two->cycles() == 250);
|
||||
REQUIRE(expect_two->line() == 678);
|
||||
REQUIRE(expect_two->func()->str() == "do_match");
|
||||
REQUIRE(expect_two->file()->str() == "ruleset.cpp");
|
||||
REQUIRE(expect_two->childs() != nullptr);
|
||||
REQUIRE(expect_two->childs()->size() == 1);
|
||||
REQUIRE(expect_two->childs()->Get(0) == flatbuffers::GetTemporaryPointer(builder, node_two_one));
|
||||
|
||||
auto expect_two_one = expect_two->childs()->Get(0);
|
||||
REQUIRE(expect_two_one->cycles() == 100);
|
||||
REQUIRE(expect_two_one->line() == 690);
|
||||
REQUIRE(expect_two_one->func()->str() == "do_match2");
|
||||
REQUIRE(expect_two_one->file()->str() == "ruleset.cpp");
|
||||
REQUIRE(expect_two_one->childs() == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void profile_fake_root_launching_threads()
|
||||
{
|
||||
PROFILEME();
|
||||
std::thread ta(aa_threaded);
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(1));
|
||||
bb();
|
||||
|
||||
ta.join();
|
||||
}
|
||||
|
||||
TEST_CASE("profiler multi threading", "[profiler]")
|
||||
{
|
||||
profiler::alloc_chunk();
|
||||
REQUIRE(profiler::chunks.size() == 1);
|
||||
profile_fake_root_launching_threads();
|
||||
}
|
||||
@@ -21,7 +21,7 @@ set(FALCO_ENGINE_SOURCE_FILES
|
||||
formats.cpp)
|
||||
|
||||
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
|
||||
add_dependencies(falco_engine njson lyaml lpeg)
|
||||
add_dependencies(falco_engine njson lyaml lpeg string-view-lite)
|
||||
|
||||
target_include_directories(
|
||||
falco_engine
|
||||
@@ -30,6 +30,7 @@ target_include_directories(
|
||||
"${NJSON_INCLUDE}"
|
||||
"${CURL_INCLUDE_DIR}"
|
||||
"${TBB_INCLUDE_DIR}"
|
||||
"${STRING_VIEW_LITE_INCLUDE}"
|
||||
"${SYSDIG_SOURCE_DIR}/userspace/libsinsp/third-party/jsoncpp"
|
||||
"${SYSDIG_SOURCE_DIR}/userspace/libscap"
|
||||
"${SYSDIG_SOURCE_DIR}/userspace/libsinsp"
|
||||
|
||||
@@ -16,9 +16,9 @@ limitations under the License.
|
||||
|
||||
// The version of rules/filter fields/etc supported by this falco
|
||||
// engine.
|
||||
#define FALCO_ENGINE_VERSION (5)
|
||||
#define FALCO_ENGINE_VERSION (6)
|
||||
|
||||
// This is the result of running "falco --list -N | sha256sum" and
|
||||
// represents the fields supported by this version of falco. It's used
|
||||
// at build time to detect a changed set of fields.
|
||||
#define FALCO_FIELDS_CHECKSUM "ca9e75fa41fe4480cdfad8cf275cdbbc334e656569f070c066d87cbd2955c1ae"
|
||||
#define FALCO_FIELDS_CHECKSUM "2f324e2e66d4b423f53600e7e0fcf2f0ff72e4a87755c490f2ae8f310aba9386"
|
||||
|
||||
@@ -16,6 +16,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
#include <cstring>
|
||||
|
||||
#include "falco_utils.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
@@ -26,7 +27,7 @@ namespace falco
|
||||
namespace utils
|
||||
{
|
||||
|
||||
std::string wrap_text(const std::string &str, uint32_t initial_pos, uint32_t indent, uint32_t line_len)
|
||||
std::string wrap_text(const std::string& str, uint32_t initial_pos, uint32_t indent, uint32_t line_len)
|
||||
{
|
||||
std::string ret;
|
||||
|
||||
@@ -51,6 +52,28 @@ std::string wrap_text(const std::string &str, uint32_t initial_pos, uint32_t ind
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
void readfile(const std::string& filename, std::string& data)
|
||||
{
|
||||
std::ifstream file(filename.c_str(), std::ios::in);
|
||||
|
||||
if(file.is_open())
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << file.rdbuf();
|
||||
|
||||
file.close();
|
||||
|
||||
data = ss.str();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
namespace network
|
||||
{
|
||||
bool is_unix_scheme(nonstd::string_view url)
|
||||
{
|
||||
return url.starts_with(UNIX_SCHEME);
|
||||
}
|
||||
} // namespace network
|
||||
} // namespace utils
|
||||
} // namespace falco
|
||||
|
||||
@@ -17,7 +17,11 @@ limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <nonstd/string_view.hpp>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -27,8 +31,13 @@ namespace falco
|
||||
namespace utils
|
||||
{
|
||||
|
||||
std::string wrap_text(const std::string &str, uint32_t initial_pos, uint32_t indent, uint32_t line_len);
|
||||
std::string wrap_text(const std::string& str, uint32_t initial_pos, uint32_t indent, uint32_t line_len);
|
||||
|
||||
void readfile(const std::string& filename, std::string& data);
|
||||
namespace network
|
||||
{
|
||||
static const std::string UNIX_SCHEME("unix://");
|
||||
bool is_unix_scheme(nonstd::string_view url);
|
||||
} // namespace network
|
||||
} // namespace utils
|
||||
|
||||
} // namespace falco
|
||||
|
||||
@@ -52,14 +52,13 @@ add_executable(
|
||||
grpc_server_impl.cpp
|
||||
grpc_request_context.cpp
|
||||
grpc_server.cpp
|
||||
utils.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.grpc.pb.cc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.pb.cc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/output.grpc.pb.cc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/output.pb.cc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/schema.pb.cc)
|
||||
|
||||
add_dependencies(falco civetweb)
|
||||
add_dependencies(falco civetweb string-view-lite)
|
||||
|
||||
if(USE_BUNDLED_DEPS)
|
||||
add_dependencies(falco yamlcpp)
|
||||
@@ -69,11 +68,10 @@ target_include_directories(
|
||||
falco
|
||||
PUBLIC
|
||||
"${SYSDIG_SOURCE_DIR}/userspace/sysdig"
|
||||
"${HEDLEY_INCLUDE}"
|
||||
"${PROJECT_SOURCE_DIR}/userspace/profiler"
|
||||
"${PROJECT_SOURCE_DIR}/userspace/engine"
|
||||
"${PROJECT_BINARY_DIR}/userspace/falco"
|
||||
"${PROJECT_BINARY_DIR}/driver/src"
|
||||
"${STRING_VIEW_LITE_INCLUDE}"
|
||||
"${YAMLCPP_INCLUDE_DIR}"
|
||||
"${CIVETWEB_INCLUDE_DIR}"
|
||||
"${GRPC_INCLUDE}"
|
||||
@@ -86,7 +84,6 @@ target_link_libraries(
|
||||
falco
|
||||
falco_engine
|
||||
sinsp
|
||||
falco_profiler
|
||||
"${GPR_LIB}"
|
||||
"${GRPC_LIB}"
|
||||
"${GRPCPP_LIB}"
|
||||
|
||||
@@ -151,7 +151,7 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
|
||||
m_grpc_threadiness = m_config->get_scalar<uint32_t>("grpc", "threadiness", 8); // todo > limit it to avoid overshubscription? std::thread::hardware_concurrency()
|
||||
if(m_grpc_threadiness == 0)
|
||||
{
|
||||
throw logic_error("error reading config file (" + m_config_file +"): gRPC threadiness must be greater than 0");
|
||||
throw logic_error("error reading config file (" + m_config_file + "): gRPC threadiness must be greater than 0");
|
||||
}
|
||||
m_grpc_private_key = m_config->get_scalar<string>("grpc", "private_key", "/etc/falco/certs/server.key");
|
||||
m_grpc_cert_chain = m_config->get_scalar<string>("grpc", "cert_chain", "/etc/falco/certs/server.crt");
|
||||
@@ -170,9 +170,9 @@ void falco_configuration::init(string conf_filename, list<string> &cmdline_optio
|
||||
throw logic_error("Error reading config file (" + m_config_file + "): No outputs configured. Please configure at least one output file output enabled but no filename in configuration block");
|
||||
}
|
||||
|
||||
string log_level = m_config->get_scalar<string>("log_level", "info");
|
||||
m_log_level = m_config->get_scalar<string>("log_level", "info");
|
||||
|
||||
falco_logger::set_level(log_level);
|
||||
falco_logger::set_level(m_log_level);
|
||||
|
||||
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs", "rate", 1);
|
||||
m_notifications_max_burst = m_config->get_scalar<uint32_t>("outputs", "max_burst", 1000);
|
||||
|
||||
@@ -195,6 +195,7 @@ public:
|
||||
std::list<std::string> m_rules_filenames;
|
||||
bool m_json_output;
|
||||
bool m_json_include_output_property;
|
||||
std::string m_log_level;
|
||||
std::vector<falco_outputs::output_config> m_outputs;
|
||||
uint32_t m_notifications_rate;
|
||||
uint32_t m_notifications_max_burst;
|
||||
|
||||
@@ -45,7 +45,6 @@ limitations under the License.
|
||||
#include "statsfilewriter.h"
|
||||
#include "webserver.h"
|
||||
#include "grpc_server.h"
|
||||
#include "profiler.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
typedef function<void(sinsp* inspector)> open_t;
|
||||
@@ -236,7 +235,6 @@ uint64_t do_inspect(falco_engine *engine,
|
||||
bool all_events,
|
||||
int &result)
|
||||
{
|
||||
PROFILEME();
|
||||
uint64_t num_evts = 0;
|
||||
int32_t rc;
|
||||
sinsp_evt* ev;
|
||||
@@ -1205,12 +1203,19 @@ int falco_init(int argc, char **argv)
|
||||
webserver.start();
|
||||
}
|
||||
|
||||
// grpc server
|
||||
// gRPC server
|
||||
if(config.m_grpc_enabled)
|
||||
{
|
||||
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per thread, or implement
|
||||
// different queuing mechanisms, round robin, fanout? What we want to achieve?
|
||||
grpc_server.init(config.m_grpc_bind_address, config.m_grpc_threadiness, config.m_grpc_private_key, config.m_grpc_cert_chain, config.m_grpc_root_certs);
|
||||
grpc_server.init(
|
||||
config.m_grpc_bind_address,
|
||||
config.m_grpc_threadiness,
|
||||
config.m_grpc_private_key,
|
||||
config.m_grpc_cert_chain,
|
||||
config.m_grpc_root_certs,
|
||||
config.m_log_level
|
||||
);
|
||||
grpc_server_thread = std::thread([&grpc_server] {
|
||||
grpc_server.run();
|
||||
});
|
||||
@@ -1293,7 +1298,6 @@ exit:
|
||||
//
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
alloc_chunk();
|
||||
int rc;
|
||||
|
||||
// g_restart will cause the falco loop to exit, but we
|
||||
|
||||
@@ -23,7 +23,7 @@ limitations under the License.
|
||||
#include "logger.h"
|
||||
#include "grpc_server.h"
|
||||
#include "grpc_request_context.h"
|
||||
#include "utils.h"
|
||||
#include "falco_utils.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
#define REGISTER_STREAM(req, res, svc, rpc, impl, num) \
|
||||
@@ -44,6 +44,25 @@ limitations under the License.
|
||||
c.start(this); \
|
||||
}
|
||||
|
||||
static void gpr_log_dispatcher_func(gpr_log_func_args* args)
|
||||
{
|
||||
int priority;
|
||||
switch(args->severity)
|
||||
{
|
||||
case GPR_LOG_SEVERITY_ERROR:
|
||||
priority = LOG_ERR;
|
||||
break;
|
||||
case GPR_LOG_SEVERITY_DEBUG:
|
||||
priority = LOG_DEBUG;
|
||||
break;
|
||||
default:
|
||||
priority = LOG_INFO;
|
||||
break;
|
||||
}
|
||||
|
||||
falco_logger::log(priority, args->message);
|
||||
}
|
||||
|
||||
void falco::grpc::server::thread_process(int thread_index)
|
||||
{
|
||||
void* tag = nullptr;
|
||||
@@ -96,38 +115,81 @@ void falco::grpc::server::thread_process(int thread_index)
|
||||
}
|
||||
}
|
||||
|
||||
void falco::grpc::server::init(std::string server_addr, int threadiness, std::string private_key, std::string cert_chain, std::string root_certs)
|
||||
void falco::grpc::server::init(
|
||||
std::string server_addr,
|
||||
int threadiness,
|
||||
std::string private_key,
|
||||
std::string cert_chain,
|
||||
std::string root_certs,
|
||||
std::string log_level)
|
||||
{
|
||||
m_server_addr = server_addr;
|
||||
m_threadiness = threadiness;
|
||||
m_private_key = private_key;
|
||||
m_cert_chain = cert_chain;
|
||||
m_root_certs = root_certs;
|
||||
|
||||
// Set the verbosity level of gpr logger
|
||||
falco::schema::priority logging_level = falco::schema::INFORMATIONAL;
|
||||
falco::schema::priority_Parse(log_level, &logging_level);
|
||||
switch(logging_level)
|
||||
{
|
||||
case falco::schema::ERROR:
|
||||
gpr_set_log_verbosity(GPR_LOG_SEVERITY_ERROR);
|
||||
break;
|
||||
case falco::schema::DEBUG:
|
||||
gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
|
||||
break;
|
||||
case falco::schema::INFORMATIONAL:
|
||||
default:
|
||||
// note > info will always enter here since it is != from "informational"
|
||||
gpr_set_log_verbosity(GPR_LOG_SEVERITY_INFO);
|
||||
break;
|
||||
}
|
||||
gpr_log_verbosity_init();
|
||||
gpr_set_log_function(gpr_log_dispatcher_func);
|
||||
|
||||
if(falco::utils::network::is_unix_scheme(m_server_addr))
|
||||
{
|
||||
init_unix_server_builder();
|
||||
return;
|
||||
}
|
||||
init_mtls_server_builder();
|
||||
}
|
||||
|
||||
void falco::grpc::server::run()
|
||||
void falco::grpc::server::init_mtls_server_builder()
|
||||
{
|
||||
string private_key;
|
||||
string cert_chain;
|
||||
string root_certs;
|
||||
|
||||
falco::utils::read(m_cert_chain, cert_chain);
|
||||
falco::utils::read(m_private_key, private_key);
|
||||
falco::utils::read(m_root_certs, root_certs);
|
||||
|
||||
falco::utils::readfile(m_cert_chain, cert_chain);
|
||||
falco::utils::readfile(m_private_key, private_key);
|
||||
falco::utils::readfile(m_root_certs, root_certs);
|
||||
::grpc::SslServerCredentialsOptions::PemKeyCertPair cert_pair{private_key, cert_chain};
|
||||
|
||||
::grpc::SslServerCredentialsOptions ssl_opts(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
|
||||
ssl_opts.pem_root_certs = root_certs;
|
||||
ssl_opts.pem_key_cert_pairs.push_back(cert_pair);
|
||||
|
||||
::grpc::ServerBuilder builder;
|
||||
builder.AddListeningPort(m_server_addr, ::grpc::SslServerCredentials(ssl_opts));
|
||||
builder.RegisterService(&m_output_svc);
|
||||
builder.RegisterService(&m_version_svc);
|
||||
m_server_builder.AddListeningPort(m_server_addr, ::grpc::SslServerCredentials(ssl_opts));
|
||||
}
|
||||
|
||||
m_completion_queue = builder.AddCompletionQueue();
|
||||
m_server = builder.BuildAndStart();
|
||||
void falco::grpc::server::init_unix_server_builder()
|
||||
{
|
||||
m_server_builder.AddListeningPort(m_server_addr, ::grpc::InsecureServerCredentials());
|
||||
}
|
||||
|
||||
void falco::grpc::server::run()
|
||||
{
|
||||
m_server_builder.RegisterService(&m_output_svc);
|
||||
m_server_builder.RegisterService(&m_version_svc);
|
||||
|
||||
m_completion_queue = m_server_builder.AddCompletionQueue();
|
||||
m_server = m_server_builder.BuildAndStart();
|
||||
if(m_server == nullptr)
|
||||
{
|
||||
falco_logger::log(LOG_EMERG, "Error starting gRPC server\n");
|
||||
return;
|
||||
}
|
||||
falco_logger::log(LOG_INFO, "Starting gRPC server at " + m_server_addr + "\n");
|
||||
|
||||
// The number of contexts is multiple of the number of threads
|
||||
|
||||
@@ -29,20 +29,17 @@ namespace grpc
|
||||
class server : public server_impl
|
||||
{
|
||||
public:
|
||||
server()
|
||||
{
|
||||
}
|
||||
server(std::string server_addr, int threadiness, std::string private_key, std::string cert_chain, std::string root_certs):
|
||||
m_server_addr(server_addr),
|
||||
m_threadiness(threadiness),
|
||||
m_private_key(private_key),
|
||||
m_cert_chain(cert_chain),
|
||||
m_root_certs(root_certs)
|
||||
{
|
||||
}
|
||||
server() = default;
|
||||
virtual ~server() = default;
|
||||
|
||||
void init(std::string server_addr, int threadiness, std::string private_key, std::string cert_chain, std::string root_certs);
|
||||
void init(
|
||||
std::string server_addr,
|
||||
int threadiness,
|
||||
std::string private_key,
|
||||
std::string cert_chain,
|
||||
std::string root_certs,
|
||||
std::string log_level
|
||||
);
|
||||
void thread_process(int thread_index);
|
||||
void run();
|
||||
void stop();
|
||||
@@ -61,7 +58,10 @@ private:
|
||||
|
||||
std::unique_ptr<::grpc::Server> m_server;
|
||||
std::vector<std::thread> m_threads;
|
||||
::grpc::ServerBuilder m_server_builder;
|
||||
void init_mtls_server_builder();
|
||||
void init_unix_server_builder();
|
||||
};
|
||||
|
||||
} // namespace grpc
|
||||
} // namespace falco
|
||||
} // namespace falco
|
||||
|
||||
@@ -134,7 +134,7 @@ void falco_logger::log(int priority, const string msg)
|
||||
if(gtm != NULL &&
|
||||
(strftime(buf, sizeof(buf), "%FT%T%z", gtm) != 0))
|
||||
{
|
||||
fprintf(stderr, "%s: %s", buf, msg.c_str());
|
||||
fprintf(stderr, "%s: %s", buf, copy.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -151,7 +151,7 @@ void falco_logger::log(int priority, const string msg)
|
||||
{
|
||||
tstr = "N/A";
|
||||
}
|
||||
fprintf(stderr, "%s: %s", tstr.c_str(), msg.c_str());
|
||||
fprintf(stderr, "%s: %s", tstr.c_str(), copy.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +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.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
void falco::utils::read(const std::string& filename, std::string& data)
|
||||
{
|
||||
std::ifstream file(filename.c_str(), std::ios::in);
|
||||
|
||||
if(file.is_open())
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << file.rdbuf();
|
||||
|
||||
file.close();
|
||||
|
||||
data = ss.str();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2019 The Falco Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace falco
|
||||
{
|
||||
namespace utils
|
||||
{
|
||||
void read(const std::string& filename, std::string& data);
|
||||
} // namespace utils
|
||||
} // namespace falco
|
||||
@@ -1,19 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 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.
|
||||
|
||||
add_library(falco_profiler INTERFACE)
|
||||
|
||||
target_include_directories(falco_profiler INTERFACE "${HEDLEY_INCLUDE}" "${FLATBUFFER_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
flatbuffers_generate_c_headers(PROFILE "profile.fbs")
|
||||
add_custom_target(flatbuffer_profiler DEPENDS ${PROFILE_OUTPUTS})
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace profiler;
|
||||
|
||||
file_identifier "FPRO";
|
||||
file_extension "fpro";
|
||||
|
||||
table Node {
|
||||
func:string;
|
||||
file:string;
|
||||
line:int;
|
||||
cycles:uint64;
|
||||
childs:[Node];
|
||||
}
|
||||
|
||||
root_type Node;
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2020 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include <hedley.h>
|
||||
|
||||
namespace profiler
|
||||
{
|
||||
|
||||
#define CHUNK_ELEMENTS 7
|
||||
#define CHUNK_SIZE ((1 << 20) * CHUNK_ELEMENTS) // 20 MiB = 5242880 * sizeof(uint32_t)
|
||||
#define LABEL_MASK 0x80000000 // Largest positive int32 + 1
|
||||
|
||||
struct cursor
|
||||
{
|
||||
uint32_t* current;
|
||||
uint32_t* end;
|
||||
};
|
||||
|
||||
struct chunk
|
||||
{
|
||||
uint32_t* begin;
|
||||
uint32_t* end;
|
||||
std::thread::id thread;
|
||||
};
|
||||
|
||||
struct label
|
||||
{
|
||||
uint32_t label;
|
||||
std::string file;
|
||||
std::string func;
|
||||
int line;
|
||||
};
|
||||
|
||||
thread_local cursor c;
|
||||
std::vector<label> labels;
|
||||
std::vector<chunk> chunks;
|
||||
size_t nchunks;
|
||||
std::mutex mu;
|
||||
|
||||
HEDLEY_NEVER_INLINE void alloc_chunk()
|
||||
{
|
||||
auto d = new uint32_t[CHUNK_SIZE];
|
||||
c.current = d;
|
||||
c.end = d + CHUNK_SIZE;
|
||||
|
||||
mu.lock();
|
||||
chunks.push_back({d, d + CHUNK_SIZE, std::this_thread::get_id()});
|
||||
nchunks += 1;
|
||||
mu.unlock();
|
||||
}
|
||||
|
||||
HEDLEY_NEVER_INLINE uint32_t create_label(char const* file, int line, char const* func)
|
||||
{
|
||||
label l;
|
||||
l.label = labels.size() | LABEL_MASK;
|
||||
l.file = file;
|
||||
l.func = func;
|
||||
l.line = line;
|
||||
mu.lock();
|
||||
labels.push_back(l);
|
||||
mu.unlock();
|
||||
return l.label;
|
||||
}
|
||||
|
||||
struct profile
|
||||
{
|
||||
uint32_t* data;
|
||||
int n;
|
||||
int epochs; // (max) depth at the moment of execution
|
||||
|
||||
explicit profile(uint32_t label)
|
||||
{
|
||||
data = c.current;
|
||||
auto next = data + CHUNK_ELEMENTS;
|
||||
n = nchunks;
|
||||
epochs = (next - chunks[n - 1].begin) / CHUNK_ELEMENTS; // (next - start) / data size
|
||||
|
||||
if(HEDLEY_LIKELY(next != c.end))
|
||||
c.current = next; // adds 28 bytes
|
||||
else
|
||||
alloc_chunk(); // note: changes `c` values (current and end)
|
||||
|
||||
data[0] = label;
|
||||
data[5] = 0; // unknown parent
|
||||
data[6] = 0; // mark current instance as init
|
||||
|
||||
unsigned int lo, hi;
|
||||
__asm__ __volatile__("rdtsc"
|
||||
: "=a"(lo), "=d"(hi));
|
||||
data[1] = hi;
|
||||
data[2] = lo;
|
||||
}
|
||||
|
||||
~profile()
|
||||
{
|
||||
unsigned int lo, hi;
|
||||
__asm__ __volatile__("rdtsc"
|
||||
: "=a"(lo), "=d"(hi));
|
||||
data[3] = hi;
|
||||
data[4] = lo;
|
||||
|
||||
if(HEDLEY_LIKELY(epochs > 1))
|
||||
{
|
||||
for(int i = 0; i < epochs - 1; i++)
|
||||
{
|
||||
// Check whether the i-th destructor before this has been called (>0) or not (0)
|
||||
if(data[-1 - (i * CHUNK_ELEMENTS)] == 0)
|
||||
{
|
||||
// The head of the first destructor which has not been called yet is the parent of the current one
|
||||
data[5] = data[-((i + 1) * CHUNK_ELEMENTS)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(n > 1)
|
||||
{
|
||||
// TODO: make it span across more chunks (until n - 2 == 0)
|
||||
uint32_t* cdata = chunks[n - 2].end;
|
||||
for(int i = 0; i < (CHUNK_SIZE / CHUNK_ELEMENTS); i++)
|
||||
{
|
||||
if(cdata[-1 - (i * CHUNK_ELEMENTS)] == 0)
|
||||
{
|
||||
data[5] = cdata[-((i + 1) * CHUNK_ELEMENTS)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(n > 1 && data[5] == 0)
|
||||
{
|
||||
// TODO: same as above
|
||||
// TODO: make it span across more chunks (until n - 2 == 0)
|
||||
uint32_t* cdata = chunks[n - 2].end;
|
||||
for(int i = 0; i < (CHUNK_SIZE / CHUNK_ELEMENTS); i++)
|
||||
{
|
||||
if(cdata[-1 - (i * CHUNK_ELEMENTS)] == 0)
|
||||
{
|
||||
data[5] = cdata[-((i + 1) * CHUNK_ELEMENTS)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data[6] = n; // mark current instance as done storing the chunk index (+ 1)
|
||||
}
|
||||
};
|
||||
|
||||
#define PROFILE_VARIABLE_IMPL(arg1, arg2) arg1##arg2
|
||||
#define PROFILE_VARIABLE(arg1, arg2) PROFILE_VARIABLE_IMPL(arg1, arg2)
|
||||
|
||||
#define PROFILEME() \
|
||||
static uint32_t PROFILE_VARIABLE(_label, __LINE__) = profiler::create_label(__FILE__, __LINE__, __FUNCTION__); \
|
||||
profiler::profile PROFILE_VARIABLE(_profile_, __LINE__)(PROFILE_VARIABLE(_label, __LINE__));
|
||||
|
||||
}; // namespace profiler
|
||||
Reference in New Issue
Block a user