-
Notifications
You must be signed in to change notification settings - Fork 0
feat(security): add CrowdStrike Falcon and Kolide to matic host #724
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
Changes from all commits
bfcc59a
57645a1
98f4eb2
94939cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,96 @@ | ||||||||||||
| # CrowdStrike Falcon sensor configuration for NixOS | ||||||||||||
| # | ||||||||||||
| # Prerequisites (manual steps): | ||||||||||||
| # 1. Obtain the Falcon sensor .deb from IT | ||||||||||||
| # 2. Create /etc/falcon-sensor.env with: FALCON_CID=<your-cid> | ||||||||||||
| # 3. Extract and place sensor files (see README for details) | ||||||||||||
| # | ||||||||||||
| # Based on: https://gist.github.com/klDen/c90d9798828e31fecbb603f85e27f4f1 | ||||||||||||
| { | ||||||||||||
| config, | ||||||||||||
| lib, | ||||||||||||
| pkgs, | ||||||||||||
| ... | ||||||||||||
| }: | ||||||||||||
|
|
||||||||||||
| let | ||||||||||||
| # FHS environment for CrowdStrike Falcon | ||||||||||||
| # NixOS doesn't have standard /opt paths, so we create an FHS-compatible environment | ||||||||||||
| falconFhs = pkgs.buildFHSEnv { | ||||||||||||
| name = "falcon-sensor-fhs"; | ||||||||||||
| targetPkgs = | ||||||||||||
| pkgs: with pkgs; [ | ||||||||||||
| # Runtime dependencies for Falcon sensor | ||||||||||||
| bash | ||||||||||||
| coreutils | ||||||||||||
| curl | ||||||||||||
| glibc | ||||||||||||
| gnugrep | ||||||||||||
| libnl | ||||||||||||
| openssl | ||||||||||||
| zlib | ||||||||||||
| ]; | ||||||||||||
| runScript = "/opt/CrowdStrike/falcond"; | ||||||||||||
| }; | ||||||||||||
| in | ||||||||||||
| { | ||||||||||||
| # Create necessary directories and symlinks for CrowdStrike | ||||||||||||
| systemd.tmpfiles.rules = [ | ||||||||||||
| # Create /opt/CrowdStrike directory | ||||||||||||
| "d /opt/CrowdStrike 0770 root root -" | ||||||||||||
| ]; | ||||||||||||
|
|
||||||||||||
| # CrowdStrike Falcon sensor service | ||||||||||||
| systemd.services.falcon-sensor = { | ||||||||||||
| description = "CrowdStrike Falcon Sensor"; | ||||||||||||
| wantedBy = [ "multi-user.target" ]; | ||||||||||||
| after = [ | ||||||||||||
| "network.target" | ||||||||||||
| "local-fs.target" | ||||||||||||
| ]; | ||||||||||||
|
|
||||||||||||
| # Load the CID from environment file | ||||||||||||
| serviceConfig = { | ||||||||||||
| Type = "forking"; | ||||||||||||
| ExecStartPre = pkgs.writeShellScript "falcon-sensor-pre" '' | ||||||||||||
| # Ensure CID is configured | ||||||||||||
| if [ ! -f /etc/falcon-sensor.env ]; then | ||||||||||||
| echo "ERROR: /etc/falcon-sensor.env not found. Create it with FALCON_CID=<your-cid>" | ||||||||||||
| exit 1 | ||||||||||||
| fi | ||||||||||||
|
|
||||||||||||
| # Source the CID | ||||||||||||
| source /etc/falcon-sensor.env | ||||||||||||
| if [ -z "$FALCON_CID" ]; then | ||||||||||||
| echo "ERROR: FALCON_CID not set in /etc/falcon-sensor.env" | ||||||||||||
| exit 1 | ||||||||||||
| fi | ||||||||||||
|
|
||||||||||||
| # Set the CID if not already set | ||||||||||||
| if ! /opt/CrowdStrike/falconctl -g --cid | grep -q "$FALCON_CID"; then | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||||||||
| /opt/CrowdStrike/falconctl -s --cid="$FALCON_CID" | ||||||||||||
| fi | ||||||||||||
| ''; | ||||||||||||
| ExecStart = "${falconFhs}/bin/falcon-sensor-fhs"; | ||||||||||||
| ExecStop = "/bin/kill -TERM $MAINPID"; | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
|
||||||||||||
| ExecStop = "/bin/kill -TERM $MAINPID"; | |
| ExecStop = "${pkgs.coreutils}/bin/kill -TERM $MAINPID"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the falcon.nix file to understand the context
find . -type f -name "falcon.nix" | head -5Repository: shunkakinoki/dotfiles
Length of output: 95
🏁 Script executed:
# Search for how /bin/kill is typically handled in NixOS repositories
rg "/bin/kill" --type nix -B 2 -A 2 | head -30Repository: shunkakinoki/dotfiles
Length of output: 737
🏁 Script executed:
# Look for ExecStop patterns in the repository
rg "ExecStop" --type nix -B 1 -A 1 | head -40Repository: shunkakinoki/dotfiles
Length of output: 909
🌐 Web query:
NixOS systemd ExecStop /bin/kill best practices
💡 Result:
Best practice: don’t use ExecStop=/bin/kill … in most cases
- If you omit
ExecStop=, systemd will stop the service by sendingKillSignal=(defaultSIGTERM) to the service, wait up toTimeoutStopSec=, then (by default) sendSIGKILLif it’s still running. This is the normal/expected model. [1][2][3] - Instead of running
killyourself, prefer configuring systemd’s native knobs:KillSignal=(e.g.SIGINTif that’s what your daemon expects) [4]TimeoutStopSec=(increase/decrease graceful shutdown time) [2]KillMode=(defaults tocontrol-group, typically what you want so child processes are handled too) [4]SendSIGKILL=/FinalKillSignal=(only if you really need to change the final “hard kill” behavior) [4]
When ExecStop= is appropriate
Use ExecStop= only when the service cannot be stopped correctly by signals alone (e.g., it needs a CLI “shutdown” command, socket command, etc.). Even then, you usually still let systemd do the actual killing if the stop command doesn’t complete in time (via TimeoutStopSec= + default kill behavior). [2][4]
NixOS-specific recommendations
- Avoid
/bin/kill: on NixOS it may not exist or may not be what you expect; prefer either:- No
ExecStopat all (recommended), plusserviceConfig.KillSignal = ...;, or - an explicit store path like
${pkgs.coreutils}/bin/kill/${pkgs.procps}/bin/pkillif you truly must run a kill command.
- No
- Prefer systemd options inside
systemd.services.<name>.serviceConfig = { ... };(NixOS passes these through to systemd). The NixOS wiki examples show configuringExecStart/ExecStopviaserviceConfig. [5]
Good NixOS patterns (examples)
1) Typical long-running service: no ExecStop, tune signal/timeout
systemd.services.myDaemon = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.myDaemon}/bin/my-daemon"; # should not daemonize
Type = "simple";
KillSignal = "SIGTERM"; # or "SIGINT" if that’s what it expects
TimeoutStopSec = "30s";
KillMode = "control-group";
};
};2) If you truly need a custom stop command
systemd.services.myDaemon = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${pkgs.myDaemon}/bin/my-daemon";
ExecStop = "${pkgs.myDaemon}/bin/my-daemon --shutdown";
TimeoutStopSec = "60s"; # if shutdown is slow
};
};Rule of thumb: if you’re reaching for ExecStop=… kill …, first try KillSignal= (and ensure the daemon runs in the foreground so systemd can track it). That’s the “systemd-native” approach. [1][4]
Sources
[1] https://unix.stackexchange.com/questions/737186/how-can-a-service-daemon-shut-down-normally-without-an-execstop-syntax
[2] https://man7.org/linux/man-pages/man5/systemd.service.5%40%40systemd.html
[3] https://unix.stackexchange.com/questions/255438/making-systemctl-to-shutdown-process-gracefully
[4] https://man7.org/linux/man-pages/man5/systemd.kill.5.html
[5] https://wiki.nixos.org/wiki/Systemd/Hardening/en
🏁 Script executed:
# Let's see the full systemd service configuration in falcon.nix
cat -n named-hosts/matic/falcon.nix | sed -n '50,80p'Repository: shunkakinoki/dotfiles
Length of output: 1143
🏁 Script executed:
# Check if there's any Type configuration that affects how the service stops
rg -A 15 "ExecStart.*falcon-sensor" named-hosts/matic/falcon.nixRepository: shunkakinoki/dotfiles
Length of output: 1093
Avoid hard‑coding /bin/kill in ExecStop on NixOS.
Line 66 assumes /bin/kill exists, which isn't guaranteed on NixOS. Since the service already has KillMode = "process" configured, omit ExecStop entirely to let systemd handle the graceful SIGTERM shutdown natively (default behavior). If a custom stop command is truly required, use an explicit store path like ${pkgs.coreutils}/bin/kill.
✅ Minimal fix (remove ExecStop)
- ExecStop = "/bin/kill -TERM $MAINPID";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ExecStart = "${falconFhs}/bin/falcon-sensor-fhs"; | |
| ExecStop = "/bin/kill -TERM $MAINPID"; | |
| Restart = "on-failure"; | |
| ExecStart = "${falconFhs}/bin/falcon-sensor-fhs"; | |
| Restart = "on-failure"; |
🤖 Prompt for AI Agents
In `@named-hosts/matic/falcon.nix` around lines 65 - 67, Remove the hard-coded
ExecStop entry that calls "/bin/kill" and let systemd handle termination via the
existing KillMode = "process" (i.e. delete the ExecStop = "/bin/kill -TERM
$MAINPID"; line), or if you truly need a custom stop command, replace it with
the explicit Nix store path for kill (e.g. use ${pkgs.coreutils}/bin/kill) so
ExecStop references a store path instead of /bin/kill; update the unit block
containing ExecStart = "${falconFhs}/bin/falcon-sensor-fhs"; Restart =
"on-failure"; and KillMode accordingly.
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment # Security hardening is followed by settings that explicitly disable hardening (ProtectHome = false, ProtectSystem = false, PrivateTmp = false). Either update the comment to reflect that these are compatibility overrides, or adjust the settings so the label matches the configuration.
| # Security hardening | |
| # Security hardening compatibility overrides (disabled for sensor requirements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabling all systemd security hardening (ProtectHome, ProtectSystem, PrivateTmp) should be justified with comments explaining why each protection must be disabled. CrowdStrike likely needs system access for EDR functionality, but blanket disabling all protections without documentation makes it difficult to assess if these are truly necessary or could be scoped more narrowly (e.g., ProtectSystem = "strict" with specific writable paths).
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#724
File: named-hosts/matic/falcon.nix#L72
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
Disabling all systemd security hardening (ProtectHome, ProtectSystem, PrivateTmp) should be justified with comments explaining why each protection must be disabled. CrowdStrike likely needs system access for EDR functionality, but blanket disabling all protections without documentation makes it difficult to assess if these are truly necessary or could be scoped more narrowly (e.g., ProtectSystem = "strict" with specific writable paths).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabling systemd's security hardening features (ProtectHome, ProtectSystem, PrivateTmp) significantly weakens the service's sandbox and increases the system's attack surface. While an endpoint security tool might require this level of access, it's a major security trade-off. The comment on line 71, "Security hardening", is also misleading since these settings disable it. The comment should be updated to reflect this, and if possible, more granular permissions should be investigated instead of disabling these protections entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading a custom kernel module 'falcon' without any source, verification, or error handling is a significant security and stability risk. This module isn't defined anywhere in this configuration and must be manually compiled/installed from the CrowdStrike .deb. Consider: 1) Adding a check in ExecStartPre that fails gracefully if the module isn't available, 2) Documenting where this module comes from and how to install it, 3) Adding a commented-out boot.extraModulePackages if there's a way to package it declaratively.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#724
File: named-hosts/matic/falcon.nix#L84
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
Loading a custom kernel module 'falcon' without any source, verification, or error handling is a significant security and stability risk. This module isn't defined anywhere in this configuration and must be manually compiled/installed from the CrowdStrike .deb. Consider: 1) Adding a check in ExecStartPre that fails gracefully if the module isn't available, 2) Documenting where this module comes from and how to install it, 3) Adding a commented-out boot.extraModulePackages if there's a way to package it declaratively.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,120 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Kolide Launcher configuration for NixOS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Prerequisites (manual steps): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 1. Obtain the Kolide launcher .deb from IT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 2. Extract the enrollment secret: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # nix-shell -p dpkg --run 'dpkg-deb -x ~/Downloads/kolide-launcher.deb /tmp/kolide-deb' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # cat /tmp/kolide-deb/etc/kolide-k2/secret | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 3. Install secret to /etc/kolide-k2/secret (root:root, 0600) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # The dpkg status shim below satisfies Kolide's osquery deb_packages check | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # for CrowdStrike compliance on NixOS (which has no dpkg database). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lib, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Kolide launcher package (download from company portal) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This is a placeholder - the actual binary needs to be extracted from the .deb | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kolideLauncher = pkgs.stdenv.mkDerivation { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This creates a non-functional package that just wraps a manually-installed binary. This approach bypasses NixOS's declarative package management and prevents reproducible deployments. Consider: 1) Fetching the .deb file from a private source using fetchurl with a hash, 2) Extracting and patching the binary in the derivation using autoPatchelfHook, or 3) Creating an overlay that properly packages the launcher binary. This would align with NixOS principles and enable 'nixos-rebuild' to fully manage the installation. Prompt for Agent |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pname = "kolide-launcher"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version = "1.0.0"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+25
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # No source - we expect the binary to be manually installed to /opt/kolide-k2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dontUnpack = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dontBuild = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| installPhase = '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mkdir -p $out/bin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Create a wrapper that points to the manually installed binary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cat > $out/bin/kolide-launcher << 'EOF' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/bin/sh | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exec /opt/kolide-k2/bin/launcher "$@" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| chmod +x $out/bin/kolide-launcher | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # FHS environment for Kolide launcher | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kolideFhs = pkgs.buildFHSEnv { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name = "kolide-launcher-fhs"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| targetPkgs = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pkgs: with pkgs; [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| coreutils | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| glibc | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gnugrep | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nodejs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| openssl | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| zlib | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runScript = "/opt/kolide-k2/bin/launcher"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # dpkg status shim for Kolide/osquery compliance | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # NixOS has no dpkg database, so Kolide's osquery deb_packages check fails. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This shim reports falcon-sensor as "installed" to satisfy the CrowdStrike check. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd.tmpfiles.rules = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Create dpkg directory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "d /var/lib/dpkg 0755 root root -" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Create dpkg status file with falcon-sensor entry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "f /var/lib/dpkg/status 0644 root root - Package: falcon-sensor\nStatus: install ok installed\nPriority: optional\nSection: misc\nInstalled-Size: 0\nMaintainer: CrowdStrike\nArchitecture: amd64\nVersion: 7.31.0-18410\nDescription: CrowdStrike Falcon Sensor (shim for Kolide/osquery on NixOS)\n" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Comment on lines
+61
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: In Newlines / escapes in
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| systemd.tmpfiles.rules = [ | |
| # Create dpkg directory | |
| "d /var/lib/dpkg 0755 root root -" | |
| # Create dpkg status file with falcon-sensor entry | |
| "f /var/lib/dpkg/status 0644 root root - Package: falcon-sensor\nStatus: install ok installed\nPriority: optional\nSection: misc\nInstalled-Size: 0\nMaintainer: CrowdStrike\nArchitecture: amd64\nVersion: 7.31.0-18410\nDescription: CrowdStrike Falcon Sensor (shim for Kolide/osquery on NixOS)\n" | |
| systemd.tmpfiles.rules = [ | |
| # Create dpkg directory | |
| "d /var/lib/dpkg 0755 root root -" | |
| # Create dpkg status file with falcon-sensor entry | |
| "f /var/lib/dpkg/status 0644 root root - ${ | |
| lib.concatStringsSep "\\n" [ | |
| "Package: falcon-sensor" | |
| "Status: install ok installed" | |
| "Priority: optional" | |
| "Section: misc" | |
| "Installed-Size: 0" | |
| "Maintainer: CrowdStrike" | |
| "Architecture: amd64" | |
| "Version: 7.31.0-18410" | |
| "Description: CrowdStrike Falcon Sensor (shim for Kolide/osquery on NixOS)" | |
| "" | |
| ] | |
| }" |
🤖 Prompt for AI Agents
In `@named-hosts/matic/kolide.nix` around lines 54 - 58, The
systemd.tmpfiles.rules entry that creates "/var/lib/dpkg/status" uses Nix "\n"
which becomes real newlines and will break tmpfiles' single-line rule format;
update the string in systemd.tmpfiles.rules (the rule that starts with "f
/var/lib/dpkg/status") to escape backslashes so C-style escape sequences are
preserved (replace each "\n" with "\\n") so systemd sees literal "\n" characters
in the rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This dpkg status shim hardcodes version '7.31.0-18410' which will immediately become stale. When the actual Falcon sensor is updated (either manually or via the service), this shim will report an incorrect version to Kolide's compliance checks, potentially causing false positives/negatives. Consider: 1) Reading the version dynamically from the actual Falcon installation, 2) Using a variable that can be kept in sync, or 3) Documenting that this needs manual updates when Falcon is upgraded.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#724
File: named-hosts/matic/kolide.nix#L58
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
This dpkg status shim hardcodes version '7.31.0-18410' which will immediately become stale. When the actual Falcon sensor is updated (either manually or via the service), this shim will report an incorrect version to Kolide's compliance checks, potentially causing false positives/negatives. Consider: 1) Reading the version dynamically from the actual Falcon installation, 2) Using a variable that can be kept in sync, or 3) Documenting that this needs manual updates when Falcon is upgraded.
Copilot
AI
Feb 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tmpfiles rule for /var/lib/dpkg/status embeds literal newlines (via \n) inside a single rule string. When Nix writes the tmpfiles.d file, this becomes multiple lines; only the first line starts with a tmpfiles directive, and the following lines (e.g. Status: ...) will be parsed as invalid tmpfiles entries, likely causing systemd-tmpfiles failures at boot/activation. Write the status file via a tmpfiles C (copy) rule from a pkgs.writeText file, or generate the file in an activation/script step, so the tmpfiles rules remain single-line entries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Kolide enrollment secret should be managed via the repository's existing agenix/sops-nix secrets infrastructure rather than requiring manual file placement. This would: 1) Enable declarative secret management, 2) Provide proper encryption at rest in the git repository, 3) Follow the established pattern used elsewhere in this dotfiles repo (see named-hosts/SECRETS.md). Consider using age.secrets.kolide-enrollment-secret similar to how other secrets are managed.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#724
File: named-hosts/matic/kolide.nix#L76
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
The Kolide enrollment secret should be managed via the repository's existing agenix/sops-nix secrets infrastructure rather than requiring manual file placement. This would: 1) Enable declarative secret management, 2) Provide proper encryption at rest in the git repository, 3) Follow the established pattern used elsewhere in this dotfiles repo (see named-hosts/SECRETS.md). Consider using age.secrets.kolide-enrollment-secret similar to how other secrets are managed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce secure permissions for the enrollment secret before starting.
Line 75‑83 only checks for existence; if the secret is world-readable, the service still starts. Fail fast unless owner is root and mode is 0600.
🔐 Suggested fix
if [ ! -f /etc/kolide-k2/secret ]; then
echo "ERROR: /etc/kolide-k2/secret not found."
echo "Extract from company .deb and install with:"
echo " sudo install -d -m 755 /etc/kolide-k2"
echo " sudo sh -c 'cat <secret> > /etc/kolide-k2/secret'"
echo " sudo chown root:root /etc/kolide-k2/secret"
echo " sudo chmod 600 /etc/kolide-k2/secret"
exit 1
fi
+
+ # Enforce secure permissions on enrollment secret
+ if [ "$(stat -c '%a' /etc/kolide-k2/secret)" != "600" ] || \
+ [ "$(stat -c '%U:%G' /etc/kolide-k2/secret)" != "root:root" ]; then
+ echo "ERROR: /etc/kolide-k2/secret must be root:root with 0600 permissions."
+ exit 1
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ExecStartPre = pkgs.writeShellScript "kolide-launcher-pre" '' | |
| # Ensure enrollment secret exists | |
| if [ ! -f /etc/kolide-k2/secret ]; then | |
| echo "ERROR: /etc/kolide-k2/secret not found." | |
| echo "Extract from company .deb and install with:" | |
| echo " sudo install -d -m 755 /etc/kolide-k2" | |
| echo " sudo sh -c 'cat <secret> > /etc/kolide-k2/secret'" | |
| echo " sudo chown root:root /etc/kolide-k2/secret" | |
| echo " sudo chmod 600 /etc/kolide-k2/secret" | |
| exit 1 | |
| ExecStartPre = pkgs.writeShellScript "kolide-launcher-pre" '' | |
| # Ensure enrollment secret exists | |
| if [ ! -f /etc/kolide-k2/secret ]; then | |
| echo "ERROR: /etc/kolide-k2/secret not found." | |
| echo "Extract from company .deb and install with:" | |
| echo " sudo install -d -m 755 /etc/kolide-k2" | |
| echo " sudo sh -c 'cat <secret> > /etc/kolide-k2/secret'" | |
| echo " sudo chown root:root /etc/kolide-k2/secret" | |
| echo " sudo chmod 600 /etc/kolide-k2/secret" | |
| exit 1 | |
| fi | |
| # Enforce secure permissions on enrollment secret | |
| if [ "$(stat -c '%a' /etc/kolide-k2/secret)" != "600" ] || \ | |
| [ "$(stat -c '%U:%G' /etc/kolide-k2/secret)" != "root:root" ]; then | |
| echo "ERROR: /etc/kolide-k2/secret must be root:root with 0600 permissions." | |
| exit 1 | |
| fi |
🤖 Prompt for AI Agents
In `@named-hosts/matic/kolide.nix` around lines 74 - 83, The pre-start script
currently only checks for existence of /etc/kolide-k2/secret; update
ExecStartPre (kolide-launcher-pre) to also verify the file is owned by root (UID
0) and has mode 0600, and fail if not. Specifically, after the existence check,
call stat to read the file owner UID and permission bits and if owner != 0 or
permissions != 600, print a clear error explaining the required owner/mode and
exit 1; keep the message referencing /etc/kolide-k2/secret and the script name
kolide-launcher-pre so the check is easy to locate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to Falcon, all systemd security hardening is disabled without justification. Add comments explaining why Kolide requires each of these protections to be disabled, or scope them more narrowly if possible. For example, if Kolide only needs read access to /home, consider 'ProtectHome = "read-only"' instead of false.
Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#724
File: named-hosts/matic/kolide.nix#L98
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.
Feedback:
Similar to Falcon, all systemd security hardening is disabled without justification. Add comments explaining why Kolide requires each of these protections to be disabled, or scope them more narrowly if possible. For example, if Kolide only needs read access to /home, consider 'ProtectHome = "read-only"' instead of false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the Falcon service, systemd's security hardening features (ProtectHome, ProtectSystem, PrivateTmp) are disabled here. While the comment provides a reason, this still represents a significant security risk by weakening the service's sandbox. If possible, consider using more granular permissions (e.g., ReadWritePaths with ProtectSystem=strict) instead of disabling these protections entirely to limit the service's access to only what is necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This configuration requires manual management of secrets in /etc/falcon-sensor.env, but this repository already has agenix/sops-nix infrastructure (see named-hosts/SECRETS.md and multiple .age files in named-hosts/). Consider integrating with the existing secrets management system using age.secrets to provide the FALCON_CID, which would be more consistent with the repository's security patterns and enable declarative secret deployment.
Prompt for Agent