Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to the falco-driver-loader script #1158

Merged
merged 4 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
include(GetFalcoVersion)

set(PACKAGE_NAME "falco")
set(PROBE_NAME "falco-probe")
set(PROBE_NAME "falco")
set(PROBE_DEVICE_NAME "falco")
set(DRIVER_LOOKUP_URL "https://s3.amazonaws.com/download.draios.com")
set(DRIVERS_REPO "https://dl.bintray.com/falcosecurity/driver")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
/usr
Expand Down
172 changes: 99 additions & 73 deletions scripts/falco-driver-loader
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ cos_version_greater()
return 0
}


get_kernel_config() {
if [ -f /proc/config.gz ]; then
echo "Found kernel config at /proc/config.gz"
Expand Down Expand Up @@ -102,62 +101,100 @@ get_kernel_config() {
fi
}

get_target_id() {
if [ -f "${HOST_ROOT}/etc/os-release" ]; then
# freedesktop.org and systemd
# shellcheck source=/dev/null
source "${HOST_ROOT}/etc/os-release"
OS_ID=$ID
elif [ -f "${HOST_ROOT}/etc/debian_version" ]; then
# Older Debian
# fixme > can this happen on older Ubuntu?
OS_ID=debian
elif [ -f "${HOST_ROOT}/etc/centos-release" ]; then
# Older CentOS
OS_ID=centos
else
>&2 echo "Detected an unsupported target system, please get in touch with the Falco community"
exit 1
fi

case "${OS_ID}" in
("amzn")
if [[ $VERSION_ID == "2" ]]; then
TARGET_ID="amazonlinux2"
else
TARGET_ID="amazonlinux"
fi
;;
("ubuntu")
if [[ $KERNEL_RELEASE == *"aws"* ]]; then
TARGET_ID="ubuntu-aws"
else
TARGET_ID="ubuntu"
fi
;;
(*)
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
esac
}

load_kernel_module() {
if ! hash lsmod > /dev/null 2>&1; then
echo "This program requires lsmod"
>&2 echo "This program requires lsmod"
exit 1
fi

if ! hash modprobe > /dev/null 2>&1; then
echo "This program requires modprobe"
>&2 echo "This program requires modprobe"
exit 1
fi

if ! hash rmmod > /dev/null 2>&1; then
echo "This program requires rmmod"
>&2 echo "This program requires rmmod"
exit 1
fi

echo "* Unloading ${PROBE_NAME}, if present"
rmmod "${PROBE_NAME}" 2>/dev/null
echo "* Unloading ${DRIVER_NAME} module, if present"
rmmod "${DRIVER_NAME}" 2>/dev/null
WAIT_TIME=0
KMOD_NAME=$(echo "${PROBE_NAME}" | tr "-" "_")
KMOD_NAME=$(echo "${DRIVER_NAME}" | tr "-" "_")
while lsmod | grep "${KMOD_NAME}" > /dev/null 2>&1 && [ $WAIT_TIME -lt "${MAX_RMMOD_WAIT}" ]; do
if rmmod "${PROBE_NAME}" 2>/dev/null; then
echo "* Unloading ${PROBE_NAME} succeeded after ${WAIT_TIME}s"
if rmmod "${DRIVER_NAME}" 2>/dev/null; then
echo "* Unloading ${DRIVER_NAME} module succeeded after ${WAIT_TIME}s"
break
fi
((++WAIT_TIME))
if (( WAIT_TIME % 5 == 0 )); then
echo "* ${PROBE_NAME} still loaded, waited ${WAIT_TIME}s (max wait ${MAX_RMMOD_WAIT}s)"
echo "* ${DRIVER_NAME} module still loaded, waited ${WAIT_TIME}s (max wait ${MAX_RMMOD_WAIT}s)"
fi
sleep 1
done

if lsmod | grep "${KMOD_NAME}" > /dev/null 2>&1; then
echo "* ${PROBE_NAME} seems to still be loaded, hoping the best"
echo "* ${DRIVER_NAME} module seems to still be loaded, hoping the best"
exit 0
fi

# skip dkms on UEK hosts because it will always fail
# skip dkms on UEK hosts because it will always fail`
if [[ $(uname -r) == *uek* ]]; then
echo "* Skipping dkms install for UEK host"
else
echo "* Running dkms install for ${PACKAGE_NAME}"
if dkms install -m "${PACKAGE_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}"; then
echo "* Trying to load a dkms ${PROBE_NAME}, if present"
if hash dkms &>/dev/null && dkms install -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* Trying to load a dkms ${DRIVER_NAME} module, if present"

if insmod "/var/lib/dkms/${PACKAGE_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${PROBE_NAME}.ko" > /dev/null 2>&1; then
echo "${PROBE_NAME} found and loaded in dkms"
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
echo "${DRIVER_NAME} module found and loaded in dkms"
exit 0
elif insmod "/var/lib/dkms/${PACKAGE_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${PROBE_NAME}.ko.xz" > /dev/null 2>&1; then
echo "${PROBE_NAME} found and loaded in dkms (xz)"
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
echo "${DRIVER_NAME} module found and loaded in dkms (xz)"
exit 0
else
echo "* Unable to insmod"
fi
else
DKMS_LOG="/var/lib/dkms/${PACKAGE_NAME}/${DRIVER_VERSION}/build/make.log"
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
if [ -f "${DKMS_LOG}" ]; then
echo "* Running dkms build failed, dumping ${DKMS_LOG}"
cat "${DKMS_LOG}"
Expand All @@ -167,35 +204,35 @@ load_kernel_module() {
fi
fi

echo "* Trying to load a system ${PROBE_NAME}, if present"
echo "* Trying to load a system ${DRIVER_NAME} driver, if present"

if modprobe "${PROBE_NAME}" > /dev/null 2>&1; then
echo "${PROBE_NAME} found and loaded with modprobe"
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
echo "${DRIVER_NAME} module found and loaded with modprobe"
exit 0
fi

echo "* Trying to find precompiled ${PROBE_NAME} for ${KERNEL_RELEASE}"
echo "* Trying to find a prebuilt ${DRIVER_NAME} module for kernel ${KERNEL_RELEASE}"

get_kernel_config
get_target_id

local FALCO_PROBE_FILENAME="${PROBE_NAME}-${DRIVER_VERSION}-${ARCH}-${KERNEL_RELEASE}-${HASH}.ko"
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"

if [ -f "${HOME}/.falco/${FALCO_PROBE_FILENAME}" ]; then
echo "Found precompiled module at ~/.falco/${FALCO_PROBE_FILENAME}, loading module"
insmod "${HOME}/.falco/${FALCO_PROBE_FILENAME}"
if [ -f "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" ]; then
echo "Found a prebuilt module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"
exit $?
fi

local URL
URL=$(echo "${PROBE_URL}/${PACKAGES_REPOSITORY}/sysdig-probe-binaries/${FALCO_PROBE_FILENAME}" | sed s/+/%2B/g)
URL=$(echo "${DRIVERS_REPO}/kernel-module/${DRIVER_VERSION}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)

echo "* Trying to download precompiled module from ${URL}"
if curl --create-dirs "${FALCO_PROBE_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_PROBE_FILENAME}" "${URL}"; then
echo "* Trying to download prebuilt module from ${URL}"
if curl --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
echo "Download succeeded, loading module"
insmod "${HOME}/.falco/${FALCO_PROBE_FILENAME}"
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"
exit $?
else
echo "Download failed, consider compiling your own ${PROBE_NAME} and loading it or getting in touch with the Falco community"
>&2 echo "Download failed, consider compiling your own ${DRIVER_NAME} module and loading it or getting in touch with the Falco community"
exit 1
fi
}
Expand All @@ -211,7 +248,7 @@ load_bpf_probe() {

if [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/etc/os-release" ]; then
# shellcheck source=/dev/null
. "${HOST_ROOT}/etc/os-release"
source "${HOST_ROOT}/etc/os-release"

if [ "${ID}" == "cos" ]; then
COS=1
Expand All @@ -223,7 +260,9 @@ load_bpf_probe() {
MINIKUBE_VERSION="$(cat "${HOST_ROOT}/etc/VERSION")"
fi

local BPF_PROBE_FILENAME="${BPF_PROBE_NAME}-${DRIVER_VERSION}-${ARCH}-${KERNEL_RELEASE}-${HASH}.o"
get_target_id

local BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"

if [ ! -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then

Expand Down Expand Up @@ -267,7 +306,7 @@ load_bpf_probe() {
if [[ greater_ret -eq 1 ]]; then
export KBUILD_EXTRA_CPPFLAGS=-DCOS_73_WORKAROUND
fi
}
}
fi

if [ -n "${MINIKUBE}" ]; then
Expand Down Expand Up @@ -301,7 +340,7 @@ load_bpf_probe() {
mkdir -p /tmp/kernel
cd /tmp/kernel || exit
cd "$(mktemp -d -p /tmp/kernel)" || exit
if ! curl -o kernel-sources.tgz --create-dirs "${FALCO_PROBE_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then
if ! curl -o kernel-sources.tgz --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then
exit 1;
fi

Expand All @@ -323,12 +362,12 @@ load_bpf_probe() {
customize_kernel_build
fi

echo "* Trying to compile BPF probe ${BPF_PROBE_NAME} (${BPF_PROBE_FILENAME})"
echo "* Trying to compile the eBPF probe (${BPF_PROBE_FILENAME})"

make -C "/usr/src/${PACKAGE_NAME}-${DRIVER_VERSION}/bpf" > /dev/null
make -C "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf" > /dev/null

mkdir -p ~/.falco
mv "/usr/src/${PACKAGE_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${BPF_PROBE_FILENAME}"
mkdir -p "${HOME}/.falco"
mv "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${BPF_PROBE_FILENAME}"

if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
rm -r /tmp/kernel
Expand All @@ -337,62 +376,49 @@ load_bpf_probe() {

if [ ! -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
local URL
URL=$(echo "${PROBE_URL}/${PACKAGES_REPOSITORY}/sysdig-probe-binaries/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
URL=$(echo "${DRIVERS_REPO}/ebpf-probe/${DRIVER_VERSION}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)

echo "* Trying to download precompiled BPF probe from ${URL}"
echo "* Trying to download a prebuilt eBPF probe from ${URL}"

curl --create-dirs "${FALCO_PROBE_CURL_OPTIONS}" -o "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${URL}"
curl --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${URL}"
fi

if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
if [ ! -f /proc/sys/net/core/bpf_jit_enable ]; then
echo "**********************************************************"
echo "** BPF doesn't have JIT enabled, performance might be **"
echo "** degraded. Please ensure to run on a kernel with **"
echo "** CONFIG_BPF_JIT enabled and/or use --net=host if **"
echo "** running inside a container. **"
echo "**********************************************************"
echo "******************************************************************"
echo "** BPF doesn't have JIT enabled, performance might be degraded. **"
echo "** Please ensure to run on a kernel with CONFIG_BPF_JIT on. **"
echo "******************************************************************"
fi

echo "* BPF probe located, it's now possible to start falco"
echo "* eBPF probe located, it's now possible to start Falco"

ln -sf "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${HOME}/.falco/${BPF_PROBE_NAME}.o"
ln -sf "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${HOME}/.falco/${DRIVER_NAME}-bpf.o"
exit $?
else
echo "* Failure to find a BPF probe"
echo "* Failure to find an eBPF probe"
exit 1
fi
}

ARCH=$(uname -m)
KERNEL_RELEASE=$(uname -r)
SCRIPT_NAME=$(basename "${0}")
PROBE_URL=${PROBE_URL:-"@DRIVER_LOOKUP_URL@"}
if [ -n "$PROBE_INSECURE_DOWNLOAD" ]
KERNEL_VERSION=$(uname -v | sed 's/#\([[:digit:]]\+\).*/\1/')
DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"}
if [ -n "$DRIVER_INSECURE_DOWNLOAD" ]
then
FALCO_PROBE_CURL_OPTIONS=-fsSk
FALCO_DRIVER_CURL_OPTIONS=-fsSk
else
FALCO_PROBE_CURL_OPTIONS=-fsS
FALCO_DRIVER_CURL_OPTIONS=-fsS
fi

MAX_RMMOD_WAIT=60
if [[ $# -ge 1 ]]; then
MAX_RMMOD_WAIT=$1
fi

if [ -z "${PACKAGES_REPOSITORY}" ]; then
PACKAGES_REPOSITORY="stable"
fi

if [ "${SCRIPT_NAME}" = "falco-driver-loader" ]; then
DRIVER_VERSION="@PROBE_VERSION@"
PROBE_NAME="@PROBE_NAME@"
BPF_PROBE_NAME="@PROBE_NAME@-bpf"
PACKAGE_NAME="@PACKAGE_NAME@"
else
echo "This script must be called as falco-driver-loader"
exit 1
fi
DRIVER_VERSION="@PROBE_VERSION@"
DRIVER_NAME="@PROBE_NAME@"

if [ "$(id -u)" != 0 ]; then
echo "Installer must be run as root (or with sudo)."
Expand All @@ -408,4 +434,4 @@ if [ -v FALCO_BPF_PROBE ] || [ "${1}" = "bpf" ]; then
load_bpf_probe
else
load_kernel_module
fi
fi