From f4562ae1c6f7ed46ba496239780c284bfd33dc41 Mon Sep 17 00:00:00 2001 From: Shawn Wells Date: Fri, 31 Jul 2020 16:43:36 -0400 Subject: [PATCH] Initial Commit --- .gitignore | 2 ++ Dockerfile | 60 ++++++++++++++++++++++++++++++++++++++ README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-- entrypoint.sh | 51 ++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 entrypoint.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1dc6658 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Don't accidentally commit the sensor RPM into the repo ;) +*.rpm \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e202c37 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# +# RHEL Universal Base Image (RHEL UBI) is a stripped down, OCI-compliant, +# base operating system image purpose built for containers. For more information +# see https://developers.redhat.com/products/rhel/ubi +# +FROM registry.access.redhat.com/ubi8/ubi +USER root + +# +# Friendly reminder that generated container images are from an open source +# project, and not a formal CrowdStrike product. +# +LABEL maintainer="https://github.com/CrowdStrike/openshift-falcon-daemonset" + +# +# Apply updates to base image. +# +RUN yum -y update --disablerepo=* --enablerepo=ubi-8-appstream --enablerepo=ubi-8-baseos && yum -y clean all && rm -rf /var/cache/yum + +# +# Copy Falcon Agent RPM into container & install it, then remove the RPM +# +# TO DO: For now this script copies the full RPM and renames to /tmp/falcon-agent.rpm. This should be +# changed to a parameter at some point. +# +COPY ./falcon-sensor-5.33.0-9808.el8.x86_64.rpm /tmp/falcon-agent.rpm +RUN yum -y install --disablerepo=* --enablerepo=ubi-8-appstream --enablerepo=ubi-8-baseos /tmp/falcon-agent.rpm && yum -y clean all && rm -rf /var/cache/yum && rm /tmp/falcon-agent.rpm + +# +# Copy the entrypoint script into the container and make sure +# that its executable. Add the symlink for backwards compatability +# +COPY entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/entrypoint.sh +RUN ln -s /usr/local/bin/entrypoint.sh / + + +ARG container_version +ARG BUILD_DATE # BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') +ARG VCS_REF # VCS_REF=$(git rev-parse --short HEAD) + +LABEL org.label-schema.build-date=$BUILD_DATE +LABEL org.label-schema.schema-version "1.0" +LABEL org.label-schema.description "CrowdStrike Falcon Linux Sensor" +LABEL org.label-schema.vendor "https://github.com/CrowdStrike/openshift-falcon-daemonset" +LABEL org.label-schema.url="https://github.com/CrowdStrike/openshift-falcon-daemonset" +LABEL org.label-schema.vcs-url="https://github.com/CrowdStrike/openshift-falcon-daemonset" +LABEL org.label-schema.vcs-ref=$VCS_REF +LABEL org.label-schema.docker.cmd \ + "docker run -d --privileged -v /var/log:/var/log \ + --mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock \ + --net=host --pid=host --uts=host --ipc=host \ + falcon-sensor" +LABEL org.label-schema.container_version $container_version + +ENV PATH ".:/bin:/usr/bin:/sbin:/usr/sbin" +WORKDIR /opt/CrowdStrike + +VOLUME /var/log +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index dc7c011..e432232 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,78 @@ -# dockerfiles -Automation to help create container images pre-loaded with the CrowdStrike Falcon sensor. +# Package CrowdStrike Falcon Linux sensor as a container + +## Pre-reqs + +* Build user mode, kernel modules and KMA bits for the respective build type. + They'll be picked up by container packaging. +* Install `docker` and `ldd` if not already present on the build host. + +## Build + +* Build the container using the included ``Dockerfile``: + * ``$ docker build --no-cache=true --build-arg \ + BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ + VCS_REF=$(git rev-parse --short HEAD) \ + -t falcon-sensor:latest .`` + +## Run + +`falcon-sensor` is the default command of the container. It can be invoked +as follows: + +``` +docker run --rm -ti --privileged --net=host -v /var/log:/var/log falcon-sensor +``` + +This is like running falcon-sensor directly on the console. Standard terminal +output appears. Pressing Control-C would cause `docker` client to pass +`SIGINT` along to the sensor, which would then exit. + +`--net=host` is required for the containerized sensor to talk to the kernel +module over netlink and to Cloudsim over localhost. Host `pid`, `uts` and +`ipc` namespaces are passed through to sensor container for easy access to +host resources. Following additional host files and directories need to be +provided to the sensor by mounting them within the container: + +``` +/var/run/docker.sock # for the sensor to query Docker engine +/var/log # for logs +/etc/os-release # or its equivalent based on the distro +``` + +Sensor container picks up `falconctl` configuration from its environment. +Following variables are supported. They map to the similarly named +`SET_OPTIONS` of `falconctl`. Typically, the environment variables +are set through a Kubernetes `configmap`. They can also be set with +`-e` option to `docker run` on the command line. + +``` +FALCONCTL_OPT_CID +FALCONCTL_OPT_AID +FALCONCTL_OPT_APD +FALCONCTL_OPT_APH +FALCONCTL_OPT_APP +FALCONCTL_OPT_TRACE +FALCONCTL_OPT_FEATURE +FALCONCTL_OPT_MESSAGE_LOG +FALCONCTL_OPT_BILLING +FALCONCTL_OPT_ASSERT +FALCONCTL_OPT_MEMFAIL_GRACE_PERIOD +FALCONCTL_OPT_MEMFAIL_EVERY_N +``` + +The sensor can be run as a background service as follows: + +``` +CONTAINER_ID=$(docker run -d -e FALCONCTL_OPT_CID=<> -e FALCONCTL_OPT_TRACE=debug --privileged --net=host -v /var/log:/var/log falcon-sensor:0.1) +``` + +### Running `falconctl` + +`falconctl` can be invoked inside a running sensor container with `docker exec`: + +``` +docker exec -it $CONTAINER_ID falconctl -g --trace +``` + +## Post-reqs +Push the image to a registry (like ECR) if the container needs to be accessed outside of the build host. \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..f2b6d7d --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -e + +CSROOT=/opt/CrowdStrike +FALCONCTL=$CSROOT/falconctl +FALCON_SENSOR=$CSROOT/falcon-sensor +CLOUDSIM_CID="YOURCID" + +# +# Initialize ``opts`` as one-dimensional array +# +declare -A opts + +# +# Pull options from the environment (passed to us through a Kubernetes +# config map). If $CLOUDSIM_CID is defined assume a local build. +# +# Reference output of ``falconctl --help`` for option descriptions. +# +opts['--cid']="${FALCONCTL_OPT_CID:-$CLOUDSIM_CID}" +opts['--aid']="$FALCONCTL_OPT_AID" +opts['--apd']="$FALCONCTL_OPT_APD" +opts['--aph']="$FALCONCTL_OPT_APH" +opts['--app']="$FALCONCTL_OPT_APP" +opts['--trace']="$FALCONCTL_OPT_TRACE" +opts['--feature']="$FALCONCTL_OPT_FEATURE" +opts['--message-log']="$FALCONCTL_OPT_MESSAGE_LOG" +opts['--billing']="$FALCONCTL_OPT_BILLING" +opts['--assert']="$FALCONCTL_OPT_ASSERT" +opts['--memfail-grace-period']="$FALCONCTL_OPT_MEMFAIL_GRACE_PERIOD" +opts['--memfail-every-n']="$FALCONCTL_OPT_MEMFAIL_EVERY_N" + +# +# Iterate through the ``opts`` array and pull out defined options. Build a unified +# ``falconctl -s -f [OPTS]`` style command. +# +cmd="$FALCONCTL -s -f" +for opt in "${!opts[@]}" +do + [ -z ${opts[$opt]} ] || cmd+=" $opt=${opts[$opt]}" +done + +# +# Set the sensor config by running $cmd, and then +# exec the sensor ($FALCON_SENSOR) +# +# Note this is why the ``set -e`` line earlier is so important. If $cmd fails +# we do not want the sensor daemon to initiate, as that would mean the sensor +# was not properly initiated. +echo $cmd +$cmd && exec $FALCON_SENSOR \ No newline at end of file