diff --git a/scripts/falco-driver-loader b/scripts/falco-driver-loader index e3855071..24989a36 100755 --- a/scripts/falco-driver-loader +++ b/scripts/falco-driver-loader @@ -107,12 +107,14 @@ get_target_id() { 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? + # Older debian distros + # fixme > Can this happen on older Ubuntu? OS_ID=debian elif [ -f "${HOST_ROOT}/etc/centos-release" ]; then - # Older CentOS + # Older CentOS distros OS_ID=centos + elif [ -f "${HOST_ROOT}/etc/VERSION" ]; then + OS_ID=minikube else >&2 echo "Detected an unsupported target system, please get in touch with the Falco community" exit 1 @@ -153,20 +155,20 @@ load_kernel_module_compile() { # Try to compile using all the available gcc versions for CURRENT_GCC in $(which gcc) $(ls "$(dirname "$(which gcc)")"/gcc-* | grep 'gcc-[0-9]\+' | sort -r); do - echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}" + echo "* Trying to dkms install the Falco module with GCC ${CURRENT_GCC}" echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make chmod +x /tmp/falco-dkms-make if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then - echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod" + echo "* Falco module installed in dkms, trying to insmod" if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then - echo "* Success: ${DRIVER_NAME} module found and loaded in dkms" + echo "* Success: Falco module found and loaded in dkms" exit 0 elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then - echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)" + echo "* Success: Falco module found and loaded in dkms (xz)" exit 0 else - echo "* Unable to insmod ${DRIVER_NAME} module" + echo "* Unable to insmod the Falco module" fi else DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log" @@ -188,13 +190,13 @@ load_kernel_module_download() { local URL URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g) - echo "* Trying to download prebuilt ${DRIVER_NAME} module from ${URL}" + echo "* Trying to download a prebuilt Falco module from ${URL}" if curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then echo "* Download succeeded" - insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module loaded" + insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: Falco module found and inserted" exit $? else - >&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module" + >&2 echo "Unable to find a prebuilt Falco module" return fi } @@ -215,42 +217,42 @@ load_kernel_module() { exit 1 fi - echo "* Unloading ${DRIVER_NAME} module, if present" + echo "* Unloading the Falco module, if present" rmmod "${DRIVER_NAME}" 2>/dev/null WAIT_TIME=0 KMOD_NAME=$(echo "${DRIVER_NAME}" | tr "-" "_") while lsmod | cut -d' ' -f1 | grep -qx "${KMOD_NAME}" && [ $WAIT_TIME -lt "${MAX_RMMOD_WAIT}" ]; do if rmmod "${DRIVER_NAME}" 2>/dev/null; then - echo "* Unloading ${DRIVER_NAME} module succeeded after ${WAIT_TIME}s" + echo "* Unloading the Falco module succeeded after ${WAIT_TIME}s" break fi ((++WAIT_TIME)) if (( WAIT_TIME % 5 == 0 )); then - echo "* ${DRIVER_NAME} module still loaded, waited ${WAIT_TIME}s (max wait ${MAX_RMMOD_WAIT}s)" + echo "* Falco module still loaded, waited ${WAIT_TIME}s (max wait ${MAX_RMMOD_WAIT}s)" fi sleep 1 done if lsmod | cut -d' ' -f1 | grep -qx "${KMOD_NAME}" > /dev/null 2>&1; then - echo "* ${DRIVER_NAME} module seems to still be loaded, hoping the best" + echo "* Falco} module seems to still be loaded, hoping the best" exit 0 fi - echo "* Trying to load a system ${DRIVER_NAME} driver, if present" + echo "* Trying to load a system Falco module, if present" if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then - echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe" + echo "* Success: Falco module found and loaded with modprobe" exit 0 fi - echo "* Looking for a prebuilt ${DRIVER_NAME} module for kernel ${KERNEL_RELEASE} locally" + echo "* Looking for a prebuilt Falco module for kernel ${KERNEL_RELEASE} locally" get_target_id local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko" if [ -f "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" ]; then - echo "* Found a prebuilt ${DRIVER_NAME} module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it" - insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module loaded" + echo "* Found a prebuilt Falco module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it" + insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: Falco module found and inserted" exit $? fi @@ -263,7 +265,7 @@ load_kernel_module() { fi # Not able to download a prebuilt module nor to compile one on-the-fly - >&2 echo "Consider compiling your own ${DRIVER_NAME} module and loading it or getting in touch with the Falco community" + >&2 echo "Consider compiling your own Falco driver and loading it or getting in touch with the Falco community" exit 1 } @@ -281,12 +283,12 @@ clean_kernel_module() { KMOD_NAME=$(echo "${DRIVER_NAME}" | tr "-" "_") if lsmod | cut -d' ' -f1 | grep -qx "${KMOD_NAME}"; then if rmmod "${DRIVER_NAME}" 2>/dev/null; then - echo "* Unloading ${DRIVER_NAME} module succeeded" + echo "* Unloading the Falco module succeeded" else - echo "* Unloading ${DRIVER_NAME} module failed" + echo "* Unloading the Falco module failed" fi else - echo "* No ${DRIVER_NAME} module loaded" + echo "* There is no Falco module loaded" fi if ! hash dkms >/dev/null 2>&1; then @@ -296,14 +298,14 @@ clean_kernel_module() { DRIVER_VERSIONS=$(dkms status -m "${DRIVER_NAME}" | cut -d',' -f2 | sed -e 's/^[[:space:]]*//') if [ -z "${DRIVER_VERSIONS}" ]; then - echo "* No ${DRIVER_NAME} module found in dkms" + echo "* There is no Falco module in dkms" return fi for CURRENT_VER in ${DRIVER_VERSIONS}; do if dkms remove -m "${DRIVER_NAME}" -v "${CURRENT_VER}" --all 2>/dev/null; then - echo "* Removing ${DRIVER_NAME}/${CURRENT_VER} succeeded" + echo "* Removing the Falco module (version ${CURRENT_VER}) succeeded" else - echo "* Removing ${DRIVER_NAME}/${CURRENT_VER} failed" + echo "* Removing the Falco module (version ${CURRENT_VER}) failed" exit 1 fi done @@ -315,14 +317,14 @@ load_bpf_probe_compile() { customize_kernel_build() { if [ -n "${KERNEL_EXTRA_VERSION}" ]; then - sed -i "s/LOCALVERSION=\"\"/LOCALVERSION=\"${KERNEL_EXTRA_VERSION}\"/" .config + sed -i "s/LOCALVERSION=\"\"/LOCALVERSION=\"${KERNEL_EXTRA_VERSION}\"/" .config fi make olddefconfig > /dev/null make modules_prepare > /dev/null } - if [ -n "${COS}" ]; then - echo "* COS detected (build ${BUILD_ID}), using cos kernel headers" + if [ "${TARGET_ID}" == "cos" ]; then + echo "* COS detected (build ${BUILD_ID}), using COS kernel headers" BPF_KERNEL_SOURCES_URL="https://storage.googleapis.com/cos-tools/${BUILD_ID}/kernel-headers.tgz" KERNEL_EXTRA_VERSION="+" @@ -353,7 +355,8 @@ load_bpf_probe_compile() { } fi - if [ -n "${MINIKUBE}" ]; then + if [ "${TARGET_ID}" == "minikube" ]; then + MINIKUBE_VERSION="$(cat "${HOST_ROOT}/etc/VERSION")" echo "* Minikube detected (${MINIKUBE_VERSION}), using linux kernel sources for minikube kernel" local kernel_version kernel_version=$(uname -r) @@ -379,14 +382,16 @@ load_bpf_probe_compile() { fi if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then + get_kernel_config + echo "* Downloading ${BPF_KERNEL_SOURCES_URL}" mkdir -p /tmp/kernel cd /tmp/kernel || exit cd "$(mktemp -d -p /tmp/kernel)" || exit if ! curl -L -o kernel-sources.tgz --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" "${BPF_KERNEL_SOURCES_URL}"; then - >&2 echo "Download failed" - exit 1; + >&2 echo "Unable to download the kernel sources" + return fi echo "* Extracting kernel sources" @@ -427,46 +432,16 @@ load_bpf_probe_download() { echo "* Trying to download a prebuilt eBPF probe from ${URL}" if ! curl -L --create-dirs "${FALCO_DRIVER_CURL_OPTIONS}" -o "${HOME}/.falco/${BPF_PROBE_FILENAME}" "${URL}"; then - >&2 echo "Download failed" - exit 1; + >&2 echo "Unable to find a prebuilt Falco eBPF probe" + return fi } load_bpf_probe() { - echo "* Mounting debugfs" - - if [ ! -d /sys/kernel/debug/tracing ]; then - mount -t debugfs nodev /sys/kernel/debug - fi - - get_kernel_config - - if [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/etc/os-release" ]; then - # shellcheck source=/dev/null - source "${HOST_ROOT}/etc/os-release" - - if [ "${ID}" == "cos" ]; then - COS=1 - fi - fi - - if [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/etc/VERSION" ]; then - MINIKUBE=1 - MINIKUBE_VERSION="$(cat "${HOST_ROOT}/etc/VERSION")" - fi - get_target_id BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o" - if [ -n "$ENABLE_COMPILE" ]; then - if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then - echo "* Skipping compile, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}" - else - load_bpf_probe_compile - fi - fi - if [ -n "$ENABLE_DOWNLOAD" ]; then if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then echo "* Skipping download, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}" @@ -475,6 +450,14 @@ load_bpf_probe() { fi fi + if [ -n "$ENABLE_COMPILE" ]; then + if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then + echo "* Skipping compilation, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}" + else + load_bpf_probe_compile + fi + fi + if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then echo "* eBPF probe located in ${HOME}/.falco/${BPF_PROBE_FILENAME}" @@ -489,7 +472,7 @@ load_bpf_probe() { && echo "* Success: eBPF probe symlinked to ${HOME}/.falco/${DRIVER_NAME}-bpf.o" exit $? else - >&2 echo "Failure to find an eBPF probe" + >&2 echo "Unable to load the Falco eBPF probe" exit 1 fi } @@ -506,13 +489,14 @@ print_usage() { echo "Options:" echo " --help show brief help" echo " --clean try to remove an already present driver installation" - echo " --compile try to compile the driver locally" - echo " --download try to download a prebuilt driver" + echo " --compile try to compile the driver locally (default on)" + echo " --download try to download a prebuilt driver (default on)" echo " --source-only skip execution and allow sourcing in another script" echo "" echo "Environment variables:" - echo " DRIVER_REPO specify a different URL where to look for prebuilt Falco drivers" - echo " DRIVER_NAME specify a different name for the driver" + echo " DRIVER_REPO specify a different URL where to look for prebuilt Falco drivers" + echo " DRIVER_NAME specify a different name for the driver" + echo " DRIVER_INSECURE_DOWNLOAD whether you want to allow insecure downloads or not" echo "" echo "Versions:" echo " Falco version ${FALCO_VERSION}" @@ -521,8 +505,15 @@ print_usage() { } ARCH=$(uname -m) + KERNEL_RELEASE=$(uname -r) + +if ! hash sed > /dev/null 2>&1; then + >&2 echo "This program requires sed" + exit 1 +fi KERNEL_VERSION=$(uname -v | sed 's/#\([[:digit:]]\+\).*/\1/') + DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"} if [ -n "$DRIVER_INSECURE_DOWNLOAD" ] @@ -625,7 +616,7 @@ if [ -z "$source_only" ]; then clean_kernel_module ;; bpf) - >&2 echo "--clean not supported for driver=$DRIVER" + >&2 echo "--clean not supported for driver=bpf" exit 1 esac else