Compare commits

..

18 Commits

Author SHA1 Message Date
Mark Stemm
94df00e512 Merge branch 'dev' 2018-01-18 09:07:00 -08:00
Mark Stemm
070a67d069 Use http dependencies (#317)
Some versions of cmake include a libcurl that don't have ssl support,
and verifying the md5sums should be enough.
2018-01-18 09:04:08 -08:00
Mark Stemm
3ee76637f4 Merge branch 'dev' 2018-01-17 20:30:28 -08:00
Mark Stemm
1feae90c74 Rule updates vdec2 (#315)
* Additional rpm writers, root directories

salt-minion can also touch the rpm database, and some node packages
write below /root/.config/configstore.

* Add smbd as a protected shell spawner.

It's a server-like program.

* Also handle .ash_history

default shell for alpine linux

* Add exceptions for veritas

Let many veritas programs write below /etc/vx.

Let one veritas-related perl script read sensitive files.

* Allow postgres to run wal-e

https://github.com/wal-e/wal-e, archiving program for postgres.

* Let consul (agent) run addl scripts

Also let consul (agent, but the distinction is in the command line args)
to run nc in addition to curl. Also rename the macro.

* Let postgres setuid to itself

Let postgres setuid to itself. Seen by archiving programs like wal-e.

* Also allow consul to run alert check scripts

"sh -c /bin/consul-alerts watch checks --alert-addr 0.0.0.0:9000 ..."

* Add additional privileged containers.

Openshift's logging support containers generally run privileged.

* Let addl progs write below /etc/lvm

Add lvcreate as a program that can write below /etc/lvm and rename the
macro to lvprogs_writing_lvm_archive.

* Let glide write below root

https://glide.sh/, package management for go.

* Let sosreport read sensitive files.

* Let scom server read sensitive files.

Microsoft System Center Operations Manager (SCOM).

* Let kube-router run privileged.

https://github.com/cloudnativelabs/kube-router

* Let needrestart_binaries spawns shells

Was included in prior version of shell rules, adding back.

* Let splunk spawn shells below /opt/splunkforwarder

* Add yum-cron as a rpm binary

* Add a different way to run denyhosts.

Strange that the program is denyhosts.py but observed in actual
environments.

* Let nrpe setuid to nagios.

* Also let postgres run wal-e wrt shells

Previously added as an exception for db program spawned process, need to
add as an exception for run shell untrusted.

* Remove installer shell-related rules

They aren't used that often and removing them cleans up space for new
rules we want to add soon.
2018-01-17 20:29:45 -08:00
Mark Stemm
8aeef034a6 Remove installer-related traces
We removed the installer-related rules, so remove the installer-related
traces as well.
2018-01-17 17:40:38 -08:00
Mark Stemm
c7bcc2dce0 Addl CHANGELOG changes for 0.9.0 2018-01-17 17:00:42 -08:00
Mark Stemm
3e2f9f63d3 Update changelog/README for 0.9.0 (#316) 2018-01-17 16:58:44 -08:00
Michael Ducy
cef147708a Update K8S Daemon Set for RBAC & ConfigMap (#309)
* Update K8S Daemon Set for RBAC & ConfigMap

* Fix typo in command
2017-12-20 22:58:20 -05:00
Mark Stemm
db0d913acc Rule updates vdec (#307)
* Let kubelet running loopback spawn shells

Seen by @JPLachance, thanks for the heads up!

* Let docker's "exe" broadly write to files.

As a part of some docker commands like "docker save", etc, the program
exe can write from files on the host filesystem /var/lib/docker/... to a
variety of files within the container.

Allow this via a macro exe_running_docker_save that checks the
commandline as well as the parent and use it as an exclusion for the
write below binary dir/root/etc rules.

* Let chef perform more tasks

- Let chef-client generally read sensitive files and write below /etc.
- Let python running a chef script yum-dump.py write the rpm database.
2017-12-11 22:34:50 -08:00
Mark Stemm
af564f17a6 Add ability to override shell spawning binaries (#304)
Rename user_known_container_shell_spawn_binaries to
user_known_shell_spawn_binaries (the container distinction doesn't exist
any longer) and add it as an exception for run shell untrusted.

That way others can easily exclude shell spawning programs in a second
rules file.
2017-12-01 12:30:04 -08:00
Mark Stemm
d6d975e28c Refactor shell rules (#301)
* Refactor shell rules to avoid FPs.

Refactoring the shell related rules to avoid FPs. Instead of considering
all shells suspicious and trying to carve out exceptions for the
legitimate uses of shells, only consider shells spawned below certain
processes suspicious.

The set of processes is a collection of commonly used web servers,
databases, nosql document stores, mail programs, message queues, process
monitors, application servers, etc.

Also, runsv is also considered a top level process that denotes a
service. This allows a way for more flexible servers like ad-hoc nodejs
express apps, etc to denote themselves as a full server process.

* Update event generator to reflect new shell rules

spawn_shell is now a silent action. its replacement is
spawn_shell_under_httpd, which respawns itself as httpd and then runs a
shell.

db_program_spawn_binaries now runs ls instead of a shell so it only
matches db_program_spawn_process.

* Comment out old shell related rules

* Modify nodejs example to work w/ new shell rules

Start the express server using runit's runsv, which allows falco to
consider any shells run by it as suspicious.

* Use the updated argument for mkdir

In https://github.com/draios/sysdig/pull/757 the path argument for mkdir
moved to the second argument. This only became visible in the unit tests
once the trace files were updated to reflect the other shell rule
changes--the trace files had the old format.

* Update unit tests for shell rules changes

Shell in container doesn't exist any longer and its functionality has
been subsumed by run shell untrusted.

* Allow git binaries to run shells

In some cases, these are run below a service runsv so we still need
exceptions for them.

* Let consul agent spawn curl for health checks

* Don't protect tomcat

There's enough evidence of people spawning general commands that we
can't protect it.

* Reorder exceptions, add rabbitmq exception

Move the nginx exception to the main rule instead of the
protected_shell_spawner macro. Also add erl_child_setup (related to
rabbitmq) as an allowed shell spawner.

* Add additional spawn binaries

All off these are either below nginx, httpd, or runsv but should still
be allowed to spawn shells.

* Exclude shells when ancestor is a pkg mgmt binary

Skip shells when any process ancestor (parent, gparent, etc) is a
package management binary. This includes the program needrestart. This
is a deep search but should prevent a lot of other more detailed
exceptions trying to find the specific scripts run as a part of
installations.

* Skip shells related to serf

Serf is a service discovery tool and can in some cases be spawned by
apache/nginx. Also allow shells that are just checking the status of
pids via kill -0.

* Add several exclusions back

Add several exclusions back from the shell in container rule. These are
all allowed shell spawns that happen to be below
nginx/fluentd/apache/etc.

* Remove commented-out rules

This saves space as well as cleanup. I haven't yet removed the
macros/lists used by these rules and not used anywhere else. I'll do
that cleanup in a separate step.

* Also exclude based on command lines

Add back the exclusions based on command lines, using the existing set
of command lines.

* Add addl exclusions for shells

Of note is runsv, which means it can directly run shells (the ./run and
./finish scripts), but the things it runs can not.

* Don't trigger on shells spawning shells

We'll detect the first shell and not any other shells it spawns.

* Allow "runc:" parents to count as a cont entrypnt

In some cases, the initial process for a container can have a parent
"runc:[0:PARENT]", so also allow those cases to count as a container
entrypoint.

* Use container_entrypoint macro

Use the container_entrypoint macro to denote entering a container and
also allow exe to be one of the processes that's the parent of an
entrypoint.
2017-11-28 07:04:37 -08:00
Mark Stemm
60af4166de Rule updates vnov (#300)
* Let supervisor write more generally below /etc

* Let perl+plesk scripts run shells/write below etc

* Allow spaces after some cmdlines

* Add additional shell spawner.

* Add addl package mgmt binaries.

* Add addl cases for java + jenkins

Addl jar files to consider.

* Add addl jenkins-related cmdlines

Mostly related to node scripts run by jenkins

* Let python running some mesos tasks spawn shells

In this case marathon run by python

* Let ucf write below etc

Only below /etc/gconf for now.

* Let dpkg-reconfigur indirectly write below /etc

It may run programs that modify files below /etc

* Add files/dirs/prefixes for writes below root

Build a set of acceptable files/dirs/prefixes for writes below
/root. Mostly triggered by apps that run directly as root.

* Add addl shell spawn binaries.

* Also let java + sbt spawn shells in containers

Not seen only at host level

* Make sure the file below etc is /etc/

Make sure the file below /etc is really below the directory etc aka
/etc/xxx. Otherwise it would match a file /etcfoo.

* Let rancher healthcheck spawn shells

The name healthcheck is relatively innocuous so also look at the parent
process.

* Add addl shell container shell spawn binaries

* Add addl x2go binaries

* Let rabbitq write its config files

* Let rook write below /etc

toolbox.sh is fairly generic so add a condition based on the image name.

* Let consul-template spawn shells

* Add rook/toolbox as a trusted container

Their github pages recommend running privileged.

* Add addl mail binary that can setuid

* Let plesk autoinstaller spawn shells

The name autoinstaller is fairly generic so also look at the parent.

* Let php handlers write its config

* Let addl pkg-* binary write to /etc indirectly

* Add additional shell spawning binaries.

* Add ability to specify user trusted containers

New macro user_trusted_containers allows a user-provided set of
containers that are trusted and are allowed to run privileged.

* If npm runs node, let node spawn shells

* Let python run airflow via a shell.

* Add addl passenger commandlines (for shells)

* Add addl ways datadog can be run

* Let find run shells in containers.

* Add rpmq as a rpm binary

* Let httpd write below /etc/httpd/

* Let awstats/sa-update spawn shells

* Add container entrypoint as a shell

Some images have an extra shell level for image entrypoints.

* Add an additional jenkins commandline

* Let mysql write its config

* Let openvpn write its config

* Add addl root dirs/files

Also move /root/.java to be a general prefix.

* Let mysql_upgrade/opkg-cl spawn shells

* Allow login to perform dns lookups

With run with -h <host> to specify a remote host, some versions of login
will do a dns lookup to try to resolve the host.

* Let consul-template write haproxy config.

* Also let mysql indirectly edit its config

It might spawn a program to edit the config in addition to directly.

* Allow certain sed temp files below /etc/

* Allow debian binaries to indirectly write to /etc

They may spawn programs like sed, touch, etc to change files below /etc.

* Add additional root file

* Let rancher healthcheck be run more indirectly

The grandparent as well as parent of healthcheck can be tini.

* Add more cases for haproxy writing config

Allow more files as well as more scripts to update the config.

* Let vmtoolsd spawn shells on the host

* Add an additional innocuous entrypoint shell

* Let peer-finder (mongodb) spawn shells

* Split application rules to separate file.

Move the contents of application rules, which have never been enabled by
default, to a separate file. It's only installed in the mail falco packages.

* Add more build-related command lines

* Let perl running openresty spawn shells

* Let countly write nginx config

* Let confd spawn shells

* Also let aws spawn shells in containers.
2017-11-16 12:12:31 -08:00
Mark Stemm
e8aee19f6c Merge remote-tracking branch 'origin/dev', 0.8.1 2017-10-10 10:49:27 -07:00
Mark Stemm
74556e5f6e Merge branch 'dev' 2017-10-09 17:17:12 -07:00
Mark Stemm
809d20c294 Merge pull request #246 from draios/dev
Merging for 0.7.0
2017-05-30 13:30:39 -07:00
Mark Stemm
b0ae29c23a Merge branch 'dev' 2017-05-15 11:12:11 -07:00
Mark Stemm
d1b6b2be87 Merge pull request #229 from draios/dev
Merging for 0.6.0
2017-03-29 16:00:06 -07:00
Mark Stemm
e00181d553 Merge pull request #174 from draios/dev
Merging for 0.5.0
2016-12-22 13:25:32 -08:00
16 changed files with 729 additions and 466 deletions

View File

@@ -2,6 +2,24 @@
This file documents all notable changes to Falco. The release numbering uses [semantic versioning](http://semver.org).
## v0.9.0
Released 2018-01-18
### Bug Fixes
* Fix driver incompatibility problems with some linux kernel versions that can disable pagefault tracepoints [[#sysdig/1034](https://github.com/draios/sysdig/pull/1034)]
* Fix OSX Build incompatibility with latest version of libcurl [[#291](https://github.com/draios/falco/pull/291)]
### Minor Changes
* Updated the Kubernetes example to provide an additional example: Daemon Set using RBAC and a ConfigMap for configuration. Also expanded the documentation for both the RBAC and non-RBAC examples. [[#309](https://github.com/draios/falco/pull/309)]
### Rule Changes
* Refactor the shell-related rules to reduce false positives. These changes significantly decrease the scope of the rules so they trigger only for shells spawned below specific processes instead of anywhere. [[#301](https://github.com/draios/falco/pull/301)] [[#304](https://github.com/draios/falco/pull/304)]
* Lots of rule changes based on feedback from Sysdig Secure community [[#293](https://github.com/draios/falco/pull/293)] [[#298](https://github.com/draios/falco/pull/298)] [[#300](https://github.com/draios/falco/pull/300)] [[#307](https://github.com/draios/falco/pull/307)] [[#315](https://github.com/draios/falco/pull/315)]
## v0.8.1
Released 2017-10-10

View File

@@ -78,7 +78,7 @@ else()
set(ZLIB_INCLUDE "${ZLIB_SRC}")
set(ZLIB_LIB "${ZLIB_SRC}/libz.a")
ExternalProject_Add(zlib
URL "https://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.8.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/zlib-1.2.8.tar.gz"
URL_MD5 "44d667c142d7cda120332623eab69f40"
CONFIGURE_COMMAND "./configure"
BUILD_COMMAND ${CMD_MAKE}
@@ -104,7 +104,7 @@ else()
set(JQ_INCLUDE "${JQ_SRC}")
set(JQ_LIB "${JQ_SRC}/.libs/libjq.a")
ExternalProject_Add(jq
URL "https://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/jq-1.5.tar.gz"
URL_MD5 "0933532b086bd8b6a41c1b162b1731f9"
CONFIGURE_COMMAND ./configure --disable-maintainer-mode --enable-all-static --disable-dependency-tracking
BUILD_COMMAND ${CMD_MAKE} LDFLAGS=-all-static
@@ -134,7 +134,7 @@ else()
set(CURSES_LIBRARIES "${CURSES_BUNDLE_DIR}/lib/libncurses.a")
message(STATUS "Using bundled ncurses in '${CURSES_BUNDLE_DIR}'")
ExternalProject_Add(ncurses
URL "https://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/ncurses-6.0-20150725.tgz"
URL_MD5 "32b8913312e738d707ae68da439ca1f4"
CONFIGURE_COMMAND ./configure --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo
BUILD_COMMAND ${CMD_MAKE}
@@ -161,7 +161,7 @@ else()
set(B64_INCLUDE "${B64_SRC}/include")
set(B64_LIB "${B64_SRC}/src/libb64.a")
ExternalProject_Add(b64
URL "https://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/libb64-1.2.src.zip"
URL_MD5 "a609809408327117e2c643bed91b76c5"
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMD_MAKE}
@@ -215,7 +215,7 @@ else()
message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'")
ExternalProject_Add(openssl
URL "https://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2j.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/openssl-1.0.2j.tar.gz"
URL_MD5 "96322138f0b69e61b7212bc53d5e912b"
CONFIGURE_COMMAND ./config shared --prefix=${OPENSSL_INSTALL_DIR}
BUILD_COMMAND ${CMD_MAKE}
@@ -246,7 +246,7 @@ else()
ExternalProject_Add(curl
DEPENDS openssl
URL "https://s3.amazonaws.com/download.draios.com/dependencies/curl-7.56.0.tar.bz2"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/curl-7.56.0.tar.bz2"
URL_MD5 "e0caf257103e0c77cee5be7e9ac66ca4"
CONFIGURE_COMMAND ./configure ${CURL_SSL_OPTION} --disable-shared --enable-optimize --disable-curldebug --disable-rt --enable-http --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp --without-winssl --without-darwinssl --without-polarssl --without-cyassl --without-nss --without-axtls --without-ca-path --without-ca-bundle --without-libmetalink --without-librtmp --without-winidn --without-libidn --without-nghttp2 --without-libssh2 --disable-threaded-resolver
BUILD_COMMAND ${CMD_MAKE}
@@ -280,7 +280,7 @@ else()
set(LUAJIT_INCLUDE "${LUAJIT_SRC}")
set(LUAJIT_LIB "${LUAJIT_SRC}/libluajit.a")
ExternalProject_Add(luajit
URL "https://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/LuaJIT-2.0.3.tar.gz"
URL_MD5 "f14e9104be513913810cd59c8c658dc0"
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMD_MAKE}
@@ -310,7 +310,7 @@ else()
endif()
ExternalProject_Add(lpeg
DEPENDS ${LPEG_DEPENDENCIES}
URL "https://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/lpeg-1.0.0.tar.gz"
URL_MD5 "0aec64ccd13996202ad0c099e2877ece"
BUILD_COMMAND LUA_INCLUDE=${LUAJIT_INCLUDE} "${PROJECT_SOURCE_DIR}/scripts/build-lpeg.sh" "${LPEG_SRC}/build"
BUILD_IN_SOURCE 1
@@ -345,7 +345,7 @@ else()
set(LIBYAML_LIB "${LIBYAML_SRC}/.libs/libyaml.a")
message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'")
ExternalProject_Add(libyaml
URL "https://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/libyaml-0.1.4.tar.gz"
URL_MD5 "4a4bced818da0b9ae7fc8ebc690792a7"
BUILD_COMMAND ${CMD_MAKE}
BUILD_IN_SOURCE 1
@@ -381,7 +381,7 @@ else()
endif()
ExternalProject_Add(lyaml
DEPENDS ${LYAML_DEPENDENCIES}
URL "https://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz"
URL "http://s3.amazonaws.com/download.draios.com/dependencies/lyaml-release-v6.0.tar.gz"
URL_MD5 "dc3494689a0dce7cf44e7a99c72b1f30"
BUILD_COMMAND ${CMD_MAKE}
BUILD_IN_SOURCE 1

View File

@@ -2,7 +2,7 @@
#### Latest release
**v0.8.1**
**v0.9.0**
Read the [change log](https://github.com/draios/falco/blob/dev/CHANGELOG.md)
Dev Branch: [![Build Status](https://travis-ci.org/draios/falco.svg?branch=dev)](https://travis-ci.org/draios/falco)<br />

View File

@@ -1,3 +1,4 @@
/etc/falco/falco.yaml
/etc/falco/falco_rules.yaml
/etc/falco/application_rules.yaml
/etc/falco/falco_rules.local.yaml

View File

@@ -50,6 +50,8 @@ void usage(char *program)
printf(" then read a sensitive file\n");
printf(" write_rpm_database Write to files below /var/lib/rpm\n");
printf(" spawn_shell Run a shell (bash)\n");
printf(" Used by spawn_shell_under_httpd below\n");
printf(" spawn_shell_under_httpd Run a shell (bash) under a httpd process\n");
printf(" db_program_spawn_process As a database program, try to spawn\n");
printf(" another program\n");
printf(" modify_binary_dirs Modify a file below /bin\n");
@@ -64,7 +66,7 @@ void usage(char *program)
printf(" non_sudo_setuid Setuid as a non-root user\n");
printf(" create_files_below_dev Create files below /dev\n");
printf(" exec_ls execve() the program ls\n");
printf(" (used by user_mgmt_binaries below)\n");
printf(" (used by user_mgmt_binaries, db_program_spawn_process)\n");
printf(" user_mgmt_binaries Become the program \"vipw\", which triggers\n");
printf(" rules related to user management programs\n");
printf(" exfiltration Read /etc/shadow and send it via udp to a\n");
@@ -230,9 +232,14 @@ void spawn_shell() {
}
}
void spawn_shell_under_httpd() {
printf("Becoming the program \"httpd\" and then spawning a shell\n");
respawn("./httpd", "spawn_shell", "0");
}
void db_program_spawn_process() {
printf("Becoming the program \"mysql\" and then spawning a shell\n");
respawn("./mysqld", "spawn_shell", "0");
printf("Becoming the program \"mysql\" and then running ls\n");
respawn("./mysqld", "exec_ls", "0");
}
void modify_binary_dirs() {
@@ -360,6 +367,7 @@ map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
{"read_sensitive_file_after_startup", read_sensitive_file_after_startup},
{"write_rpm_database", write_rpm_database},
{"spawn_shell", spawn_shell},
{"spawn_shell_under_httpd", spawn_shell_under_httpd},
{"db_program_spawn_process", db_program_spawn_process},
{"modify_binary_dirs", modify_binary_dirs},
{"mkdir_binary_dirs", mkdir_binary_dirs},
@@ -375,7 +383,7 @@ map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
// Some actions don't directly result in suspicious behavior. These
// actions are excluded from the ones run with -a all.
set<string> exclude_from_all_actions = {"exec_ls", "network_activity"};
set<string> exclude_from_all_actions = {"spawn_shell", "exec_ls", "network_activity"};
void create_symlinks(const char *program)
{

View File

@@ -1,5 +1,92 @@
# Example K8s Services for Falco
# Example Kubernetes Daemon Sets for Sysdig Falco
The yaml file in this directory installs the following:
- Open Source Falco, as a DaemonSet. Falco is configured to communicate with the K8s API server via its service account, and changes its output to be K8s-friendly. It also sends to a slack webhook for the `#demo-falco-alerts` channel on our [public slack](https://sysdig.slack.com/messages/demo-falco-alerts/).
- The [Falco Event Generator](https://github.com/draios/falco/wiki/Generating-Sample-Events), as a deployment that ensures it runs on exactly 1 node.
This directory gives you the required YAML files to stand up Sysdig Falco on Kubernetes as a Daemon Set. This will result in a Falco Pod being deployed to each node, and thus the ability to monitor any running containers for abnormal behavior.
The two options are provided to deploy a Daemon Set:
- `k8s-with-rbac` - This directory provides a definition to deploy a Daemon Set on Kubernetes with RBAC enabled.
- `k8s-without-rbac` - This directory provides a definition to deploy a Daemon Set on Kubernetes without RBAC enabled.
Also provided:
- `falco-event-generator-deployment.yaml` - A Kubernetes Deployment to generate sample events. This is useful for testing, but note it will generate a large number of events.
## Deploying to Kubernetes with RBAC enabled
Since v1.8 RBAC has been available in Kubernetes, and running with RBAC enabled is considered the best practice. The `k8s-with-rbac` directory provides the YAML to create a Service Account for Falco, as well as the ClusterRoles and bindings to grant the appropriate permissions to the Service Account.
```
k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-account.yaml
serviceaccount "falco-account" created
clusterrole "falco-cluster-role" created
clusterrolebinding "falco-cluster-role-binding" created
k8s-using-daemonset$
```
The Daemon Set also relies on a Kubernetes ConfigMap to store the Falco configuration and make the configuration available to the Falco Pods. This allows you to manage custom configuration without rebuilding and redeploying the underlying Pods. In order to create the ConfigMap you'll need to first need to copy the required configuration from their location in this GitHub repo to the `k8s-with-rbac/falco-config/` directory. Any modification of the configuration should be performed on these copies rather than the original files.
```
k8s-using-daemonset$ cp ../../falco.yaml k8s-with-rbac/falco-config/
k8s-using-daemonset$ cp ../../rules/falco_rules.* k8s-with-rbac/falco-config/
```
If you want to send Falco alerts to a Slack channel, you'll want to modify the `falco.yaml` file to point to your Slack webhook. For more information on getting a webhook URL for your Slack team, refer to the [Slack documentation](https://api.slack.com/incoming-webhooks). Add the below to the bottom of the `falco.yaml` config file you just copied to enable Slack messages.
```
program_output:
enabled: true
keep_alive: false
program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/see_your_slack_team/apps_settings_for/a_webhook_url"
```
You will also need to enable JSON output. Find the `json_output: false` setting in the `falco.yaml` file and change it to read `json_output: true`. Any custom rules for your environment can be added to into the `falco_rules.local.yaml` file and they will be picked up by Falco at start time. You can now create the ConfigMap in Kubernetes.
```
k8s-using-daemonset$ kubectl create configmap falco-config --from-file=k8s-with-rbac/falco-config
configmap "falco-config" created
k8s-using-daemonset$
```
Now that we have the requirements for our Daemon Set in place, we can create our Daemon Set.
```
k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-daemonset-configmap.yaml
daemonset "falco" created
k8s-using-daemonset$
```
## Deploying to Kubernetes without RBAC enabled
If you are running Kubernetes with Legacy Authorization enabled, you can use `kubectl` to deploy the Daemon Set provided in the `k8s-without-rbac` directory. The example provides the ability to post messages to a Slack channel via a webhook. For more information on getting a webhook URL for your Slack team, refer to the [Slack documentation](https://api.slack.com/incoming-webhooks). Modify the [`args`](https://github.com/draios/falco/blob/dev/examples/k8s-using-daemonset/falco-daemonset.yaml#L21) passed to the Falco container to point to the appropriate URL for your webhook.
```
k8s-using-daemonset$ kubectl create -f k8s-without-rbac/falco-daemonset.yaml
```
## Verifying the installation
In order to test that Falco is working correctly, you can launch a shell in a Pod. You should see a message in your Slack channel (if configured), or in the logs of the Falco pod.
```
k8s-using-daemonset$ kubectl get pods
NAME READY STATUS RESTARTS AGE
falco-74htl 1/1 Running 0 13h
falco-fqz2m 1/1 Running 0 13h
falco-sgjfx 1/1 Running 0 13h
k8s-using-daemonset$ kubectl exec -it falco-74htl bash
root@falco-74htl:/# exit
k8s-using-daemonset$ kubectl logs falco-74htl
{"output":"17:48:58.590038385: Notice A shell was spawned in a container with an attached terminal (user=root k8s.pod=falco-74htl container=a98c2aa8e670 shell=bash parent=<NA> cmdline=bash terminal=34816)","priority":"Notice","rule":"Terminal shell in container","time":"2017-12-20T17:48:58.590038385Z", "output_fields": {"container.id":"a98c2aa8e670","evt.time":1513792138590038385,"k8s.pod.name":"falco-74htl","proc.cmdline":"bash ","proc.name":"bash","proc.pname":null,"proc.tty":34816,"user.name":"root"}}
k8s-using-daemonset$
```
Alternatively, you can deploy the [Falco Event Generator](https://github.com/draios/falco/wiki/Generating-Sample-Events) deployement to have events automatically generated. Please note that this Deployment will generate a large number of events.
```
k8s-using-daemonset$ kubectl create -f falco-event-generator-deployment.yaml \
&& sleep 1 \
&& kubectl delete -f falco-event-generator-deployment.yaml
deployment "falco-event-generator-deployment" created
deployment "falco-event-generator-deployment" deleted
k8s-using-daemonset$
```

View File

@@ -0,0 +1,29 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: falco-account
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: falco-cluster-role
rules:
- apiGroups: ["extensions",""]
resources: ["nodes","namespaces","pods","replicationcontrollers","services","events","configmaps"]
verbs: ["get","list","watch"]
- nonResourceURLs: ["/healthz", "/healthz/*"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: falco-cluster-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: falco-account
namespace: default
roleRef:
kind: ClusterRole
name: falco-cluster-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,65 @@
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: falco
labels:
name: falco-daemonset
app: demo
spec:
template:
metadata:
labels:
name: falco
app: demo
role: security
spec:
serviceAccount: falco-account
containers:
- name: falco
image: sysdig/falco:latest
securityContext:
privileged: true
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk"]
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket
readOnly: true
- mountPath: /host/dev
name: dev-fs
readOnly: true
- mountPath: /host/proc
name: proc-fs
readOnly: true
- mountPath: /host/boot
name: boot-fs
readOnly: true
- mountPath: /host/lib/modules
name: lib-modules
readOnly: true
- mountPath: /host/usr
name: usr-fs
readOnly: true
- mountPath: /etc/falco
name: falco-config
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
- name: dev-fs
hostPath:
path: /dev
- name: proc-fs
hostPath:
path: /proc
- name: boot-fs
hostPath:
path: /boot
- name: lib-modules
hostPath:
path: /lib/modules
- name: usr-fs
hostPath:
path: /usr
- name: falco-config
configMap:
name: falco-config

View File

@@ -18,7 +18,7 @@ spec:
image: sysdig/falco:latest
securityContext:
privileged: true
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk", "-o", "json_output=true", "-o", "program_output.enabled=true", "-o", "program_output.program=jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/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"]
args: [ "/usr/bin/falco", "-K", "/var/run/secrets/kubernetes.io/serviceaccount/token", "-k", "https://kubernetes", "-pk", "-o", "json_output=true", "-o", "program_output.enabled=true", "-o", "program_output.program=jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/see_your_slack_team/apps_settings_for/a_webhook_url"]
volumeMounts:
- mountPath: /host/var/run/docker.sock
name: docker-socket

View File

@@ -1,9 +1,7 @@
# Owned by software vendor, serving install-software.sh.
express_server:
container_name: express_server
image: node:latest
working_dir: /usr/src/app
command: bash -c "npm install && node server.js"
command: bash -c "apt-get -y update && apt-get -y install runit && npm install && runsv /usr/src/app"
ports:
- "8181:8181"
volumes:

View File

@@ -0,0 +1,2 @@
#!/bin/sh
node server.js

View File

@@ -5,6 +5,7 @@ endif()
if(NOT DEFINED FALCO_RULES_DEST_FILENAME)
set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml")
set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml")
set(FALCO_APP_RULES_DEST_FILENAME "application_rules.yaml")
endif()
if(DEFINED FALCO_COMPONENT)
@@ -17,6 +18,9 @@ install(FILES falco_rules.local.yaml
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
# Intentionally *not* installing application_rules.yaml. Not needed
# when falco is embedded in other projects.
else()
install(FILES falco_rules.yaml
DESTINATION "${FALCO_ETC_DIR}"
@@ -25,5 +29,9 @@ install(FILES falco_rules.yaml
install(FILES falco_rules.local.yaml
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
install(FILES application_rules.yaml
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_APP_RULES_DEST_FILENAME}")
endif()

View File

@@ -0,0 +1,169 @@
################################################################
# By default all application-related rules are disabled for
# performance reasons. Depending on the application(s) you use,
# uncomment the corresponding rule definitions for
# application-specific activity monitoring.
################################################################
# Elasticsearch ports
- macro: elasticsearch_cluster_port
condition: fd.sport=9300
- macro: elasticsearch_api_port
condition: fd.sport=9200
- macro: elasticsearch_port
condition: elasticsearch_cluster_port or elasticsearch_api_port
# - rule: Elasticsearch unexpected network inbound traffic
# desc: inbound network traffic to elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and inbound and not elasticsearch_port
# output: "Inbound network traffic to Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Elasticsearch unexpected network outbound traffic
# desc: outbound network traffic from elasticsearch on a port other than the standard ports
# condition: user.name = elasticsearch and outbound and not elasticsearch_cluster_port
# output: "Outbound network traffic from Elasticsearch on unexpected port (connection=%fd.name)"
# priority: WARNING
# ActiveMQ ports
- macro: activemq_cluster_port
condition: fd.sport=61616
- macro: activemq_web_port
condition: fd.sport=8161
- macro: activemq_port
condition: activemq_web_port or activemq_cluster_port
# - rule: Activemq unexpected network inbound traffic
# desc: inbound network traffic to activemq on a port other than the standard ports
# condition: user.name = activemq and inbound and not activemq_port
# output: "Inbound network traffic to ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Activemq unexpected network outbound traffic
# desc: outbound network traffic from activemq on a port other than the standard ports
# condition: user.name = activemq and outbound and not activemq_cluster_port
# output: "Outbound network traffic from ActiveMQ on unexpected port (connection=%fd.name)"
# priority: WARNING
# Cassandra ports
# https://docs.datastax.com/en/cassandra/2.0/cassandra/security/secureFireWall_r.html
- macro: cassandra_thrift_client_port
condition: fd.sport=9160
- macro: cassandra_cql_port
condition: fd.sport=9042
- macro: cassandra_cluster_port
condition: fd.sport=7000
- macro: cassandra_ssl_cluster_port
condition: fd.sport=7001
- macro: cassandra_jmx_port
condition: fd.sport=7199
- macro: cassandra_port
condition: >
cassandra_thrift_client_port or
cassandra_cql_port or cassandra_cluster_port or
cassandra_ssl_cluster_port or cassandra_jmx_port
# - rule: Cassandra unexpected network inbound traffic
# desc: inbound network traffic to cassandra on a port other than the standard ports
# condition: user.name = cassandra and inbound and not cassandra_port
# output: "Inbound network traffic to Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Cassandra unexpected network outbound traffic
# desc: outbound network traffic from cassandra on a port other than the standard ports
# condition: user.name = cassandra and outbound and not (cassandra_ssl_cluster_port or cassandra_cluster_port)
# output: "Outbound network traffic from Cassandra on unexpected port (connection=%fd.name)"
# priority: WARNING
# Couchdb ports
# https://github.com/davisp/couchdb/blob/master/etc/couchdb/local.ini
- macro: couchdb_httpd_port
condition: fd.sport=5984
- macro: couchdb_httpd_ssl_port
condition: fd.sport=6984
# xxx can't tell what clustering ports are used. not writing rules for this
# yet.
# Fluentd ports
- macro: fluentd_http_port
condition: fd.sport=9880
- macro: fluentd_forward_port
condition: fd.sport=24224
# - rule: Fluentd unexpected network inbound traffic
# desc: inbound network traffic to fluentd on a port other than the standard ports
# condition: user.name = td-agent and inbound and not (fluentd_forward_port or fluentd_http_port)
# output: "Inbound network traffic to Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Tdagent unexpected network outbound traffic
# desc: outbound network traffic from fluentd on a port other than the standard ports
# condition: user.name = td-agent and outbound and not fluentd_forward_port
# output: "Outbound network traffic from Fluentd on unexpected port (connection=%fd.name)"
# priority: WARNING
# Gearman ports
# http://gearman.org/protocol/
# - rule: Gearman unexpected network outbound traffic
# desc: outbound network traffic from gearman on a port other than the standard ports
# condition: user.name = gearman and outbound and outbound and not fd.sport = 4730
# output: "Outbound network traffic from Gearman on unexpected port (connection=%fd.name)"
# priority: WARNING
# Zookeeper
- macro: zookeeper_port
condition: fd.sport = 2181
# Kafka ports
# - rule: Kafka unexpected network inbound traffic
# desc: inbound network traffic to kafka on a port other than the standard ports
# condition: user.name = kafka and inbound and fd.sport != 9092
# output: "Inbound network traffic to Kafka on unexpected port (connection=%fd.name)"
# priority: WARNING
# Memcached ports
# - rule: Memcached unexpected network inbound traffic
# desc: inbound network traffic to memcached on a port other than the standard ports
# condition: user.name = memcached and inbound and fd.sport != 11211
# output: "Inbound network traffic to Memcached on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: Memcached unexpected network outbound traffic
# desc: any outbound network traffic from memcached. memcached never initiates outbound connections.
# condition: user.name = memcached and outbound
# output: "Unexpected Memcached outbound connection (connection=%fd.name)"
# priority: WARNING
# MongoDB ports
- macro: mongodb_server_port
condition: fd.sport = 27017
- macro: mongodb_shardserver_port
condition: fd.sport = 27018
- macro: mongodb_configserver_port
condition: fd.sport = 27019
- macro: mongodb_webserver_port
condition: fd.sport = 28017
# - rule: Mongodb unexpected network inbound traffic
# desc: inbound network traffic to mongodb on a port other than the standard ports
# condition: >
# user.name = mongodb and inbound and not (mongodb_server_port or
# mongodb_shardserver_port or mongodb_configserver_port or mongodb_webserver_port)
# output: "Inbound network traffic to MongoDB on unexpected port (connection=%fd.name)"
# priority: WARNING
# MySQL ports
# - rule: Mysql unexpected network inbound traffic
# desc: inbound network traffic to mysql on a port other than the standard ports
# condition: user.name = mysql and inbound and fd.sport != 3306
# output: "Inbound network traffic to MySQL on unexpected port (connection=%fd.name)"
# priority: WARNING
# - rule: HTTP server unexpected network inbound traffic
# desc: inbound network traffic to a http server program on a port other than the standard ports
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING

File diff suppressed because it is too large Load Diff

View File

@@ -319,7 +319,7 @@ trace_files: !mux
detect_counts:
- "Write below binary dir": 1
- "Read sensitive file untrusted": 3
- "Run shell in container": 1
- "Run shell untrusted": 1
- "Write below rpm database": 1
- "Write below etc": 1
- "System procs network activity": 1

View File

@@ -43,11 +43,11 @@ traces: !mux
falco-event-generator:
trace_file: traces-positive/falco-event-generator.scap
detect: True
detect_level: [ERROR, WARNING, INFO, NOTICE]
detect_level: [ERROR, WARNING, INFO, NOTICE, DEBUG]
detect_counts:
- "Write below binary dir": 1
- "Read sensitive file untrusted": 3
- "Run shell in container": 1
- "Run shell untrusted": 1
- "Write below rpm database": 1
- "Write below etc": 1
- "System procs network activity": 1
@@ -59,44 +59,6 @@ traces: !mux
- "Modify binary dirs": 2
- "Change thread namespace": 2
installer-fbash-manages-service:
trace_file: traces-info/installer-fbash-manages-service.scap
detect: True
detect_level: INFO
detect_counts:
- "Installer bash manages service": 4
installer-bash-non-https-connection:
trace_file: traces-positive/installer-bash-non-https-connection.scap
detect: True
detect_level: NOTICE
detect_counts:
- "Installer bash non https connection": 1
installer-fbash-runs-pkgmgmt:
trace_file: traces-info/installer-fbash-runs-pkgmgmt.scap
detect: True
detect_level: [NOTICE, INFO]
detect_counts:
- "Installer bash runs pkgmgmt program": 4
- "Installer bash non https connection": 4
installer-bash-starts-network-server:
trace_file: traces-positive/installer-bash-starts-network-server.scap
detect: True
detect_level: NOTICE
detect_counts:
- "Installer bash starts network server": 2
- "Installer bash non https connection": 3
installer-bash-starts-session:
trace_file: traces-positive/installer-bash-starts-session.scap
detect: True
detect_level: NOTICE
detect_counts:
- "Installer bash starts session": 1
- "Installer bash non https connection": 3
mkdir-binary-dirs:
trace_file: traces-positive/mkdir-binary-dirs.scap
detect: True
@@ -111,13 +73,6 @@ traces: !mux
detect_counts:
- "Modify binary dirs": 1
modify-package-repo-list-installer:
trace_file: traces-info/modify-package-repo-list-installer.scap
detect: True
detect_level: INFO
detect_counts:
- "Write below etc in installer": 1
non-sudo-setuid:
trace_file: traces-positive/non-sudo-setuid.scap
detect: True
@@ -146,13 +101,6 @@ traces: !mux
detect_counts:
- "Run shell untrusted": 1
shell-in-container:
trace_file: traces-positive/shell-in-container.scap
detect: True
detect_level: DEBUG
detect_counts:
- "Run shell in container": 1
system-binaries-network-activity:
trace_file: traces-positive/system-binaries-network-activity.scap
detect: True
@@ -188,13 +136,6 @@ traces: !mux
detect_counts:
- "Write below etc": 1
write-etc-installer:
trace_file: traces-info/write-etc-installer.scap
detect: True
detect_level: INFO
detect_counts:
- "Write below etc in installer": 1
write-rpm-database:
trace_file: traces-positive/write-rpm-database.scap
detect: True