Skip to content

Commit

Permalink
Add automated tests for K8s PSP Support
Browse files Browse the repository at this point in the history
Add ~75 new automated tests that verify K8s PSP Support.

For each PSP attribute, add both positive and negative test cases. For
some of the more complicated attributes like runAsUser/Group/etc,
include cases where the uids are specicified both at the container
security context level and pod security context level and then combined
with mayRunAs/mustRunAs, etc.

Also, some existing tests are updated to handle proper use of "in" and
"intersects" in expressions.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
  • Loading branch information
mstemm committed Sep 10, 2019
1 parent 04a4eb7 commit f750e5e
Show file tree
Hide file tree
Showing 71 changed files with 1,184 additions and 3 deletions.
165 changes: 165 additions & 0 deletions test/confs/psp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#
# Copyright (C) 2016-2018 Draios Inc dba Sysdig.
#
# This file is part of falco .
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# File(s) or Directories containing Falco rules, loaded at startup.
# The name "rules_file" is only for backwards compatibility.
# If the entry is a file, it will be read directly. If the entry is a directory,
# every file in that directory will be read, in alphabetical order.
#
# falco_rules.yaml ships with the falco package and is overridden with
# every new software version. falco_rules.local.yaml is only created
# if it doesn't exist. If you want to customize the set of rules, add
# your customizations to falco_rules.local.yaml.
#
# The files will be read in the order presented here, so make sure if
# you have overrides they appear in later files.
rules_file: []

# If true, the times displayed in log messages and output messages
# will be in ISO 8601. By default, times are displayed in the local
# time zone, as governed by /etc/localtime.
time_format_iso_8601: false

# Whether to output events in json or text
json_output: false

# When using json output, whether or not to include the "output" property
# itself (e.g. "File below a known binary directory opened for writing
# (user=root ....") in the json output.
json_include_output_property: true

# Send information logs to stderr and/or syslog Note these are *not* security
# notification logs! These are just Falco lifecycle (and possibly error) logs.
log_stderr: true
log_syslog: true

# Minimum log level to include in logs. Note: these levels are
# separate from the priority field of rules. This refers only to the
# log level of falco's internal logging. Can be one of "emergency",
# "alert", "critical", "error", "warning", "notice", "info", "debug".
log_level: info

# 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",
# "info", "debug".
priority: debug

# Whether or not output to any of the output channels below is
# buffered. Defaults to false
buffered_outputs: false

# Falco uses a shared buffer between the kernel and userspace to pass
# system call information. When falco detects that this buffer is
# full and system calls have been dropped, it can take one or more of
# the following actions:
# - "ignore": do nothing. If an empty list is provided, ignore is assumed.
# - "log": log a CRITICAL message noting that the buffer was full.
# - "alert": emit a falco alert noting that the buffer was full.
# - "exit": exit falco with a non-zero rc.
#
# The rate at which log/alert messages are emitted is governed by a
# token bucket. The rate corresponds to one message every 30 seconds
# with a burst of 10 messages.

syscall_event_drops:
actions:
- log
- alert
rate: .03333
max_burst: 10

# A throttling mechanism implemented as a token bucket limits the
# rate of falco notifications. This throttling is controlled by the following configuration
# options:
# - rate: the number of tokens (i.e. right to send a notification)
# gained per second. Defaults to 1.
# - max_burst: the maximum number of tokens outstanding. Defaults to 1000.
#
# With these defaults, falco could send up to 1000 notifications after
# an initial quiet period, and then up to 1 notification per second
# afterward. It would gain the full burst back after 1000 seconds of
# no activity.

outputs:
rate: 1
max_burst: 1000

# Where security notifications should go.
# Multiple outputs can be enabled.

syslog_output:
enabled: true

# If keep_alive is set to true, the file will be opened once and
# continuously written to, with each output message on its own
# line. If keep_alive is set to false, the file will be re-opened
# for each output message.
#
# Also, the file will be closed and reopened if falco is signaled with
# SIGUSR1.

file_output:
enabled: false
keep_alive: false
filename: ./events.txt

stdout_output:
enabled: true

# Falco contains an embedded webserver that can be used to accept K8s
# Audit Events. These config options control the behavior of that
# webserver. (By default, the webserver is disabled).
#
# The ssl_certificate is a combination SSL Certificate and corresponding
# key contained in a single file. You can generate a key/cert as follows:
#
# $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
# $ cat certificate.pem key.pem > falco.pem
# $ sudo cp falco.pem /etc/falco/falco.pem

webserver:
enabled: true
listen_port: 8765
k8s_audit_endpoint: /k8s_audit
ssl_enabled: false
ssl_certificate: /etc/falco/falco.pem

# Possible additional things you might want to do with program output:
# - send to a slack webhook:
# program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX"
# - logging (alternate method than syslog):
# program: logger -t falco-test
# - send over a network connection:
# program: nc host.example.com 80

# If keep_alive is set to true, the program will be started once and
# continuously written to, with each output message on its own
# line. If keep_alive is set to false, the program will be re-spawned
# for each output message.
#
# Also, the program will be closed and reopened if falco is signaled with
# SIGUSR1.
program_output:
enabled: false
keep_alive: false
program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/XXX"

http_output:
enabled: false
url: http://some.url
17 changes: 17 additions & 0 deletions test/falco_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ def setUp(self):
if not isinstance(self.validate_rules_file, list):
self.validate_rules_file = [self.validate_rules_file]

self.psp_file = self.params.get('psp_file', '*', default=False)
self.k8s_psp_rules_template_file = self.params.get('k8s_psp_rules_template', '*', default=os.path.join(self.basedir, '../rules/templates/k8s_psp_rules.yaml.tmpl'))

if self.psp_file == False:
self.psp_file = []
else:
if not isinstance(self.psp_file, list):
self.psp_file = [self.psp_file]

self.rules_args = ""

for file in self.validate_rules_file:
Expand All @@ -105,6 +114,14 @@ def setUp(self):
file = os.path.join(self.basedir, file)
self.rules_args = self.rules_args + "-r " + file + " "

for file in self.psp_file:
if not os.path.isabs(file):
file = os.path.join(self.basedir, file)
self.rules_args = self.rules_args + "--psp " + file + " "

if self.psp_file:
self.rules_args = self.rules_args + "-o k8s_psp_rules_template=" + self.k8s_psp_rules_template_file + " "

self.conf_file = self.params.get('conf_file', '*', default=os.path.join(self.basedir, '../falco.yaml'))
if not os.path.isabs(self.conf_file):
self.conf_file = os.path.join(self.basedir, self.conf_file)
Expand Down
Loading

0 comments on commit f750e5e

Please sign in to comment.