Skip to content
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 named-hosts/matic/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ import ../../hosts/nixos {
"tpm2-device=auto"
];

# Pin kernel: Falcon sensor 7.31.0 lacks kernel module for 6.18+, RFM on 6.19
boot.kernelPackages = pkgs.linuxPackages_6_17;
# Pin kernel to 6.18 for CrowdStrike Falcon compatibility (RFM on 6.19)
boot.kernelPackages = pkgs.linuxPackages_6_18;

# Filesystem hardening
boot.kernel.sysctl = {
Expand Down
35 changes: 27 additions & 8 deletions named-hosts/matic/falcon-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,33 @@ fi

install -d -m 0770 /opt/CrowdStrike

# Update binaries from the nix store, but preserve runtime state files.
# falconstore contains the Agent ID (AID) — if lost, the sensor re-registers
# as a new host and consumes another license seat.
@rsync@/bin/rsync -a --delete \
--exclude=falconstore \
--exclude=falconstore.bak \
--exclude=CsConfig \
"@falcon@/opt/CrowdStrike/" /opt/CrowdStrike/
# CrowdStrike pushes OTA updates that write newer versioned binaries into
# /opt/CrowdStrike/. Only rsync the packaged binaries when the installed
# version is not newer than the package, otherwise the rsync clobbers the
# update and the running sensor can't find its helper binaries (ENOENT).
pkg_ver="@falcon@/opt/CrowdStrike/falconctl"
installed_ver=/opt/CrowdStrike/falconctl

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: pkg_ver / installed_ver are misleading — they're paths to falconctl, not version strings. Renaming to pkg_path / installed_path would line up with the pkg_build / inst_build variables that do hold versions.

need_sync=true

if [ -x "$installed_ver" ]; then
pkg_build=$(readlink -f "$pkg_ver" | grep -oP '\d+$' || echo "0")
inst_build=$(readlink -f "$installed_ver" | grep -oP '\d+$' || echo "0")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version detection silently no-ops on a plain-file falconctl. readlink -f /opt/CrowdStrike/falconctl only ends in build digits when CrowdStrike's installer keeps falconctl as a symlink to falconctl<build> (the documented layout per yaleman.org's CrowdStrike cleanup post, and what the .deb ships). If that ever isn't true on this host — partial OTA, manual reinstall, future packaging change — grep -oP '\d+$' misses, || echo "0" kicks in, inst_build=0, 0 -gt $pkg_build is false, and the rsync below clobbers the OTA exactly as before. There's no log of the detected values on the sync path either (only the skip branch logs), so the degradation is invisible in the journal.

Reproduced locally:

$ readlink -f /tmp/test/opt/CrowdStrike/falconctl   # plain file
/tmp/test/opt/CrowdStrike/falconctl
$ readlink -f /tmp/test/opt/CrowdStrike/falconctl | grep -oP '\d+$' || echo 0
0

Consider either (a) calling falconctl -g --version (or reading the build from the sensor directly) instead of inferring from the symlink target, or at minimum (b) echo "falcon-init: installed=$inst_build packaged=$pkg_build" unconditionally so a regression is obvious in journalctl -u falcon-sensor.

if [ "$inst_build" -gt "$pkg_build" ] 2>/dev/null; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the 2>/dev/null is redundant — pkg_build and inst_build are both normalized to integers by the || echo "0" fallback, so [ -gt ] can't print a non-integer error here. Removing it makes the intent ("this is a plain integer compare") clearer.

Suggested change
if [ "$inst_build" -gt "$pkg_build" ] 2>/dev/null; then
if [ "$inst_build" -gt "$pkg_build" ]; then

echo "falcon-init: installed build $inst_build is newer than packaged $pkg_build, skipping rsync"
need_sync=false
fi
fi
Comment on lines +21 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using external grep -oP in a pipeline under set -euo pipefail can be fragile and spawns unnecessary subprocesses. Additionally, if the extracted build numbers are not valid integers, the -gt comparison will throw a bash evaluation error (which is currently suppressed with 2>/dev/null).

We can make this much more robust and efficient by using Bash's built-in regular expression matching ([[ ... =~ ... ]]). This avoids spawning grep processes, guarantees that the variables are valid integers, and eliminates the need to suppress comparison errors.

Suggested change
if [ -x "$installed_ver" ]; then
pkg_build=$(readlink -f "$pkg_ver" | grep -oP '\d+$' || echo "0")
inst_build=$(readlink -f "$installed_ver" | grep -oP '\d+$' || echo "0")
if [ "$inst_build" -gt "$pkg_build" ] 2>/dev/null; then
echo "falcon-init: installed build $inst_build is newer than packaged $pkg_build, skipping rsync"
need_sync=false
fi
fi
if [ -x "$installed_ver" ]; then
pkg_target=$(readlink -f "$pkg_ver" 2>/dev/null || true)
inst_target=$(readlink -f "$installed_ver" 2>/dev/null || true)
pkg_build=0
if [[ "$pkg_target" =~ ([0-9]+)$ ]]; then
pkg_build=${BASH_REMATCH[1]}
fi
inst_build=0
if [[ "$inst_target" =~ ([0-9]+)$ ]]; then
inst_build=${BASH_REMATCH[1]}
fi
if [ "$inst_build" -gt "$pkg_build" ]; then
echo "falcon-init: installed build $inst_build is newer than packaged $pkg_build, skipping rsync"
need_sync=false
fi
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider logging the detected builds unconditionally (e.g. echo "falcon-init: installed=$inst_build packaged=$pkg_build" right after the if [ -x "$installed_ver" ] block) so the next time someone debugs a clobbered OTA they can see whether the comparison ran correctly or silently fell back to 0.


if [ "$need_sync" = true ]; then
# Update binaries from the nix store, but preserve runtime state files.
# falconstore contains the Agent ID (AID) - if lost, the sensor re-registers
# as a new host and consumes another license seat.
@rsync@/bin/rsync -a --delete \
--exclude=falconstore \
--exclude=falconstore.bak \
--exclude=CsConfig \
"@falcon@/opt/CrowdStrike/" /opt/CrowdStrike/
fi

chown -R root:root /opt/CrowdStrike

Expand Down
Loading