mirror of
https://github.com/falcosecurity/falco.git
synced 2026-03-22 04:32:21 +00:00
Compare commits
141 Commits
0.32.0
...
test/new_l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db92f04474 | ||
|
|
8e61e46016 | ||
|
|
3c7b6e037a | ||
|
|
49b7f0474f | ||
|
|
98c1e3d3f1 | ||
|
|
0828296abc | ||
|
|
6971ed2dce | ||
|
|
be10b1f8cb | ||
|
|
1efea20f57 | ||
|
|
fefd23f2f1 | ||
|
|
2a640daf13 | ||
|
|
0ab66c6fb5 | ||
|
|
1588f37788 | ||
|
|
66af8ad52b | ||
|
|
ff247f922d | ||
|
|
e9ba5d751f | ||
|
|
c81f3fc87e | ||
|
|
a37e2252b2 | ||
|
|
550cdbd176 | ||
|
|
f7f6d72ac0 | ||
|
|
cbe7cceb87 | ||
|
|
bb44d992ab | ||
|
|
0066ba49ea | ||
|
|
8497f25a43 | ||
|
|
6b7be38e41 | ||
|
|
9d443685ea | ||
|
|
928d3225b9 | ||
|
|
a531e8b3ed | ||
|
|
07fde46e7c | ||
|
|
136b528849 | ||
|
|
a46cbcffe8 | ||
|
|
577ba5904b | ||
|
|
1b8c8a86ec | ||
|
|
7317d80dd8 | ||
|
|
c8bc5758c3 | ||
|
|
ae43f30b0d | ||
|
|
fb579615a3 | ||
|
|
b759e77fda | ||
|
|
74b6186f7d | ||
|
|
baf5540c30 | ||
|
|
c3ddd7d5f1 | ||
|
|
b378c3a77d | ||
|
|
0cab9ba6ed | ||
|
|
8cb6fc532f | ||
|
|
35db0b4a24 | ||
|
|
4136a27de1 | ||
|
|
e73dbd4b42 | ||
|
|
b57a2d5a5f | ||
|
|
1bf5f864bc | ||
|
|
c40d1a5141 | ||
|
|
409ca4382e | ||
|
|
a71a635b7e | ||
|
|
07024a2e0f | ||
|
|
6feeaee0cd | ||
|
|
a7153f2fd8 | ||
|
|
c078f7c21d | ||
|
|
46f625c449 | ||
|
|
4c4ed56c19 | ||
|
|
773156de04 | ||
|
|
62c1e875d5 | ||
|
|
7dade32688 | ||
|
|
bae68b37ee | ||
|
|
3ddabc3b95 | ||
|
|
a8b9ec18b0 | ||
|
|
34404141e4 | ||
|
|
315b44dc17 | ||
|
|
161fe6fb3c | ||
|
|
3cde70eda8 | ||
|
|
982e8663be | ||
|
|
993516f430 | ||
|
|
60b149709d | ||
|
|
698eda8680 | ||
|
|
0b75433cee | ||
|
|
0ba492c280 | ||
|
|
927c1c4126 | ||
|
|
1966fa1f91 | ||
|
|
e4fe6a3353 | ||
|
|
610b67838b | ||
|
|
effabf533d | ||
|
|
3c2effb498 | ||
|
|
555bf9971c | ||
|
|
c309107949 | ||
|
|
b6245d77c7 | ||
|
|
2f208b52fc | ||
|
|
f3bc178e40 | ||
|
|
308f001b87 | ||
|
|
fda9fb36de | ||
|
|
92fdbbcc52 | ||
|
|
4b694896a4 | ||
|
|
d589ec2144 | ||
|
|
6c08fa2a20 | ||
|
|
9af20a000d | ||
|
|
7e1e7c2e42 | ||
|
|
1f2e6d4629 | ||
|
|
85ca1eb3dd | ||
|
|
5dce4d2025 | ||
|
|
d90421387f | ||
|
|
07b4d5a47a | ||
|
|
8a1f43f284 | ||
|
|
fcac635780 | ||
|
|
5d10e54ad4 | ||
|
|
5f17b7bd41 | ||
|
|
9231fe3c1f | ||
|
|
99784874eb | ||
|
|
a3c8fa85d4 | ||
|
|
bcda81f700 | ||
|
|
1e5ef912de | ||
|
|
50039316ce | ||
|
|
eb365f1a3e | ||
|
|
625201f9f6 | ||
|
|
583ac4192c | ||
|
|
85f91a3ec4 | ||
|
|
6d56571e23 | ||
|
|
9d7153e119 | ||
|
|
4097661ba8 | ||
|
|
83700d6d6a | ||
|
|
fccd3fa7b6 | ||
|
|
1327c796d0 | ||
|
|
c782655a53 | ||
|
|
ba6c86696f | ||
|
|
9d2aba240d | ||
|
|
b059e83dd2 | ||
|
|
6a034c17e0 | ||
|
|
e6f99a61c9 | ||
|
|
7b83943059 | ||
|
|
2111699a96 | ||
|
|
b6d0607716 | ||
|
|
1c83a449bc | ||
|
|
534f66e601 | ||
|
|
a98bf52345 | ||
|
|
aad70f3de2 | ||
|
|
4aa0fe1b95 | ||
|
|
0ebc7cd969 | ||
|
|
4f759b6b2b | ||
|
|
ca677db651 | ||
|
|
0a98e11428 | ||
|
|
7068e9958f | ||
|
|
e5af3899f9 | ||
|
|
3f29660258 | ||
|
|
62794966b1 | ||
|
|
984b94f734 |
@@ -1,4 +1,2 @@
|
||||
approvers:
|
||||
- jonahjon
|
||||
reviewers:
|
||||
emeritus_approvers:
|
||||
- jonahjon
|
||||
|
||||
@@ -1,8 +1,56 @@
|
||||
version: 2
|
||||
version: 2.1
|
||||
jobs:
|
||||
"build-arm64":
|
||||
machine:
|
||||
enabled: true
|
||||
image: ubuntu-2004:202101-01
|
||||
resource_class: arm.medium
|
||||
steps:
|
||||
- checkout:
|
||||
path: /tmp/source-arm64/falco
|
||||
- run:
|
||||
name: Prepare project
|
||||
command: |
|
||||
mkdir -p /tmp/build-arm64 && mkdir -p /tmp/build-arm64/release && \
|
||||
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
|
||||
falcosecurity/falco-builder:latest \
|
||||
cmake
|
||||
- run:
|
||||
name: Build
|
||||
command: |
|
||||
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
|
||||
falcosecurity/falco-builder:latest \
|
||||
all
|
||||
- run:
|
||||
name: Run unit tests
|
||||
command: |
|
||||
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
|
||||
falcosecurity/falco-builder:latest \
|
||||
tests
|
||||
- run:
|
||||
name: Build packages
|
||||
command: |
|
||||
docker run -e BUILD_TYPE="release" -it -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
|
||||
falcosecurity/falco-builder:latest \
|
||||
package
|
||||
- run:
|
||||
name: Prepare Artifacts
|
||||
command: |
|
||||
mkdir -p /tmp/packages
|
||||
cp /tmp/build-arm64/release/*.deb /tmp/packages
|
||||
cp /tmp/build-arm64/release/*.tar.gz /tmp/packages
|
||||
cp /tmp/build-arm64/release/*.rpm /tmp/packages
|
||||
- store_artifacts:
|
||||
path: /tmp/packages
|
||||
destination: /packages
|
||||
- persist_to_workspace:
|
||||
root: /tmp
|
||||
paths:
|
||||
- build-arm64/release
|
||||
- source-arm64
|
||||
# Build a statically linked Falco release binary using musl
|
||||
# This build is 100% static, there are no host dependencies
|
||||
"build/musl":
|
||||
"build-musl":
|
||||
docker:
|
||||
- image: alpine:3.12
|
||||
steps:
|
||||
@@ -50,7 +98,7 @@ jobs:
|
||||
- source-static
|
||||
# Build using our own builder base image using centos 7
|
||||
# This build is static, dependencies are bundled in the Falco binary
|
||||
"build/centos7":
|
||||
"build-centos7":
|
||||
docker:
|
||||
- image: falcosecurity/falco-builder:latest
|
||||
environment:
|
||||
@@ -85,8 +133,8 @@ jobs:
|
||||
- store_artifacts:
|
||||
path: /tmp/packages
|
||||
destination: /packages
|
||||
# Execute integration tests based on the build results coming from the "build/centos7" job
|
||||
"tests/integration":
|
||||
# Execute integration tests based on the build results coming from the "build-centos7" job
|
||||
"tests-integration":
|
||||
docker:
|
||||
- image: falcosecurity/falco-tester:latest
|
||||
environment:
|
||||
@@ -102,7 +150,7 @@ jobs:
|
||||
command: /usr/bin/entrypoint test
|
||||
- store_test_results:
|
||||
path: /build/release/integration-tests-xunit
|
||||
"tests/integration-static":
|
||||
"tests-integration-static":
|
||||
docker:
|
||||
- image: falcosecurity/falco-tester:latest
|
||||
environment:
|
||||
@@ -120,7 +168,24 @@ jobs:
|
||||
command: /usr/bin/entrypoint test
|
||||
- store_test_results:
|
||||
path: /build-static/release/integration-tests-xunit
|
||||
"tests/driver-loader/integration":
|
||||
# Execute integration tests based on the build results coming from the "build-arm64" job
|
||||
"tests-integration-arm64":
|
||||
machine:
|
||||
enabled: true
|
||||
image: ubuntu-2004:202101-01
|
||||
resource_class: arm.medium
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp
|
||||
- run:
|
||||
name: Execute integration tests
|
||||
command: |
|
||||
docker run -e BUILD_TYPE="release" -e BUILD_DIR="/build" -e SOURCE_DIR="/source" -it -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/source-arm64:/source -v /tmp/build-arm64:/build \
|
||||
falcosecurity/falco-tester:latest \
|
||||
test
|
||||
- store_test_results:
|
||||
path: /tmp/build-arm64/release/integration-tests-xunit
|
||||
"tests-driver-loader-integration":
|
||||
machine:
|
||||
image: ubuntu-2004:202107-02
|
||||
steps:
|
||||
@@ -130,7 +195,7 @@ jobs:
|
||||
name: Execute driver-loader integration tests
|
||||
command: /tmp/ws/source/falco/test/driver-loader/run_test.sh /tmp/ws/build/release/
|
||||
# Code quality
|
||||
"quality/static-analysis":
|
||||
"quality-static-analysis":
|
||||
docker:
|
||||
- image: falcosecurity/falco-builder:latest
|
||||
environment:
|
||||
@@ -157,7 +222,7 @@ jobs:
|
||||
path: /build/release/static-analysis-reports
|
||||
destination: /static-analysis-reports
|
||||
# Sign rpm packages
|
||||
"rpm/sign":
|
||||
"rpm-sign":
|
||||
docker:
|
||||
- image: falcosecurity/falco-builder:latest
|
||||
steps:
|
||||
@@ -169,26 +234,39 @@ jobs:
|
||||
yum update -y
|
||||
yum install rpm-sign -y
|
||||
- run:
|
||||
name: Sign rpm
|
||||
name: Prepare
|
||||
command: |
|
||||
echo "%_signature gpg" > ~/.rpmmacros
|
||||
echo "%_gpg_name Falcosecurity Package Signing" >> ~/.rpmmacros
|
||||
cd /build/release/
|
||||
echo '#!/usr/bin/expect -f' > sign
|
||||
echo 'spawn rpmsign --addsign {*}$argv' >> sign
|
||||
echo 'expect -exact "Enter pass phrase: "' >> sign
|
||||
echo 'send -- "\n"' >> sign
|
||||
echo 'expect eof' >> sign
|
||||
chmod +x sign
|
||||
echo "%__gpg_sign_cmd %{__gpg} --force-v3-sigs --batch --no-armor --passphrase-fd 3 --no-secmem-warning -u \"%{_gpg_name}\" -sb --digest-algo sha256 %{__plaintext_filename}'" >> ~/.rpmmacros
|
||||
cat > ~/sign \<<EOF
|
||||
#!/usr/bin/expect -f
|
||||
spawn rpmsign --addsign {*}\$argv
|
||||
expect -exact "Enter pass phrase: "
|
||||
send -- "\n"
|
||||
expect eof
|
||||
EOF
|
||||
chmod +x ~/sign
|
||||
echo $GPG_KEY | base64 -d | gpg --import
|
||||
./sign *.rpm
|
||||
test "$(rpm -qpi *.rpm | awk '/Signature/' | grep -i none | wc -l)" -eq 0
|
||||
- run:
|
||||
name: Sign rpm x86_64
|
||||
command: |
|
||||
cd /build/release/
|
||||
~/sign *.rpm
|
||||
rpm --qf %{SIGPGP:pgpsig} -qp *.rpm | grep SHA256
|
||||
- run:
|
||||
name: Sign rpm arm64
|
||||
command: |
|
||||
cd /build-arm64/release/
|
||||
~/sign *.rpm
|
||||
rpm --qf %{SIGPGP:pgpsig} -qp *.rpm | grep SHA256
|
||||
- persist_to_workspace:
|
||||
root: /
|
||||
paths:
|
||||
- build/release/*.rpm
|
||||
- build-arm64/release/*.rpm
|
||||
# Publish the dev packages
|
||||
"publish/packages-dev":
|
||||
"publish-packages-dev":
|
||||
docker:
|
||||
- image: docker.io/centos:7
|
||||
steps:
|
||||
@@ -206,19 +284,20 @@ jobs:
|
||||
name: Publish rpm-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm-dev
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.rpm -r rpm-dev
|
||||
- run:
|
||||
name: Publish bin-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
|
||||
/source/falco/scripts/publish-bin -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.tar.gz -r bin-dev -a aarch64
|
||||
- run:
|
||||
name: Publish bin-static-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin-dev -a x86_64
|
||||
"publish/packages-deb-dev":
|
||||
"publish-packages-deb-dev":
|
||||
docker:
|
||||
- image: docker.io/debian:stable
|
||||
steps:
|
||||
@@ -235,80 +314,174 @@ jobs:
|
||||
name: Publish deb-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -r deb-dev
|
||||
# Publish docker packages
|
||||
"publish/docker-dev":
|
||||
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.deb -r deb-dev
|
||||
|
||||
"build-docker-dev":
|
||||
docker:
|
||||
- image: docker:stable
|
||||
steps:
|
||||
- image: alpine:3.16
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- setup_remote_docker:
|
||||
version: 20.10.12
|
||||
docker_layer_caching: true
|
||||
- run:
|
||||
name: Install deps
|
||||
command: |
|
||||
apk update
|
||||
apk add make bash git docker docker-cli-buildx py3-pip
|
||||
pip install awscli
|
||||
- run:
|
||||
name: Login to registries
|
||||
command: |
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
- run:
|
||||
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=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
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
|
||||
-t falcosecurity/falco-no-driver:x86_64-master \
|
||||
-t falcosecurity/falco:x86_64-master-slim \
|
||||
-t public.ecr.aws/falcosecurity/falco-no-driver:x86_64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco:x86_64-master-slim \
|
||||
docker/no-driver
|
||||
- run:
|
||||
name: Build and publish dev
|
||||
name: Build and publish falco-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/falco
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push falcosecurity/falco:master
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
|
||||
-t falcosecurity/falco:x86_64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco:x86_64-master \
|
||||
docker/falco
|
||||
- run:
|
||||
name: Build and publish dev falco-driver-loader-dev
|
||||
name: Build and publish falco-driver-loader-dev
|
||||
command: |
|
||||
docker build --build-arg FALCO_IMAGE_TAG=master -t falcosecurity/falco-driver-loader:master docker/driver-loader
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push falcosecurity/falco-driver-loader:master
|
||||
# Publish container images to AWS ECR Public
|
||||
"publish/container-images-aws-dev":
|
||||
docker:
|
||||
- image: docker:stable
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg FALCO_IMAGE_TAG=master \
|
||||
-t falcosecurity/falco-driver-loader:x86_64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-master \
|
||||
docker/driver-loader
|
||||
|
||||
"build-docker-dev-arm64":
|
||||
machine:
|
||||
enabled: true
|
||||
image: ubuntu-2004:202101-01
|
||||
docker_layer_caching: true
|
||||
resource_class: arm.medium
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
at: /tmp
|
||||
- run:
|
||||
name: Build and publish no-driver (dev) to AWS
|
||||
name: Install deps
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
sudo apt update
|
||||
sudo apt install groff less python3-pip
|
||||
pip install awscli
|
||||
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=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} -t "public.ecr.aws/falcosecurity/falco-no-driver:master" docker/no-driver
|
||||
docker tag public.ecr.aws/falcosecurity/falco-no-driver:master public.ecr.aws/falcosecurity/falco:master-slim
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco-no-driver:master"
|
||||
docker push "public.ecr.aws/falcosecurity/falco:master-slim"
|
||||
- run:
|
||||
name: Build and publish falco (dev) to AWS
|
||||
name: Login to registries
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
pip install awscli
|
||||
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 "public.ecr.aws/falcosecurity/falco:master" docker/falco
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco:master"
|
||||
- run:
|
||||
name: Build and publish driver-loader (dev) to AWS
|
||||
name: Build and publish no-driver-dev
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
FALCO_VERSION=$(cat /tmp/build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
|
||||
-t falcosecurity/falco-no-driver:aarch64-master \
|
||||
-t falcosecurity/falco:aarch64-master-slim \
|
||||
-t public.ecr.aws/falcosecurity/falco-no-driver:aarch64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco:aarch64-master-slim \
|
||||
docker/no-driver
|
||||
- run:
|
||||
name: Build and publish falco-dev
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /tmp/build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
|
||||
-t falcosecurity/falco:aarch64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco:aarch64-master \
|
||||
docker/falco
|
||||
- run:
|
||||
name: Build and publish falco-driver-loader-dev
|
||||
command: |
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg FALCO_IMAGE_TAG=master \
|
||||
-t falcosecurity/falco-driver-loader:aarch64-master \
|
||||
-t public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-master \
|
||||
docker/driver-loader
|
||||
|
||||
# Publish docker packages
|
||||
"publish-docker-dev":
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
user: root
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
version: 20.10.12
|
||||
- run:
|
||||
name: Install deps
|
||||
command: |
|
||||
sudo apt update
|
||||
sudo apt install groff less python3-pip
|
||||
pip install awscli
|
||||
docker build --build-arg FALCO_IMAGE_TAG=master -t "public.ecr.aws/falcosecurity/falco-driver-loader:master" docker/driver-loader
|
||||
- run:
|
||||
name: Login to registries
|
||||
command: |
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco-driver-loader:master"
|
||||
- run:
|
||||
name: Upload no-driver-dev manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco-no-driver:master \
|
||||
falcosecurity/falco-no-driver:aarch64-master \
|
||||
falcosecurity/falco-no-driver:x86_64-master
|
||||
docker manifest push falcosecurity/falco-no-driver:master
|
||||
|
||||
docker manifest create falcosecurity/falco:master-slim \
|
||||
falcosecurity/falco:aarch64-master-slim \
|
||||
falcosecurity/falco:x86_64-master-slim
|
||||
docker manifest push falcosecurity/falco:master-slim
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:master \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-master \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-master
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:master
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:master-slim \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-master-slim \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-master-slim
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:master-slim
|
||||
- run:
|
||||
name: Upload falco-dev manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco:master \
|
||||
falcosecurity/falco:aarch64-master \
|
||||
falcosecurity/falco:x86_64-master
|
||||
docker manifest push falcosecurity/falco:master
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:master \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-master \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-master
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:master
|
||||
- run:
|
||||
name: Upload falco-driver-loader-dev manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco-driver-loader:master \
|
||||
falcosecurity/falco-driver-loader:aarch64-master \
|
||||
falcosecurity/falco-driver-loader:x86_64-master
|
||||
docker manifest push falcosecurity/falco-driver-loader:master
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:master \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-master \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-master
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:master
|
||||
|
||||
# Publish the packages
|
||||
"publish/packages":
|
||||
"publish-packages":
|
||||
docker:
|
||||
- image: docker.io/centos:7
|
||||
steps:
|
||||
@@ -326,19 +499,20 @@ jobs:
|
||||
name: Publish rpm
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -r rpm
|
||||
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.rpm -r rpm
|
||||
- run:
|
||||
name: Publish bin
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
|
||||
/source/falco/scripts/publish-bin -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.tar.gz -r bin -a aarch64
|
||||
- run:
|
||||
name: Publish bin-static
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
|
||||
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin -a x86_64
|
||||
"publish/packages-deb":
|
||||
"publish-packages-deb":
|
||||
docker:
|
||||
- image: docker.io/debian:stable
|
||||
steps:
|
||||
@@ -355,106 +529,244 @@ jobs:
|
||||
name: Publish deb
|
||||
command: |
|
||||
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
|
||||
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -r deb
|
||||
# Publish docker packages
|
||||
"publish/docker":
|
||||
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.deb -r deb
|
||||
|
||||
"build-docker":
|
||||
docker:
|
||||
- image: docker:stable
|
||||
steps:
|
||||
- image: alpine:3.16
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- setup_remote_docker:
|
||||
version: 20.10.12
|
||||
docker_layer_caching: true
|
||||
- run:
|
||||
name: Install deps
|
||||
command: |
|
||||
apk update
|
||||
apk add make bash git docker docker-cli-buildx py3-pip
|
||||
pip install awscli
|
||||
- run:
|
||||
name: Login to registries
|
||||
command: |
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
- run:
|
||||
name: Build and publish no-driver
|
||||
command: |
|
||||
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"
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${CIRCLE_TAG} \
|
||||
-t "falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}" \
|
||||
-t falcosecurity/falco-no-driver:x86_64-latest \
|
||||
-t "falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim" \
|
||||
-t "falcosecurity/falco:x86_64-latest-slim" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-no-driver:x86_64-latest" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:x86_64-latest-slim" \
|
||||
docker/no-driver
|
||||
- run:
|
||||
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/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}"
|
||||
docker push "falcosecurity/falco:latest"
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${CIRCLE_TAG} \
|
||||
-t "falcosecurity/falco:x86_64-${CIRCLE_TAG}" \
|
||||
-t "falcosecurity/falco:x86_64-latest" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:x86_64-latest" \
|
||||
docker/falco
|
||||
- run:
|
||||
name: Build and publish falco-driver-loader
|
||||
command: |
|
||||
docker build --build-arg FALCO_IMAGE_TAG=${CIRCLE_TAG} -t "falcosecurity/falco-driver-loader:${CIRCLE_TAG}" docker/driver-loader
|
||||
docker tag "falcosecurity/falco-driver-loader:${CIRCLE_TAG}" falcosecurity/falco-driver-loader:latest
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
docker push "falcosecurity/falco-driver-loader:${CIRCLE_TAG}"
|
||||
docker push "falcosecurity/falco-driver-loader:latest"
|
||||
# Publish container images to AWS ECR Public
|
||||
"publish/container-images-aws":
|
||||
docker:
|
||||
- image: docker:stable
|
||||
cd /source/falco
|
||||
docker buildx build --push --build-arg FALCO_IMAGE_TAG=${CIRCLE_TAG} \
|
||||
-t "falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}" \
|
||||
-t "falcosecurity/falco-driver-loader:x86_64-latest" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-latest" \
|
||||
docker/driver-loader
|
||||
|
||||
"build-docker-arm64":
|
||||
machine:
|
||||
enabled: true
|
||||
image: ubuntu-2004:202101-01
|
||||
docker_layer_caching: true
|
||||
resource_class: arm.medium
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
at: /tmp
|
||||
- run:
|
||||
name: Build and publish no-driver to AWS
|
||||
name: Install deps
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
sudo apt update
|
||||
sudo apt install groff less python3-pip
|
||||
pip install awscli
|
||||
docker build --build-arg VERSION_BUCKET=bin --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}" docker/no-driver
|
||||
docker tag "public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}" public.ecr.aws/falcosecurity/falco-no-driver:latest
|
||||
docker tag "public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}" "public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim"
|
||||
docker tag "public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}" "public.ecr.aws/falcosecurity/falco:latest-slim"
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim"
|
||||
docker push "public.ecr.aws/falcosecurity/falco:latest-slim"
|
||||
docker push "public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}"
|
||||
docker push "public.ecr.aws/falcosecurity/falco-no-driver:latest"
|
||||
- run:
|
||||
name: Build and publish falco to AWS
|
||||
name: Login to registries
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
pip install awscli
|
||||
docker build --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} -t "public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}" docker/falco
|
||||
docker tag "public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}" public.ecr.aws/falcosecurity/falco:latest
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}"
|
||||
docker push "public.ecr.aws/falcosecurity/falco:latest"
|
||||
- run:
|
||||
name: Build and publish falco-driver-loader to AWS
|
||||
name: Build and publish no-driver
|
||||
command: |
|
||||
apk update
|
||||
apk add --update groff less py-pip
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=bin --build-arg FALCO_VERSION=${CIRCLE_TAG} \
|
||||
-t falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
|
||||
-t falcosecurity/falco-no-driver:aarch64-latest \
|
||||
-t falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
|
||||
-t "falcosecurity/falco:aarch64-latest-slim" \
|
||||
-t public.ecr.aws/falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
|
||||
-t "public.ecr.aws/falcosecurity/falco-no-driver:aarch64-latest" \
|
||||
-t public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
|
||||
-t "public.ecr.aws/falcosecurity/falco:aarch64-latest-slim" \
|
||||
docker/no-driver
|
||||
- run:
|
||||
name: Build and publish falco
|
||||
command: |
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${CIRCLE_TAG} \
|
||||
-t "falcosecurity/falco:aarch64-${CIRCLE_TAG}" \
|
||||
-t "falcosecurity/falco:aarch64-latest" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}" \
|
||||
-t "public.ecr.aws/falcosecurity/falco:aarch64-latest" \
|
||||
docker/falco
|
||||
- run:
|
||||
name: Build and publish falco-driver-loader
|
||||
command: |
|
||||
cd /tmp/source-arm64/falco
|
||||
docker buildx build --push --build-arg FALCO_IMAGE_TAG=${CIRCLE_TAG} \
|
||||
-t "falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG}" \
|
||||
-t "falcosecurity/falco-driver-loader:aarch64-latest" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG}" \
|
||||
-t "public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-latest" \
|
||||
docker/driver-loader
|
||||
|
||||
# Publish docker packages
|
||||
"publish-docker":
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
user: root
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
version: 20.10.12
|
||||
- run:
|
||||
name: Install deps
|
||||
command: |
|
||||
sudo apt update
|
||||
sudo apt install groff less python3-pip
|
||||
pip install awscli
|
||||
docker build --build-arg FALCO_IMAGE_TAG=${CIRCLE_TAG} -t "public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG}" docker/driver-loader
|
||||
docker tag "public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG}" public.ecr.aws/falcosecurity/falco-driver-loader:latest
|
||||
- run:
|
||||
name: Login to registries
|
||||
command: |
|
||||
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
|
||||
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
|
||||
docker push "public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG}"
|
||||
docker push "public.ecr.aws/falcosecurity/falco-driver-loader:latest"
|
||||
- run:
|
||||
name: Upload no-driver manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco-no-driver:${CIRCLE_TAG} \
|
||||
falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
|
||||
falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push falcosecurity/falco-no-driver:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create falcosecurity/falco-no-driver:latest \
|
||||
falcosecurity/falco-no-driver:aarch64-latest \
|
||||
falcosecurity/falco-no-driver:x86_64-latest
|
||||
docker manifest push falcosecurity/falco-no-driver:latest
|
||||
|
||||
docker manifest create falcosecurity/falco:${CIRCLE_TAG}-slim \
|
||||
falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
|
||||
falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim
|
||||
docker manifest push falcosecurity/falco:${CIRCLE_TAG}-slim
|
||||
|
||||
docker manifest create falcosecurity/falco:latest-slim \
|
||||
falcosecurity/falco:aarch64-latest-slim \
|
||||
falcosecurity/falco:x86_64-latest-slim
|
||||
docker manifest push falcosecurity/falco:latest-slim
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:latest \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-latest \
|
||||
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-latest
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:latest
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:latest-slim \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-latest-slim \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-latest-slim
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:latest-slim
|
||||
- run:
|
||||
name: Upload falco manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco:${CIRCLE_TAG} \
|
||||
falcosecurity/falco:aarch64-${CIRCLE_TAG} \
|
||||
falcosecurity/falco:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push falcosecurity/falco:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create falcosecurity/falco:latest \
|
||||
falcosecurity/falco:aarch64-latest \
|
||||
falcosecurity/falco:x86_64-latest
|
||||
docker manifest push falcosecurity/falco:latest
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco:latest \
|
||||
public.ecr.aws/falcosecurity/falco:aarch64-latest \
|
||||
public.ecr.aws/falcosecurity/falco:x86_64-latest
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco:latest
|
||||
- run:
|
||||
name: Upload falco-driver-loader manifest to registries
|
||||
command: |
|
||||
docker manifest create falcosecurity/falco-driver-loader:${CIRCLE_TAG} \
|
||||
falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG} \
|
||||
falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push falcosecurity/falco-driver-loader:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create falcosecurity/falco-driver-loader:latest \
|
||||
falcosecurity/falco-driver-loader:aarch64-latest \
|
||||
falcosecurity/falco-driver-loader:x86_64-latest
|
||||
docker manifest push falcosecurity/falco-driver-loader:latest
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG} \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG}
|
||||
|
||||
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:latest \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-latest \
|
||||
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-latest
|
||||
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:latest
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
version: 2.1
|
||||
build_and_test:
|
||||
jobs:
|
||||
- "build/musl"
|
||||
- "build/centos7"
|
||||
- "tests/integration":
|
||||
- "build-musl"
|
||||
- "build-arm64"
|
||||
- "build-centos7"
|
||||
- "tests-integration":
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "tests/integration-static":
|
||||
- "build-centos7"
|
||||
- "tests-integration-arm64":
|
||||
requires:
|
||||
- "build/musl"
|
||||
- "tests/driver-loader/integration":
|
||||
- "build-arm64"
|
||||
- "tests-integration-static":
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "rpm/sign":
|
||||
- "build-musl"
|
||||
- "tests-driver-loader-integration":
|
||||
requires:
|
||||
- "build-centos7"
|
||||
- "rpm-sign":
|
||||
context: falco
|
||||
filters:
|
||||
tags:
|
||||
@@ -462,8 +774,9 @@ workflows:
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "tests/integration"
|
||||
- "publish/packages-dev":
|
||||
- "tests-integration"
|
||||
- "tests-integration-arm64"
|
||||
- "publish-packages-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
@@ -473,9 +786,9 @@ workflows:
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "rpm/sign"
|
||||
- "tests/integration-static"
|
||||
- "publish/packages-deb-dev":
|
||||
- "rpm-sign"
|
||||
- "tests-integration-static"
|
||||
- "publish-packages-deb-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
@@ -485,90 +798,132 @@ workflows:
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "tests/integration"
|
||||
- "publish/docker-dev":
|
||||
context: falco
|
||||
- "tests-integration"
|
||||
- "tests-integration-arm64"
|
||||
- "build-docker-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "publish/packages-dev"
|
||||
- "publish/packages-deb-dev"
|
||||
- "tests/driver-loader/integration"
|
||||
- "publish/container-images-aws-dev":
|
||||
context: test-infra # contains Falco AWS credentials
|
||||
- "publish-packages-dev"
|
||||
- "publish-packages-deb-dev"
|
||||
- "tests-driver-loader-integration"
|
||||
- "build-docker-dev-arm64":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- publish/docker-dev
|
||||
- "publish-packages-dev"
|
||||
- "publish-packages-deb-dev"
|
||||
- "tests-driver-loader-integration"
|
||||
- "publish-docker-dev":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
filters:
|
||||
tags:
|
||||
ignore: /.*/
|
||||
branches:
|
||||
only: master
|
||||
requires:
|
||||
- "build-docker-dev"
|
||||
- "build-docker-dev-arm64"
|
||||
# - "quality/static-analysis" # This is temporarily disabled: https://github.com/falcosecurity/falco/issues/1526
|
||||
release:
|
||||
jobs:
|
||||
- "build/musl":
|
||||
- "build-musl":
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "build/centos7":
|
||||
- "build-centos7":
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "rpm/sign":
|
||||
- "build-arm64":
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "rpm-sign":
|
||||
context: falco
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "build-centos7"
|
||||
- "build-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish/packages":
|
||||
- "publish-packages":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build/musl"
|
||||
- "rpm/sign"
|
||||
- "build-musl"
|
||||
- "rpm-sign"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish/packages-deb":
|
||||
- "publish-packages-deb":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build/centos7"
|
||||
- "build-centos7"
|
||||
- "build-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish/docker":
|
||||
- "build-docker":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "publish/packages"
|
||||
- "publish/packages-deb"
|
||||
- "publish-packages"
|
||||
- "publish-packages-deb"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish/container-images-aws":
|
||||
context: test-infra # contains Falco AWS credentials
|
||||
- "build-docker-arm64":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "publish/docker"
|
||||
- "publish-packages"
|
||||
- "publish-packages-deb"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- "publish-docker":
|
||||
context:
|
||||
- falco
|
||||
- test-infra
|
||||
requires:
|
||||
- "build-docker"
|
||||
- "build-docker-arm64"
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
|
||||
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -22,6 +22,8 @@
|
||||
|
||||
> /kind feature
|
||||
|
||||
> /kind release
|
||||
|
||||
> If contributing rules or changes to rules, please make sure to also uncomment one of the following line:
|
||||
|
||||
> /kind rule-update
|
||||
@@ -46,6 +48,8 @@ Please remove the leading whitespace before the `/kind <>` you uncommented.
|
||||
|
||||
> /area proposals
|
||||
|
||||
> /area CI
|
||||
|
||||
<!--
|
||||
Please remove the leading whitespace before the `/area <>` you uncommented.
|
||||
-->
|
||||
|
||||
76
CHANGELOG.md
76
CHANGELOG.md
@@ -1,5 +1,81 @@
|
||||
# Change Log
|
||||
|
||||
## v0.32.2
|
||||
|
||||
Released on 2022-08-09
|
||||
|
||||
### Major Changes
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix: Added ARCH to bpf download URL [[#2142](https://github.com/falcosecurity/falco/pull/2142)] - [@eric-engberg](https://github.com/eric-engberg)
|
||||
|
||||
|
||||
## v0.32.1
|
||||
|
||||
Released on 2022-07-11
|
||||
|
||||
### Major Changes
|
||||
|
||||
* new(falco): add gVisor support [[#2078](https://github.com/falcosecurity/falco/pull/2078)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* new(docker,scripts): add multiarch images and ARM64 packages [[#1990](https://github.com/falcosecurity/falco/pull/1990)] - [@FedeDP](https://github.com/FedeDP)
|
||||
|
||||
|
||||
### Minor Changes
|
||||
|
||||
* update(build): Switch from RSA/SHA1 to RSA/SHA256 signature in the RPM package [[#2044](https://github.com/falcosecurity/falco/pull/2044)] - [@vjjmiras](https://github.com/vjjmiras)
|
||||
* refactor(userspace/engine): drop macro source field in rules and rule loader [[#2094](https://github.com/falcosecurity/falco/pull/2094)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* build: introduce `DRIVER_VERSION` that allows setting a driver version (which may differ from the falcosecurity/libs version) [[#2086](https://github.com/falcosecurity/falco/pull/2086)] - [@leogr](https://github.com/leogr)
|
||||
* update: add more info to `--version` output [[#2086](https://github.com/falcosecurity/falco/pull/2086)] - [@leogr](https://github.com/leogr)
|
||||
* build(scripts): publish deb repo has now a InRelease file [[#2060](https://github.com/falcosecurity/falco/pull/2060)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update(userspace/falco): make plugin init config optional and add --plugin-info CLI option [[#2059](https://github.com/falcosecurity/falco/pull/2059)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* update(userspace/falco): support libs logging [[#2093](https://github.com/falcosecurity/falco/pull/2093)] - [@jasondellaluce](https://github.com/jasondellaluce)
|
||||
* update(falco): update libs to 0.7.0 [[#2119](https://github.com/falcosecurity/falco/pull/2119)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix(userspace/falco): ensure that only rules files named with `-V` are loaded when validating rules files. [[#2088](https://github.com/falcosecurity/falco/pull/2088)] - [@mstemm](https://github.com/mstemm)
|
||||
* fix(rules): use exit event in reverse shell detection rule [[#2076](https://github.com/falcosecurity/falco/pull/2076)] - [@alacuku](https://github.com/alacuku)
|
||||
* fix(scripts): falco-driver-loader script will now seek for drivers in driver/${ARCH}/ for x86_64 too. [[#2057](https://github.com/falcosecurity/falco/pull/2057)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(falco-driver-loader): building falco module with DKMS on Flatcar and supporting fetching pre-built module/eBPF probe [[#2043](https://github.com/falcosecurity/falco/pull/2043)] - [@jepio](https://github.com/jepio)
|
||||
|
||||
|
||||
### Rule Changes
|
||||
|
||||
* rule(Redirect STDOUT/STDIN to Network Connection in Container): changed priority to NOTICE [[#2092](https://github.com/falcosecurity/falco/pull/2092)] - [@leogr](https://github.com/leogr)
|
||||
* rule(Java Process Class Download): detect potential log4shell exploitation [[#2041](https://github.com/falcosecurity/falco/pull/2041)] - [@pirxthepilot](https://github.com/pirxthepilot)
|
||||
|
||||
|
||||
### Non user-facing changes
|
||||
|
||||
* remove kaizhe from falco rule owner [[#2050](https://github.com/falcosecurity/falco/pull/2050)] - [@Kaizhe](https://github.com/Kaizhe)
|
||||
* docs(readme): added arm64 mention + packages + badge. [[#2101](https://github.com/falcosecurity/falco/pull/2101)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* new(circleci): enable integration tests for arm64. [[#2099](https://github.com/falcosecurity/falco/pull/2099)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* chore(cmake): bump plugins versions [[#2102](https://github.com/falcosecurity/falco/pull/2102)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* fix(docker): fixed deb tester sub image. [[#2100](https://github.com/falcosecurity/falco/pull/2100)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(ci): fix sign script - avoid interpreting '{*}$argv' too soon [[#2075](https://github.com/falcosecurity/falco/pull/2075)] - [@vjjmiras](https://github.com/vjjmiras)
|
||||
* fix(tests): make tests run locally (take 2) [[#2089](https://github.com/falcosecurity/falco/pull/2089)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* fix(ci): creates ~/sign instead of ./sign [[#2072](https://github.com/falcosecurity/falco/pull/2072)] - [@vjjmiras](https://github.com/vjjmiras)
|
||||
* fix(ci): sign arm64 rpm packages. [[#2069](https://github.com/falcosecurity/falco/pull/2069)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update(falco_scripts): Change Flatcar dynlinker path [[#2066](https://github.com/falcosecurity/falco/pull/2066)] - [@jepio](https://github.com/jepio)
|
||||
* fix(scripts): fixed path in publish-deb script. [[#2062](https://github.com/falcosecurity/falco/pull/2062)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): docker-container buildx engine does not support retagging images. Tag all images together. [[#2058](https://github.com/falcosecurity/falco/pull/2058)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): fixed publish-docker-dev job context. [[#2056](https://github.com/falcosecurity/falco/pull/2056)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* Correct linting issue in rules [[#2055](https://github.com/falcosecurity/falco/pull/2055)] - [@stephanmiehe](https://github.com/stephanmiehe)
|
||||
* Fix falco compilation issues with new libs [[#2053](https://github.com/falcosecurity/falco/pull/2053)] - [@alacuku](https://github.com/alacuku)
|
||||
* fix(scripts): forcefully create packages dir for debian packages. [[#2054](https://github.com/falcosecurity/falco/pull/2054)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): removed leftover line in circleci config. [[#2052](https://github.com/falcosecurity/falco/pull/2052)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): fixed circleCI artifacts publish for arm64. [[#2051](https://github.com/falcosecurity/falco/pull/2051)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update(docker): updated falco-builder to fix multiarch support. [[#2049](https://github.com/falcosecurity/falco/pull/2049)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): use apt instead of apk when installing deps for aws ecr publish [[#2047](https://github.com/falcosecurity/falco/pull/2047)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* fix(build): try to use root user for cimg/base [[#2045](https://github.com/falcosecurity/falco/pull/2045)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* update(build): avoid double build of docker images when pushing to aws ecr [[#2046](https://github.com/falcosecurity/falco/pull/2046)] - [@FedeDP](https://github.com/FedeDP)
|
||||
* chore(k8s_audit_plugin): bump k8s audit plugin version [[#2042](https://github.com/falcosecurity/falco/pull/2042)] - [@Andreagit97](https://github.com/Andreagit97)
|
||||
* fix(tests): make run_regression_tests.sh work locally [[#2020](https://github.com/falcosecurity/falco/pull/2020)] - [@LucaGuerra](https://github.com/LucaGuerra)
|
||||
* Circle CI build job for ARM64 [[#1997](https://github.com/falcosecurity/falco/pull/1997)] - [@odidev](https://github.com/odidev)
|
||||
|
||||
|
||||
## v0.32.0
|
||||
|
||||
Released on 2022-06-03
|
||||
|
||||
@@ -19,6 +19,14 @@ option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags" OFF
|
||||
option(MINIMAL_BUILD "Build a minimal version of Falco, containing only the engine and basic input/output (EXPERIMENTAL)" OFF)
|
||||
option(MUSL_OPTIMIZED_BUILD "Enable if you want a musl optimized build" OFF)
|
||||
|
||||
# gVisor is currently only supported on Linux x86_64
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
|
||||
option(BUILD_FALCO_GVISOR "Build gVisor support for Falco" ON)
|
||||
if (BUILD_FALCO_GVISOR)
|
||||
add_definitions(-DHAS_GVISOR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# We shouldn't need to set this, see https://gitlab.kitware.com/cmake/cmake/-/issues/16419
|
||||
option(EP_UPDATE_DISCONNECTED "ExternalProject update disconnected" OFF)
|
||||
if (${EP_UPDATE_DISCONNECTED})
|
||||
@@ -48,6 +56,9 @@ if(NOT DEFINED FALCO_ETC_DIR)
|
||||
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
|
||||
endif()
|
||||
|
||||
# This will be used to print the architecture for which Falco is compiled.
|
||||
set(FALCO_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
|
||||
|
||||
if(NOT DRAIOS_DEBUG_FLAGS)
|
||||
set(DRAIOS_DEBUG_FLAGS "-D_DEBUG")
|
||||
endif()
|
||||
|
||||
12
OWNERS
12
OWNERS
@@ -1,16 +1,12 @@
|
||||
approvers:
|
||||
- fntlnz
|
||||
- kris-nova
|
||||
- leodido
|
||||
- mstemm
|
||||
- leogr
|
||||
- jasondellaluce
|
||||
- fededp
|
||||
reviewers:
|
||||
- fntlnz
|
||||
- kaizhe
|
||||
- mfdii
|
||||
emeritus_approvers:
|
||||
- fntlnz
|
||||
- kris-nova
|
||||
- leodido
|
||||
- mfdii
|
||||
- mstemm
|
||||
- leogr
|
||||
- jasondellaluce
|
||||
|
||||
17
README.md
17
README.md
@@ -3,7 +3,7 @@
|
||||
|
||||
<hr>
|
||||
|
||||
[](https://circleci.com/gh/falcosecurity/falco) [](https://bestpractices.coreinfrastructure.org/projects/2317) [](COPYING)
|
||||
[](https://circleci.com/gh/falcosecurity/falco) [](https://bestpractices.coreinfrastructure.org/projects/2317) [](COPYING) [](https://github.com/falcosecurity/falco/releases/latest) 
|
||||
|
||||
Want to talk? Join us on the [#falco](https://kubernetes.slack.com/messages/falco) channel in the [Kubernetes Slack](https://slack.k8s.io).
|
||||
|
||||
@@ -49,11 +49,14 @@ Notes:
|
||||
|
||||
-->
|
||||
|
||||
| | development | stable |
|
||||
|--------|-----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| rpm | [][1] | [][2] |
|
||||
| deb | [][3] | [][4] |
|
||||
| binary | [][5] | [][6] |
|
||||
| | development | stable |
|
||||
|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| rpm-x86_64 | [][1] | [][2] |
|
||||
| deb-x86_64 | [][3] | [][4] |
|
||||
| binary-x86_64 | [][5] | [][6] |
|
||||
| rpm-aarch64 | [][1] | [][2] |
|
||||
| deb-aarch64 | [][3] | [][4] |
|
||||
| binary-aarch64 | [][7] | [][8] |
|
||||
|
||||
---
|
||||
|
||||
@@ -160,3 +163,5 @@ Falco is licensed to you under the [Apache 2.0](./COPYING) open source license.
|
||||
[4]: https://download.falco.org/?prefix=packages/deb/stable/
|
||||
[5]: https://download.falco.org/?prefix=packages/bin-dev/x86_64/
|
||||
[6]: https://download.falco.org/?prefix=packages/bin/x86_64/
|
||||
[7]: https://download.falco.org/?prefix=packages/bin-dev/aarch64/
|
||||
[8]: https://download.falco.org/?prefix=packages/bin/aarch64/
|
||||
|
||||
@@ -68,9 +68,12 @@ Now assume `x.y.z` is the new version.
|
||||
|
||||
| Packages | Download |
|
||||
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| rpm | [](https://download.falco.org/packages/rpm/falco-x.y.z-x86_64.rpm) |
|
||||
| deb | [](https://download.falco.org/packages/deb/stable/falco-x.y.z-x86_64.deb) |
|
||||
| tgz | [](https://download.falco.org/packages/bin/x86_64/falco-x.y.z-x86_64.tar.gz) |
|
||||
| rpm-x86_64 | [](https://download.falco.org/packages/rpm/falco-x.y.z-x86_64.rpm) |
|
||||
| deb-x86_64 | [](https://download.falco.org/packages/deb/stable/falco-x.y.z-x86_64.deb) |
|
||||
| tgz-x86_64 | [](https://download.falco.org/packages/bin/x86_64/falco-x.y.z-x86_64.tar.gz) |
|
||||
| rpm-aarch64 | [](https://download.falco.org/packages/rpm/falco-x.y.z-aarch64.rpm) |
|
||||
| deb-aarch64 | [](https://download.falco.org/packages/deb/stable/falco-x.y.z-aarch64.deb) |
|
||||
| tgz-aarch64 | [](https://download.falco.org/packages/bin/aarch64/falco-x.y.z-aarch64.tar.gz) |
|
||||
|
||||
| Images |
|
||||
| --------------------------------------------------------------------------- |
|
||||
|
||||
29
cmake/modules/driver-repo/CMakeLists.txt
Normal file
29
cmake/modules/driver-repo/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright (C) 2022 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
project(driver-repo NONE)
|
||||
|
||||
include(ExternalProject)
|
||||
message(STATUS "Driver version: ${DRIVER_VERSION}")
|
||||
|
||||
ExternalProject_Add(
|
||||
driver
|
||||
URL "https://github.com/falcosecurity/libs/archive/${DRIVER_VERSION}.tar.gz"
|
||||
URL_HASH "${DRIVER_CHECKSUM}"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND ""
|
||||
PATCH_COMMAND sh -c "mv ./driver ../driver.tmp && rm -rf ./* && mv ../driver.tmp/* ."
|
||||
)
|
||||
48
cmake/modules/driver.cmake
Normal file
48
cmake/modules/driver.cmake
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright (C) 2022 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
#
|
||||
|
||||
set(DRIVER_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/driver-repo")
|
||||
set(DRIVER_CMAKE_WORKING_DIR "${CMAKE_BINARY_DIR}/driver-repo")
|
||||
|
||||
file(MAKE_DIRECTORY ${DRIVER_CMAKE_WORKING_DIR})
|
||||
|
||||
if(DRIVER_SOURCE_DIR)
|
||||
set(DRIVER_VERSION "0.0.0-local")
|
||||
message(STATUS "Using local version for driver: '${DRIVER_SOURCE_DIR}'")
|
||||
else()
|
||||
# DRIVER_VERSION accepts a git reference (branch name, commit hash, or tag) to the falcosecurity/libs repository
|
||||
# which contains the driver source code under the `/driver` directory.
|
||||
# The chosen driver version must be compatible with the given FALCOSECURITY_LIBS_VERSION.
|
||||
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
||||
if(NOT DRIVER_VERSION)
|
||||
set(DRIVER_VERSION "d673b2722e8a730013bfe525eaa417945ef8b723")
|
||||
set(DRIVER_CHECKSUM "SHA256=de7a2fb42da781d5b867f25a009cfdf8b03a1c12dc9a5d2abba08c7afb5a14d4")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -DDRIVER_VERSION=${DRIVER_VERSION} -DDRIVER_CHECKSUM=${DRIVER_CHECKSUM}
|
||||
${DRIVER_CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${DRIVER_CMAKE_WORKING_DIR})
|
||||
|
||||
# cmake --build .
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${DRIVER_CMAKE_WORKING_DIR}")
|
||||
set(DRIVER_SOURCE_DIR "${DRIVER_CMAKE_WORKING_DIR}/driver-prefix/src/driver")
|
||||
endif()
|
||||
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
set(DRIVER_NAME "falco")
|
||||
set(DRIVER_PACKAGE_NAME "falco")
|
||||
set(DRIVER_COMPONENT_NAME "falco-driver")
|
||||
|
||||
add_subdirectory(${DRIVER_SOURCE_DIR} ${PROJECT_BINARY_DIR}/driver)
|
||||
@@ -15,7 +15,7 @@ cmake_minimum_required(VERSION 3.5.1)
|
||||
project(falcosecurity-libs-repo NONE)
|
||||
|
||||
include(ExternalProject)
|
||||
message(STATUS "Driver version: ${FALCOSECURITY_LIBS_VERSION}")
|
||||
message(STATUS "Libs version: ${FALCOSECURITY_LIBS_VERSION}")
|
||||
|
||||
ExternalProject_Add(
|
||||
falcosecurity-libs
|
||||
@@ -24,4 +24,5 @@ ExternalProject_Add(
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
TEST_COMMAND "")
|
||||
TEST_COMMAND ""
|
||||
)
|
||||
|
||||
@@ -16,27 +16,26 @@ set(FALCOSECURITY_LIBS_CMAKE_WORKING_DIR "${CMAKE_BINARY_DIR}/falcosecurity-libs
|
||||
|
||||
file(MAKE_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
|
||||
|
||||
# explicitly disable the bundled driver, since we pull it separately
|
||||
set(USE_BUNDLED_DRIVER OFF CACHE BOOL "")
|
||||
|
||||
if(FALCOSECURITY_LIBS_SOURCE_DIR)
|
||||
set(FALCOSECURITY_LIBS_VERSION "local")
|
||||
message(STATUS "Using local falcosecurity/libs in '${FALCOSECURITY_LIBS_SOURCE_DIR}'")
|
||||
set(FALCOSECURITY_LIBS_VERSION "0.0.0-local")
|
||||
message(STATUS "Using local version of falcosecurity/libs: '${FALCOSECURITY_LIBS_SOURCE_DIR}'")
|
||||
else()
|
||||
# The falcosecurity/libs git reference (branch name, commit hash, or tag) To update falcosecurity/libs version for the next release, change the
|
||||
# default below In case you want to test against another falcosecurity/libs version just pass the variable - ie., `cmake
|
||||
# -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
# FALCOSECURITY_LIBS_VERSION accepts a git reference (branch name, commit hash, or tag) to the falcosecurity/libs repository.
|
||||
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||
set(FALCOSECURITY_LIBS_VERSION "39ae7d40496793cf3d3e7890c9bbdc202263836b")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=b9034baeff4518b044574956f5768fac080c269bacad4a1e17a7f6fdb872ce66")
|
||||
set(FALCOSECURITY_LIBS_VERSION "d673b2722e8a730013bfe525eaa417945ef8b723")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=de7a2fb42da781d5b867f25a009cfdf8b03a1c12dc9a5d2abba08c7afb5a14d4")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -DFALCOSECURITY_LIBS_VERSION=${FALCOSECURITY_LIBS_VERSION} -DFALCOSECURITY_LIBS_CHECKSUM=${FALCOSECURITY_LIBS_CHECKSUM}
|
||||
${FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
|
||||
|
||||
# todo(leodido, fntlnz) > use the following one when CMake version will be >= 3.13
|
||||
|
||||
# execute_process(COMMAND "${CMAKE_COMMAND}" -B ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR} WORKING_DIRECTORY
|
||||
# "${FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR}")
|
||||
${FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
|
||||
|
||||
# cmake --build .
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}")
|
||||
set(FALCOSECURITY_LIBS_SOURCE_DIR "${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}/falcosecurity-libs-prefix/src/falcosecurity-libs")
|
||||
endif()
|
||||
@@ -45,22 +44,23 @@ set(LIBS_PACKAGE_NAME "falcosecurity")
|
||||
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
add_definitions(-DHAS_CAPTURE)
|
||||
|
||||
if(MUSL_OPTIMIZED_BUILD)
|
||||
add_definitions(-DMUSL_OPTIMIZED)
|
||||
endif()
|
||||
|
||||
set(DRIVER_VERSION "${FALCOSECURITY_LIBS_VERSION}")
|
||||
set(DRIVER_NAME "falco")
|
||||
set(DRIVER_PACKAGE_NAME "falco")
|
||||
set(DRIVER_COMPONENT_NAME "falco-driver")
|
||||
set(SCAP_BPF_PROBE_ENV_VAR_NAME "FALCO_BPF_PROBE")
|
||||
set(SCAP_HOST_ROOT_ENV_VAR_NAME "HOST_ROOT")
|
||||
|
||||
if(NOT LIBSCAP_DIR)
|
||||
set(LIBSCAP_DIR "${FALCOSECURITY_LIBS_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
set(LIBSINSP_DIR "${FALCOSECURITY_LIBS_SOURCE_DIR}")
|
||||
|
||||
# configure gVisor support
|
||||
set(BUILD_LIBSCAP_GVISOR ${BUILD_FALCO_GVISOR} CACHE BOOL "")
|
||||
|
||||
# explicitly disable the tests/examples of this dependency
|
||||
set(CREATE_TEST_TARGETS OFF CACHE BOOL "")
|
||||
set(BUILD_LIBSCAP_EXAMPLES OFF CACHE BOOL "")
|
||||
@@ -68,18 +68,20 @@ set(BUILD_LIBSCAP_EXAMPLES OFF CACHE BOOL "")
|
||||
set(USE_BUNDLED_TBB ON CACHE BOOL "")
|
||||
set(USE_BUNDLED_B64 ON CACHE BOOL "")
|
||||
set(USE_BUNDLED_JSONCPP ON CACHE BOOL "")
|
||||
set(USE_BUNDLED_VALIJSON ON CACHE BOOL "")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${FALCOSECURITY_LIBS_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
include(CheckSymbolExists)
|
||||
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
|
||||
|
||||
if(HAVE_STRLCPY)
|
||||
message(STATUS "Existing strlcpy found, will *not* use local definition by setting -DHAVE_STRLCPY.")
|
||||
add_definitions(-DHAVE_STRLCPY)
|
||||
message(STATUS "Existing strlcpy found, will *not* use local definition by setting -DHAVE_STRLCPY.")
|
||||
add_definitions(-DHAVE_STRLCPY)
|
||||
else()
|
||||
message(STATUS "No strlcpy found, will use local definition")
|
||||
message(STATUS "No strlcpy found, will use local definition")
|
||||
endif()
|
||||
|
||||
include(driver)
|
||||
include(libscap)
|
||||
include(libsinsp)
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ if(NOT DEFINED PLUGINS_COMPONENT_NAME)
|
||||
set(PLUGINS_COMPONENT_NAME "${CMAKE_PROJECT_NAME}-plugins")
|
||||
endif()
|
||||
|
||||
set(PLUGIN_K8S_AUDIT_VERSION "0.2.0")
|
||||
set(PLUGIN_K8S_AUDIT_VERSION "0.3.0")
|
||||
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
|
||||
set(PLUGIN_K8S_AUDIT_HASH "8e61952eefae9e3f8906336a11c9cc3919c7fed7efa24132426b3a789f5e60d8")
|
||||
set(PLUGIN_K8S_AUDIT_HASH "214915fc2a61d147d64aaf4cb29c3fc6a513eda621dad1dfe77f2fd7099b31e1")
|
||||
else() # aarch64
|
||||
set(PLUGIN_K8S_AUDIT_HASH "24631e21cf5626b15fe16045068200ee9924ea64c009d9d51f5a28035ec0730d")
|
||||
set(PLUGIN_K8S_AUDIT_HASH "d9b4610714df581043db76ecb4caf3a41aae5494cf61ab8740a3749bfac8457e")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(
|
||||
@@ -39,18 +39,18 @@ install(FILES "${PROJECT_BINARY_DIR}/k8saudit-plugin-prefix/src/k8saudit-plugin/
|
||||
ExternalProject_Add(
|
||||
k8saudit-rules
|
||||
URL "https://download.falco.org/plugins/stable/k8saudit-rules-${PLUGIN_K8S_AUDIT_VERSION}.tar.gz"
|
||||
URL_HASH "SHA256=301183e8aab6964cf2b2f5946225f571d176e68093026ec45d17249b78b7021e"
|
||||
URL_HASH "SHA256=3913a8c6095794c7de6a97a2a64953a0fa4f87caab014d11b2c8f9221eb77591"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
install(FILES "${PROJECT_BINARY_DIR}/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
|
||||
|
||||
set(PLUGIN_CLOUDTRAIL_VERSION "0.4.0")
|
||||
set(PLUGIN_CLOUDTRAIL_VERSION "0.5.0")
|
||||
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
|
||||
set(PLUGIN_CLOUDTRAIL_HASH "e7327046c49097b01a6b7abbf18e31584c1ef62e6ba9bf14ead0badccde9a87c")
|
||||
set(PLUGIN_CLOUDTRAIL_HASH "ca6c0d087b37090145ef0c92f10d1dd32bb2a08c7bae83cc6fb7a1ba712f3182")
|
||||
else() # aarch64
|
||||
set(PLUGIN_CLOUDTRAIL_HASH "6a0dff848179e397f25ee7e6455cb108a6ec5811acaac42d718e49e0dcdd9722")
|
||||
set(PLUGIN_CLOUDTRAIL_HASH "f6e12d3bd16ae0f504ed2bb56d13531d15b7d55beb1b63932cbe603cff941372")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(
|
||||
@@ -66,18 +66,18 @@ install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plu
|
||||
ExternalProject_Add(
|
||||
cloudtrail-rules
|
||||
URL "https://download.falco.org/plugins/stable/cloudtrail-rules-${PLUGIN_CLOUDTRAIL_VERSION}.tar.gz"
|
||||
URL_HASH "SHA256=1ed9a72a2bc8cdf7c024cc5e383672eea2d2ebd8ffa78fa2117284bc65e99849"
|
||||
URL_HASH "SHA256=7f88fb6b530f8ee739b65d38a36c69cdc70398576299b90118bd7324dbdb5f46"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-rules-prefix/src/cloudtrail-rules/aws_cloudtrail_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
|
||||
|
||||
set(PLUGIN_JSON_VERSION "0.4.0")
|
||||
set(PLUGIN_JSON_VERSION "0.5.0")
|
||||
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
|
||||
set(PLUGIN_JSON_HASH "f6acc12e695f9a05602dc941c64ca7749604be72a4e24cb179133e3513c5fac6")
|
||||
set(PLUGIN_JSON_HASH "b422c4f08bb54ccd384a87c5922e120d5731028c87742ef657cacf936447c202")
|
||||
else() # aarch64
|
||||
set(PLUGIN_JSON_HASH "da96a4ca158d0ea7a030d2b7c2a13d018e96a9e3f7fea2c399f85fd2bdd0827a")
|
||||
set(PLUGIN_JSON_HASH "8358f04325d8a9e9675f38fae8d13a250fb132dcf6741fd0f9830e8c39f48aed")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(
|
||||
|
||||
@@ -2,5 +2,4 @@ labels:
|
||||
- area/integration
|
||||
approvers:
|
||||
- leogr
|
||||
reviewers:
|
||||
- leogr
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ ARG BUILD_BPF=OFF
|
||||
ARG BUILD_WARNINGS_AS_ERRORS=ON
|
||||
ARG MAKE_JOBS=4
|
||||
ARG FALCO_VERSION
|
||||
ARG CMAKE_VERSION=3.22.5
|
||||
|
||||
ENV BUILD_TYPE=${BUILD_TYPE}
|
||||
ENV BUILD_DRIVER=${BUILD_DRIVER}
|
||||
@@ -17,22 +18,22 @@ ENV BUILD_BPF=${BUILD_BPF}
|
||||
ENV BUILD_WARNINGS_AS_ERRORS=${BUILD_WARNINGS_AS_ERRORS}
|
||||
ENV MAKE_JOBS=${MAKE_JOBS}
|
||||
ENV FALCO_VERSION=${FALCO_VERSION}
|
||||
ENV CMAKE_VERSION=${CMAKE_VERSION}
|
||||
|
||||
# build toolchain
|
||||
RUN yum -y install centos-release-scl && \
|
||||
INSTALL_PKGS="devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-toolchain devtoolset-7-libstdc++-devel devtoolset-7-elfutils-libelf-devel llvm-toolset-7 glibc-static autoconf automake libtool createrepo expect git which libcurl-devel zlib-devel rpm-build libyaml-devel" && \
|
||||
INSTALL_PKGS="devtoolset-7-gcc devtoolset-7-gcc-c++ devtoolset-7-toolchain devtoolset-7-libstdc++-devel devtoolset-7-elfutils-libelf-devel llvm-toolset-7.0 glibc-static autoconf automake libtool createrepo expect git which libcurl-devel zlib-devel rpm-build libyaml-devel" && \
|
||||
yum -y install --setopt=tsflags=nodocs $INSTALL_PKGS && \
|
||||
rpm -V $INSTALL_PKGS
|
||||
|
||||
ARG CMAKE_VERSION=3.6.3
|
||||
RUN source scl_source enable devtoolset-7 llvm-toolset-7 && \
|
||||
cd /tmp && \
|
||||
curl -L https://github.com/kitware/cmake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz | tar xz; \
|
||||
cd cmake-${CMAKE_VERSION} && \
|
||||
./bootstrap --system-curl && \
|
||||
make -j${MAKE_JOBS} && \
|
||||
make install && \
|
||||
rm -rf /tmp/cmake-${CMAKE_VERSION}
|
||||
|
||||
RUN source scl_source enable devtoolset-7 llvm-toolset-7.0
|
||||
|
||||
RUN curl -L -o /tmp/cmake-${CMAKE_VERSION}-linux-$(uname -m).tar.gz https://github.com/kitware/cmake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-$(uname -m).tar.gz && \
|
||||
gzip -d /tmp/cmake-${CMAKE_VERSION}-linux-$(uname -m).tar.gz && \
|
||||
tar -xpf /tmp/cmake-${CMAKE_VERSION}-linux-$(uname -m).tar --directory=/tmp && \
|
||||
cp -R /tmp/cmake-${CMAKE_VERSION}-linux-$(uname -m)/* /usr && \
|
||||
rm -rf /tmp/cmake-${CMAKE_VERSION}-linux-$(uname -m)
|
||||
|
||||
COPY ./root /
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
#
|
||||
# This will make scl collection binaries work out of box.
|
||||
unset BASH_ENV PROMPT_COMMAND ENV
|
||||
source scl_source enable devtoolset-7 llvm-toolset-7
|
||||
source scl_source enable devtoolset-7 llvm-toolset-7.0
|
||||
|
||||
@@ -4,6 +4,8 @@ LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
LABEL usage="docker run -i -t --privileged -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 -v /etc:/host/etc --name NAME IMAGE"
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
ARG FALCO_VERSION=latest
|
||||
ARG VERSION_BUCKET=deb
|
||||
ENV VERSION_BUCKET=${VERSION_BUCKET}
|
||||
@@ -29,45 +31,53 @@ RUN apt-get update \
|
||||
jq \
|
||||
libc6-dev \
|
||||
libelf-dev \
|
||||
libmpx2 \
|
||||
libssl-dev \
|
||||
llvm-7 \
|
||||
netcat \
|
||||
patchelf \
|
||||
xz-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; \
|
||||
then apt-get install -y --no-install-recommends libmpx2; \
|
||||
fi
|
||||
|
||||
# gcc 6 is no longer included in debian stable, but we need it to
|
||||
# build kernel modules on the default debian-based ami used by
|
||||
# kops. So grab copies we've saved from debian snapshots with the
|
||||
# prefix https://snapshot.debian.org/archive/debian/20170517T033514Z
|
||||
# or so.
|
||||
|
||||
RUN curl -L -o cpp-6_6.3.0-18_amd64.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o gcc-6-base_6.3.0-18_amd64.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o gcc-6_6.3.0-18_amd64.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libasan3_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libcilkrts5_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libgcc-6-dev_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libubsan0_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libmpfr4_3.1.3-2_amd64.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_amd64.deb \
|
||||
&& curl -L -o libisl15_0.18-1_amd64.deb https://download.falco.org/dependencies/libisl15_0.18-1_amd64.deb \
|
||||
&& dpkg -i cpp-6_6.3.0-18_amd64.deb gcc-6-base_6.3.0-18_amd64.deb gcc-6_6.3.0-18_amd64.deb libasan3_6.3.0-18_amd64.deb libcilkrts5_6.3.0-18_amd64.deb libgcc-6-dev_6.3.0-18_amd64.deb libubsan0_6.3.0-18_amd64.deb libmpfr4_3.1.3-2_amd64.deb libisl15_0.18-1_amd64.deb \
|
||||
&& rm -f cpp-6_6.3.0-18_amd64.deb gcc-6-base_6.3.0-18_amd64.deb gcc-6_6.3.0-18_amd64.deb libasan3_6.3.0-18_amd64.deb libcilkrts5_6.3.0-18_amd64.deb libgcc-6-dev_6.3.0-18_amd64.deb libubsan0_6.3.0-18_amd64.deb libmpfr4_3.1.3-2_amd64.deb libisl15_0.18-1_amd64.deb
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
|
||||
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-6-base_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libasan3_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libubsan0_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libmpfr4_3.1.3-2_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_${TARGETARCH}.deb \
|
||||
&& curl -L -o libisl15_0.18-1_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-1_${TARGETARCH}.deb \
|
||||
&& dpkg -i cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb; \
|
||||
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
|
||||
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
|
||||
&& rm -f cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb libcilkrts5_6.3.0-18_${TARGETARCH}.deb libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb
|
||||
|
||||
# gcc 5 is no longer included in debian stable, but we need it to
|
||||
# build centos kernels, which are 3.x based and explicitly want a gcc
|
||||
# version 3, 4, or 5 compiler. So grab copies we've saved from debian
|
||||
# snapshots with the prefix https://snapshot.debian.org/archive/debian/20190122T000000Z.
|
||||
|
||||
RUN curl -L -o cpp-5_5.5.0-12_amd64.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o gcc-5-base_5.5.0-12_amd64.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o gcc-5_5.5.0-12_amd64.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libasan2_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libgcc-5-dev_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libisl15_0.18-4_amd64.deb https://download.falco.org/dependencies/libisl15_0.18-4_amd64.deb \
|
||||
&& curl -L -o libmpx0_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_amd64.deb \
|
||||
&& dpkg -i cpp-5_5.5.0-12_amd64.deb gcc-5-base_5.5.0-12_amd64.deb gcc-5_5.5.0-12_amd64.deb libasan2_5.5.0-12_amd64.deb libgcc-5-dev_5.5.0-12_amd64.deb libisl15_0.18-4_amd64.deb libmpx0_5.5.0-12_amd64.deb \
|
||||
&& rm -f cpp-5_5.5.0-12_amd64.deb gcc-5-base_5.5.0-12_amd64.deb gcc-5_5.5.0-12_amd64.deb libasan2_5.5.0-12_amd64.deb libgcc-5-dev_5.5.0-12_amd64.deb libisl15_0.18-4_amd64.deb libmpx0_5.5.0-12_amd64.deb
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libmpx0_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
|
||||
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-5-base_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libasan2_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libisl15_0.18-4_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-4_${TARGETARCH}.deb \
|
||||
&& dpkg -i cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb; \
|
||||
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
|
||||
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
|
||||
&& rm -f cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb libmpx0_5.5.0-12_${TARGETARCH}.deb
|
||||
|
||||
# Since our base Debian image ships with GCC 7 which breaks older kernels, revert the
|
||||
# default to gcc-5.
|
||||
@@ -99,10 +109,16 @@ RUN rm -df /lib/modules \
|
||||
# debian:stable head contains binutils 2.31, which generates
|
||||
# binaries that are incompatible with kernels < 4.16. So manually
|
||||
# forcibly install binutils 2.30-22 instead.
|
||||
RUN curl -L -o binutils_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils_2.30-22_amd64.deb \
|
||||
&& curl -L -o libbinutils_2.30-22_amd64.deb https://download.falco.org/dependencies/libbinutils_2.30-22_amd64.deb \
|
||||
&& curl -L -o binutils-x86-64-linux-gnu_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_amd64.deb \
|
||||
&& curl -L -o binutils-common_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils-common_2.30-22_amd64.deb \
|
||||
|
||||
RUN if [ "$TARGETARCH" = "amd64" ] ; then \
|
||||
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
|
||||
else \
|
||||
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
|
||||
fi
|
||||
|
||||
RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils_2.30-22_${TARGETARCH}.deb \
|
||||
&& curl -L -o libbinutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/libbinutils_2.30-22_${TARGETARCH}.deb \
|
||||
&& curl -L -o binutils-common_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-common_2.30-22_${TARGETARCH}.deb \
|
||||
&& dpkg -i *binutils*.deb \
|
||||
&& rm -f *binutils*.deb
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
FROM debian:stable
|
||||
FROM debian:buster
|
||||
|
||||
LABEL usage="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"
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
ARG FALCO_VERSION=
|
||||
RUN test -n FALCO_VERSION
|
||||
ENV FALCO_VERSION ${FALCO_VERSION}
|
||||
@@ -37,43 +39,50 @@ RUN apt-get update \
|
||||
libatomic1 \
|
||||
liblsan0 \
|
||||
libtsan0 \
|
||||
libmpx2 \
|
||||
libquadmath0 \
|
||||
libcc1-0 \
|
||||
patchelf \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; \
|
||||
then apt-get install -y --no-install-recommends libmpx2 libquadmath0; \
|
||||
fi
|
||||
|
||||
# gcc 6 is no longer included in debian stable, but we need it to
|
||||
# build kernel modules on the default debian-based ami used by
|
||||
# kops. So grab copies we've saved from debian snapshots with the
|
||||
# prefix https://snapshot.debian.org/archive/debian/20170517T033514Z
|
||||
# or so.
|
||||
|
||||
RUN curl -L -o cpp-6_6.3.0-18_amd64.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o gcc-6-base_6.3.0-18_amd64.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o gcc-6_6.3.0-18_amd64.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libasan3_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libcilkrts5_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libgcc-6-dev_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libubsan0_6.3.0-18_amd64.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_amd64.deb \
|
||||
&& curl -L -o libmpfr4_3.1.3-2_amd64.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_amd64.deb \
|
||||
&& curl -L -o libisl15_0.18-1_amd64.deb https://download.falco.org/dependencies/libisl15_0.18-1_amd64.deb \
|
||||
&& dpkg -i cpp-6_6.3.0-18_amd64.deb gcc-6-base_6.3.0-18_amd64.deb gcc-6_6.3.0-18_amd64.deb libasan3_6.3.0-18_amd64.deb libcilkrts5_6.3.0-18_amd64.deb libgcc-6-dev_6.3.0-18_amd64.deb libubsan0_6.3.0-18_amd64.deb libmpfr4_3.1.3-2_amd64.deb libisl15_0.18-1_amd64.deb \
|
||||
&& rm -f cpp-6_6.3.0-18_amd64.deb gcc-6-base_6.3.0-18_amd64.deb gcc-6_6.3.0-18_amd64.deb libasan3_6.3.0-18_amd64.deb libcilkrts5_6.3.0-18_amd64.deb libgcc-6-dev_6.3.0-18_amd64.deb libubsan0_6.3.0-18_amd64.deb libmpfr4_3.1.3-2_amd64.deb libisl15_0.18-1_amd64.deb
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
|
||||
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-6-base_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libasan3_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libubsan0_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_${TARGETARCH}.deb \
|
||||
&& curl -L -o libmpfr4_3.1.3-2_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_${TARGETARCH}.deb \
|
||||
&& curl -L -o libisl15_0.18-1_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-1_${TARGETARCH}.deb \
|
||||
&& dpkg -i cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb; \
|
||||
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
|
||||
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
|
||||
&& rm -f cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb libcilkrts5_6.3.0-18_${TARGETARCH}.deb libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb
|
||||
|
||||
# gcc 5 is no longer included in debian stable, but we need it to
|
||||
# build centos kernels, which are 3.x based and explicitly want a gcc
|
||||
# version 3, 4, or 5 compiler. So grab copies we've saved from debian
|
||||
# snapshots with the prefix https://snapshot.debian.org/archive/debian/20190122T000000Z.
|
||||
|
||||
RUN curl -L -o cpp-5_5.5.0-12_amd64.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o gcc-5-base_5.5.0-12_amd64.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o gcc-5_5.5.0-12_amd64.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libasan2_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libgcc-5-dev_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_amd64.deb \
|
||||
&& curl -L -o libisl15_0.18-4_amd64.deb https://download.falco.org/dependencies/libisl15_0.18-4_amd64.deb \
|
||||
&& curl -L -o libmpx0_5.5.0-12_amd64.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_amd64.deb \
|
||||
&& dpkg -i cpp-5_5.5.0-12_amd64.deb gcc-5-base_5.5.0-12_amd64.deb gcc-5_5.5.0-12_amd64.deb libasan2_5.5.0-12_amd64.deb libgcc-5-dev_5.5.0-12_amd64.deb libisl15_0.18-4_amd64.deb libmpx0_5.5.0-12_amd64.deb \
|
||||
&& rm -f cpp-5_5.5.0-12_amd64.deb gcc-5-base_5.5.0-12_amd64.deb gcc-5_5.5.0-12_amd64.deb libasan2_5.5.0-12_amd64.deb libgcc-5-dev_5.5.0-12_amd64.deb libisl15_0.18-4_amd64.deb libmpx0_5.5.0-12_amd64.deb
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libmpx0_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
|
||||
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-5-base_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o gcc-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libasan2_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb \
|
||||
&& curl -L -o libisl15_0.18-4_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-4_${TARGETARCH}.deb \
|
||||
&& dpkg -i cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb; \
|
||||
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
|
||||
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
|
||||
&& rm -f cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb libmpx0_5.5.0-12_${TARGETARCH}.deb
|
||||
|
||||
# Since our base Debian image ships with GCC 7 which breaks older kernels, revert the
|
||||
# default to gcc-5.
|
||||
@@ -90,8 +99,8 @@ RUN rm -rf /usr/bin/clang \
|
||||
RUN rm -df /lib/modules \
|
||||
&& ln -s $HOST_ROOT/lib/modules /lib/modules
|
||||
|
||||
ADD falco-${FALCO_VERSION}-x86_64.deb /
|
||||
RUN dpkg -i /falco-${FALCO_VERSION}-x86_64.deb
|
||||
ADD falco-${FALCO_VERSION}-*.deb /
|
||||
RUN dpkg -i /falco-${FALCO_VERSION}-$(uname -m).deb
|
||||
|
||||
# Change the falco config within the container to enable ISO 8601
|
||||
# output.
|
||||
@@ -101,10 +110,15 @@ RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /etc/fa
|
||||
# debian:stable head contains binutils 2.31, which generates
|
||||
# binaries that are incompatible with kernels < 4.16. So manually
|
||||
# forcibly install binutils 2.30-22 instead.
|
||||
RUN curl -L -o binutils_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils_2.30-22_amd64.deb \
|
||||
&& curl -L -o libbinutils_2.30-22_amd64.deb https://download.falco.org/dependencies/libbinutils_2.30-22_amd64.deb \
|
||||
&& curl -L -o binutils-x86-64-linux-gnu_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_amd64.deb \
|
||||
&& curl -L -o binutils-common_2.30-22_amd64.deb https://download.falco.org/dependencies/binutils-common_2.30-22_amd64.deb \
|
||||
RUN if [ "$TARGETARCH" = "amd64" ] ; then \
|
||||
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
|
||||
else \
|
||||
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
|
||||
fi
|
||||
|
||||
RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils_2.30-22_${TARGETARCH}.deb \
|
||||
&& curl -L -o libbinutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/libbinutils_2.30-22_${TARGETARCH}.deb \
|
||||
&& curl -L -o binutils-common_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-common_2.30-22_${TARGETARCH}.deb \
|
||||
&& dpkg -i *binutils*.deb \
|
||||
&& rm -f *binutils*.deb
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ RUN apt-get -y update && apt-get -y install gridsite-clients curl
|
||||
WORKDIR /
|
||||
|
||||
RUN curl -L -o falco.tar.gz \
|
||||
https://download.falco.org/packages/${VERSION_BUCKET}/x86_64/falco-$(urlencode ${FALCO_VERSION})-x86_64.tar.gz && \
|
||||
https://download.falco.org/packages/${VERSION_BUCKET}/$(uname -m)/falco-$(urlencode ${FALCO_VERSION})-$(uname -m).tar.gz && \
|
||||
tar -xvf falco.tar.gz && \
|
||||
rm -f falco.tar.gz && \
|
||||
mv falco-${FALCO_VERSION}-x86_64 falco && \
|
||||
mv falco-${FALCO_VERSION}-$(uname -m) falco && \
|
||||
rm -rf /falco/usr/src/falco-* /falco/usr/bin/falco-driver-loader
|
||||
|
||||
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 \
|
||||
@@ -32,4 +32,4 @@ ENV HOME /root
|
||||
|
||||
COPY --from=ubuntu /falco /
|
||||
|
||||
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]
|
||||
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]
|
||||
|
||||
@@ -4,17 +4,24 @@ LABEL name="falcosecurity/falco-tester"
|
||||
LABEL usage="docker run -v /boot:/boot:ro -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/..:/source -v $PWD/build:/build --name <name> falcosecurity/falco-tester test"
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
ENV FALCO_VERSION=
|
||||
ENV BUILD_TYPE=release
|
||||
|
||||
ADD https://github.com/fullstorydev/grpcurl/releases/download/v1.6.0/grpcurl_1.6.0_linux_x86_64.tar.gz /
|
||||
RUN if [ "$TARGETARCH" = "amd64" ] ; then curl -L -o grpcurl.tar.gz \
|
||||
https://github.com/fullstorydev/grpcurl/releases/download/v1.8.6/grpcurl_1.8.6_linux_x86_64.tar.gz; \
|
||||
else curl -L -o grpcurl.tar.gz \
|
||||
https://github.com/fullstorydev/grpcurl/releases/download/v1.8.6/grpcurl_1.8.6_linux_arm64.tar.gz; \
|
||||
fi;
|
||||
|
||||
RUN dnf install -y python-pip python docker findutils jq unzip && dnf clean all
|
||||
ENV PATH="/root/.local/bin/:${PATH}"
|
||||
RUN pip install --user avocado-framework==69.0
|
||||
RUN pip install --user avocado-framework-plugin-varianter-yaml-to-mux==69.0
|
||||
RUN pip install --user watchdog==0.10.2
|
||||
RUN pip install --user pathtools==0.1.2
|
||||
RUN tar -C /usr/bin -xvf grpcurl_1.6.0_linux_x86_64.tar.gz
|
||||
RUN tar -C /usr/bin -xvf grpcurl.tar.gz
|
||||
|
||||
COPY ./root /
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ ENV FALCO_VERSION ${FALCO_VERSION}
|
||||
RUN apt update -y
|
||||
RUN apt install dkms -y
|
||||
|
||||
ADD falco-${FALCO_VERSION}-x86_64.deb /
|
||||
RUN dpkg -i /falco-${FALCO_VERSION}-x86_64.deb
|
||||
ADD falco-${FALCO_VERSION}-*.deb /
|
||||
RUN dpkg -i /falco-${FALCO_VERSION}-$(uname -m).deb
|
||||
|
||||
# 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 \
|
||||
|
||||
@@ -9,8 +9,8 @@ ENV FALCO_VERSION ${FALCO_VERSION}
|
||||
RUN yum update -y
|
||||
RUN yum install epel-release -y
|
||||
|
||||
ADD falco-${FALCO_VERSION}-x86_64.rpm /
|
||||
RUN yum install -y /falco-${FALCO_VERSION}-x86_64.rpm
|
||||
ADD falco-${FALCO_VERSION}-*.rpm /
|
||||
RUN yum install -y /falco-${FALCO_VERSION}-$(uname -m).rpm
|
||||
|
||||
# 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 \
|
||||
|
||||
@@ -8,8 +8,8 @@ ENV FALCO_VERSION ${FALCO_VERSION}
|
||||
RUN apt update -y
|
||||
RUN apt install dkms curl -y
|
||||
|
||||
ADD falco-${FALCO_VERSION}-x86_64.tar.gz /
|
||||
RUN cp -R /falco-${FALCO_VERSION}-x86_64/* /
|
||||
ADD falco-${FALCO_VERSION}-*.tar.gz /
|
||||
RUN cp -R /falco-${FALCO_VERSION}-$(uname -m)/* /
|
||||
|
||||
# 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 \
|
||||
|
||||
@@ -25,7 +25,7 @@ build_image() {
|
||||
BUILD_TYPE=$2
|
||||
FALCO_VERSION=$3
|
||||
PACKAGE_TYPE=$4
|
||||
PACKAGE="$BUILD_DIR/$BUILD_TYPE/falco-$FALCO_VERSION-x86_64.${PACKAGE_TYPE}"
|
||||
PACKAGE="$BUILD_DIR/$BUILD_TYPE/falco-$FALCO_VERSION-$(uname -m).${PACKAGE_TYPE}"
|
||||
if [ ! -f "$PACKAGE" ]; then
|
||||
echo "Package not found: ${PACKAGE}." >&2
|
||||
exit 1
|
||||
|
||||
@@ -35,8 +35,8 @@ RUN dnf -y update && \
|
||||
RUN mkdir /build && cd /build/ && curl --remote-name-all -L https://github.com/dell/dkms/archive/refs/tags/v3.0.3.tar.gz && \
|
||||
tar xvf v3.0.3.tar.gz && cd dkms-3.0.3 && make install-redhat && rm -rf /build
|
||||
|
||||
RUN mkdir /deploy && cd /deploy/ && curl --remote-name-all -L https://download.falco.org/packages/bin/x86_64/falco-${FALCO_VERSION}-x86_64.tar.gz && \
|
||||
cd / && tar --strip-components=1 -xvf /deploy/falco-${FALCO_VERSION}-x86_64.tar.gz && \
|
||||
RUN mkdir /deploy && cd /deploy/ && curl --remote-name-all -L https://download.falco.org/packages/bin/$(uname -m)/falco-${FALCO_VERSION}-$(uname -m).tar.gz && \
|
||||
cd / && tar --strip-components=1 -xvf /deploy/falco-${FALCO_VERSION}-$(uname -m).tar.gz && \
|
||||
rm -rf /deploy
|
||||
|
||||
COPY ./docker-entrypoint.sh /
|
||||
|
||||
26
falco.yaml
26
falco.yaml
@@ -45,17 +45,16 @@ plugins:
|
||||
- name: k8saudit
|
||||
library_path: libk8saudit.so
|
||||
init_config:
|
||||
""
|
||||
# maxEventBytes: 1048576
|
||||
# sslCertificate: /etc/falco/falco.pem
|
||||
# maxEventSize: 262144
|
||||
# webhookMaxBatchSize: 12582912
|
||||
# sslCertificate: /etc/falco/falco.pem
|
||||
open_params: "http://:9765/k8s-audit"
|
||||
- name: cloudtrail
|
||||
library_path: libcloudtrail.so
|
||||
init_config: ""
|
||||
open_params: ""
|
||||
# see docs for init_config and open_params:
|
||||
# https://github.com/falcosecurity/plugins/blob/master/plugins/cloudtrail/README.md
|
||||
- name: json
|
||||
library_path: libjson.so
|
||||
init_config: ""
|
||||
|
||||
# Setting this list to empty ensures that the above plugins are *not*
|
||||
# loaded and enabled by default. If you want to use the above plugins,
|
||||
@@ -74,7 +73,9 @@ watch_config_files: true
|
||||
# time zone, as governed by /etc/localtime.
|
||||
time_format_iso_8601: false
|
||||
|
||||
# Whether to output events in json or text
|
||||
# If "true", print falco alert messages and rules file
|
||||
# loading/validation results as json, which allows for easier
|
||||
# consumption by downstream programs. Default is "false".
|
||||
json_output: false
|
||||
|
||||
# When using json output, whether or not to include the "output" property
|
||||
@@ -99,6 +100,17 @@ log_syslog: true
|
||||
# "alert", "critical", "error", "warning", "notice", "info", "debug".
|
||||
log_level: info
|
||||
|
||||
# Falco is capable of managing the logs coming from libs. If enabled,
|
||||
# the libs logger send its log records the same outputs supported by
|
||||
# Falco (stderr and syslog). Disabled by default.
|
||||
libs_logger:
|
||||
enabled: false
|
||||
# Minimum log severity to include in the libs logs. Note: this value is
|
||||
# separate from the log level of the Falco logger and does not affect it.
|
||||
# Can be one of "fatal", "critical", "error", "warning", "notice",
|
||||
# "info", "debug", "trace".
|
||||
severity: debug
|
||||
|
||||
# Minimum rule priority level to load and run. All rules having a
|
||||
# priority more severe than this level will be loaded/run. Can be one
|
||||
# of "emergency", "alert", "critical", "error", "warning", "notice",
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
approvers:
|
||||
- mstemm
|
||||
- kaizhe
|
||||
reviewers:
|
||||
- leodido
|
||||
- fntlnz
|
||||
- mfdii
|
||||
- kaizhe
|
||||
- mstemm
|
||||
- darryk10
|
||||
labels:
|
||||
- area/rules
|
||||
|
||||
|
||||
@@ -360,6 +360,7 @@
|
||||
- rule: Disallowed SSH Connection
|
||||
desc: Detect any new ssh connection to a host other than those in an allowed group of hosts
|
||||
condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts
|
||||
enabled: false
|
||||
output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name user_loginuid=%user.loginuid container_id=%container.id image=%container.image.repository)
|
||||
priority: NOTICE
|
||||
tags: [network, mitre_remote_service]
|
||||
@@ -959,9 +960,6 @@
|
||||
# This rule is disabled by default as many system management tools
|
||||
# like ansible, etc can read these files/paths. Enable it using this macro.
|
||||
|
||||
- macro: consider_ssh_reads
|
||||
condition: (never_true)
|
||||
|
||||
- macro: user_known_read_ssh_information_activities
|
||||
condition: (never_true)
|
||||
|
||||
@@ -969,10 +967,10 @@
|
||||
desc: Any attempt to read files below ssh directories by non-ssh programs
|
||||
condition: >
|
||||
((open_read or open_directory) and
|
||||
consider_ssh_reads and
|
||||
(user_ssh_directory or fd.name startswith /root/.ssh) and
|
||||
not user_known_read_ssh_information_activities and
|
||||
not proc.name in (ssh_binaries))
|
||||
enabled: false
|
||||
output: >
|
||||
ssh-related file/directory read by non-ssh program (user=%user.name user_loginuid=%user.loginuid
|
||||
command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline container_id=%container.id image=%container.image.repository)
|
||||
@@ -1148,6 +1146,9 @@
|
||||
- macro: user_known_write_below_etc_activities
|
||||
condition: (never_true)
|
||||
|
||||
- macro: calico_node
|
||||
condition: (container.image.repository endswith calico/node and proc.name=calico-node)
|
||||
|
||||
- macro: write_etc_common
|
||||
condition: >
|
||||
etc_dir and evt.dir = < and open_write
|
||||
@@ -1253,6 +1254,7 @@
|
||||
and not mcafee_writing_cma_d
|
||||
and not avinetworks_supervisor_writing_ssh
|
||||
and not multipath_writing_conf
|
||||
and not calico_node
|
||||
|
||||
- rule: Write below etc
|
||||
desc: an attempt to write to any file below /etc
|
||||
@@ -1471,7 +1473,7 @@
|
||||
tags: [filesystem, software_mgmt, mitre_persistence]
|
||||
|
||||
- macro: postgres_running_wal_e
|
||||
condition: (proc.pname=postgres and proc.cmdline startswith "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e")
|
||||
condition: (proc.pname=postgres and (proc.cmdline startswith "sh -c envdir /etc/wal-e.d/env /usr/local/bin/wal-e" or proc.cmdline startswith "sh -c envdir \"/run/etc/wal-e.d/env\" wal-g wal-push"))
|
||||
|
||||
- macro: redis_running_prepost_scripts
|
||||
condition: (proc.aname[2]=redis-server and (proc.cmdline contains "redis-server.post-up.d" or proc.cmdline contains "redis-server.pre-up.d"))
|
||||
@@ -1550,9 +1552,6 @@
|
||||
- list: network_plugin_binaries
|
||||
items: [aws-cni, azure-vnet]
|
||||
|
||||
- macro: calico_node
|
||||
condition: (container.image.repository endswith calico/node and proc.name=calico-node)
|
||||
|
||||
- macro: weaveworks_scope
|
||||
condition: (container.image.repository endswith weaveworks/scope and proc.name=scope)
|
||||
|
||||
@@ -1759,6 +1758,13 @@
|
||||
container.image.repository endswith /prometheus-node-exporter or
|
||||
container.image.repository endswith /image-inspector))
|
||||
|
||||
- list: redhat_io_images_privileged
|
||||
items: [registry.redhat.io/openshift-logging/fluentd-rhel8, registry.redhat.io/openshift4/ose-csi-node-driver-registrar, registry.redhat.io/openshift4/ose-kubernetes-nmstate-handler-rhel8, registry.redhat.io/openshift4/ose-local-storage-diskmaker]
|
||||
|
||||
- macro: redhat_image
|
||||
condition: >
|
||||
(container.image.repository in (redhat_io_images_privileged))
|
||||
|
||||
# https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html
|
||||
# official AWS EKS registry list. AWS has different ECR repo per region
|
||||
- macro: allowed_aws_ecr_registry_root_for_eks
|
||||
@@ -1841,7 +1847,8 @@
|
||||
public.ecr.aws/falcosecurity/falco,
|
||||
quay.io/calico/node,
|
||||
sysdig/sysdig,
|
||||
sematext_images
|
||||
sematext_images,
|
||||
k8s.gcr.io/dns/k8s-dns-node-cache
|
||||
]
|
||||
|
||||
- macro: falco_privileged_containers
|
||||
@@ -1881,7 +1888,8 @@
|
||||
aws_eks_image_sensitive_mount or
|
||||
container.image.repository in (trusted_images) or
|
||||
container.image.repository in (falco_sensitive_mount_images) or
|
||||
container.image.repository startswith quay.io/sysdig/)
|
||||
container.image.repository startswith quay.io/sysdig/ or
|
||||
container.image.repository=k8scloudprovider/cinder-csi-plugin)
|
||||
|
||||
# Add conditions to this macro (probably in a separate file,
|
||||
# overwriting this macro) to specify additional containers that are
|
||||
@@ -1899,6 +1907,7 @@
|
||||
and container.privileged=true
|
||||
and not falco_privileged_containers
|
||||
and not user_privileged_containers
|
||||
and not redhat_image
|
||||
output: Privileged container started (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag)
|
||||
priority: INFO
|
||||
tags: [container, cis, mitre_privilege_escalation, mitre_lateral_movement]
|
||||
@@ -2143,20 +2152,13 @@
|
||||
# In some environments, any attempt by a interpreted program (perl,
|
||||
# python, ruby, etc) to listen for incoming connections or perform
|
||||
# outgoing connections might be suspicious. These rules are not
|
||||
# enabled by default, but you can modify the following macros to
|
||||
# enable them.
|
||||
|
||||
- macro: consider_interpreted_inbound
|
||||
condition: (never_true)
|
||||
|
||||
- macro: consider_interpreted_outbound
|
||||
condition: (never_true)
|
||||
# enabled by default.
|
||||
|
||||
- rule: Interpreted procs inbound network activity
|
||||
desc: Any inbound network activity performed by any interpreted program (perl, python, ruby, etc.)
|
||||
condition: >
|
||||
(inbound and consider_interpreted_inbound
|
||||
and interpreted_procs)
|
||||
(inbound and interpreted_procs)
|
||||
enabled: false
|
||||
output: >
|
||||
Interpreted program received/listened for network traffic
|
||||
(user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository)
|
||||
@@ -2166,8 +2168,8 @@
|
||||
- rule: Interpreted procs outbound network activity
|
||||
desc: Any outbound network activity performed by any interpreted program (perl, python, ruby, etc.)
|
||||
condition: >
|
||||
(outbound and consider_interpreted_outbound
|
||||
and interpreted_procs)
|
||||
(outbound and interpreted_procs)
|
||||
enabled: false
|
||||
output: >
|
||||
Interpreted program performed outgoing network connection
|
||||
(user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline connection=%fd.name container_id=%container.id image=%container.image.repository)
|
||||
@@ -2197,9 +2199,6 @@
|
||||
- list: test_connect_ports
|
||||
items: [0, 9, 80, 3306]
|
||||
|
||||
- macro: do_unexpected_udp_check
|
||||
condition: (never_true)
|
||||
|
||||
- list: expected_udp_ports
|
||||
items: [53, openvpn_udp_ports, l2tp_udp_ports, statsd_ports, ntp_ports, test_connect_ports]
|
||||
|
||||
@@ -2208,7 +2207,8 @@
|
||||
|
||||
- rule: Unexpected UDP Traffic
|
||||
desc: UDP traffic not on port 53 (DNS) or other commonly used ports
|
||||
condition: (inbound_outbound) and do_unexpected_udp_check and fd.l4proto=udp and not expected_udp_traffic
|
||||
condition: (inbound_outbound) and fd.l4proto=udp and not expected_udp_traffic
|
||||
enabled: false
|
||||
output: >
|
||||
Unexpected UDP Traffic Seen
|
||||
(user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline connection=%fd.name proto=%fd.l4proto evt=%evt.type %evt.args container_id=%container.id image=%container.image.repository)
|
||||
@@ -2355,10 +2355,7 @@
|
||||
|
||||
|
||||
# This rule is not enabled by default, since this rule is for cloud environment(GCP, AWS and Azure) only.
|
||||
# If you want to enable this rule, overwrite the first macro,
|
||||
# And you can filter the container that you want to allow access to metadata by overwriting the second macro.
|
||||
- macro: consider_metadata_access
|
||||
condition: (never_true)
|
||||
# You can filter the container that you want to allow access to metadata by overwriting user_known_metadata_access macro.
|
||||
|
||||
- macro: user_known_metadata_access
|
||||
condition: (k8s.ns.name = "kube-system")
|
||||
@@ -2367,7 +2364,8 @@
|
||||
# metadata about the instance. The metadata could be used to get credentials by attackers.
|
||||
- rule: Contact cloud metadata service from container
|
||||
desc: Detect attempts to contact the Cloud Instance Metadata Service from a container
|
||||
condition: outbound and fd.sip="169.254.169.254" and container and consider_metadata_access and not user_known_metadata_access
|
||||
condition: outbound and fd.sip="169.254.169.254" and container and not user_known_metadata_access
|
||||
enabled: false
|
||||
output: Outbound connection to cloud instance metadata service (command=%proc.cmdline connection=%fd.name %container.info image=%container.image.repository:%container.image.tag)
|
||||
priority: NOTICE
|
||||
tags: [network, container, mitre_discovery]
|
||||
@@ -2391,7 +2389,12 @@
|
||||
sysdig/sysdig, falcosecurity/falco,
|
||||
fluent/fluentd-kubernetes-daemonset, prom/prometheus,
|
||||
ibm_cloud_containers,
|
||||
public.ecr.aws/falcosecurity/falco)
|
||||
public.ecr.aws/falcosecurity/falco, velero/velero,
|
||||
quay.io/jetstack/cert-manager-cainjector, weaveworks/kured,
|
||||
quay.io/prometheus-operator/prometheus-operator,
|
||||
k8s.gcr.io/ingress-nginx/kube-webhook-certgen, quay.io/spotahome/redis-operator,
|
||||
registry.opensource.zalan.do/acid/postgres-operator, registry.opensource.zalan.do/acid/postgres-operator-ui,
|
||||
rabbitmqoperator/cluster-operator)
|
||||
or (k8s.ns.name = "kube-system"))
|
||||
|
||||
- macro: k8s_api_server
|
||||
@@ -2445,6 +2448,11 @@
|
||||
condition: (never_true)
|
||||
|
||||
# Container is supposed to be immutable. Package management should be done in building the image.
|
||||
- macro: pkg_mgmt_in_kube_proxy
|
||||
condition: >
|
||||
proc.cmdline startswith "update-alternat"
|
||||
and container.image.repository = "k8s.gcr.io/kube-proxy"
|
||||
|
||||
- rule: Launch Package Management Process in Container
|
||||
desc: Package management process ran inside container
|
||||
condition: >
|
||||
@@ -2454,6 +2462,7 @@
|
||||
and package_mgmt_procs
|
||||
and not package_mgmt_ancestor_procs
|
||||
and not user_known_package_manager_in_container
|
||||
and not pkg_mgmt_in_kube_proxy
|
||||
output: >
|
||||
Package management process launched in container (user=%user.name user_loginuid=%user.loginuid
|
||||
command=%proc.cmdline container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
|
||||
@@ -2983,12 +2992,15 @@
|
||||
- macro: user_known_stand_streams_redirect_activities
|
||||
condition: (never_true)
|
||||
|
||||
- macro: dup
|
||||
condition: evt.type in (dup, dup2, dup3)
|
||||
|
||||
- rule: Redirect STDOUT/STDIN to Network Connection in Container
|
||||
desc: Detect redirecting stdout/stdin to network connection in container (potential reverse shell).
|
||||
condition: evt.type=dup and evt.dir=> and container and fd.num in (0, 1, 2) and fd.type in ("ipv4", "ipv6") and not user_known_stand_streams_redirect_activities
|
||||
condition: dup and container and evt.rawres in (0, 1, 2) and fd.type in ("ipv4", "ipv6") and not user_known_stand_streams_redirect_activities
|
||||
output: >
|
||||
Redirect stdout/stdin to network connection (user=%user.name user_loginuid=%user.loginuid %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
|
||||
priority: NOTICE
|
||||
|
||||
# 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.
|
||||
@@ -3137,8 +3149,8 @@
|
||||
- macro: user_known_ingress_remote_file_copy_activities
|
||||
condition: (never_true)
|
||||
|
||||
- macro: curl_download
|
||||
condition: proc.name = curl and
|
||||
- macro: curl_download
|
||||
condition: proc.name = curl and
|
||||
(proc.cmdline contains " -o " or
|
||||
proc.cmdline contains " --output " or
|
||||
proc.cmdline contains " -O " or
|
||||
@@ -3178,6 +3190,19 @@
|
||||
priority: CRITICAL
|
||||
tags: [container, mitre_privilege_escalation, mitre_lateral_movement]
|
||||
|
||||
# Rule for detecting potential Log4Shell (CVE-2021-44228) exploitation
|
||||
# Note: Not compatible with Java 17+, which uses read() syscalls
|
||||
- macro: java_network_read
|
||||
condition: (evt.type=recvfrom and fd.type in (ipv4, ipv6) and proc.name=java)
|
||||
|
||||
- rule: Java Process Class File Download
|
||||
desc: Detected Java process downloading a class file which could indicate a successful exploit of the log4shell Log4j vulnerability (CVE-2021-44228)
|
||||
condition: >
|
||||
java_network_read and evt.buffer bcontains cafebabe
|
||||
output: Java process class file download (user=%user.name user_loginname=%user.loginname user_loginuid=%user.loginuid event=%evt.type connection=%fd.name server_ip=%fd.sip server_port=%fd.sport proto=%fd.l4proto process=%proc.name command=%proc.cmdline parent=%proc.pname buffer=%evt.buffer container_id=%container.id image=%container.image.repository)
|
||||
priority: CRITICAL
|
||||
tags: [mitre_initial_access]
|
||||
|
||||
# Application rules have moved to application_rules.yaml. Please look
|
||||
# there if you want to enable them by adding to
|
||||
# falco_rules.local.yaml.
|
||||
|
||||
@@ -135,12 +135,42 @@ get_target_id() {
|
||||
TARGET_ID="ubuntu-generic"
|
||||
fi
|
||||
;;
|
||||
("flatcar")
|
||||
KERNEL_RELEASE="${VERSION_ID}"
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
;;
|
||||
(*)
|
||||
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
flatcar_relocate_tools() {
|
||||
local -a tools=(
|
||||
scripts/basic/fixdep
|
||||
scripts/mod/modpost
|
||||
tools/objtool/objtool
|
||||
)
|
||||
local -r hostld=$(ls /host/usr/lib64/ld-linux-*.so.*)
|
||||
local -r kdir=/lib/modules/$(ls /lib/modules/)/build
|
||||
echo "** Found host dl interpreter: ${hostld}"
|
||||
for host_tool in ${tools[@]}; do
|
||||
t=${host_tool}
|
||||
tool=$(basename $t)
|
||||
tool_dir=$(dirname $t)
|
||||
host_tool=${kdir}/${host_tool}
|
||||
if [ ! -f ${host_tool} ]; then
|
||||
continue
|
||||
fi
|
||||
umount ${host_tool} 2>/dev/null || true
|
||||
mkdir -p /tmp/${tool_dir}/
|
||||
cp -a ${host_tool} /tmp/${tool_dir}/
|
||||
echo "** Setting host dl interpreter for $host_tool"
|
||||
patchelf --set-interpreter ${hostld} --set-rpath /host/usr/lib64 /tmp/${tool_dir}/${tool}
|
||||
mount -o bind /tmp/${tool_dir}/${tool} ${host_tool}
|
||||
done
|
||||
}
|
||||
|
||||
load_kernel_module_compile() {
|
||||
# Skip dkms on UEK hosts because it will always fail
|
||||
if [[ $(uname -r) == *uek* ]]; then
|
||||
@@ -153,6 +183,12 @@ load_kernel_module_compile() {
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "${TARGET_ID}" == "flatcar" ]; then
|
||||
KERNEL_RELEASE=$(uname -r)
|
||||
echo "* Flatcar detected (version ${VERSION_ID}); relocating kernel tools"
|
||||
flatcar_relocate_tools
|
||||
fi
|
||||
|
||||
# Try to compile using all the available gcc versions
|
||||
for CURRENT_GCC in $(which gcc) $(ls "$(dirname "$(which gcc)")"/gcc-* | grep 'gcc-[0-9]\+' | sort -n -r -k 2 -t -); do
|
||||
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
|
||||
@@ -199,9 +235,7 @@ 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)
|
||||
local URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)
|
||||
|
||||
echo "* Trying to download a prebuilt ${DRIVER_NAME} module from ${URL}"
|
||||
if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
|
||||
@@ -227,6 +261,13 @@ print_clean_termination() {
|
||||
echo
|
||||
}
|
||||
|
||||
print_filename_components() {
|
||||
echo " - driver name: ${DRIVER_NAME}"
|
||||
echo " - target identifier: ${TARGET_ID}"
|
||||
echo " - kernel release: ${KERNEL_RELEASE}"
|
||||
echo " - kernel version: ${KERNEL_VERSION}"
|
||||
}
|
||||
|
||||
clean_kernel_module() {
|
||||
echo
|
||||
echo "================ Cleaning phase ================"
|
||||
@@ -315,6 +356,8 @@ load_kernel_module() {
|
||||
get_target_id
|
||||
|
||||
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
|
||||
echo "* Filename '${FALCO_KERNEL_MODULE_FILENAME}' is composed of:"
|
||||
print_filename_components
|
||||
|
||||
if [ -f "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" ]; then
|
||||
echo "* Found a prebuilt ${DRIVER_NAME} module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
|
||||
@@ -459,7 +502,7 @@ load_bpf_probe_compile() {
|
||||
|
||||
load_bpf_probe_download() {
|
||||
local URL
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
|
||||
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
|
||||
|
||||
echo "* Trying to download a prebuilt eBPF probe from ${URL}"
|
||||
|
||||
@@ -470,15 +513,17 @@ load_bpf_probe_download() {
|
||||
}
|
||||
|
||||
load_bpf_probe() {
|
||||
echo "* Mounting debugfs"
|
||||
|
||||
if [ ! -d /sys/kernel/debug/tracing ]; then
|
||||
echo "* Mounting debugfs"
|
||||
mount -t debugfs nodev /sys/kernel/debug
|
||||
fi
|
||||
|
||||
get_target_id
|
||||
|
||||
BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
|
||||
echo "* Filename '${BPF_PROBE_FILENAME}' is composed of:"
|
||||
print_filename_components
|
||||
|
||||
if [ -n "$ENABLE_DOWNLOAD" ]; then
|
||||
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
|
||||
@@ -628,7 +673,7 @@ if [ -z "$has_opts" ]; then
|
||||
fi
|
||||
|
||||
if [ -z "$source_only" ]; then
|
||||
echo "* Running falco-driver-loader for: falco version=${FALCO_VERSION}, driver version=${DRIVER_VERSION}"
|
||||
echo "* Running falco-driver-loader for: falco version=${FALCO_VERSION}, driver version=${DRIVER_VERSION}, arch=${ARCH}, kernel release=${KERNEL_RELEASE}, kernel version=${KERNEL_VERSION}"
|
||||
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
>&2 echo "This program must be run as root (or with sudo)"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 -f <package.deb> -r <deb|deb-dev>"
|
||||
echo "usage: $0 -f <package_x86_64.deb> -f <package_aarch64.deb> -r <deb|deb-dev>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ check_program() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Used to get comma separated list of architectures
|
||||
join_arr() {
|
||||
local IFS="$1"
|
||||
shift
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
# Add a package to the local DEB repository
|
||||
#
|
||||
# $1: path of the repository.
|
||||
@@ -25,6 +32,26 @@ add_deb() {
|
||||
rm -f $(basename -- $3).asc
|
||||
gpg --detach-sign --digest-algo SHA256 --armor $(basename -- $3)
|
||||
popd > /dev/null
|
||||
|
||||
# Get package architecture from dpkg
|
||||
local arch=$(dpkg --info $3 | awk '/Architecture/ {printf "%s", $2}')
|
||||
# Store architecture in array
|
||||
architectures+=("${arch}")
|
||||
}
|
||||
|
||||
falco_arch_from_deb_arch() {
|
||||
case "$1" in
|
||||
"amd64")
|
||||
echo -n "x86_64"
|
||||
;;
|
||||
"arm64")
|
||||
echo -n "aarch64"
|
||||
;;
|
||||
*)
|
||||
echo "Wrong arch."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Update the local DEB repository
|
||||
@@ -32,26 +59,25 @@ add_deb() {
|
||||
# $1: path of the repository
|
||||
# $2: suite (eg. "stable")
|
||||
update_repo() {
|
||||
# fixme(leogr): we cannot use apt-ftparchive --arch packages ...
|
||||
# since our .deb files ends with "_x86_64" instead of "amd64".
|
||||
# See https://manpages.debian.org/jessie/apt-utils/apt-ftparchive.1.en.html
|
||||
#
|
||||
# As a workaround, we temporarily stick here with "amd64"
|
||||
# (the only supported arch at the moment)
|
||||
local arch=amd64
|
||||
|
||||
local component=main
|
||||
local debs_dir=$2
|
||||
local release_dir=dists/$2
|
||||
local packages_dir=${release_dir}/${component}/binary-${arch}
|
||||
|
||||
pushd $1 > /dev/null
|
||||
|
||||
# packages metadata
|
||||
apt-ftparchive packages ${debs_dir} > ${packages_dir}/Packages
|
||||
gzip -c ${packages_dir}/Packages > ${packages_dir}/Packages.gz
|
||||
bzip2 -z -c ${packages_dir}/Packages > ${packages_dir}/Packages.bz2
|
||||
|
||||
for arch in "${architectures[@]}"; do
|
||||
local packages_dir=${release_dir}/${component}/binary-${arch}
|
||||
mkdir -p ${packages_dir}
|
||||
truncate -s 0 ${packages_dir}/Packages
|
||||
# Find all ${arch} deb files.
|
||||
# Note that debian uses {arm64,amd64}, while
|
||||
# Falco packages use {x86_64,aarch64}.
|
||||
find ${debs_dir} -name "falco-*-$(falco_arch_from_deb_arch ${arch}).deb" -exec apt-ftparchive packages {} \; >> ${packages_dir}/Packages
|
||||
gzip -c ${packages_dir}/Packages > ${packages_dir}/Packages.gz
|
||||
bzip2 -z -c ${packages_dir}/Packages > ${packages_dir}/Packages.bz2
|
||||
done
|
||||
|
||||
# release metadata
|
||||
apt-ftparchive release \
|
||||
-o APT::FTPArchive::Release::Origin=Falco \
|
||||
@@ -59,13 +85,18 @@ update_repo() {
|
||||
-o APT::FTPArchive::Release::Suite=$2 \
|
||||
-o APT::FTPArchive::Release::Codename=$2 \
|
||||
-o APT::FTPArchive::Release::Components=${component} \
|
||||
-o APT::FTPArchive::Release::Architectures=${arch} \
|
||||
-o APT::FTPArchive::Release::Architectures="$(join_arr , "${architectures[@]}")" \
|
||||
${release_dir} > ${release_dir}/Release
|
||||
|
||||
# release signature
|
||||
# release signature - Release.gpg file
|
||||
gpg --detach-sign --digest-algo SHA256 --armor ${release_dir}/Release
|
||||
rm -f ${release_dir}/Release.gpg
|
||||
mv ${release_dir}/Release.asc ${release_dir}/Release.gpg
|
||||
|
||||
# release signature - InRelease file
|
||||
gpg --armor --sign --clearsign --digest-algo SHA256 ${release_dir}/Release
|
||||
rm -f ${release_dir}/InRelease
|
||||
mv ${release_dir}/Release.asc ${release_dir}/InRelease
|
||||
|
||||
popd > /dev/null
|
||||
}
|
||||
@@ -74,7 +105,7 @@ update_repo() {
|
||||
while getopts ":f::r:" opt; do
|
||||
case "${opt}" in
|
||||
f )
|
||||
file=${OPTARG}
|
||||
files+=("${OPTARG}")
|
||||
;;
|
||||
r )
|
||||
repo="${OPTARG}"
|
||||
@@ -93,7 +124,7 @@ done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# check options
|
||||
if [ -z "${file}" ] || [ -z "${repo}" ]; then
|
||||
if [ ${#files[@]} -eq 0 ] || [ -z "${repo}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
@@ -103,6 +134,7 @@ check_program gzip
|
||||
check_program bzip2
|
||||
check_program gpg
|
||||
check_program aws
|
||||
check_program dpkg
|
||||
|
||||
# settings
|
||||
debSuite=stable
|
||||
@@ -116,17 +148,23 @@ mkdir -p ${tmp_repo_path}
|
||||
aws s3 cp ${s3_bucket_repo} ${tmp_repo_path} --recursive
|
||||
|
||||
# update the repo
|
||||
echo "Adding ${file}..."
|
||||
add_deb ${tmp_repo_path} ${debSuite} ${file}
|
||||
for file in "${files[@]}"; do
|
||||
echo "Adding ${file}..."
|
||||
add_deb ${tmp_repo_path} ${debSuite} ${file}
|
||||
done
|
||||
update_repo ${tmp_repo_path} ${debSuite}
|
||||
|
||||
# publish
|
||||
package=$(basename -- ${file})
|
||||
echo "Publishing ${package} to ${s3_bucket_repo}..."
|
||||
aws s3 cp ${tmp_repo_path}/${debSuite}/${package} ${s3_bucket_repo}/${debSuite}/${package} --acl public-read
|
||||
aws s3 cp ${tmp_repo_path}/${debSuite}/${package}.asc ${s3_bucket_repo}/${debSuite}/${package}.asc --acl public-read
|
||||
aws s3 sync ${tmp_repo_path}/dists ${s3_bucket_repo}/dists --delete --acl public-read
|
||||
for file in "${files[@]}"; do
|
||||
package=$(basename -- ${file})
|
||||
echo "Publishing ${package} to ${s3_bucket_repo}..."
|
||||
aws s3 cp ${tmp_repo_path}/${debSuite}/${package} ${s3_bucket_repo}/${debSuite}/${package} --acl public-read
|
||||
aws s3 cp ${tmp_repo_path}/${debSuite}/${package}.asc ${s3_bucket_repo}/${debSuite}/${package}.asc --acl public-read
|
||||
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}.asc
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${debSuite}/${package}.asc
|
||||
done
|
||||
|
||||
# sync dists
|
||||
aws s3 sync ${tmp_repo_path}/dists ${s3_bucket_repo}/dists --delete --acl public-read
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/dists/*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 -f <package.rpm> -r <rpm|rpm-dev>"
|
||||
echo "usage: $0 -f <package_x86_64.rpm> -f <package_aarch64.rpm> -r <rpm|rpm-dev>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ update_repo() {
|
||||
while getopts ":f::r:" opt; do
|
||||
case "${opt}" in
|
||||
f )
|
||||
file=${OPTARG}
|
||||
files+=("${OPTARG}")
|
||||
;;
|
||||
r )
|
||||
repo="${OPTARG}"
|
||||
@@ -60,7 +60,7 @@ while getopts ":f::r:" opt; do
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ -z "${file}" ] || [ -z "${repo}" ]; then
|
||||
if [ ${#files[@]} -eq 0 ] || [ -z "${repo}" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
@@ -80,17 +80,23 @@ mkdir -p ${tmp_repo_path}
|
||||
aws s3 cp ${s3_bucket_repo} ${tmp_repo_path} --recursive
|
||||
|
||||
# update the repo
|
||||
echo "Adding ${file}..."
|
||||
add_rpm ${tmp_repo_path} ${file}
|
||||
for file in "${files[@]}"; do
|
||||
echo "Adding ${file}..."
|
||||
add_rpm ${tmp_repo_path} ${file}
|
||||
done
|
||||
update_repo ${tmp_repo_path}
|
||||
|
||||
# publish
|
||||
package=$(basename -- ${file})
|
||||
echo "Publishing ${package} to ${s3_bucket_repo}..."
|
||||
aws s3 cp ${tmp_repo_path}/${package} ${s3_bucket_repo}/${package} --acl public-read
|
||||
aws s3 cp ${tmp_repo_path}/${package}.asc ${s3_bucket_repo}/${package}.asc --acl public-read
|
||||
aws s3 sync ${tmp_repo_path}/repodata ${s3_bucket_repo}/repodata --delete --acl public-read
|
||||
for file in "${files[@]}"; do
|
||||
package=$(basename -- ${file})
|
||||
echo "Publishing ${package} to ${s3_bucket_repo}..."
|
||||
aws s3 cp ${tmp_repo_path}/${package} ${s3_bucket_repo}/${package} --acl public-read
|
||||
aws s3 cp ${tmp_repo_path}/${package}.asc ${s3_bucket_repo}/${package}.asc --acl public-read
|
||||
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}.asc
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/${package}.asc
|
||||
done
|
||||
|
||||
# sync repodata
|
||||
aws s3 sync ${tmp_repo_path}/repodata ${s3_bucket_repo}/repodata --delete --acl public-read
|
||||
aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_DIST_ID} --paths ${cloudfront_path}/repodata/*
|
||||
|
||||
@@ -17,13 +17,7 @@ This step assumes you already built Falco.
|
||||
|
||||
Note that the tests are intended to be run against a [release build](https://falco.org/docs/getting-started/source/#specify-the-build-type) of Falco, at the moment.
|
||||
|
||||
Also, it assumes you prepared [falco_traces](#falco_traces) (see the section below) and you already run the following command from the build directory:
|
||||
|
||||
```console
|
||||
make test-trace-files
|
||||
```
|
||||
|
||||
It prepares the fixtures (`json` and `scap` files) needed by the integration tests.
|
||||
Also, it assumes you prepared [falco_traces](#falco_traces) (see the section below).
|
||||
|
||||
**Requirements**
|
||||
|
||||
@@ -116,7 +110,7 @@ In case you want to run all the test suites at once, you can directly use the `r
|
||||
|
||||
```console
|
||||
cd test
|
||||
./run_regression_tests.sh -v
|
||||
./run_regression_tests.sh -v -d ../build
|
||||
```
|
||||
|
||||
Just make sure you followed all the previous setup steps.
|
||||
|
||||
@@ -692,7 +692,6 @@ trace_files: !mux
|
||||
|
||||
fal_01_003:
|
||||
detect: False
|
||||
exit_status: 1
|
||||
rules_file:
|
||||
- ../rules/falco_rules.yaml
|
||||
- BUILD_DIR/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml
|
||||
|
||||
@@ -77,6 +77,10 @@ class FalcoTest(Test):
|
||||
else:
|
||||
self.stderr_not_contains = [self.stderr_not_contains]
|
||||
|
||||
self.validate_ok = self.params.get('validate_ok', '*', default='')
|
||||
self.validate_warnings = self.params.get('validate_warnings', '*', default='')
|
||||
self.validate_errors = self.params.get('validate_errors', '*', default='')
|
||||
|
||||
self.exit_status = self.params.get('exit_status', '*', default=0)
|
||||
self.should_detect = self.params.get('detect', '*', default=False)
|
||||
self.check_detection_counts = self.params.get('check_detection_counts', '*', default=True)
|
||||
@@ -105,6 +109,9 @@ class FalcoTest(Test):
|
||||
if self.validate_rules_file == False:
|
||||
self.validate_rules_file = []
|
||||
else:
|
||||
# Always enable json output when validating rules
|
||||
# files. Makes parsing errors/warnings easier
|
||||
self.json_output = True
|
||||
if not isinstance(self.validate_rules_file, list):
|
||||
self.validate_rules_file = [self.validate_rules_file]
|
||||
|
||||
@@ -153,13 +160,6 @@ class FalcoTest(Test):
|
||||
detect_counts[key] = value
|
||||
self.detect_counts = detect_counts
|
||||
|
||||
self.rules_warning = self.params.get(
|
||||
'rules_warning', '*', default=False)
|
||||
if self.rules_warning == False:
|
||||
self.rules_warning = set()
|
||||
else:
|
||||
self.rules_warning = set(self.rules_warning)
|
||||
|
||||
# Maps from rule name to set of evttypes
|
||||
self.rules_events = self.params.get('rules_events', '*', default=False)
|
||||
if self.rules_events == False:
|
||||
@@ -265,22 +265,6 @@ class FalcoTest(Test):
|
||||
if self.package != 'None':
|
||||
self.uninstall_package()
|
||||
|
||||
def check_rules_warnings(self, res):
|
||||
|
||||
found_warning = set()
|
||||
|
||||
for match in re.finditer('Rule ([^:]+): warning \(([^)]+)\):', res.stderr.decode("utf-8")):
|
||||
rule = match.group(1)
|
||||
warning = match.group(2)
|
||||
found_warning.add(rule)
|
||||
|
||||
self.log.debug("Expected warning rules: {}".format(self.rules_warning))
|
||||
self.log.debug("Actual warning rules: {}".format(found_warning))
|
||||
|
||||
if found_warning != self.rules_warning:
|
||||
self.fail("Expected rules with warnings {} does not match actual rules with warnings {}".format(
|
||||
self.rules_warning, found_warning))
|
||||
|
||||
def check_rules_events(self, res):
|
||||
|
||||
found_events = {}
|
||||
@@ -376,7 +360,68 @@ class FalcoTest(Test):
|
||||
|
||||
return True
|
||||
|
||||
def check_json_output(self, res):
|
||||
def get_validate_json(self, res):
|
||||
if self.validate_json is None:
|
||||
# The first line of stdout should be the validation result as json
|
||||
self.validate_json = json.loads(res.stdout.decode("utf-8").partition('\n')[0])
|
||||
return self.validate_json
|
||||
|
||||
def check_validate_ok(self, res):
|
||||
if self.validate_ok != '':
|
||||
vobj = self.get_validate_json(res)
|
||||
for expected in self.validate_ok:
|
||||
found = False
|
||||
for vres in vobj["falco_load_results"]:
|
||||
if vres["successful"] and os.path.basename(vres["name"]) == expected:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
self.fail("Validation json did not contain a successful result for file '{}'".format(expected))
|
||||
|
||||
def check_validate_warnings(self, res):
|
||||
if self.validate_warnings != '':
|
||||
vobj = self.get_validate_json(res)
|
||||
for warnobj in self.validate_warnings:
|
||||
found = False
|
||||
for vres in vobj["falco_load_results"]:
|
||||
for warning in vres["warnings"]:
|
||||
if warning["code"] == warnobj["code"]:
|
||||
if ("message" in warnobj and warning["message"] == warnobj["message"]) or ("message_contains" in warnobj and warnobj["message_contains"] in warning["message"]):
|
||||
for loc in warning["context"]["locations"]:
|
||||
if loc["item_type"] == warnobj["item_type"] and loc["item_name"] == warnobj["item_name"]:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
if "message" in warnobj:
|
||||
self.fail("Validation json did not contain a warning '{}' for '{}' '{}' with message '{}'".format(
|
||||
warnobj["code"], warnobj["item_type"], warnobj["item_name"], warnobj["message"]))
|
||||
else:
|
||||
self.fail("Validation json did not contain a warning '{}' for '{}' '{}' with message containing '{}'".format(
|
||||
warnobj["code"], warnobj["item_type"], warnobj["item_name"], warnobj["message_contains"]))
|
||||
|
||||
def check_validate_errors(self, res):
|
||||
if self.validate_errors != '':
|
||||
vobj = self.get_validate_json(res)
|
||||
for errobj in self.validate_errors:
|
||||
found = False
|
||||
for vres in vobj["falco_load_results"]:
|
||||
for error in vres["errors"]:
|
||||
if error["code"] == errobj["code"]:
|
||||
if ("message" in errobj and error["message"] == errobj["message"]) or ("message_contains" in errobj and errobj["message_contains"] in error["message"]):
|
||||
for loc in error["context"]["locations"]:
|
||||
if loc["item_type"] == errobj["item_type"] and loc["item_name"] == errobj["item_name"]:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
if "message" in errobj:
|
||||
self.fail("Validation json did not contain a error '{}' for '{}' '{}' with message '{}'".format(
|
||||
errobj["code"], errobj["item_type"], errobj["item_name"], errobj["message"]))
|
||||
else:
|
||||
self.fail("Validation json did not contain a error '{}' for '{}' '{}' with message containing '{}'".format(
|
||||
errobj["code"], errobj["item_type"], errobj["item_name"], errobj["message_contains"]))
|
||||
|
||||
|
||||
def check_json_event_output(self, res):
|
||||
if self.json_output:
|
||||
# Just verify that any lines starting with '{' are valid json objects.
|
||||
# Doesn't do any deep inspection of the contents.
|
||||
@@ -578,6 +623,8 @@ class FalcoTest(Test):
|
||||
# This sets falco_binary_path as a side-effect.
|
||||
self.install_package()
|
||||
|
||||
self.validate_json = None
|
||||
|
||||
trace_arg = self.trace_file
|
||||
|
||||
if self.trace_file:
|
||||
@@ -644,18 +691,22 @@ class FalcoTest(Test):
|
||||
self.error("Falco command \"{}\" exited with unexpected return value {} (!= {})".format(
|
||||
cmd, res.exit_status, self.exit_status))
|
||||
|
||||
self.check_validate_ok(res)
|
||||
self.check_validate_errors(res)
|
||||
self.check_validate_warnings(res)
|
||||
|
||||
# No need to check any outputs if the falco process exited abnormally.
|
||||
if res.exit_status != 0:
|
||||
return
|
||||
|
||||
self.check_rules_warnings(res)
|
||||
if len(self.rules_events) > 0:
|
||||
self.check_rules_events(res)
|
||||
if len(self.validate_rules_file) == 0 and self.check_detection_counts:
|
||||
self.check_detections(res)
|
||||
if len(self.detect_counts) > 0:
|
||||
self.check_detections_by_rule(res)
|
||||
self.check_json_output(res)
|
||||
if not self.validate_rules_file:
|
||||
self.check_json_event_output(res)
|
||||
self.check_outputs()
|
||||
self.check_output_strictly_contains(res)
|
||||
self.check_grpc()
|
||||
|
||||
@@ -20,22 +20,55 @@ trace_files: !mux
|
||||
builtin_rules_no_warnings:
|
||||
detect: False
|
||||
trace_file: trace_files/empty.scap
|
||||
rules_warning: False
|
||||
|
||||
# The rules_events part of this test was mistakenly disabled when
|
||||
# generic events (e.g. k8s_audit support) was added (#1715).
|
||||
# The implementation no longer prints messages of the form:
|
||||
# "Event types for rule (<RULE>): (<EVENT TYPES>)
|
||||
# And without that output, none of the checks below rules_events
|
||||
# are considered.
|
||||
# XXX/mstemm add it back
|
||||
test_warnings:
|
||||
detect: False
|
||||
trace_file: trace_files/empty.scap
|
||||
rules_file: rules/falco_rules_warnings.yaml
|
||||
rules_warning:
|
||||
- no_evttype
|
||||
- evttype_not_equals
|
||||
- leading_not
|
||||
- not_equals_at_end
|
||||
- not_at_end
|
||||
- not_equals_and_not
|
||||
- leading_in_not_equals_at_evttype
|
||||
- not_with_evttypes
|
||||
- not_with_evttypes_addl
|
||||
validate_rules_file: rules/falco_rules_warnings.yaml
|
||||
validate_warnings:
|
||||
- item_type: rule
|
||||
item_name: no_evttype
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: evttype_not_equals
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: leading_not
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: not_equals_at_end
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: not_at_end
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: not_equals_and_not
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: leading_in_not_equals_at_evttype
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: not_with_evttypes
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
- item_type: rule
|
||||
item_name: not_with_evttypes_addl
|
||||
code: LOAD_NO_EVTTYPE
|
||||
message: "Rule matches too many evt.type values. This has a significant performance penalty."
|
||||
rules_events:
|
||||
- no_warnings: [execve]
|
||||
- no_evttype: [all]
|
||||
@@ -251,159 +284,149 @@ trace_files: !mux
|
||||
|
||||
invalid_not_yaml:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rules content is not yaml
|
||||
validate_errors:
|
||||
- item_type: file
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Rules content is not yaml"
|
||||
validate_rules_file:
|
||||
- rules/invalid_not_yaml.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_not_array:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rules content is not yaml array of objects
|
||||
validate_errors:
|
||||
- item_type: file
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Rules content is not yaml array of objects"
|
||||
validate_rules_file:
|
||||
- rules/invalid_not_array.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_array_item_not_object:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Unexpected element type. Each element should be a yaml associative array.
|
||||
---
|
||||
- foo
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: item
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Unexpected element type. Each element should be a yaml associative array."
|
||||
validate_rules_file:
|
||||
- rules/invalid_array_item_not_object.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_engine_version_not_number:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Value of required_engine_version must be a number
|
||||
---
|
||||
- required_engine_version: not-a-number
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: required_engine_version
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Can't decode YAML scalar value"
|
||||
validate_rules_file:
|
||||
- rules/invalid_engine_version_not_number.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_yaml_parse_error:
|
||||
exit_status: 1
|
||||
validate_errors:
|
||||
- item_type: file
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_PARSE
|
||||
message: "yaml-cpp: error at line 1, column 11: illegal map value"
|
||||
validate_rules_file:
|
||||
- rules/invalid_yaml_parse_error.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_list_without_items:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
List must have property items
|
||||
---
|
||||
- list: bad_list
|
||||
no_items: foo
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: list
|
||||
item_name: bad_list
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'items'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_list_without_items.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_macro_without_condition:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Macro must have property condition
|
||||
---
|
||||
- macro: bad_macro
|
||||
nope: 1
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: bad_macro
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'condition'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_macro_without_condition.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_rule_without_output:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule must have properties 'condition', 'output', 'desc', and 'priority'
|
||||
---
|
||||
- rule: no output rule
|
||||
desc: some desc
|
||||
condition: evt.type=fork
|
||||
priority: INFO
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: no output rule
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'output'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_rule_without_output.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_append_rule_without_condition:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Appended rule must have exceptions or condition property
|
||||
---
|
||||
- rule: no condition rule
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: no condition rule
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Appended rule must have exceptions or condition property"
|
||||
validate_rules_file:
|
||||
- rules/invalid_append_rule_without_condition.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_append_macro_dangling:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Macro dangling append has 'append' key but no macro by that name already exists
|
||||
---
|
||||
- macro: dangling append
|
||||
condition: and evt.type=execve
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: dangling append
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Macro has 'append' key but no macro by that name already exists"
|
||||
validate_rules_file:
|
||||
- rules/invalid_append_macro_dangling.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_list_append_dangling:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
List my_list has 'append' key but no list by that name already exists
|
||||
---
|
||||
- list: my_list
|
||||
items: [not-cat]
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: list
|
||||
item_name: my_list
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "List has 'append' key but no list by that name already exists"
|
||||
validate_rules_file:
|
||||
- rules/list_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_rule_append_dangling:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule my_rule has 'append' key but no rule by that name already exists
|
||||
---
|
||||
- rule: my_rule
|
||||
condition: evt.type=open
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: my_rule
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Rule has 'append' key but no rule by that name already exists"
|
||||
validate_rules_file:
|
||||
- rules/rule_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_overwrite_macro:
|
||||
exit_status: 1
|
||||
stdout_contains: |+
|
||||
.*invalid_base_macro.yaml: Ok
|
||||
.*invalid_overwrite_macro.yaml: 1 errors:
|
||||
Compilation error when compiling "foo": Undefined macro 'foo' used in filter.
|
||||
---
|
||||
- macro: some macro
|
||||
condition: foo
|
||||
append: false
|
||||
---
|
||||
validate_ok: [invalid_base_macro.yaml]
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Undefined macro 'foo' used in filter."
|
||||
validate_warnings:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_UNUSED_MACRO
|
||||
message: "Macro not referred to by any other rule/macro"
|
||||
validate_rules_file:
|
||||
- rules/invalid_base_macro.yaml
|
||||
- rules/invalid_overwrite_macro.yaml
|
||||
@@ -411,18 +434,17 @@ trace_files: !mux
|
||||
|
||||
invalid_append_macro:
|
||||
exit_status: 1
|
||||
stdout_contains: |+
|
||||
.*invalid_base_macro.yaml: Ok
|
||||
.*invalid_append_macro.yaml: 1 errors:
|
||||
Compilation error when compiling "evt.type=execve foo": 17: unexpected token after 'execve', expecting 'or', 'and'
|
||||
---
|
||||
- macro: some macro
|
||||
condition: evt.type=execve
|
||||
|
||||
- macro: some macro
|
||||
condition: foo
|
||||
append: true
|
||||
---
|
||||
validate_ok: [invalid_base_macro.yaml]
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "unexpected token after 'execve', expecting 'or', 'and'"
|
||||
validate_warnings:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_UNUSED_MACRO
|
||||
message: "Macro not referred to by any other rule/macro"
|
||||
validate_rules_file:
|
||||
- rules/invalid_base_macro.yaml
|
||||
- rules/invalid_append_macro.yaml
|
||||
@@ -430,49 +452,39 @@ trace_files: !mux
|
||||
|
||||
invalid_overwrite_macro_multiple_docs:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Compilation error when compiling "foo": Undefined macro 'foo' used in filter.
|
||||
---
|
||||
- macro: some macro
|
||||
condition: foo
|
||||
append: false
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Undefined macro 'foo' used in filter."
|
||||
validate_warnings:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_UNUSED_MACRO
|
||||
message: "Macro not referred to by any other rule/macro"
|
||||
validate_rules_file:
|
||||
- rules/invalid_overwrite_macro_multiple_docs.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_append_macro_multiple_docs:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Compilation error when compiling "evt.type=execve foo": 17: unexpected token after 'execve', expecting 'or', 'and'
|
||||
---
|
||||
- macro: some macro
|
||||
condition: evt.type=execve
|
||||
|
||||
- macro: some macro
|
||||
condition: foo
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: some macro
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "unexpected token after 'execve', expecting 'or', 'and'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_append_macro_multiple_docs.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_overwrite_rule:
|
||||
exit_status: 1
|
||||
stdout_contains: |+
|
||||
.*invalid_base_rule.yaml: Ok
|
||||
.*invalid_overwrite_rule.yaml: 1 errors:
|
||||
Undefined macro 'bar' used in filter.
|
||||
---
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: bar
|
||||
output: some output
|
||||
priority: INFO
|
||||
append: false
|
||||
---
|
||||
validate_ok: [invalid_base_rule.yaml]
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: some rule
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Undefined macro 'bar' used in filter."
|
||||
validate_rules_file:
|
||||
- rules/invalid_base_rule.yaml
|
||||
- rules/invalid_overwrite_rule.yaml
|
||||
@@ -480,24 +492,12 @@ trace_files: !mux
|
||||
|
||||
invalid_append_rule:
|
||||
exit_status: 1
|
||||
stdout_contains: |+
|
||||
.*invalid_base_rule.yaml: Ok
|
||||
.*invalid_append_rule.yaml: 1 errors:
|
||||
Compilation error when compiling "evt.type=open bar": 15: unexpected token after 'open', expecting 'or', 'and'
|
||||
---
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: evt.type=open
|
||||
output: some output
|
||||
priority: INFO
|
||||
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: bar
|
||||
output: some output
|
||||
priority: INFO
|
||||
append: true
|
||||
---
|
||||
validate_ok: [invalid_base_rule.yaml]
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: some rule
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "unexpected token after 'open', expecting 'or', 'and'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_base_rule.yaml
|
||||
- rules/invalid_append_rule.yaml
|
||||
@@ -505,96 +505,66 @@ trace_files: !mux
|
||||
|
||||
invalid_overwrite_rule_multiple_docs:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Undefined macro 'bar' used in filter.
|
||||
---
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: bar
|
||||
output: some output
|
||||
priority: INFO
|
||||
append: false
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: some rule
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Undefined macro 'bar' used in filter."
|
||||
validate_rules_file:
|
||||
- rules/invalid_overwrite_rule_multiple_docs.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_append_rule_multiple_docs:
|
||||
exit_status: 1
|
||||
stdout_contains: |+
|
||||
Compilation error when compiling "evt.type=open bar": 15: unexpected token after 'open', expecting 'or', 'and'
|
||||
---
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: evt.type=open
|
||||
output: some output
|
||||
priority: INFO
|
||||
|
||||
- rule: some rule
|
||||
desc: some desc
|
||||
condition: bar
|
||||
output: some output
|
||||
priority: INFO
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: some rule
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "unexpected token after 'open', expecting 'or', 'and'"
|
||||
validate_rules_file:
|
||||
- rules/invalid_append_rule_multiple_docs.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_missing_rule_name:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule name is empty
|
||||
---
|
||||
- rule:
|
||||
desc: some desc
|
||||
condition: evt.type=execve
|
||||
output: some output
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Mapping for key 'rule' is empty"
|
||||
validate_rules_file:
|
||||
- rules/invalid_missing_rule_name.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_missing_list_name:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
List name is empty
|
||||
---
|
||||
- list:
|
||||
items: [foo]
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: list
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Mapping for key 'list' is empty"
|
||||
validate_rules_file:
|
||||
- rules/invalid_missing_list_name.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_missing_macro_name:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Macro name is empty
|
||||
---
|
||||
- macro:
|
||||
condition: evt.type=execve
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Mapping for key 'macro' is empty"
|
||||
validate_rules_file:
|
||||
- rules/invalid_missing_macro_name.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_rule_output:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Invalid output format 'An open was seen %not_a_real_field': 'invalid formatting token not_a_real_field'
|
||||
---
|
||||
- rule: rule_with_invalid_output
|
||||
desc: A rule with an invalid output field
|
||||
condition: evt.type=open
|
||||
output: "An open was seen %not_a_real_field"
|
||||
priority: WARNING
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: rule_with_invalid_output
|
||||
code: LOAD_ERR_COMPILE_OUTPUT
|
||||
message: "invalid formatting token not_a_real_field"
|
||||
validate_rules_file:
|
||||
- rules/invalid_rule_output.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
@@ -622,13 +592,13 @@ trace_files: !mux
|
||||
rules_file:
|
||||
- rules/single_rule_enabled_flag.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
|
||||
disabled_rule_using_false_enabled_flag_only:
|
||||
detect: False
|
||||
rules_file:
|
||||
- rules/disabled_rule_using_enabled_flag_only.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
|
||||
enabled_rule_using_false_enabled_flag_only:
|
||||
detect: True
|
||||
detect_level: WARNING
|
||||
@@ -1025,13 +995,6 @@ trace_files: !mux
|
||||
- open_12: 0
|
||||
- open_13: 0
|
||||
|
||||
list_append_failure:
|
||||
exit_status: 1
|
||||
stderr_contains: "List my_list has 'append' key but no list by that name already exists"
|
||||
rules_file:
|
||||
- rules/list_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
list_append:
|
||||
detect: True
|
||||
detect_level: WARNING
|
||||
@@ -1045,13 +1008,6 @@ trace_files: !mux
|
||||
- rules/list_append_false.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
macro_append_failure:
|
||||
exit_status: 1
|
||||
stderr_contains: "Macro my_macro has 'append' key but no macro by that name already exists"
|
||||
rules_file:
|
||||
- rules/macro_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
macro_append:
|
||||
detect: True
|
||||
detect_level: WARNING
|
||||
@@ -1065,13 +1021,6 @@ trace_files: !mux
|
||||
- rules/macro_append_false.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_append_failure:
|
||||
exit_status: 1
|
||||
stderr_contains: "Rule my_rule has 'append' key but no rule by that name already exists"
|
||||
rules_file:
|
||||
- rules/rule_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_append_skipped:
|
||||
detect: False
|
||||
priority: ERROR
|
||||
@@ -1152,10 +1101,18 @@ trace_files: !mux
|
||||
dev_null: 0
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
skip_unknown_noevt:
|
||||
validate_skip_unknown_noevt:
|
||||
validate_warnings:
|
||||
- item_type: rule
|
||||
item_name: "Contains Unknown Event And Skipping"
|
||||
code: LOAD_UNKNOWN_FIELD
|
||||
message: "filter_check called with nonexistent field proc.nobody"
|
||||
validate_rules_file:
|
||||
- rules/skip_unknown_evt.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
detect_skip_unknown_noevt:
|
||||
detect: False
|
||||
rules_warning:
|
||||
- Contains Unknown Event And Skipping
|
||||
rules_file:
|
||||
- rules/skip_unknown_evt.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
@@ -1168,41 +1125,34 @@ trace_files: !mux
|
||||
|
||||
skip_unknown_error:
|
||||
exit_status: 1
|
||||
stderr_contains: |+
|
||||
Could not load rules file.*skip_unknown_error.yaml: 1 errors:
|
||||
Rule Contains Unknown Event And Not Skipping: error filter_check called with nonexistent field proc.nobody
|
||||
---
|
||||
- rule: Contains Unknown Event And Not Skipping
|
||||
desc: Contains an unknown event
|
||||
condition: proc.nobody=cat
|
||||
output: Never
|
||||
skip-if-unknown-filter: false
|
||||
priority: INFO
|
||||
---
|
||||
rules_file:
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: "Contains Unknown Event And Not Skipping"
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "filter_check called with nonexistent field proc.nobody"
|
||||
validate_rules_file:
|
||||
- rules/skip_unknown_error.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
skip_unknown_unspec_error:
|
||||
exit_status: 1
|
||||
stderr_contains: |+
|
||||
Could not load rules file .*skip_unknown_unspec.yaml: 1 errors:
|
||||
Rule Contains Unknown Event And Unspecified: error filter_check called with nonexistent field proc.nobody
|
||||
---
|
||||
- rule: Contains Unknown Event And Unspecified
|
||||
desc: Contains an unknown event
|
||||
condition: proc.nobody=cat
|
||||
output: Never
|
||||
priority: INFO
|
||||
---
|
||||
rules_file:
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: "Contains Unknown Event And Unspecified"
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "filter_check called with nonexistent field proc.nobody"
|
||||
validate_rules_file:
|
||||
- rules/skip_unknown_unspec.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
engine_version_mismatch:
|
||||
exit_status: 1
|
||||
stderr_contains: Rules require engine version 9999999, but engine version is
|
||||
rules_file:
|
||||
validate_errors:
|
||||
- item_type: required_engine_version
|
||||
item_name: ""
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message_contains: "Rules require engine version 9999999, but engine version is"
|
||||
validate_rules_file:
|
||||
- rules/engine_version_mismatch.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
|
||||
@@ -20,175 +20,99 @@ trace_files: !mux
|
||||
|
||||
rule_exception_no_fields:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item ex1: must have fields property with a list of fields
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'fields'"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_no_fields.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_no_name:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item must have name property
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- fields: [proc.name, fd.filename]
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'name'"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_no_name.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_append_no_name:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item must have name property
|
||||
---
|
||||
- rule: My Rule
|
||||
exceptions:
|
||||
- values:
|
||||
- [nginx, /tmp/foo]
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ""
|
||||
code: LOAD_ERR_YAML_VALIDATE
|
||||
message: "Item has no mapping for key 'name'"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/append_item_no_name.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_unknown_fields:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item ex1: field name not.exist is not a supported filter field
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
fields: [not.exist]
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "'not.exist' is not a supported filter field"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_unknown_fields.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_comps_fields_len_mismatch:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item ex1: fields and comps lists must have equal length
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
fields: [proc.name, fd.filename]
|
||||
comps: [=]
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Fields and comps lists must have equal length"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_comps_fields_len_mismatch.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_unknown_comp:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception item ex1: comparison operator no-comp is not a supported comparison operator
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
fields: [proc.name, fd.filename]
|
||||
comps: [=, no-comp]
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "'no-comp' is not a supported comparison operator"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_unknown_comp.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_fields_values_len_mismatch:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Exception item ex1: fields and values lists must have equal length
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
fields: [proc.name, fd.filename]
|
||||
values:
|
||||
- [nginx]
|
||||
priority: error
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Fields and values lists must have equal length"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/item_fields_values_len_mismatch.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_append_fields_values_len_mismatch:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Exception item ex1: fields and values lists must have equal length
|
||||
---
|
||||
- rule: My Rule
|
||||
desc: Some desc
|
||||
condition: evt.type=open and proc.name=cat
|
||||
output: Some output
|
||||
exceptions:
|
||||
- name: ex1
|
||||
fields: [proc.name, fd.filename]
|
||||
priority: error
|
||||
|
||||
- rule: My Rule
|
||||
exceptions:
|
||||
- name: ex1
|
||||
values:
|
||||
- [nginx]
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex1
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Fields and values lists must have equal length"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/append_item_fields_values_len_mismatch.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
rule_exception_append_item_not_in_rule:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception new item ex2: must have fields property with a list of fields
|
||||
---
|
||||
- rule: My Rule
|
||||
exceptions:
|
||||
- name: ex2
|
||||
values:
|
||||
- [apache, /tmp]
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: ex2
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Rule exception must have fields property with a list of fields"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/append_item_not_in_rule.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
@@ -325,7 +249,7 @@ trace_files: !mux
|
||||
rules_file:
|
||||
- rules/exceptions/rule_exception_new_single_field_append.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
|
||||
rule_exception_new_second_field_append:
|
||||
detect: False
|
||||
detect_level: WARNING
|
||||
@@ -335,18 +259,11 @@ trace_files: !mux
|
||||
|
||||
rule_exception_new_append_no_field:
|
||||
exit_status: 1
|
||||
stdout_is: |+
|
||||
1 errors:
|
||||
Rule exception new item proc_cmdline: must have fields property with a list of fields
|
||||
---
|
||||
- rule: Open From Cat
|
||||
exceptions:
|
||||
- name: proc_cmdline
|
||||
comps: in
|
||||
values:
|
||||
- "cat /dev/null"
|
||||
append: true
|
||||
---
|
||||
validate_errors:
|
||||
- item_type: exception
|
||||
item_name: proc_cmdline
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message: "Rule exception must have fields property with a list of fields"
|
||||
validate_rules_file:
|
||||
- rules/exceptions/rule_exception_new_no_field_append.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
@@ -75,7 +75,7 @@ trace_files: !mux
|
||||
|
||||
incompat_plugin_api:
|
||||
exit_status: 1
|
||||
stderr_contains: "Unsupported plugin required api version 10000000.0.0"
|
||||
stderr_contains: "plugin required API version '10000000.0.0' not compatible with the framework's API version '.*'"
|
||||
conf_file: BUILD_DIR/test/confs/plugins/incompatible_plugin_api.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances.yaml
|
||||
@@ -89,34 +89,30 @@ trace_files: !mux
|
||||
|
||||
wrong_plugin_path:
|
||||
exit_status: 1
|
||||
stderr_contains: "error loading plugin.*No such file or directory. Exiting"
|
||||
stderr_contains: "cannot load plugin.*No such file or directory"
|
||||
conf_file: BUILD_DIR/test/confs/plugins/wrong_plugin_path.yaml
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_incompat_plugin_version.yaml
|
||||
|
||||
no_plugins_unknown_source:
|
||||
detect: False
|
||||
rules_file:
|
||||
exit_status: 0
|
||||
validate_warnings:
|
||||
- item_type: rule
|
||||
item_name: Cloudtrail Create Instance
|
||||
code: LOAD_UNKNOWN_SOURCE
|
||||
message: "Unknown source aws_cloudtrail, skipping"
|
||||
validate_rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances.yaml
|
||||
trace_file: trace_files/empty.scap
|
||||
rules_warning:
|
||||
- Cloudtrail Create Instance
|
||||
stderr_contains: "Rule Cloudtrail Create Instance: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
no_plugins_unknown_source_macro:
|
||||
detect: False
|
||||
rules_file:
|
||||
- rules/plugins/cloudtrail_macro.yaml
|
||||
trace_file: trace_files/empty.scap
|
||||
stderr_contains: "Macro Some Cloudtrail Macro: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
no_plugins_unknown_source_rule_exception:
|
||||
detect: False
|
||||
rules_file:
|
||||
exit_status: 0
|
||||
validate_warnings:
|
||||
- item_type: rule
|
||||
item_name: Cloudtrail Create Instance
|
||||
code: LOAD_UNKNOWN_SOURCE
|
||||
message: "Unknown source aws_cloudtrail, skipping"
|
||||
validate_rules_file:
|
||||
- rules/plugins/cloudtrail_create_instances_exceptions.yaml
|
||||
trace_file: trace_files/empty.scap
|
||||
rules_warning:
|
||||
- Cloudtrail Create Instance
|
||||
stderr_contains: "Rule Cloudtrail Create Instance: warning .unknown-source.: unknown source aws_cloudtrail, skipping"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ traces: !mux
|
||||
|
||||
container-privileged:
|
||||
trace_file: traces-positive/container-privileged.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: INFO
|
||||
detect_counts:
|
||||
@@ -37,6 +38,7 @@ traces: !mux
|
||||
|
||||
container-sensitive-mount:
|
||||
trace_file: traces-positive/container-sensitive-mount.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: INFO
|
||||
detect_counts:
|
||||
@@ -51,6 +53,7 @@ traces: !mux
|
||||
|
||||
db-program-spawned-process:
|
||||
trace_file: traces-positive/db-program-spawned-process.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: NOTICE
|
||||
detect_counts:
|
||||
@@ -132,6 +135,7 @@ traces: !mux
|
||||
|
||||
system-user-interactive:
|
||||
trace_file: traces-positive/system-user-interactive.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: INFO
|
||||
detect_counts:
|
||||
@@ -139,6 +143,7 @@ traces: !mux
|
||||
|
||||
user-mgmt-binaries:
|
||||
trace_file: traces-positive/user-mgmt-binaries.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: NOTICE
|
||||
detect_counts:
|
||||
@@ -164,3 +169,13 @@ traces: !mux
|
||||
detect_level: ERROR
|
||||
detect_counts:
|
||||
- "Write below rpm database": 1
|
||||
|
||||
# This generates two notices starting from https://github.com/falcosecurity/falco/pull/2092
|
||||
# When a new version of the scap files is generated this should then become "traces-positive"
|
||||
docker-compose:
|
||||
trace_file: traces-negative/docker-compose.scap
|
||||
all_events: True
|
||||
detect: True
|
||||
detect_level: NOTICE
|
||||
detect_counts:
|
||||
- "Redirect STDOUT/STDIN to Network Connection in Container": 2
|
||||
|
||||
@@ -6,7 +6,7 @@ idna==2.9
|
||||
pathtools==0.1.2
|
||||
pbr==5.4.5
|
||||
PyYAML==5.4
|
||||
requests==2.23.0
|
||||
requests==2.26.0
|
||||
six==1.14.0
|
||||
stevedore==1.32.0
|
||||
urllib3==1.26.5
|
||||
|
||||
@@ -1,19 +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.
|
||||
#
|
||||
- macro: my_macro
|
||||
condition: proc.name=not-cat
|
||||
append: true
|
||||
@@ -1,4 +0,0 @@
|
||||
- macro: Some Cloudtrail Macro
|
||||
condition: aws.user=bob
|
||||
source: aws_cloudtrail
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# Run sysdig excluding all events that aren't used by Falco and also
|
||||
# excluding other high-volume events that aren't essential. This
|
||||
# results in smaller trace files.
|
||||
|
||||
# The remaining arguments are taken from the command line.
|
||||
|
||||
exec sudo sysdig not evt.type in '(mprotect,brk,mq_timedreceive,mq_receive,mq_timedsend,mq_send,getrusage,procinfo,rt_sigprocmask,rt_sigaction,ioctl,clock_getres,clock_gettime,clock_nanosleep,clock_settime,close,epoll_create,epoll_create1,epoll_ctl,epoll_pwait,epoll_wait,eventfd,fcntl,fcntl64,fstat,fstat64,fstatat64,fstatfs,fstatfs64,futex,getitimer,gettimeofday,ioprio_get,ioprio_set,llseek,lseek,lstat,lstat64,mmap,mmap2,munmap,nanosleep,poll,ppoll,pread,pread64,preadv,procinfo,pselect6,pwrite,pwrite64,pwritev,read,readv,recv,recvfrom,recvmmsg,recvmsg,sched_yield,select,send,sendfile,sendfile64,sendmmsg,sendmsg,sendto,setitimer,settimeofday,shutdown,splice,stat,stat64,statfs,statfs64,switch,tee,timer_create,timer_delete,timerfd_create,timerfd_gettime,timerfd_settime,timer_getoverrun,timer_gettime,timer_settime,wait4,write,writev) and user.name!=ec2-user' "$@"
|
||||
@@ -57,12 +57,14 @@ ast::expr* compile(const string &fltstr)
|
||||
TEST_CASE("Should find event types from filter", "[rule_loader]")
|
||||
{
|
||||
set<uint16_t> openat_only{
|
||||
PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X,
|
||||
PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X };
|
||||
|
||||
set<uint16_t> close_only{
|
||||
PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X };
|
||||
|
||||
set<uint16_t> openat_close{
|
||||
PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X,
|
||||
PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X,
|
||||
PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X };
|
||||
|
||||
@@ -73,9 +75,8 @@ TEST_CASE("Should find event types from filter", "[rule_loader]")
|
||||
set<uint16_t> no_events;
|
||||
for(uint32_t i = 2; i < PPM_EVENT_MAX; i++)
|
||||
{
|
||||
// Skip "old" event versions that have been replaced
|
||||
// by newer event versions, or events that are unused.
|
||||
if(g_infotables.m_event_info[i].flags & (EF_OLD_VERSION | EF_UNUSED))
|
||||
// Skip events that are unused.
|
||||
if(g_infotables.m_event_info[i].flags & EF_UNUSED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -231,4 +232,4 @@ TEST_CASE("Should find event types from filter", "[rule_loader]")
|
||||
auto f = compile("not (not evt.type=openat)");
|
||||
compare_evttypes(f, openat_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
|
||||
static bool warns(const std::string& condition)
|
||||
{
|
||||
std::set<std::string> w;
|
||||
std::set<falco::load_result::warning_code> w;
|
||||
auto ast = libsinsp::filter::parser(condition).parse();
|
||||
filter_warning_resolver().run(ast, w);
|
||||
delete ast;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
set(FALCO_ENGINE_SOURCE_FILES
|
||||
falco_common.cpp
|
||||
falco_engine.cpp
|
||||
falco_load_result.cpp
|
||||
falco_utils.cpp
|
||||
json_evt.cpp
|
||||
evttype_index_ruleset.cpp
|
||||
|
||||
@@ -18,6 +18,8 @@ limitations under the License.
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include <sinsp.h>
|
||||
#include <plugin.h>
|
||||
@@ -36,6 +38,7 @@ limitations under the License.
|
||||
const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
|
||||
|
||||
using namespace std;
|
||||
using namespace falco;
|
||||
|
||||
falco_engine::falco_engine(bool seed_rng)
|
||||
: m_next_ruleset_id(0),
|
||||
@@ -165,80 +168,65 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
|
||||
|
||||
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events)
|
||||
{
|
||||
uint64_t dummy;
|
||||
static const std::string no_name = "N/A";
|
||||
|
||||
return load_rules(rules_content, verbose, all_events, dummy);
|
||||
std::unique_ptr<load_result> res = load_rules(rules_content, no_name);
|
||||
|
||||
interpret_load_result(res, no_name, rules_content, verbose);
|
||||
}
|
||||
|
||||
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version)
|
||||
std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_content, const std::string &name)
|
||||
{
|
||||
rule_loader::configuration cfg(rules_content, m_sources);
|
||||
rule_loader::configuration cfg(rules_content, m_sources, name);
|
||||
cfg.min_priority = m_min_priority;
|
||||
cfg.output_extra = m_extra;
|
||||
cfg.replace_output_container_info = m_replace_container_info;
|
||||
cfg.default_ruleset_id = m_default_ruleset_id;
|
||||
|
||||
std::ostringstream os;
|
||||
rule_reader reader;
|
||||
bool success = reader.load(cfg, m_rule_loader);
|
||||
if (success)
|
||||
if (reader.load(cfg, m_rule_loader))
|
||||
{
|
||||
for (auto &src : m_sources)
|
||||
{
|
||||
src.ruleset = src.ruleset_factory->new_ruleset();
|
||||
}
|
||||
m_rules.clear();
|
||||
success = m_rule_loader.compile(cfg, m_rules);
|
||||
}
|
||||
if (!cfg.errors.empty())
|
||||
{
|
||||
os << cfg.errors.size() << " errors:" << std::endl;
|
||||
for(auto &err : cfg.errors)
|
||||
{
|
||||
os << err << std::endl;
|
||||
}
|
||||
}
|
||||
if (!cfg.warnings.empty())
|
||||
{
|
||||
os << cfg.warnings.size() << " warnings:" << std::endl;
|
||||
for(auto &warn : cfg.warnings)
|
||||
{
|
||||
os << warn << std::endl;
|
||||
}
|
||||
}
|
||||
if(!success)
|
||||
{
|
||||
throw falco_exception(os.str());
|
||||
}
|
||||
if (verbose && os.str() != "") {
|
||||
// todo(jasondellaluce): introduce a logging callback in Falco
|
||||
fprintf(stderr, "When reading rules content: %s", os.str().c_str());
|
||||
m_rule_loader.compile(cfg, m_rules);
|
||||
}
|
||||
|
||||
return std::move(cfg.res);
|
||||
}
|
||||
|
||||
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
|
||||
void falco_engine::load_rules_file(const std::string &rules_filename, bool verbose, bool all_events)
|
||||
{
|
||||
uint64_t dummy;
|
||||
std::string rules_content;
|
||||
|
||||
return load_rules_file(rules_filename, verbose, all_events, dummy);
|
||||
read_file(rules_filename, rules_content);
|
||||
|
||||
std::unique_ptr<load_result> res = load_rules(rules_content, rules_filename);
|
||||
|
||||
interpret_load_result(res, rules_filename, rules_content, verbose);
|
||||
}
|
||||
|
||||
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events, uint64_t &required_engine_version)
|
||||
std::unique_ptr<load_result> falco_engine::load_rules_file(const string &rules_filename)
|
||||
{
|
||||
ifstream is;
|
||||
std::string rules_content;
|
||||
|
||||
is.open(rules_filename);
|
||||
if (!is.is_open())
|
||||
try {
|
||||
read_file(rules_filename, rules_content);
|
||||
}
|
||||
catch (falco_exception &e)
|
||||
{
|
||||
throw falco_exception("Could not open rules filename " +
|
||||
rules_filename + " " +
|
||||
"for reading");
|
||||
rule_loader::context ctx(rules_filename);
|
||||
|
||||
std::unique_ptr<rule_loader::result> res(new rule_loader::result(rules_filename));
|
||||
|
||||
res->add_error(load_result::LOAD_ERR_FILE_READ, e.what(), ctx);
|
||||
|
||||
return std::move(res);
|
||||
}
|
||||
|
||||
string rules_content((istreambuf_iterator<char>(is)),
|
||||
istreambuf_iterator<char>());
|
||||
|
||||
load_rules(rules_content, verbose, all_events, required_engine_version);
|
||||
return load_rules(rules_content, rules_filename);
|
||||
}
|
||||
|
||||
void falco_engine::enable_rule(const string &substring, bool enabled, const string &ruleset)
|
||||
@@ -339,7 +327,7 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t so
|
||||
{
|
||||
return unique_ptr<struct rule_result>();
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<struct rule_result> res(new rule_result());
|
||||
res->evt = ev;
|
||||
res->rule = rule.name;
|
||||
@@ -415,6 +403,44 @@ bool falco_engine::is_source_valid(const std::string &source)
|
||||
return m_sources.at(source) != nullptr;
|
||||
}
|
||||
|
||||
void falco_engine::read_file(const std::string& filename, std::string& contents)
|
||||
{
|
||||
ifstream is;
|
||||
|
||||
is.open(filename);
|
||||
if (!is.is_open())
|
||||
{
|
||||
throw falco_exception("Could not open " + filename + " for reading.");
|
||||
}
|
||||
|
||||
contents.assign(istreambuf_iterator<char>(is),
|
||||
istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
void falco_engine::interpret_load_result(std::unique_ptr<load_result>& res,
|
||||
const std::string& rules_filename,
|
||||
const std::string& rules_content,
|
||||
bool verbose)
|
||||
{
|
||||
falco::load_result::rules_contents_t rc = {{rules_filename, rules_content}};
|
||||
|
||||
if(!res->successful())
|
||||
{
|
||||
// The output here is always the full e.g. "verbose" output.
|
||||
throw falco_exception(res->as_string(true, rc).c_str());
|
||||
}
|
||||
|
||||
if(verbose && res->has_warnings())
|
||||
{
|
||||
// Here, verbose controls whether to additionally
|
||||
// "log" e.g. print to stderr. What's logged is always
|
||||
// non-verbose so it fits on a single line.
|
||||
// todo(jasondellaluce): introduce a logging callback in Falco
|
||||
fprintf(stderr, "%s\n", res->as_string(false, rc).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool falco_engine::check_plugin_requirements(
|
||||
const std::vector<plugin_version_requirement>& plugins,
|
||||
std::string& err)
|
||||
@@ -441,8 +467,8 @@ bool falco_engine::check_plugin_requirements(
|
||||
if (!plugin_version.check(req_version))
|
||||
{
|
||||
err = "Plugin '" + plugin.name
|
||||
+ "' version '" + plugin.version
|
||||
+ "' is not compatible with required plugin version '"
|
||||
+ "' version '" + plugin.version
|
||||
+ "' is not compatible with required plugin version '"
|
||||
+ reqver + "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ limitations under the License.
|
||||
#include "stats_manager.h"
|
||||
#include "falco_common.h"
|
||||
#include "falco_source.h"
|
||||
#include "falco_load_result.h"
|
||||
|
||||
//
|
||||
// This class acts as the primary interface between a program and the
|
||||
@@ -64,11 +65,10 @@ public:
|
||||
void load_rules(const std::string &rules_content, bool verbose, bool all_events);
|
||||
|
||||
//
|
||||
// Identical to above, but also returns the required engine version for the file/content.
|
||||
// (If no required engine version is specified, returns 0).
|
||||
//
|
||||
void load_rules_file(const std::string &rules_filename, bool verbose, bool all_events, uint64_t &required_engine_version);
|
||||
void load_rules(const std::string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version);
|
||||
// Identical to above, but returns a result object instead of
|
||||
// throwing exceptions on error.
|
||||
std::unique_ptr<falco::load_result> load_rules_file(const std::string &rules_filename);
|
||||
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content, const std::string &name);
|
||||
|
||||
//
|
||||
// Enable/Disable any rules matching the provided substring.
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
std::size_t add_source(const std::string &source,
|
||||
std::shared_ptr<gen_event_filter_factory> filter_factory,
|
||||
std::shared_ptr<gen_event_formatter_factory> formatter_factory);
|
||||
|
||||
|
||||
//
|
||||
// Equivalent to above, but allows specifying a ruleset factory
|
||||
// for the newly added source.
|
||||
@@ -233,6 +233,17 @@ public:
|
||||
std::string& err);
|
||||
|
||||
private:
|
||||
|
||||
// Throws falco_exception if the file can not be read
|
||||
void read_file(const std::string& filename, std::string& contents);
|
||||
|
||||
// For load_rules methods that throw exceptions on error,
|
||||
// interpret a load_result and throw an exception if needed.
|
||||
void interpret_load_result(std::unique_ptr<falco::load_result>& res,
|
||||
const std::string& rules_filename,
|
||||
const std::string& rules_content,
|
||||
bool verbose);
|
||||
|
||||
indexed_vector<falco_source> m_sources;
|
||||
|
||||
falco_source* find_source(std::size_t index);
|
||||
|
||||
@@ -16,9 +16,9 @@ limitations under the License.
|
||||
|
||||
// The version of rules/filter fields/etc supported by this Falco
|
||||
// engine.
|
||||
#define FALCO_ENGINE_VERSION (12)
|
||||
#define FALCO_ENGINE_VERSION (14)
|
||||
|
||||
// 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 "a557747a209f2d16e90a3324d84d56c02cf54d000b6e3ee44598413f19885fcc"
|
||||
#define FALCO_FIELDS_CHECKSUM "674c6cf2bc1c105038c8676f018fa3d1431d86597df428453441f5d859cad284"
|
||||
|
||||
104
userspace/engine/falco_load_result.cpp
Normal file
104
userspace/engine/falco_load_result.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "falco_load_result.h"
|
||||
|
||||
static const std::string error_codes[] = {
|
||||
"LOAD_ERR_FILE_READ",
|
||||
"LOAD_ERR_YAML_PARSE",
|
||||
"LOAD_ERR_YAML_VALIDATE",
|
||||
"LOAD_ERR_COMPILE_CONDITION",
|
||||
"LOAD_ERR_COMPILE_OUTPUT",
|
||||
"LOAD_ERR_VALIDATE"
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::error_code_str(error_code ec)
|
||||
{
|
||||
return error_codes[ec];
|
||||
}
|
||||
|
||||
static const std::string error_strings[] = {
|
||||
"File read error",
|
||||
"YAML parse error",
|
||||
"Error validating internal structure of YAML file",
|
||||
"Error compiling condition",
|
||||
"Error compiling output",
|
||||
"Error validating rule/macro/list/exception objects"
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::error_str(error_code ec)
|
||||
{
|
||||
return error_strings[ec];
|
||||
}
|
||||
|
||||
static const std::string error_descs[] = {
|
||||
"This occurs when falco can not read a given file. Check permissions and whether the file exists.",
|
||||
"This occurs when the rules content is not valid YAML.",
|
||||
"This occurs when the internal structure of the YAML file is incorrect. Examples include not consisting of a sequence of maps, a given rule/macro/list item not having required keys, values not having the right type (e.g. the items property of a list not being a sequence), etc.",
|
||||
"This occurs when a condition string can not be compiled to a filter object.",
|
||||
"This occurs when an output string can not be compiled to an output object.",
|
||||
"This occurs when a rule/macro/list item is incorrect. Examples include a condition field referring to an undefined macro, falco engine/plugin version mismatches, items with append without any existing item, exception fields/comps having different lengths, etc."
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::error_desc(error_code ec)
|
||||
{
|
||||
return error_strings[ec];
|
||||
}
|
||||
|
||||
static const std::string warning_codes[] = {
|
||||
"LOAD_UNKNOWN_SOURCE",
|
||||
"LOAD_UNSAFE_NA_CHECK",
|
||||
"LOAD_NO_EVTTYPE",
|
||||
"LOAD_UNKNOWN_FIELD",
|
||||
"LOAD_UNUSED_MACRO",
|
||||
"LOAD_UNUSED_LIST",
|
||||
"LOAD_UNKNOWN_ITEM"
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::warning_code_str(warning_code wc)
|
||||
{
|
||||
return warning_codes[wc];
|
||||
}
|
||||
|
||||
static const std::string warning_strings[] = {
|
||||
"Unknown event source",
|
||||
"Unsafe <NA> comparison in condition",
|
||||
"Condition has no event-type restriction",
|
||||
"Unknown field in condition",
|
||||
"Unused macro",
|
||||
"Unused list",
|
||||
"Unknown rules file item"
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::warning_str(warning_code wc)
|
||||
{
|
||||
return warning_strings[wc];
|
||||
}
|
||||
|
||||
static const std::string warning_descs[] = {
|
||||
"A rule has a unknown event source. This can occur when reading rules content without having a corresponding plugin loaded, etc. The rule will be silently ignored.",
|
||||
"Comparing a field value with <NA> is unsafe and can lead to unpredictable behavior of the rule condition. If you need to check for the existence of a field, consider using the 'exists' operator instead.",
|
||||
"A rule condition matches too many evt.type values. This has a significant performance penalty. Make the condition more specific by adding an evt.type field or further restricting the number of evt.type values in the condition.",
|
||||
"A rule condition refers to a field that does not exist. This is normally an error, but if a rule has a skip-if-unknown-filter property, the error is downgraded to a warning.",
|
||||
"A macro is defined in the rules content but is not used by any other macro or rule.",
|
||||
"A list is defined in the rules content but is not used by any other list, macro, or rule.",
|
||||
"An unknown top-level object is in the rules content. It will be ignored."
|
||||
};
|
||||
|
||||
const std::string& falco::load_result::warning_desc(warning_code wc)
|
||||
{
|
||||
return warning_descs[wc];
|
||||
}
|
||||
110
userspace/engine/falco_load_result.h
Normal file
110
userspace/engine/falco_load_result.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace falco
|
||||
{
|
||||
|
||||
// Represents the result of loading a rules file.
|
||||
class load_result {
|
||||
public:
|
||||
|
||||
enum error_code {
|
||||
LOAD_ERR_FILE_READ = 0,
|
||||
LOAD_ERR_YAML_PARSE,
|
||||
LOAD_ERR_YAML_VALIDATE,
|
||||
LOAD_ERR_COMPILE_CONDITION,
|
||||
LOAD_ERR_COMPILE_OUTPUT,
|
||||
LOAD_ERR_VALIDATE
|
||||
};
|
||||
|
||||
// The error code as a string
|
||||
static const std::string& error_code_str(error_code ec);
|
||||
|
||||
// A short string representation of the error
|
||||
static const std::string& error_str(error_code ec);
|
||||
|
||||
// A longer description of what the error represents and the
|
||||
// impact.
|
||||
static const std::string& error_desc(error_code ec);
|
||||
|
||||
enum warning_code {
|
||||
LOAD_UNKNOWN_SOURCE = 0,
|
||||
LOAD_UNSAFE_NA_CHECK,
|
||||
LOAD_NO_EVTTYPE,
|
||||
LOAD_UNKNOWN_FIELD,
|
||||
LOAD_UNUSED_MACRO,
|
||||
LOAD_UNUSED_LIST,
|
||||
LOAD_UNKNOWN_ITEM
|
||||
};
|
||||
|
||||
// The warning code as a string
|
||||
static const std::string& warning_code_str(warning_code ec);
|
||||
|
||||
// A short string representation of the warning
|
||||
static const std::string& warning_str(warning_code ec);
|
||||
|
||||
// A longer description of what the warning represents and the
|
||||
// impact.
|
||||
static const std::string& warning_desc(warning_code ec);
|
||||
|
||||
// If true, the rules were loaded successfully and can be used
|
||||
// against events. If false, there were one or more
|
||||
// errors--use one of the as_xxx methods to return information
|
||||
// about why the rules could not be loaded.
|
||||
virtual bool successful() = 0;
|
||||
|
||||
// If true, there were one or more warnings. successful() and
|
||||
// has_warnings() can both be true if there were only warnings.
|
||||
virtual bool has_warnings() = 0;
|
||||
|
||||
// This represents a set of rules contents as a mapping from
|
||||
// rules content name (usually filename) to rules content. The
|
||||
// rules content is actually a reference to the actual string
|
||||
// to avoid copies. Using reference_wrapper allows the
|
||||
// reference to be held in the stl map (bare references can't
|
||||
// be copied/assigned, but reference_wrappers can).
|
||||
//
|
||||
// It's used in the as_string/as_json() methods below.
|
||||
typedef std::map<std::string, std::reference_wrapper<const std::string>> rules_contents_t;
|
||||
|
||||
// This contains a human-readable version of the result,
|
||||
// suitable for display to end users.
|
||||
//
|
||||
// The provided rules_contents_t should map from content name
|
||||
// to rules content (reference) for each rules_content that has
|
||||
// been passed to rule_loader::compile() or
|
||||
// rule_reader::load().
|
||||
//
|
||||
// When verbose is true, the returned value has full details
|
||||
// on the result including document locations/context.
|
||||
//
|
||||
// When verbose is false, the returned value is a short string
|
||||
// with the success value and a list of
|
||||
// errors/warnings. Suitable for simple one-line display.
|
||||
virtual const std::string& as_string(bool verbose, const rules_contents_t& contents) = 0;
|
||||
|
||||
// This contains the full result structure as json, suitable
|
||||
// for automated parsing/interpretation downstream.
|
||||
virtual const nlohmann::json& as_json(const rules_contents_t& contents) = 0;
|
||||
};
|
||||
|
||||
} // namespace falco
|
||||
@@ -48,9 +48,8 @@ void filter_evttype_resolver::visitor::evttypes(string evtname, set<uint16_t>& o
|
||||
const struct ppm_event_info* etable = g_infotables.m_event_info;
|
||||
for(uint16_t i = 2; i < PPM_EVENT_MAX; i++)
|
||||
{
|
||||
// Skip "old" event versions, unused events, or events not matching
|
||||
// the requested evtname
|
||||
if(!(etable[i].flags & (EF_OLD_VERSION | EF_UNUSED))
|
||||
// Skip unused events or events not matching the requested evtname
|
||||
if(!(etable[i].flags & EF_UNUSED)
|
||||
&& (evtname.empty() || string(etable[i].name) == evtname))
|
||||
{
|
||||
out.insert(i);
|
||||
|
||||
@@ -17,8 +17,9 @@ limitations under the License.
|
||||
#include <sinsp.h>
|
||||
#include "filter_warning_resolver.h"
|
||||
|
||||
using namespace falco;
|
||||
|
||||
static const char* no_value = "<NA>";
|
||||
static const char* warn_unsafe_na_check = "unsafe-na-check";
|
||||
|
||||
static inline bool is_unsafe_field(const string& f)
|
||||
{
|
||||
@@ -34,7 +35,7 @@ static inline bool is_equality_operator(const string& op)
|
||||
|
||||
bool filter_warning_resolver::run(
|
||||
libsinsp::filter::ast::expr* filter,
|
||||
std::set<string>& warnings) const
|
||||
std::set<load_result::warning_code>& warnings) const
|
||||
{
|
||||
visitor v;
|
||||
auto size = warnings.size();
|
||||
@@ -44,22 +45,6 @@ bool filter_warning_resolver::run(
|
||||
return warnings.size() > size;
|
||||
}
|
||||
|
||||
// todo(jasondellaluce): use an hard-coded map once we support more warnings
|
||||
bool filter_warning_resolver::format(
|
||||
const std::string& code,
|
||||
std::string& out) const
|
||||
{
|
||||
if (code == warn_unsafe_na_check)
|
||||
{
|
||||
out = "comparing a field value with <NA> is unsafe and can lead to "
|
||||
"unpredictable behavior of the rule condition. If you need to "
|
||||
" check for the existence of a field, consider using the "
|
||||
"'exists' operator instead.";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void filter_warning_resolver::visitor::visit(
|
||||
libsinsp::filter::ast::binary_check_expr* e)
|
||||
{
|
||||
@@ -76,7 +61,7 @@ void filter_warning_resolver::visitor::visit(
|
||||
{
|
||||
if (m_is_equality_check && e->value == no_value)
|
||||
{
|
||||
m_warnings->insert(warn_unsafe_na_check);
|
||||
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +71,6 @@ void filter_warning_resolver::visitor::visit(
|
||||
if (m_is_equality_check
|
||||
&& std::find(e->values.begin(), e->values.end(), no_value) != e->values.end())
|
||||
{
|
||||
m_warnings->insert(warn_unsafe_na_check);
|
||||
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include "falco_common.h"
|
||||
#include "falco_load_result.h"
|
||||
|
||||
/*!
|
||||
\brief Searches for bad practices in filter conditions and
|
||||
@@ -42,40 +43,13 @@ public:
|
||||
*/
|
||||
bool run(
|
||||
libsinsp::filter::ast::expr* filter,
|
||||
std::set<std::string>& warnings) const;
|
||||
|
||||
/*!
|
||||
\brief Given a warning code retrieved through run(), returns
|
||||
a verbose message describing the problem of the warning.
|
||||
\param code The warning code string
|
||||
\param out The string to be filled-out with the warning message
|
||||
\return true if the warning code is recognized, false otherwise
|
||||
*/
|
||||
bool format(const std::string& code, std::string& out) const;
|
||||
|
||||
/*!
|
||||
\brief Given a warning code retrieved through run(), returns
|
||||
a verbose message describing the problem of the warning.
|
||||
\param code The warning code string
|
||||
\return The warning message string
|
||||
\throw falco_exception if the warning code is not recognized
|
||||
|
||||
*/
|
||||
inline std::string format(const std::string& code) const
|
||||
{
|
||||
std::string v;
|
||||
if (!format(code, v))
|
||||
{
|
||||
throw falco_exception("unrecognized warning code: " + code);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
std::set<falco::load_result::warning_code>& warnings) const;
|
||||
|
||||
private:
|
||||
struct visitor : public libsinsp::filter::ast::base_expr_visitor
|
||||
{
|
||||
bool m_is_equality_check;
|
||||
std::set<std::string>* m_warnings;
|
||||
std::set<falco::load_result::warning_code>* m_warnings;
|
||||
|
||||
void visit(libsinsp::filter::ast::value_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::list_expr* e) override;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,10 @@ limitations under the License.
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "falco_rule.h"
|
||||
#include "falco_source.h"
|
||||
#include "falco_load_result.h"
|
||||
#include "indexed_vector.h"
|
||||
|
||||
|
||||
@@ -31,34 +33,112 @@ limitations under the License.
|
||||
class rule_loader
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\brief Represents a section of text from which a certain info
|
||||
struct has been decoded
|
||||
*/
|
||||
struct context
|
||||
class context
|
||||
{
|
||||
std::string content;
|
||||
public:
|
||||
static const size_t default_snippet_width = 160;
|
||||
|
||||
/*!
|
||||
\brief Wraps an error by adding info about the text section
|
||||
*/
|
||||
inline std::string error(std::string err) const
|
||||
struct location
|
||||
{
|
||||
std::string cnt = content;
|
||||
err += "\n---\n";
|
||||
err += trim(cnt);
|
||||
err += "\n---";
|
||||
return err;
|
||||
}
|
||||
// The original location in the document
|
||||
YAML::Mark mark;
|
||||
|
||||
/*!
|
||||
\brief Appends another text section info to this one
|
||||
*/
|
||||
inline void append(context& m)
|
||||
{
|
||||
content += "\n\n";
|
||||
content += m.content;
|
||||
}
|
||||
// The kind of item at this location
|
||||
// (e.g. "list", "macro", "rule", "exception", etc)
|
||||
std::string item_type;
|
||||
|
||||
// The name of this item (e.g. "Write Below Etc",
|
||||
// etc).
|
||||
std::string item_name;
|
||||
};
|
||||
|
||||
context(const std::string& name);
|
||||
context(const YAML::Node& item,
|
||||
const std::string item_type,
|
||||
const std::string item_name,
|
||||
const context& parent);
|
||||
virtual ~context() = default;
|
||||
|
||||
// Return a snippet of the provided rules content
|
||||
// corresponding to this context.
|
||||
// Uses the provided rules_contents to look up the original
|
||||
// rules content for a given location name.
|
||||
std::string snippet(const falco::load_result::rules_contents_t& rules_contents, size_t snippet_width = default_snippet_width) const;
|
||||
|
||||
std::string as_string();
|
||||
nlohmann::json as_json();
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
// A chain of locations from the current item, its
|
||||
// parent, possibly older ancestors.
|
||||
std::vector<location> m_locs;
|
||||
};
|
||||
|
||||
struct warning
|
||||
{
|
||||
falco::load_result::warning_code wc;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
};
|
||||
|
||||
struct error
|
||||
{
|
||||
falco::load_result::error_code ec;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
};
|
||||
|
||||
class rule_load_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
rule_load_exception(falco::load_result::error_code ec, std::string msg, const context& ctx);
|
||||
virtual ~rule_load_exception();
|
||||
const char* what();
|
||||
|
||||
falco::load_result::error_code ec;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
|
||||
std::string errstr;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Contains the result of loading rule definitions
|
||||
*/
|
||||
class result : public falco::load_result
|
||||
{
|
||||
public:
|
||||
result(const std::string &name);
|
||||
virtual ~result() = default;
|
||||
|
||||
virtual bool successful() override;
|
||||
virtual bool has_warnings() override;
|
||||
|
||||
virtual const std::string& as_string(bool verbose, const falco::load_result::rules_contents_t& contents) override;
|
||||
virtual const nlohmann::json& as_json(const falco::load_result::rules_contents_t& contents) override;
|
||||
|
||||
void add_error(falco::load_result::error_code ec,
|
||||
const std::string& msg,
|
||||
const context& ctx);
|
||||
|
||||
void add_warning(falco::load_result::warning_code ec,
|
||||
const std::string& msg,
|
||||
const context& ctx);
|
||||
protected:
|
||||
|
||||
const std::string& as_summary_string();
|
||||
const std::string& as_verbose_string(const falco::load_result::rules_contents_t& contents);
|
||||
std::string name;
|
||||
bool success;
|
||||
|
||||
std::vector<error> errors;
|
||||
std::vector<warning> warnings;
|
||||
|
||||
std::string res_summary_string;
|
||||
std::string res_verbose_string;
|
||||
nlohmann::json res_json;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -68,13 +148,17 @@ public:
|
||||
{
|
||||
explicit configuration(
|
||||
const std::string& cont,
|
||||
const indexed_vector<falco_source>& srcs)
|
||||
: content(cont), sources(srcs) {}
|
||||
const indexed_vector<falco_source>& srcs,
|
||||
std::string name)
|
||||
: content(cont), sources(srcs), name(name)
|
||||
{
|
||||
res.reset(new result(name));
|
||||
}
|
||||
|
||||
const std::string& content;
|
||||
const indexed_vector<falco_source>& sources;
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> warnings;
|
||||
std::string name;
|
||||
std::unique_ptr<result> res;
|
||||
std::string output_extra;
|
||||
uint16_t default_ruleset_id;
|
||||
bool replace_output_container_info;
|
||||
@@ -86,6 +170,10 @@ public:
|
||||
*/
|
||||
struct engine_version_info
|
||||
{
|
||||
engine_version_info(context &ctx);
|
||||
~engine_version_info() = default;
|
||||
|
||||
context ctx;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
@@ -94,15 +182,26 @@ public:
|
||||
*/
|
||||
struct plugin_version_info
|
||||
{
|
||||
// This differs from the other _info structs by having
|
||||
// a default constructor. This allows it to be used
|
||||
// by falco_engine, which aliases the type.
|
||||
plugin_version_info();
|
||||
plugin_version_info(context &ctx);
|
||||
~plugin_version_info() = default;
|
||||
|
||||
context ctx;
|
||||
std::string name;
|
||||
std::string version;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Represents infos about a list
|
||||
\brief Represents infos about a list
|
||||
*/
|
||||
struct list_info
|
||||
{
|
||||
list_info(context &ctx);
|
||||
~list_info() = default;
|
||||
|
||||
context ctx;
|
||||
bool used;
|
||||
size_t index;
|
||||
@@ -112,17 +211,20 @@ public:
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Represents infos about a macro
|
||||
\brief Represents infos about a macro
|
||||
*/
|
||||
struct macro_info
|
||||
{
|
||||
macro_info(context &ctx);
|
||||
~macro_info() = default;
|
||||
|
||||
context ctx;
|
||||
context cond_ctx;
|
||||
bool used;
|
||||
size_t index;
|
||||
size_t visibility;
|
||||
std::string name;
|
||||
std::string cond;
|
||||
std::string source;
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> cond_ast;
|
||||
};
|
||||
|
||||
@@ -131,6 +233,9 @@ public:
|
||||
*/
|
||||
struct rule_exception_info
|
||||
{
|
||||
rule_exception_info(context &ctx);
|
||||
~rule_exception_info() = default;
|
||||
|
||||
/*!
|
||||
\brief This is necessary due to the dynamic-typed nature of
|
||||
exceptions. Each of fields, comps, and values, can either be a
|
||||
@@ -149,6 +254,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
context ctx;
|
||||
std::string name;
|
||||
entry fields;
|
||||
entry comps;
|
||||
@@ -156,11 +262,16 @@ public:
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Represents infos about a rule
|
||||
\brief Represents infos about a rule
|
||||
*/
|
||||
struct rule_info
|
||||
{
|
||||
rule_info(context &ctx);
|
||||
~rule_info() = default;
|
||||
|
||||
context ctx;
|
||||
context cond_ctx;
|
||||
context output_ctx;
|
||||
size_t index;
|
||||
size_t visibility;
|
||||
std::string name;
|
||||
@@ -186,7 +297,7 @@ public:
|
||||
/*!
|
||||
\brief Uses the internal state to compile a list of falco_rules
|
||||
*/
|
||||
virtual bool compile(configuration& cfg, indexed_vector<falco_rule>& out) const;
|
||||
virtual void compile(configuration& cfg, indexed_vector<falco_rule>& out) const;
|
||||
|
||||
/*!
|
||||
\brief Returns the set of all required versions for each plugin according
|
||||
|
||||
@@ -16,139 +16,222 @@ limitations under the License.
|
||||
|
||||
#include "rule_reader.h"
|
||||
|
||||
#define THROW(cond, err) { if (cond) { throw falco_exception(err); } }
|
||||
#define THROW(cond, err, ctx) { if ((cond)) { throw rule_loader::rule_load_exception(load_result::LOAD_ERR_YAML_VALIDATE, (err), (ctx)); } }
|
||||
|
||||
static rule_loader::context yaml_get_context(
|
||||
const string& content,
|
||||
const vector<YAML::Node>& docs,
|
||||
vector<YAML::Node>::iterator doc,
|
||||
YAML::iterator node)
|
||||
{
|
||||
rule_loader::context m;
|
||||
YAML::Node item = *node++;
|
||||
YAML::Node cur_doc = *doc++;
|
||||
// include the "- " sequence mark
|
||||
size_t from = item.Mark().pos - 2;
|
||||
size_t to = 0;
|
||||
if (node != cur_doc.end())
|
||||
{
|
||||
// end of item is beginning of next item
|
||||
to = node->Mark().pos - 2;
|
||||
}
|
||||
else if (doc != docs.end())
|
||||
{
|
||||
// end of item is beginning of next doc
|
||||
to = doc->Mark().pos - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
// end of item is end of file contents
|
||||
to = content.length();
|
||||
}
|
||||
m.content = content.substr(from, to - from);
|
||||
m.content = trim(m.content);
|
||||
return m;
|
||||
}
|
||||
using namespace falco;
|
||||
|
||||
// Don't call this directly, call decode_val/decode_optional_val instead.
|
||||
template <typename T>
|
||||
static bool decode_val(const YAML::Node& v, T& out)
|
||||
static void decode_val_generic(const YAML::Node& item, const char *key, T& out, const rule_loader::context& ctx, bool optional)
|
||||
{
|
||||
return v.IsDefined() && v.IsScalar() && YAML::convert<T>::decode(v, out);
|
||||
}
|
||||
const YAML::Node& val = item[key];
|
||||
|
||||
template <typename T>
|
||||
static bool decode_seq(const YAML::Node& item, vector<T>& out)
|
||||
{
|
||||
if (item.IsDefined() && item.IsSequence())
|
||||
{
|
||||
T value;
|
||||
for(const YAML::Node& v : item)
|
||||
{
|
||||
THROW(!v.IsScalar() || !YAML::convert<T>::decode(v, value),
|
||||
"Can't decode YAML sequence value: " + YAML::Dump(v));
|
||||
out.push_back(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool decode_seq(const YAML::Node& item, set<T>& out)
|
||||
{
|
||||
if (item.IsDefined() && item.IsSequence())
|
||||
{
|
||||
T value;
|
||||
for(const YAML::Node& v : item)
|
||||
{
|
||||
THROW(!v.IsScalar() || !YAML::convert<T>::decode(v, value),
|
||||
"Can't decode YAML sequence value: " + YAML::Dump(v));
|
||||
out.insert(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool decode_exception_info_entry(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_exception_info::entry& out)
|
||||
{
|
||||
if (item.IsDefined())
|
||||
{
|
||||
if (item.IsScalar())
|
||||
{
|
||||
out.is_list = false;
|
||||
if (YAML::convert<string>::decode(item, out.item))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (item.IsSequence())
|
||||
{
|
||||
out.is_list = true;
|
||||
rule_loader::rule_exception_info::entry tmp;
|
||||
for(const YAML::Node& v : item)
|
||||
{
|
||||
if (!decode_exception_info_entry(v, tmp))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
out.items.push_back(tmp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void read_rule_exceptions(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_info& v)
|
||||
{
|
||||
// An exceptions property with nothing in it is allowed
|
||||
if(item.IsNull())
|
||||
if(!val.IsDefined() && optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(!item.IsSequence(), "Rule exceptions must be a sequence");
|
||||
for (auto &ex : item)
|
||||
THROW(!val.IsDefined(), std::string("Item has no mapping for key '") + key + "'", ctx);
|
||||
THROW(val.IsNull(), std::string("Mapping for key '") + key + "' is empty", ctx);
|
||||
|
||||
rule_loader::context valctx(val, "value for", key, ctx);
|
||||
THROW(!val.IsScalar(), "Value is not a scalar value", valctx);
|
||||
THROW(val.Scalar().empty(), "Value must be non-empty", valctx);
|
||||
|
||||
THROW(!YAML::convert<T>::decode(val, out), "Can't decode YAML scalar value", valctx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void decode_val(const YAML::Node& item, const char *key, T& out, const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = false;
|
||||
|
||||
decode_val_generic(item, key, out, ctx, optional);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void decode_optional_val(const YAML::Node& item, const char *key, T& out, const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = true;
|
||||
|
||||
decode_val_generic(item, key, out, ctx, optional);
|
||||
}
|
||||
|
||||
// Don't call this directly, call decode_items/decode_tags instead.
|
||||
template <typename T>
|
||||
static void decode_seq(const YAML::Node& item, const char *key,
|
||||
std::function<void(T)> inserter,
|
||||
const rule_loader::context &ctx, bool optional)
|
||||
{
|
||||
const YAML::Node& val = item[key];
|
||||
|
||||
if(!val.IsDefined() && optional)
|
||||
{
|
||||
rule_loader::rule_exception_info v_ex;
|
||||
THROW(!decode_val(ex["name"], v_ex.name) || v_ex.name.empty(),
|
||||
"Rule exception item must have name property");
|
||||
// note: the legacy lua loader used to throw a "xxx must strings" error
|
||||
decode_exception_info_entry(ex["fields"], v_ex.fields);
|
||||
decode_exception_info_entry(ex["comps"], v_ex.comps);
|
||||
if (ex["values"].IsDefined())
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(!val.IsDefined(), std::string("Item has no mapping for key '") + key + "'", ctx);
|
||||
|
||||
rule_loader::context valctx(val, "value for", key, ctx);
|
||||
THROW(!val.IsSequence(), "Value is not a sequence", valctx);
|
||||
|
||||
T value;
|
||||
for(const YAML::Node& v : val)
|
||||
{
|
||||
rule_loader::context ictx(v, "list item", "", valctx);
|
||||
THROW(!v.IsScalar(), "sequence value is not scalar", ictx);
|
||||
THROW(!YAML::convert<T>::decode(v, value), "Can't decode YAML sequence value", ictx);
|
||||
inserter(value);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void decode_items(const YAML::Node& item, vector<T>& out,
|
||||
const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = false;
|
||||
|
||||
std::function<void(T)> inserter = [&out] (T value) {
|
||||
out.push_back(value);
|
||||
};
|
||||
|
||||
decode_seq(item, "items", inserter, ctx, optional);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void decode_tags(const YAML::Node& item, set<T>& out,
|
||||
const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = true;
|
||||
|
||||
std::function<void(T)> inserter = [&out] (T value) {
|
||||
out.insert(value);
|
||||
};
|
||||
|
||||
decode_seq(item, "tags", inserter, ctx, optional);
|
||||
}
|
||||
|
||||
// Don't call this directly, call decode_exception_{fields,comps,values} instead
|
||||
static void decode_exception_info_entry(
|
||||
const YAML::Node& item,
|
||||
const char *key,
|
||||
rule_loader::rule_exception_info::entry& out,
|
||||
const rule_loader::context& ctx,
|
||||
bool optional)
|
||||
{
|
||||
const YAML::Node& val = (key == NULL ? item : item[key]);
|
||||
|
||||
if(!val.IsDefined() && optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
THROW(!val.IsDefined(), std::string("Item has no mapping for key '") + key + "'", ctx);
|
||||
|
||||
rule_loader::context valctx(val, "value for", (key == NULL ? "" : key), ctx);
|
||||
|
||||
if (val.IsScalar())
|
||||
{
|
||||
THROW(val.Scalar().empty(), "Value must be non-empty", valctx);
|
||||
out.is_list = false;
|
||||
THROW(!YAML::convert<string>::decode(val, out.item), "Could not decode scalar value", valctx);
|
||||
}
|
||||
if (val.IsSequence())
|
||||
{
|
||||
out.is_list = true;
|
||||
rule_loader::rule_exception_info::entry tmp;
|
||||
for(const YAML::Node& v : val)
|
||||
{
|
||||
THROW(!ex["values"].IsSequence(),
|
||||
"Rule exception values must be a sequence");
|
||||
for (auto &val : ex["values"])
|
||||
rule_loader::context lctx(v, "list exception entry", "", valctx);
|
||||
|
||||
// Optional is always false once you get past the outer values
|
||||
optional = false;
|
||||
decode_exception_info_entry(v, NULL, tmp, lctx, optional);
|
||||
out.items.push_back(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_exception_fields(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_exception_info::entry& out,
|
||||
const rule_loader::context& ctx,
|
||||
bool optional)
|
||||
{
|
||||
decode_exception_info_entry(item, "fields", out, ctx, optional);
|
||||
}
|
||||
|
||||
static void decode_exception_comps(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_exception_info::entry& out,
|
||||
const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = true;
|
||||
|
||||
decode_exception_info_entry(item, "comps", out, ctx, optional);
|
||||
}
|
||||
|
||||
static void decode_exception_values(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_exception_info::entry& out,
|
||||
const rule_loader::context& ctx)
|
||||
{
|
||||
bool optional = false;
|
||||
|
||||
decode_exception_info_entry(item, NULL, out, ctx, optional);
|
||||
}
|
||||
|
||||
static void read_rule_exceptions(
|
||||
const YAML::Node& item,
|
||||
rule_loader::rule_info& v,
|
||||
const rule_loader::context& parent,
|
||||
bool append)
|
||||
{
|
||||
const YAML::Node& exs = item["exceptions"];
|
||||
|
||||
// No exceptions property, or an exceptions property with
|
||||
// nothing in it, are allowed
|
||||
if(!exs.IsDefined() || exs.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rule_loader::context exes_ctx(exs, "exceptions", "", parent);
|
||||
|
||||
THROW(!exs.IsSequence(), "Rule exceptions must be a sequence", exes_ctx);
|
||||
|
||||
for (auto &ex : exs)
|
||||
{
|
||||
// Make a temp context to verify simple properties
|
||||
// about the exception.
|
||||
std::string name;
|
||||
rule_loader::context tmp(ex, "exception", "", exes_ctx);
|
||||
|
||||
THROW(!ex.IsMap(), "Rule exception must be a mapping", tmp);
|
||||
decode_val(ex, "name", name, tmp);
|
||||
|
||||
// Now use a real context including the exception name.
|
||||
rule_loader::context ex_ctx(ex, "exception", name, parent);
|
||||
rule_loader::rule_exception_info v_ex(ex_ctx);
|
||||
v_ex.name = name;
|
||||
|
||||
// note: the legacy lua loader used to throw a "xxx must strings" error
|
||||
|
||||
// fields are optional when append is true
|
||||
decode_exception_fields(ex, v_ex.fields, ex_ctx, append);
|
||||
decode_exception_comps(ex, v_ex.comps, ex_ctx);
|
||||
const YAML::Node& exvals = ex["values"];
|
||||
if (exvals.IsDefined())
|
||||
{
|
||||
rule_loader::context vals_ctx(exvals, "exception values", "", ex_ctx);
|
||||
THROW(!exvals.IsSequence(),
|
||||
"Rule exception values must be a sequence", vals_ctx);
|
||||
for (auto &val : exvals)
|
||||
{
|
||||
rule_loader::context vctx(val, "exception value", "", vals_ctx);
|
||||
rule_loader::rule_exception_info::entry v_ex_val;
|
||||
decode_exception_info_entry(val, v_ex_val);
|
||||
|
||||
decode_exception_values(val, v_ex_val, vctx);
|
||||
v_ex.values.push_back(v_ex_val);
|
||||
}
|
||||
}
|
||||
@@ -157,43 +240,65 @@ static void read_rule_exceptions(
|
||||
}
|
||||
|
||||
static void read_item(
|
||||
rule_loader::configuration& cfg,
|
||||
rule_loader& loader,
|
||||
const YAML::Node& item,
|
||||
const rule_loader::context& ctx)
|
||||
rule_loader::configuration& cfg,
|
||||
rule_loader& loader,
|
||||
const YAML::Node& item,
|
||||
const rule_loader::context& parent)
|
||||
{
|
||||
rule_loader::context tmp(item, "item", "", parent);
|
||||
THROW(!item.IsMap(), "Unexpected element type. "
|
||||
"Each element should be a yaml associative array.", tmp);
|
||||
|
||||
if (item["required_engine_version"].IsDefined())
|
||||
{
|
||||
rule_loader::engine_version_info v;
|
||||
THROW(!decode_val(item["required_engine_version"], v.version),
|
||||
"Value of required_engine_version must be a number");
|
||||
rule_loader::context ctx(item, "required_engine_version", "", parent);
|
||||
rule_loader::engine_version_info v(ctx);
|
||||
|
||||
decode_val(item, "required_engine_version", v.version, ctx);
|
||||
loader.define(cfg, v);
|
||||
}
|
||||
else if(item["required_plugin_versions"].IsDefined())
|
||||
{
|
||||
THROW(!item["required_plugin_versions"].IsSequence(),
|
||||
"Value of required_plugin_versions must be a sequence");
|
||||
const YAML::Node& req_plugin_vers = item["required_plugin_versions"];
|
||||
rule_loader::context ctx(req_plugin_vers, "required_plugin_versions", "", parent);
|
||||
|
||||
for(const YAML::Node& plugin : item["required_plugin_versions"])
|
||||
THROW(!req_plugin_vers.IsSequence(),
|
||||
"Value of required_plugin_versions must be a sequence",
|
||||
ctx);
|
||||
|
||||
for(const YAML::Node& plugin : req_plugin_vers)
|
||||
{
|
||||
rule_loader::plugin_version_info v;
|
||||
THROW(!decode_val(plugin["name"], v.name) || v.name.empty(),
|
||||
"required_plugin_versions item must have name property");
|
||||
THROW(!decode_val(plugin["version"], v.version) || v.version.empty(),
|
||||
"required_plugin_versions item must have version property");
|
||||
// Use a temp context until we can get a name
|
||||
std::string name;
|
||||
rule_loader::context tmp(plugin, "plugin version", "", ctx);
|
||||
THROW(!plugin.IsMap(), "Plugin version must be a mapping", tmp);
|
||||
decode_val(plugin, "name", name, tmp);
|
||||
|
||||
rule_loader::context pctx(plugin, "plugin version", name, ctx);
|
||||
rule_loader::plugin_version_info v(pctx);
|
||||
decode_val(plugin, "version", v.version, pctx);
|
||||
v.name = name;
|
||||
|
||||
loader.define(cfg, v);
|
||||
}
|
||||
}
|
||||
else if(item["list"].IsDefined())
|
||||
{
|
||||
rule_loader::list_info v;
|
||||
v.ctx = ctx;
|
||||
std::string name;
|
||||
// Using tmp context until name is decoded
|
||||
rule_loader::context tmp(item, "list", "", parent);
|
||||
decode_val(item, "list", name, tmp);
|
||||
|
||||
rule_loader::context ctx(item, "list", name, parent);
|
||||
rule_loader::list_info v(ctx);
|
||||
|
||||
bool append = false;
|
||||
THROW(!decode_val(item["list"], v.name) || v.name.empty(),
|
||||
"List name is empty");
|
||||
THROW(!decode_seq(item["items"], v.items),
|
||||
"List must have property items");
|
||||
if(decode_val(item["append"], append) && append)
|
||||
decode_val(item, "list", v.name, ctx);
|
||||
decode_items(item, v.items, ctx);
|
||||
|
||||
decode_optional_val(item, "append", append, ctx);
|
||||
|
||||
if(append)
|
||||
{
|
||||
loader.append(cfg, v);
|
||||
}
|
||||
@@ -204,16 +309,24 @@ static void read_item(
|
||||
}
|
||||
else if(item["macro"].IsDefined())
|
||||
{
|
||||
rule_loader::macro_info v;
|
||||
v.ctx = ctx;
|
||||
std::string name;
|
||||
// Using tmp context until name is decoded
|
||||
rule_loader::context tmp(item, "macro", "", parent);
|
||||
decode_val(item, "macro", name, tmp);
|
||||
|
||||
rule_loader::context ctx(item, "macro", name, parent);
|
||||
rule_loader::macro_info v(ctx);
|
||||
v.name = name;
|
||||
|
||||
bool append = false;
|
||||
v.source = falco_common::syscall_source;
|
||||
THROW(!decode_val(item["macro"], v.name) || v.name.empty(),
|
||||
"Macro name is empty");
|
||||
THROW(!decode_val(item["condition"], v.cond) || v.cond.empty(),
|
||||
"Macro must have property condition");
|
||||
decode_val(item["source"], v.source);
|
||||
if(decode_val(item["append"], append) && append)
|
||||
decode_val(item, "condition", v.cond, ctx);
|
||||
|
||||
// Now set the proper context for the condition now that we know it exists
|
||||
v.cond_ctx = rule_loader::context(item["condition"], "condition", "", ctx);
|
||||
|
||||
decode_optional_val(item, "append", append, ctx);
|
||||
|
||||
if(append)
|
||||
{
|
||||
loader.append(cfg, v);
|
||||
}
|
||||
@@ -224,57 +337,81 @@ static void read_item(
|
||||
}
|
||||
else if(item["rule"].IsDefined())
|
||||
{
|
||||
rule_loader::rule_info v;
|
||||
v.ctx = ctx;
|
||||
std::string name;
|
||||
|
||||
// Using tmp context until name is decoded
|
||||
rule_loader::context tmp(item, "rule", "", parent);
|
||||
decode_val(item, "rule", name, tmp);
|
||||
|
||||
rule_loader::context ctx(item, "rule", name, parent);
|
||||
rule_loader::rule_info v(ctx);
|
||||
v.name = name;
|
||||
|
||||
bool append = false;
|
||||
v.enabled = true;
|
||||
v.warn_evttypes = true;
|
||||
v.skip_if_unknown_filter = false;
|
||||
THROW(!decode_val(item["rule"], v.name) || v.name.empty(),
|
||||
"Rule name is empty");
|
||||
if(decode_val(item["append"], append) && append)
|
||||
|
||||
decode_optional_val(item, "append", append, ctx);
|
||||
|
||||
if(append)
|
||||
{
|
||||
decode_val(item["condition"], v.cond);
|
||||
if (item["exceptions"].IsDefined())
|
||||
decode_optional_val(item, "condition", v.cond, ctx);
|
||||
if(item["condition"].IsDefined())
|
||||
{
|
||||
read_rule_exceptions(item["exceptions"], v);
|
||||
v.cond_ctx = rule_loader::context(item["condition"], "condition", "", ctx);
|
||||
}
|
||||
read_rule_exceptions(item, v, ctx, append);
|
||||
loader.append(cfg, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
string priority;
|
||||
bool has_enabled = decode_val(item["enabled"], v.enabled);
|
||||
bool has_defs = decode_val(item["condition"], v.cond)
|
||||
&& decode_val(item["output"], v.output)
|
||||
&& decode_val(item["desc"], v.desc)
|
||||
&& decode_val(item["priority"], priority);
|
||||
if (!has_defs)
|
||||
// If the rule does *not* have any of
|
||||
// condition/output/desc/priority, it *must*
|
||||
// have an enabled property. Use the enabled
|
||||
// property to set the enabled status of an
|
||||
// earlier rule.
|
||||
if (!item["condition"].IsDefined() &&
|
||||
!item["output"].IsDefined() &&
|
||||
!item["desc"].IsDefined() &&
|
||||
!item["priority"].IsDefined())
|
||||
{
|
||||
THROW(!has_enabled, "Rule must have properties 'condition', 'output', 'desc', and 'priority'");
|
||||
decode_val(item, "enabled", v.enabled, ctx);
|
||||
loader.enable(cfg, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
string priority;
|
||||
|
||||
// All of these are required
|
||||
decode_val(item, "condition", v.cond, ctx);
|
||||
v.cond_ctx = rule_loader::context(item["condition"], "condition", "", ctx);
|
||||
|
||||
decode_val(item, "output", v.output, ctx);
|
||||
v.output_ctx = rule_loader::context(item["output"], "output", "", ctx);
|
||||
|
||||
decode_val(item, "desc", v.desc, ctx);
|
||||
decode_val(item, "priority", priority, ctx);
|
||||
|
||||
v.output = trim(v.output);
|
||||
v.source = falco_common::syscall_source;
|
||||
rule_loader::context prictx(item["priority"], "priority value", "", ctx);
|
||||
THROW(!falco_common::parse_priority(priority, v.priority),
|
||||
"Invalid priority");
|
||||
decode_val(item["source"], v.source);
|
||||
decode_val(item["warn_evttypes"], v.warn_evttypes);
|
||||
decode_val(item["skip-if-unknown-filter"], v.skip_if_unknown_filter);
|
||||
decode_seq(item["tags"], v.tags);
|
||||
if (item["exceptions"].IsDefined())
|
||||
{
|
||||
read_rule_exceptions(item["exceptions"], v);
|
||||
}
|
||||
"Invalid priority", prictx);
|
||||
decode_optional_val(item, "source", v.source, ctx);
|
||||
decode_optional_val(item, "enabled", v.enabled, ctx);
|
||||
decode_optional_val(item, "warn_evttypes", v.warn_evttypes, ctx);
|
||||
decode_optional_val(item, "skip-if-unknown-filter", v.skip_if_unknown_filter, ctx);
|
||||
decode_tags(item, v.tags, ctx);
|
||||
read_rule_exceptions(item, v, ctx, append);
|
||||
loader.define(cfg, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg.warnings.push_back("Unknown top level object");
|
||||
rule_loader::context ctx(item, "unknown", "", parent);
|
||||
cfg.res->add_warning(load_result::LOAD_UNKNOWN_ITEM, "Unknown top level item", ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,45 +424,45 @@ bool rule_reader::load(rule_loader::configuration& cfg, rule_loader& loader)
|
||||
}
|
||||
catch(const exception& e)
|
||||
{
|
||||
cfg.errors.push_back("Could not load YAML file: " + string(e.what()));
|
||||
rule_loader::context ctx(cfg.name);
|
||||
cfg.res->add_error(load_result::LOAD_ERR_YAML_PARSE, e.what(), ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (auto doc = docs.begin(); doc != docs.end(); doc++)
|
||||
{
|
||||
if (doc->IsDefined() && !doc->IsNull())
|
||||
{
|
||||
if(!doc->IsMap() && !doc->IsSequence())
|
||||
{
|
||||
cfg.errors.push_back("Rules content is not yaml");
|
||||
return false;
|
||||
}
|
||||
if(!doc->IsSequence())
|
||||
{
|
||||
cfg.errors.push_back(
|
||||
"Rules content is not yaml array of objects");
|
||||
return false;
|
||||
}
|
||||
for (auto it = doc->begin(); it != doc->end(); it++)
|
||||
{
|
||||
if (!it->IsNull())
|
||||
rule_loader::context ctx(cfg.name);
|
||||
|
||||
try {
|
||||
THROW(!doc->IsMap() && !doc->IsSequence(),
|
||||
"Rules content is not yaml",
|
||||
ctx);
|
||||
|
||||
THROW(!doc->IsSequence(),
|
||||
"Rules content is not yaml array of objects",
|
||||
ctx);
|
||||
|
||||
for (auto it = doc->begin(); it != doc->end(); it++)
|
||||
{
|
||||
auto ctx = yaml_get_context(cfg.content, docs, doc, it);
|
||||
YAML::Node item = *it;
|
||||
try
|
||||
if (!it->IsNull())
|
||||
{
|
||||
THROW(!item.IsMap(), "Unexpected element type. "
|
||||
"Each element should be a yaml associative array.");
|
||||
read_item(cfg, loader, item, ctx);
|
||||
}
|
||||
catch(const exception& e)
|
||||
{
|
||||
cfg.errors.push_back(ctx.error(e.what()));
|
||||
return false;
|
||||
read_item(cfg, loader, *it, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (rule_loader::rule_load_exception &e)
|
||||
{
|
||||
cfg.res->add_error(e.ec, e.msg, e.ctx);
|
||||
|
||||
// Although we *could* continue on to the next doc,
|
||||
// as it's effectively a new rules file, for
|
||||
// consistency we stop at the first error.
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2020 The Falco Authors.
|
||||
# Copyright (C) 2022 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
@@ -30,8 +30,10 @@ set(
|
||||
app_actions/load_rules_files.cpp
|
||||
app_actions/open_inspector.cpp
|
||||
app_actions/process_events.cpp
|
||||
app_actions/print_generated_gvisor_config.cpp
|
||||
app_actions/print_help.cpp
|
||||
app_actions/print_ignored_events.cpp
|
||||
app_actions/print_plugin_info.cpp
|
||||
app_actions/print_support.cpp
|
||||
app_actions/print_version.cpp
|
||||
app_actions/start_grpc_server.cpp
|
||||
|
||||
@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "application.h"
|
||||
|
||||
using namespace falco::app;
|
||||
@@ -43,6 +45,11 @@ void application::configure_output_format()
|
||||
output_format = m_options.print_additional;
|
||||
replace_container_info = false;
|
||||
}
|
||||
else if(m_options.gvisor_config != "")
|
||||
{
|
||||
output_format = "container=%container.id pid=%proc.vpid tid=%thread.vtid";
|
||||
replace_container_info = true;
|
||||
}
|
||||
|
||||
if(!output_format.empty())
|
||||
{
|
||||
@@ -84,6 +91,13 @@ application::run_result application::init_falco_engine()
|
||||
return run_result::fatal("At least one event source needs to be enabled");
|
||||
}
|
||||
|
||||
/* Print all enabled sources. */
|
||||
std::ostringstream os;
|
||||
std::copy(m_state->enabled_sources.begin(), m_state->enabled_sources.end(), std::ostream_iterator<std::string>(os, ","));
|
||||
std::string result = os.str();
|
||||
result.pop_back();
|
||||
falco_logger::log(LOG_INFO, "Enabled sources: " + result + "\n");
|
||||
|
||||
m_state->engine->set_min_priority(m_state->config->m_min_priority);
|
||||
|
||||
return run_result::ok();
|
||||
|
||||
@@ -27,21 +27,7 @@ application::run_result application::list_plugins()
|
||||
const auto &plugins = m_state->inspector->get_plugin_manager()->plugins();
|
||||
for (auto &p : plugins)
|
||||
{
|
||||
os << "Name: " << p->name() << std::endl;
|
||||
os << "Description: " << p->description() << std::endl;
|
||||
os << "Contact: " << p->contact() << std::endl;
|
||||
os << "Version: " << p->plugin_version().as_string() << std::endl;
|
||||
os << "Capabilities: " << std::endl;
|
||||
if(p->caps() & CAP_SOURCING)
|
||||
{
|
||||
os << " - Event Sourcing (ID=" << p->id();
|
||||
os << ", source='" << p->event_source() << "')" << std::endl;
|
||||
}
|
||||
if(p->caps() & CAP_EXTRACTION)
|
||||
{
|
||||
os << " - Field Extraction" << std::endl;
|
||||
}
|
||||
|
||||
format_plugin_info(p, os);
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,9 @@ application::run_result application::load_config()
|
||||
falco_logger::set_time_format_iso_8601(m_state->config->m_time_format_iso_8601);
|
||||
|
||||
// log after config init because config determines where logs go
|
||||
falco_logger::log(LOG_INFO, "Falco version " + std::string(FALCO_VERSION) + " (driver version " + std::string(DRIVER_VERSION) + ")\n");
|
||||
falco_logger::log(LOG_INFO, "Falco initialized with configuration file " + m_options.conf_filename + "\n");
|
||||
falco_logger::log(LOG_INFO, "Falco version: " + std::string(FALCO_VERSION) + "\n");
|
||||
falco_logger::log(LOG_INFO, "Falco initialized with configuration file: " + m_options.conf_filename + "\n");
|
||||
falco_logger::log(LOG_INFO, "Falco compiled for: " + std::string(FALCO_TARGET_ARCH) + "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -31,11 +31,16 @@ application::run_result application::load_plugins()
|
||||
// The only enabled event source is syscall by default
|
||||
m_state->enabled_sources = {falco_common::syscall_source};
|
||||
|
||||
std::string err = "";
|
||||
std::shared_ptr<sinsp_plugin> loaded_plugin = nullptr;
|
||||
for(auto &p : m_state->config->m_plugins)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Loading plugin (" + p.m_name + ") from file " + p.m_library_path + "\n");
|
||||
auto plugin = m_state->inspector->register_plugin(p.m_library_path, p.m_init_config);
|
||||
auto plugin = m_state->inspector->register_plugin(p.m_library_path);
|
||||
if (!plugin->init(p.m_init_config, err))
|
||||
{
|
||||
return run_result::fatal(err);
|
||||
}
|
||||
|
||||
if(plugin->caps() & CAP_SOURCING)
|
||||
{
|
||||
|
||||
@@ -93,19 +93,38 @@ application::run_result application::load_rules_files()
|
||||
falco_configuration::read_rules_file_directory(path, m_state->config->m_loaded_rules_filenames, m_state->config->m_loaded_rules_folders);
|
||||
}
|
||||
|
||||
for (const auto& filename : m_state->config->m_loaded_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
|
||||
uint64_t required_engine_version;
|
||||
std::vector<std::string> rules_contents;
|
||||
falco::load_result::rules_contents_t rc;
|
||||
|
||||
try {
|
||||
m_state->engine->load_rules_file(filename, m_options.verbose, m_options.all_events, required_engine_version);
|
||||
}
|
||||
catch(falco_exception &e)
|
||||
try {
|
||||
read_files(m_state->config->m_loaded_rules_filenames.begin(),
|
||||
m_state->config->m_loaded_rules_filenames.end(),
|
||||
rules_contents,
|
||||
rc);
|
||||
}
|
||||
catch(falco_exception& e)
|
||||
{
|
||||
return run_result::fatal(e.what());
|
||||
}
|
||||
|
||||
for(auto &filename : m_state->config->m_loaded_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + "\n");
|
||||
std::unique_ptr<falco::load_result> res;
|
||||
|
||||
res = m_state->engine->load_rules(rc.at(filename), filename);
|
||||
|
||||
if(!res->successful())
|
||||
{
|
||||
return run_result::fatal(string("Could not load rules file ") + filename + ": " + e.what());
|
||||
// Return the summary version as the error
|
||||
return run_result::fatal(res->as_string(true, rc));
|
||||
}
|
||||
|
||||
// If verbose is true, also print any warnings
|
||||
if(m_options.verbose && res->has_warnings())
|
||||
{
|
||||
fprintf(stderr, "%s\n", res->as_string(true, rc).c_str());
|
||||
}
|
||||
m_state->required_engine_versions[filename] = required_engine_version;
|
||||
}
|
||||
|
||||
// Ensure that all plugins are compatible with the loaded set of rules
|
||||
|
||||
@@ -46,14 +46,19 @@ application::run_result application::open_inspector()
|
||||
{
|
||||
try
|
||||
{
|
||||
// open_udig() is the underlying method used in the capture code to parse userspace events from the kernel.
|
||||
//
|
||||
// Falco uses a ptrace(2) based userspace implementation.
|
||||
// Regardless of the implementation, the underlying method remains the same.
|
||||
if(m_options.userspace)
|
||||
{
|
||||
// open_udig() is the underlying method used in the capture code to parse userspace events from the kernel.
|
||||
//
|
||||
// Falco uses a ptrace(2) based userspace implementation.
|
||||
// Regardless of the implementation, the underlying method remains the same.
|
||||
m_state->inspector->open_udig();
|
||||
}
|
||||
else if(m_options.gvisor_config != "")
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Enabled event collection from gVisor. Configuration path: " + m_options.gvisor_config);
|
||||
m_state->inspector->open_gvisor(m_options.gvisor_config, m_options.gvisor_root);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state->inspector->open();
|
||||
@@ -78,6 +83,14 @@ application::run_result application::open_inspector()
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: we can add a method to the inspector that tells us what
|
||||
/// is the underline engine used. Right now we print something only
|
||||
/// in case of BPF engine
|
||||
if(m_state->inspector->is_bpf_enabled())
|
||||
{
|
||||
falco_logger::log(LOG_INFO, "Falco is using the BPF probe\n");
|
||||
}
|
||||
|
||||
// This must be done after the open
|
||||
if(!m_options.all_events)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "config_falco.h"
|
||||
#include "application.h"
|
||||
|
||||
using namespace falco::app;
|
||||
|
||||
application::run_result application::print_generated_gvisor_config()
|
||||
{
|
||||
if(!m_options.gvisor_generate_config_with_socket.empty())
|
||||
{
|
||||
std::unique_ptr<sinsp> s(new sinsp());
|
||||
std::string gvisor_config = s->generate_gvisor_config(m_options.gvisor_generate_config_with_socket);
|
||||
printf("%s\n", gvisor_config.c_str());
|
||||
return run_result::exit();
|
||||
}
|
||||
return run_result::ok();
|
||||
}
|
||||
130
userspace/falco/app_actions/print_plugin_info.cpp
Normal file
130
userspace/falco/app_actions/print_plugin_info.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "application.h"
|
||||
#include <plugin_manager.h>
|
||||
|
||||
using namespace falco::app;
|
||||
|
||||
void application::format_plugin_info(std::shared_ptr<sinsp_plugin> p, std::ostream& os) const
|
||||
{
|
||||
os << "Name: " << p->name() << std::endl;
|
||||
os << "Description: " << p->description() << std::endl;
|
||||
os << "Contact: " << p->contact() << std::endl;
|
||||
os << "Version: " << p->plugin_version().as_string() << std::endl;
|
||||
os << "Capabilities: " << std::endl;
|
||||
if(p->caps() & CAP_SOURCING)
|
||||
{
|
||||
os << " - Event Sourcing (ID=" << p->id();
|
||||
os << ", source='" << p->event_source() << "')" << std::endl;
|
||||
}
|
||||
if(p->caps() & CAP_EXTRACTION)
|
||||
{
|
||||
os << " - Field Extraction" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
application::run_result application::print_plugin_info()
|
||||
{
|
||||
#ifdef MUSL_OPTIMIZED
|
||||
if(!m_options.print_plugin_info.empty())
|
||||
{
|
||||
return run_result::fatal("Can not load or use plugins with musl optimized build");
|
||||
}
|
||||
#else // MUSL_OPTIMIZED
|
||||
if(!m_options.print_plugin_info.empty())
|
||||
{
|
||||
for(auto &pc : m_state->config->m_plugins)
|
||||
{
|
||||
if (pc.m_name == m_options.print_plugin_info
|
||||
|| pc.m_library_path == m_options.print_plugin_info)
|
||||
{
|
||||
// load the plugin
|
||||
auto p = m_state->inspector->register_plugin(pc.m_library_path);
|
||||
|
||||
// print plugin descriptive info
|
||||
std::ostringstream os;
|
||||
format_plugin_info(p, os);
|
||||
os << std::endl;
|
||||
printf("%s", os.str().c_str());
|
||||
|
||||
// print plugin init schema
|
||||
os.str("");
|
||||
os.clear();
|
||||
ss_plugin_schema_type type;
|
||||
auto schema = p->get_init_schema(type);
|
||||
os << "Init config schema type: ";
|
||||
switch (type)
|
||||
{
|
||||
case SS_PLUGIN_SCHEMA_JSON:
|
||||
os << "JSON" << std::endl;
|
||||
break;
|
||||
case SS_PLUGIN_SCHEMA_NONE:
|
||||
default:
|
||||
os << "Not available, plugin does not implement the init config schema functionality" << std::endl;
|
||||
break;
|
||||
}
|
||||
os << schema << std::endl;
|
||||
os << std::endl;
|
||||
printf("%s", os.str().c_str());
|
||||
|
||||
// init the plugin
|
||||
std::string err;
|
||||
if (!p->init(pc.m_init_config, err))
|
||||
{
|
||||
return run_result::fatal(err);
|
||||
}
|
||||
|
||||
// print plugin suggested open parameters
|
||||
if (p->caps() & CAP_SOURCING)
|
||||
{
|
||||
os.str("");
|
||||
os.clear();
|
||||
auto params = p->list_open_params();
|
||||
if (params.empty())
|
||||
{
|
||||
os << "No suggested open params available: ";
|
||||
os << "plugin has not been configured, or it does not implement the open params suggestion functionality" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Suggested open params:" << std::endl;
|
||||
for(auto &oparam : p->list_open_params())
|
||||
{
|
||||
if(oparam.desc == "")
|
||||
{
|
||||
os << oparam.value << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << oparam.value << ": " << oparam.desc << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
os << std::endl;
|
||||
printf("%s", os.str().c_str());
|
||||
}
|
||||
|
||||
// exit
|
||||
return run_result::exit();
|
||||
}
|
||||
}
|
||||
return run_result::fatal("can't find plugin and print its info: " + m_options.print_plugin_info);
|
||||
}
|
||||
#endif // MUSL_OPTIMIZED
|
||||
|
||||
return run_result::ok();
|
||||
}
|
||||
@@ -58,7 +58,6 @@ application::run_result application::print_support()
|
||||
nlohmann::json finfo;
|
||||
finfo["name"] = filename;
|
||||
nlohmann::json variant;
|
||||
variant["required_engine_version"] = m_state->required_engine_versions[filename];
|
||||
variant["content"] = read_file(filename);
|
||||
finfo["variants"].push_back(variant);
|
||||
support["rules_files"].push_back(finfo);
|
||||
|
||||
@@ -23,8 +23,25 @@ application::run_result application::print_version()
|
||||
{
|
||||
if(m_options.print_version_info)
|
||||
{
|
||||
std::unique_ptr<sinsp> s(new sinsp());
|
||||
printf("Falco version: %s\n", FALCO_VERSION);
|
||||
printf("Driver version: %s\n", DRIVER_VERSION);
|
||||
printf("Libs version: %s\n", FALCOSECURITY_LIBS_VERSION);
|
||||
printf("Plugin API: %s\n", s->get_plugin_api_version());
|
||||
|
||||
// todo(leogr): move string conversion to scap
|
||||
auto driver_api_version = s->get_scap_api_version();
|
||||
unsigned long driver_api_major = PPM_API_VERSION_MAJOR(driver_api_version);
|
||||
unsigned long driver_api_minor = PPM_API_VERSION_MINOR(driver_api_version);
|
||||
unsigned long driver_api_patch = PPM_API_VERSION_PATCH(driver_api_version);
|
||||
auto driver_schema_version = s->get_scap_schema_version();
|
||||
unsigned long driver_schema_major = PPM_API_VERSION_MAJOR(driver_schema_version);
|
||||
unsigned long driver_schema_minor = PPM_API_VERSION_MINOR(driver_schema_version);
|
||||
unsigned long driver_schema_patch = PPM_API_VERSION_PATCH(driver_schema_version);
|
||||
printf("Driver:\n");
|
||||
printf(" API version: %ld.%ld.%ld\n", driver_api_major, driver_api_minor, driver_api_patch);
|
||||
printf(" Schema version: %ld.%ld.%ld\n", driver_schema_major, driver_schema_minor, driver_schema_patch);
|
||||
printf(" Default driver: %s\n", DRIVER_VERSION);
|
||||
|
||||
return run_result::exit();
|
||||
}
|
||||
return run_result::ok();
|
||||
|
||||
@@ -101,7 +101,8 @@ application::run_result application::do_inspect(syscall_evt_drop_mgr &sdropmgr,
|
||||
{
|
||||
timeouts_since_last_success_or_msg++;
|
||||
if(timeouts_since_last_success_or_msg > m_state->config->m_syscall_evt_timeout_max_consecutives
|
||||
&& is_syscall_source_enabled())
|
||||
&& is_syscall_source_enabled()
|
||||
&& !is_gvisor_enabled())
|
||||
{
|
||||
std::string rule = "Falco internal: timeouts notification";
|
||||
std::string msg = rule + ". " + std::to_string(m_state->config->m_syscall_evt_timeout_max_consecutives) + " consecutive timeouts without event.";
|
||||
@@ -122,6 +123,10 @@ application::run_result application::do_inspect(syscall_evt_drop_mgr &sdropmgr,
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(rc == SCAP_FILTERED_EVENT)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(rc == SCAP_EOF)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -15,6 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
#include "application.h"
|
||||
#include <string>
|
||||
|
||||
using namespace falco::app;
|
||||
|
||||
@@ -22,27 +23,117 @@ application::run_result application::validate_rules_files()
|
||||
{
|
||||
if(m_options.validate_rules_filenames.size() > 0)
|
||||
{
|
||||
|
||||
std::vector<std::string> rules_contents;
|
||||
falco::load_result::rules_contents_t rc;
|
||||
|
||||
try {
|
||||
read_files(m_options.validate_rules_filenames.begin(),
|
||||
m_options.validate_rules_filenames.end(),
|
||||
rules_contents,
|
||||
rc);
|
||||
}
|
||||
catch(falco_exception& e)
|
||||
{
|
||||
return run_result::fatal(e.what());
|
||||
}
|
||||
|
||||
bool successful = true;
|
||||
|
||||
// The validation result is *always* printed to
|
||||
// stdout. When json_output is true, the output is in
|
||||
// json format and contains all errors/warnings for
|
||||
// all files.
|
||||
//
|
||||
|
||||
// When json_output is false, it contains a summary of
|
||||
// each file and whether it was valid or not, along
|
||||
// with any errors. To match older falco behavior,
|
||||
// this *only* contains errors.
|
||||
//
|
||||
// So for each file stdout will contain:
|
||||
//
|
||||
// <filename>: Ok
|
||||
// or
|
||||
// <filename>: Invalid
|
||||
// [All Validation Errors]
|
||||
//
|
||||
// Warnings are only printed to stderr, and only
|
||||
// printed when verbose is true.
|
||||
std::string summary;
|
||||
|
||||
falco_logger::log(LOG_INFO, "Validating rules file(s):\n");
|
||||
for(auto file : m_options.validate_rules_filenames)
|
||||
{
|
||||
falco_logger::log(LOG_INFO, " " + file + "\n");
|
||||
}
|
||||
for(auto file : m_options.validate_rules_filenames)
|
||||
|
||||
// The json output encompasses all files so the
|
||||
// validation result is a single json object.
|
||||
nlohmann::json results = nlohmann::json::array();
|
||||
|
||||
for(auto &filename : m_options.validate_rules_filenames)
|
||||
{
|
||||
// Only include the prefix if there is more than one file
|
||||
std::string prefix = (m_options.validate_rules_filenames.size() > 1 ? file + ": " : "");
|
||||
try {
|
||||
m_state->engine->load_rules_file(file, m_options.verbose, m_options.all_events);
|
||||
}
|
||||
catch(falco_exception &e)
|
||||
std::unique_ptr<falco::load_result> res;
|
||||
|
||||
res = m_state->engine->load_rules(rc.at(filename), filename);
|
||||
|
||||
successful &= res->successful();
|
||||
|
||||
if(m_state->config->m_json_output)
|
||||
{
|
||||
printf("%s%s", prefix.c_str(), e.what());
|
||||
return run_result::fatal(prefix + e.what());
|
||||
results.push_back(res->as_json(rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(summary != "")
|
||||
{
|
||||
summary += "\n";
|
||||
}
|
||||
|
||||
// Add to the summary if not successful, or successful
|
||||
// with no warnings.
|
||||
if(!res->successful() ||
|
||||
(res->successful() && !res->has_warnings()))
|
||||
{
|
||||
summary += res->as_string(true, rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If here, there must be only warnings.
|
||||
// Add a line to the summary noting that the
|
||||
// file was ok with warnings, without actually
|
||||
// printing the warnings.
|
||||
summary += filename + ": Ok, with warnings";
|
||||
|
||||
// If verbose is true, print the warnings now.
|
||||
if(m_options.verbose)
|
||||
{
|
||||
fprintf(stderr, "%s\n", res->as_string(true, rc).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%sOk\n", prefix.c_str());
|
||||
}
|
||||
falco_logger::log(LOG_INFO, "Ok\n");
|
||||
return run_result::exit();
|
||||
|
||||
if(m_state->config->m_json_output)
|
||||
{
|
||||
nlohmann::json res;
|
||||
res["falco_load_results"] = results;
|
||||
printf("%s\n", res.dump().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s\n", summary.c_str());
|
||||
}
|
||||
|
||||
if(successful)
|
||||
{
|
||||
return run_result::exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
return run_result::fatal(summary);
|
||||
}
|
||||
}
|
||||
|
||||
return run_result::ok();
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace app {
|
||||
// initialize their linked variables.
|
||||
cmdline_options::cmdline_options()
|
||||
: event_buffer_format(sinsp_evt::PF_NORMAL),
|
||||
gvisor_config(""),
|
||||
list_plugins(false),
|
||||
m_cmdline_opts("falco", "Falco - Cloud Native Runtime Security")
|
||||
{
|
||||
@@ -162,6 +163,11 @@ void cmdline_options::define()
|
||||
("disable-source", "Disable a specific event source. Available event sources are: syscall or any source from a configured plugin with event sourcing capability. It can be passed multiple times. Can not disable all event sources.", cxxopts::value(disable_sources), "<event_source>")
|
||||
("D", "Disable any rules with names having the substring <substring>. Can be specified multiple times. Can not be specified with -t.", cxxopts::value(disabled_rule_substrings), "<substring>")
|
||||
("e", "Read the events from <events_file> in .scap format instead of tapping into live.", cxxopts::value(trace_filename), "<events_file>")
|
||||
#ifdef HAS_GVISOR
|
||||
("g,gvisor-config", "Parse events from gVisor using the specified configuration file. A falco-compatible configuration file can be generated with --gvisor-generate-config and can be used for both runsc and Falco.", cxxopts::value(gvisor_config), "<gvisor_config>")
|
||||
("gvisor-generate-config", "Generate a configuration file that can be used for gVisor.", cxxopts::value<std::string>(gvisor_generate_config_with_socket)->implicit_value("/tmp/gvisor.sock"), "<socket_path>")
|
||||
("gvisor-root", "gVisor root directory for storage of container state. Equivalent to runsc --root flag.", cxxopts::value(gvisor_root), "<gvisor_root>")
|
||||
#endif
|
||||
("i", "Print all events that are ignored by default (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false"))
|
||||
#ifndef MINIMAL_BUILD
|
||||
("k,k8s-api", "Enable Kubernetes support by connecting to the API server specified as argument. E.g. \"http://admin:password@127.0.0.1:8080\". The API server can also be specified via the environment variable FALCO_K8S_API.", cxxopts::value(k8s_api), "<url>")
|
||||
@@ -182,6 +188,7 @@ void cmdline_options::define()
|
||||
("markdown", "When used with --list/--list-syscall-events, print the content in Markdown format", cxxopts::value<bool>(markdown))
|
||||
("N", "When used with --list, only print field names.", cxxopts::value(names_only)->default_value("false"))
|
||||
("o,option", "Set the value of option <opt> to <val>. Overrides values in configuration file. <opt> can be identified using its location in configuration file using dot notation. Elements which are entries of lists can be accessed via square brackets [].\n E.g. base.id = val\n base.subvalue.subvalue2 = val\n base.list[1]=val", cxxopts::value(cmdline_config_options), "<opt>=<val>")
|
||||
("plugin-info", "Print info for a single plugin and exit.\nThis includes all descriptivo info like name and author, along with the\nschema format for the init configuration and a list of suggested open parameters.\n<plugin_name> can be the name of the plugin or its configured library_path.", cxxopts::value(print_plugin_info), "<plugin_name>")
|
||||
("p,print", "Add additional information to each falco notification's output.\nWith -pc or -pcontainer will use a container-friendly format.\nWith -pk or -pkubernetes will use a kubernetes-friendly format.\nWith -pm or -pmesos will use a mesos-friendly format.\nAdditionally, specifying -pc/-pk/-pm will change the interpretation of %container.info in rule output fields.", cxxopts::value(print_additional), "<output_format>")
|
||||
("P,pidfile", "When run as a daemon, write pid to specified file", cxxopts::value(pidfilename)->default_value("/var/run/falco.pid"), "<pid_file>")
|
||||
("r", "Rules file/directory (defaults to value set in configuration file, or /etc/falco_rules.yaml). Can be specified multiple times to read from multiple files/directories.", cxxopts::value<std::vector<std::string>>(), "<rules_file>")
|
||||
|
||||
@@ -43,6 +43,9 @@ public:
|
||||
std::vector<std::string> disable_sources;
|
||||
std::vector<std::string> disabled_rule_substrings;
|
||||
std::string trace_filename;
|
||||
std::string gvisor_config;
|
||||
std::string gvisor_generate_config_with_socket;
|
||||
std::string gvisor_root;
|
||||
std::string k8s_api;
|
||||
std::string k8s_api_cert;
|
||||
std::string k8s_node_name;
|
||||
@@ -52,6 +55,7 @@ public:
|
||||
bool list_fields;
|
||||
std::string list_source_fields;
|
||||
bool list_plugins;
|
||||
std::string print_plugin_info;
|
||||
bool list_syscall_events;
|
||||
bool markdown;
|
||||
std::string mesos_api;
|
||||
|
||||
@@ -125,17 +125,19 @@ bool application::run(std::string &errstr, bool &restart)
|
||||
std::list<std::function<run_result()>> run_steps = {
|
||||
std::bind(&application::print_help, this),
|
||||
std::bind(&application::print_version, this),
|
||||
std::bind(&application::print_generated_gvisor_config, this),
|
||||
std::bind(&application::create_signal_handlers, this),
|
||||
std::bind(&application::load_config, this),
|
||||
std::bind(&application::init_inspector, this),
|
||||
std::bind(&application::print_plugin_info, this),
|
||||
std::bind(&application::load_plugins, this),
|
||||
std::bind(&application::init_falco_engine, this),
|
||||
std::bind(&application::list_fields, this),
|
||||
std::bind(&application::list_plugins, this),
|
||||
std::bind(&application::validate_rules_files, this),
|
||||
std::bind(&application::load_rules_files, this),
|
||||
std::bind(&application::print_ignored_events, this),
|
||||
std::bind(&application::print_support, this),
|
||||
std::bind(&application::validate_rules_files, this),
|
||||
std::bind(&application::attach_inotify_signals, this),
|
||||
std::bind(&application::daemonize, this),
|
||||
std::bind(&application::init_outputs, this),
|
||||
|
||||
@@ -81,8 +81,6 @@ private:
|
||||
// from event source to filtercheck list.
|
||||
std::map<std::string, filter_check_list> plugin_filter_checks;
|
||||
|
||||
std::map<string,uint64_t> required_engine_versions;
|
||||
|
||||
std::string cmdline;
|
||||
|
||||
#ifndef MINIMAL_BUILD
|
||||
@@ -136,6 +134,49 @@ private:
|
||||
bool proceed;
|
||||
};
|
||||
|
||||
// Convenience method. Read a sequence of filenames and fill
|
||||
// in a vector of rules contents.
|
||||
// Also fill in the provided rules_contents_t with a mapping from
|
||||
// filename (reference) to content (reference).
|
||||
// falco_exception if any file could not be read.
|
||||
template<class InputIterator>
|
||||
void read_files(InputIterator begin, InputIterator end,
|
||||
std::vector<std::string>& rules_contents,
|
||||
falco::load_result::rules_contents_t& rc)
|
||||
{
|
||||
// Read the contents in a first pass
|
||||
for(auto it = begin; it != end; it++)
|
||||
{
|
||||
std::string &filename = *it;
|
||||
std::ifstream is;
|
||||
is.open(filename);
|
||||
if (!is.is_open())
|
||||
{
|
||||
throw falco_exception("Could not open file " + filename + " for reading");
|
||||
}
|
||||
|
||||
std::string rules_content((istreambuf_iterator<char>(is)),
|
||||
istreambuf_iterator<char>());
|
||||
rules_contents.emplace_back(std::move(rules_content));
|
||||
}
|
||||
|
||||
// Populate the map in a second pass to avoid
|
||||
// references becoming invalid.
|
||||
auto it = begin;
|
||||
auto rit = rules_contents.begin();
|
||||
for(; it != end && rit != rules_contents.end(); it++, rit++)
|
||||
{
|
||||
rc.emplace(*it, *rit);
|
||||
}
|
||||
|
||||
// Both it and rit must be at the end, otherwise
|
||||
// there's a bug in the above
|
||||
if(it != end || rit != rules_contents.end())
|
||||
{
|
||||
throw falco_exception("Unexpected mismatch in rules content name/rules content sets?");
|
||||
}
|
||||
}
|
||||
|
||||
// These methods comprise the code the application "runs". The
|
||||
// order in which the methods run is in application.cpp.
|
||||
run_result create_signal_handlers();
|
||||
@@ -151,8 +192,10 @@ private:
|
||||
run_result load_plugins();
|
||||
run_result load_rules_files();
|
||||
run_result open_inspector();
|
||||
run_result print_generated_gvisor_config();
|
||||
run_result print_help();
|
||||
run_result print_ignored_events();
|
||||
run_result print_plugin_info();
|
||||
run_result print_support();
|
||||
run_result print_version();
|
||||
run_result process_events();
|
||||
@@ -176,6 +219,7 @@ private:
|
||||
void configure_output_format();
|
||||
void check_for_ignored_events();
|
||||
void print_all_ignored_events();
|
||||
void format_plugin_info(std::shared_ptr<sinsp_plugin> p, std::ostream& os) const;
|
||||
run_result do_inspect(syscall_evt_drop_mgr &sdropmgr,
|
||||
uint64_t duration_to_tot_ns,
|
||||
uint64_t &num_events);
|
||||
@@ -191,6 +235,11 @@ private:
|
||||
return !m_options.trace_filename.empty();
|
||||
}
|
||||
|
||||
inline bool is_gvisor_enabled() const
|
||||
{
|
||||
return !m_options.gvisor_config.empty();
|
||||
}
|
||||
|
||||
std::unique_ptr<state> m_state;
|
||||
cmdline_options m_options;
|
||||
bool m_initialized;
|
||||
|
||||
@@ -24,11 +24,14 @@ limitations under the License.
|
||||
#define FALCO_VERSION_PATCH @FALCO_VERSION_PATCH@
|
||||
#define FALCO_VERSION_PRERELEASE "@FALCO_VERSION_PRERELEASE@"
|
||||
#define FALCO_VERSION_BUILD "@FALCO_VERSION_BUILD@"
|
||||
#define FALCO_TARGET_ARCH "@FALCO_TARGET_ARCH@"
|
||||
|
||||
#define FALCO_SOURCE_DIR "${PROJECT_SOURCE_DIR}"
|
||||
#define FALCO_SOURCE_CONF_FILE "${PROJECT_SOURCE_DIR}/falco.yaml"
|
||||
#define FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml"
|
||||
#define FALCO_ENGINE_PLUGINS_DIR "${FALCO_ABSOLUTE_SHARE_DIR}/plugins/"
|
||||
|
||||
#define FALCOSECURITY_LIBS_VERSION "${FALCOSECURITY_LIBS_VERSION}"
|
||||
|
||||
#define DRIVER_NAME "@DRIVER_NAME@"
|
||||
#define DRIVER_VERSION "@DRIVER_VERSION@"
|
||||
#define DRIVER_VERSION "@DRIVER_VERSION@"
|
||||
|
||||
@@ -183,6 +183,12 @@ void falco_configuration::init(string conf_filename, const vector<string> &cmdli
|
||||
|
||||
falco_logger::set_level(m_log_level);
|
||||
|
||||
|
||||
falco_logger::set_sinsp_logging(
|
||||
m_config->get_scalar<bool>("libs_logger.enabled", false),
|
||||
m_config->get_scalar<std::string>("libs_logger.severity", "debug"),
|
||||
"[libs]: ");
|
||||
|
||||
m_output_timeout = m_config->get_scalar<uint32_t>("output_timeout", 2000);
|
||||
|
||||
m_notifications_rate = m_config->get_scalar<uint32_t>("outputs.rate", 1);
|
||||
|
||||
@@ -373,29 +373,28 @@ namespace YAML {
|
||||
rhs.m_library_path = string(FALCO_ENGINE_PLUGINS_DIR) + rhs.m_library_path;
|
||||
}
|
||||
|
||||
if(!node["init_config"])
|
||||
if(node["init_config"] && !node["init_config"].IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// By convention, if the init config is a YAML map we convert it
|
||||
// in a JSON object string. This is useful for plugins implementing
|
||||
// the `get_init_schema` API symbol, which right now support the
|
||||
// JSON Schema specific. If we ever support other schema/data types,
|
||||
// we may want to bundle the conversion logic in an ad-hoc class.
|
||||
// The benefit of this is being able of parsing/editing the config as
|
||||
// a YAML map instead of having an opaque string.
|
||||
if (node["init_config"].IsMap())
|
||||
{
|
||||
nlohmann::json json;
|
||||
YAML::convert<nlohmann::json>::decode(node["init_config"], json);
|
||||
rhs.m_init_config = json.dump();
|
||||
}
|
||||
else
|
||||
{
|
||||
rhs.m_init_config = node["init_config"].as<std::string>();
|
||||
// By convention, if the init config is a YAML map we convert it
|
||||
// in a JSON object string. This is useful for plugins implementing
|
||||
// the `get_init_schema` API symbol, which right now support the
|
||||
// JSON Schema specific. If we ever support other schema/data types,
|
||||
// we may want to bundle the conversion logic in an ad-hoc class.
|
||||
// The benefit of this is being able of parsing/editing the config as
|
||||
// a YAML map instead of having an opaque string.
|
||||
if (node["init_config"].IsMap())
|
||||
{
|
||||
nlohmann::json json;
|
||||
YAML::convert<nlohmann::json>::decode(node["init_config"], json);
|
||||
rhs.m_init_config = json.dump();
|
||||
}
|
||||
else
|
||||
{
|
||||
rhs.m_init_config = node["init_config"].as<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
if(node["open_params"])
|
||||
if(node["open_params"] && !node["open_params"].IsNull())
|
||||
{
|
||||
rhs.m_open_params = node["open_params"].as<std::string>();
|
||||
}
|
||||
|
||||
@@ -73,6 +73,18 @@ bool syscall_evt_drop_mgr::process_event(std::shared_ptr<sinsp> inspector, sinsp
|
||||
delta.n_evts = stats.n_evts - m_last_stats.n_evts;
|
||||
delta.n_drops = stats.n_drops - m_last_stats.n_drops;
|
||||
delta.n_drops_buffer = stats.n_drops_buffer - m_last_stats.n_drops_buffer;
|
||||
delta.n_drops_buffer_clone_fork_enter = stats.n_drops_buffer_clone_fork_enter - m_last_stats.n_drops_buffer_clone_fork_enter;
|
||||
delta.n_drops_buffer_clone_fork_exit = stats.n_drops_buffer_clone_fork_exit - m_last_stats.n_drops_buffer_clone_fork_exit;
|
||||
delta.n_drops_buffer_execve_enter = stats.n_drops_buffer_execve_enter - m_last_stats.n_drops_buffer_execve_enter;
|
||||
delta.n_drops_buffer_execve_exit = stats.n_drops_buffer_execve_exit - m_last_stats.n_drops_buffer_execve_exit;
|
||||
delta.n_drops_buffer_connect_enter = stats.n_drops_buffer_connect_enter - m_last_stats.n_drops_buffer_connect_enter;
|
||||
delta.n_drops_buffer_connect_exit = stats.n_drops_buffer_connect_exit - m_last_stats.n_drops_buffer_connect_exit;
|
||||
delta.n_drops_buffer_open_enter = stats.n_drops_buffer_open_enter - m_last_stats.n_drops_buffer_open_enter;
|
||||
delta.n_drops_buffer_open_exit = stats.n_drops_buffer_open_exit - m_last_stats.n_drops_buffer_open_exit;
|
||||
delta.n_drops_buffer_dir_file_enter = stats.n_drops_buffer_dir_file_enter - m_last_stats.n_drops_buffer_dir_file_enter;
|
||||
delta.n_drops_buffer_dir_file_exit = stats.n_drops_buffer_dir_file_exit - m_last_stats.n_drops_buffer_dir_file_exit;
|
||||
delta.n_drops_buffer_other_interest_enter = stats.n_drops_buffer_other_interest_enter - m_last_stats.n_drops_buffer_other_interest_enter;
|
||||
delta.n_drops_buffer_other_interest_exit = stats.n_drops_buffer_other_interest_exit - m_last_stats.n_drops_buffer_other_interest_exit;
|
||||
delta.n_drops_scratch_map = stats.n_drops_scratch_map - m_last_stats.n_drops_scratch_map;
|
||||
delta.n_drops_pf = stats.n_drops_pf - m_last_stats.n_drops_pf;
|
||||
delta.n_drops_bug = stats.n_drops_bug - m_last_stats.n_drops_bug;
|
||||
@@ -91,8 +103,8 @@ bool syscall_evt_drop_mgr::process_event(std::shared_ptr<sinsp> inspector, sinsp
|
||||
if(delta.n_drops > 0)
|
||||
{
|
||||
double ratio = delta.n_drops;
|
||||
// Assuming the number of event does not contains the dropped ones
|
||||
ratio /= delta.n_drops + delta.n_evts;
|
||||
// The `n_evts` always contains the `n_drops`.
|
||||
ratio /= delta.n_evts;
|
||||
|
||||
// When simulating drops the threshold is always zero
|
||||
if(ratio > m_threshold)
|
||||
@@ -146,12 +158,35 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now, scap_stats &delta, bool
|
||||
case syscall_evt_drop_action::ALERT:
|
||||
{
|
||||
std::map<std::string, std::string> output_fields;
|
||||
output_fields["n_evts"] = std::to_string(delta.n_evts);
|
||||
output_fields["n_drops"] = std::to_string(delta.n_drops);
|
||||
output_fields["n_drops_buffer"] = std::to_string(delta.n_drops_buffer);
|
||||
output_fields["n_drops_scratch_map"] = std::to_string(delta.n_drops_scratch_map);
|
||||
output_fields["n_drops_pf"] = std::to_string(delta.n_drops_pf);
|
||||
output_fields["n_drops_bug"] = std::to_string(delta.n_drops_bug);
|
||||
output_fields["n_evts"] = std::to_string(delta.n_evts); /* Total number of kernel side events actively traced (not including events discarded due to simple consumer mode in eBPF case). */
|
||||
output_fields["n_drops"] = std::to_string(delta.n_drops); /* Number of all kernel side event drops out of n_evts. */
|
||||
output_fields["n_drops_buffer_total"] = std::to_string(delta.n_drops_buffer); /* Total number of kernel side drops due to full buffer, includes all categories below, likely higher than sum of syscall categories. */
|
||||
/* Kernel side drops due to full buffer for categories of system calls. Not all system calls of interest are mapped into one of the categories.
|
||||
* Insights:
|
||||
* (1) Identify statistical properties of workloads (e.g. ratios between categories).
|
||||
* (2) Data-driven optimization opportunity for kernel side filtering and prioritization.
|
||||
* (3) Response: Coarse grained insights into syscalls dropped.
|
||||
* (4) Bonus: Cost associated with syscall category (typically `open` system call category is highest by orders of magnitude).
|
||||
*/
|
||||
output_fields["n_drops_buffer_clone_fork_enter"] = std::to_string(delta.n_drops_buffer_clone_fork_enter);
|
||||
output_fields["n_drops_buffer_clone_fork_exit"] = std::to_string(delta.n_drops_buffer_clone_fork_exit);
|
||||
output_fields["n_drops_buffer_execve_enter"] = std::to_string(delta.n_drops_buffer_execve_enter);
|
||||
output_fields["n_drops_buffer_execve_exit"] = std::to_string(delta.n_drops_buffer_execve_exit);
|
||||
output_fields["n_drops_buffer_connect_enter"] = std::to_string(delta.n_drops_buffer_connect_enter);
|
||||
output_fields["n_drops_buffer_connect_exit"] = std::to_string(delta.n_drops_buffer_connect_exit);
|
||||
output_fields["n_drops_buffer_open_enter"] = std::to_string(delta.n_drops_buffer_open_enter);
|
||||
output_fields["n_drops_buffer_open_exit"] = std::to_string(delta.n_drops_buffer_open_exit);
|
||||
output_fields["n_drops_buffer_dir_file_enter"] = std::to_string(delta.n_drops_buffer_dir_file_enter);
|
||||
output_fields["n_drops_buffer_dir_file_exit"] = std::to_string(delta.n_drops_buffer_dir_file_exit);
|
||||
/* `n_drops_buffer_other_interest_*` Category consisting of other system calls of interest,
|
||||
* not all other system calls that did not match a category from above.
|
||||
* Ideal for a custom category if needed - simply patch switch statement in kernel driver code (`falcosecurity/libs` repo).
|
||||
*/
|
||||
output_fields["n_drops_buffer_other_interest_enter"] = std::to_string(delta.n_drops_buffer_other_interest_enter);
|
||||
output_fields["n_drops_buffer_other_interest_exit"] = std::to_string(delta.n_drops_buffer_other_interest_exit);
|
||||
output_fields["n_drops_scratch_map"] = std::to_string(delta.n_drops_scratch_map); /* Number of kernel side scratch map drops. */
|
||||
output_fields["n_drops_page_faults"] = std::to_string(delta.n_drops_pf); /* Number of kernel side page faults drops (invalid memory access). */
|
||||
output_fields["n_drops_bug"] = std::to_string(delta.n_drops_bug); /* Number of kernel side bug drops (invalid condition in the kernel instrumentation). */
|
||||
output_fields["ebpf_enabled"] = std::to_string(bpf_enabled);
|
||||
m_outputs->handle_msg(now, falco_common::PRIORITY_DEBUG, msg, rule, output_fields);
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,43 @@ limitations under the License.
|
||||
int falco_logger::level = LOG_INFO;
|
||||
bool falco_logger::time_format_iso_8601 = false;
|
||||
|
||||
static sinsp_logger::severity decode_sinsp_severity(const string& s)
|
||||
{
|
||||
if(s == "trace")
|
||||
{
|
||||
return sinsp_logger::SEV_TRACE;
|
||||
}
|
||||
else if(s == "debug")
|
||||
{
|
||||
return sinsp_logger::SEV_DEBUG;
|
||||
}
|
||||
else if(s == "info")
|
||||
{
|
||||
return sinsp_logger::SEV_INFO;
|
||||
}
|
||||
else if(s == "notice")
|
||||
{
|
||||
return sinsp_logger::SEV_NOTICE;
|
||||
}
|
||||
else if(s == "warning")
|
||||
{
|
||||
return sinsp_logger::SEV_WARNING;
|
||||
}
|
||||
else if(s == "error")
|
||||
{
|
||||
return sinsp_logger::SEV_ERROR;
|
||||
}
|
||||
else if(s == "critical")
|
||||
{
|
||||
return sinsp_logger::SEV_CRITICAL;
|
||||
}
|
||||
else if(s == "fatal")
|
||||
{
|
||||
return sinsp_logger::SEV_FATAL;
|
||||
}
|
||||
throw falco_exception("Unknown sinsp log severity " + s);
|
||||
}
|
||||
|
||||
void falco_logger::set_time_format_iso_8601(bool val)
|
||||
{
|
||||
falco_logger::time_format_iso_8601 = val;
|
||||
@@ -68,6 +105,31 @@ void falco_logger::set_level(string &level)
|
||||
}
|
||||
}
|
||||
|
||||
static std::string s_sinsp_logger_prefix = "";
|
||||
|
||||
void falco_logger::set_sinsp_logging(bool enable, const std::string& severity, const std::string& prefix)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
s_sinsp_logger_prefix = prefix;
|
||||
g_logger.set_severity(decode_sinsp_severity(severity));
|
||||
g_logger.disable_timestamps();
|
||||
g_logger.add_callback_log(
|
||||
[](std::string&& str, const sinsp_logger::severity sev)
|
||||
{
|
||||
// note: using falco_logger::level ensures that the sinsp
|
||||
// logs are always printed by the Falco logger. These
|
||||
// logs are pre-filtered at the sinsp level depending
|
||||
// on the configured severity
|
||||
falco_logger::log(falco_logger::level, s_sinsp_logger_prefix + str);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
g_logger.remove_callback_log();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool falco_logger::log_stderr = true;
|
||||
bool falco_logger::log_syslog = true;
|
||||
|
||||
@@ -28,6 +28,8 @@ class falco_logger
|
||||
// Will throw exception if level is unknown.
|
||||
static void set_level(string &level);
|
||||
|
||||
static void set_sinsp_logging(bool enable, const std::string& severity, const std::string& prefix);
|
||||
|
||||
static void log(int priority, const string msg);
|
||||
|
||||
static int level;
|
||||
|
||||
@@ -16,9 +16,11 @@ limitations under the License.
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "statsfilewriter.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
#include "logger.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -28,8 +30,6 @@ static void timer_handler (int signum)
|
||||
g_save_stats = true;
|
||||
}
|
||||
|
||||
extern char **environ;
|
||||
|
||||
StatsFileWriter::StatsFileWriter()
|
||||
: m_num_stats(0)
|
||||
{
|
||||
@@ -67,30 +67,6 @@ bool StatsFileWriter::init(std::shared_ptr<sinsp> inspector, string &filename, u
|
||||
return false;
|
||||
}
|
||||
|
||||
// (Undocumented) feature. Take any environment keys prefixed
|
||||
// with FALCO_STATS_EXTRA_XXX and add them to the output. Used by
|
||||
// run_performance_tests.sh.
|
||||
for(uint32_t i=0; environ[i]; i++)
|
||||
{
|
||||
char *p = strstr(environ[i], "=");
|
||||
if(!p)
|
||||
{
|
||||
errstr = string("Could not find environment separator in ") + string(environ[i]);
|
||||
return false;
|
||||
}
|
||||
string key(environ[i], p-environ[i]);
|
||||
string val(p+1, strlen(environ[i])-(p-environ[i])-1);
|
||||
if(key.compare(0, 18, "FALCO_STATS_EXTRA_") == 0)
|
||||
{
|
||||
string sub = key.substr(18);
|
||||
if (m_extra != "")
|
||||
{
|
||||
m_extra += ", ";
|
||||
}
|
||||
m_extra += "\"" + sub + "\": " + "\"" + val + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,6 +76,7 @@ void StatsFileWriter::handle()
|
||||
{
|
||||
scap_stats cstats;
|
||||
scap_stats delta;
|
||||
nlohmann::json jmsg;
|
||||
|
||||
g_save_stats = false;
|
||||
m_num_stats++;
|
||||
@@ -116,21 +93,23 @@ void StatsFileWriter::handle()
|
||||
delta.n_preemptions = cstats.n_preemptions - m_last_stats.n_preemptions;
|
||||
}
|
||||
|
||||
m_output << "{\"sample\": " << m_num_stats;
|
||||
if(m_extra != "")
|
||||
try
|
||||
{
|
||||
m_output << ", " << m_extra;
|
||||
jmsg["sample"] = m_num_stats;
|
||||
jmsg["cur"]["events"] = cstats.n_evts;
|
||||
jmsg["cur"]["drops"] = cstats.n_drops;
|
||||
jmsg["cur"]["preemptions"] = cstats.n_preemptions;
|
||||
jmsg["cur"]["drop_pct"] = (cstats.n_evts == 0 ? 0 : (100.0*cstats.n_drops/cstats.n_evts));
|
||||
jmsg["delta"]["events"] = delta.n_evts;
|
||||
jmsg["delta"]["drops"] = delta.n_drops;
|
||||
jmsg["delta"]["preemptions"] = delta.n_preemptions;
|
||||
jmsg["delta"]["drop_pct"] = (delta.n_evts == 0 ? 0 : (100.0*delta.n_drops/delta.n_evts));
|
||||
m_output << jmsg.dump() << endl;
|
||||
}
|
||||
catch(const exception &e)
|
||||
{
|
||||
falco_logger::log(LOG_ERR, "StatsFileWriter (handle): " + string(e.what()) + "\n");
|
||||
}
|
||||
m_output << ", \"cur\": {" <<
|
||||
"\"events\": " << cstats.n_evts <<
|
||||
", \"drops\": " << cstats.n_drops <<
|
||||
", \"preemptions\": " << cstats.n_preemptions <<
|
||||
"}, \"delta\": {" <<
|
||||
"\"events\": " << delta.n_evts <<
|
||||
", \"drops\": " << delta.n_drops <<
|
||||
", \"preemptions\": " << delta.n_preemptions <<
|
||||
"}, \"drop_pct\": " << (delta.n_evts == 0 ? 0 : (100.0*delta.n_drops/delta.n_evts)) <<
|
||||
"}," << endl;
|
||||
|
||||
m_last_stats = cstats;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,5 @@ protected:
|
||||
uint32_t m_num_stats;
|
||||
std::shared_ptr<sinsp> m_inspector;
|
||||
std::ofstream m_output;
|
||||
std::string m_extra;
|
||||
scap_stats m_last_stats;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user