Add support for daemonizing via the --daemon flag. If daemonized, the
pid is written to the file provided via the --pidfile flag. When
daemonized, falco immediately returns an error if stderr output or
logging was chosen on the command line.
Clean up handling of outputs to match the expected use case (daemon):
- syslog output is enabled by default
- stdout output is disabled by default
- If not configured at all, both outputs are enabled.
Also fix some bugs I found while running via packages:
- There were still some references to the old rules filename
falco_rules.conf.
- The redhat package mistakenly defined some system directories like
/etc, /etc/init.d. Add them to the exclusion list (See
https://cmake.org/Bug/view.php?id=13609 for context).
- Clean up some of the error messages to be more consistent.
After this I was able to build and install debian and rpm
packages. Starting the falco service ran falco as a daemon with syslog
output.
Add init.d scripts to debian/redhat packages as well as
postinstall/remove scripts to enable the falco service on install and
disable it on uninstall.
I still need to add support for daemonization to falco, and change the
default output options to match the expected use of being daemonized.
The ignored syscalls in macros were:
- write: renamed to open_write to make its weaker resolution more
apparent. Checks for open with any flag that could change a file.
- read: renamed to open_read. Checks for open with any read flag.
- sendto: I couldn't think of any way to replace this, so I simply
removed it with a comment.
I kept the original read/write macros commented out with a note that
they use ignored syscalls.
I have not tested these changes yet other than verifying that falco
starts properly.
Create a table containing the filtered syscalls and set it as the lua
global m_lua_ignored_syscalls == ignored_syscalls.
In the parser, add a general purpose ast traversal function
traverse_ast that calls a callback for all nodes of a specific type.
In the compiler, add a new function check_for_ignored_syscalls that uses
the traversal function to be called back for all "BinaryRelOp"
nodes (i.e. X = Y, X in [a, b, c], etc). For those nodes, if the lhs is
a field 'evt.type' or 'syscall.type' and the rhs contains one of the
ignored syscalls, throw an error.
Call check_for_ignored_syscalls after parsing any macro or rule
filter. The thrown error will contain the macro or rule that had the
ignored syscall.
In the next commit I'll change the rules to skip the ignored syscalls.
Uses yaml parsing lib to parse a yaml file comprising of a list of
macros and rules, like:
- macro: bin_dir
condition: fd.directory in (/bin, /sbin, /usr/bin, /usr/sbin)
- macro: core_binaries
condition: proc.name in (ls, mkdir, cat, less, ps)
- condition: (fd.typechar = 4 or fd.typechar=6) and core_binaries
output: "%evt.time: %proc.name network with %fd.l4proto"
- condition: evt.type = write and bin_dir
output: "%evt.time: System binary modified (file '%fd.filename' written by process %proc.name)"
- condition: container.id != host and proc.name = bash
output: "%evt.time: Shell running in container (%proc.name, %container.id)"
Based on the Dockerfiles from the sysdig repository. The only change
from the sysdig versions is to use environment variable FALCO_REPOSITORY
and to install falco instead of sysdig.
Note that the entrypoint still uses sysdig-probe-loader and
SYSDIG_HOST_ROOT, as it's building the kernel module for sysdig.
I verified I could create and run an image using the dev version using
"docker build ." from docker/dev, and run it using:
docker run -i -t --name falco --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:r\o sysdig/falco falco -r /etc/falco_rules.conf
I still need to update jenkins to create a release build.
Instead of suggesting using a kernel module from an installed version of
sysdig, always recommend unloading any existing module and using the
locally built one.
While building falco from source, I found a couple of problems related
to use of kernel modules:
1. The falco build needs driver_config.h from the sysdig repo, but it
isn't created by default.
[ 50%] Building C object userspace/libscap/CMakeFiles/scap.dir/scap.c.o
/mnt/sf_stemm/work/src/sysdig/userspace/libscap/scap.c:34:40: fatal error: ../../driver/driver_config.h: No such file or directory
compilation terminated.c
Fixed by adding ${SYSDIG_DIR}/driver to CMakeLists.txt. I did notice
that after doing this the object files were in the sysdig/driver
directory, but I don't think this is related to the Makefiles/CMakeFiles
in the sysdig/driver directory?
2. Falco needs the sysdig kernel module, but it may not be loaded if no
other sysdig is installed.
Added notes to the README that discuss loading the kernel module by hand
if no binary sysdig is installed.