Thanks to https://github.com/devusb/sentinelone-nix
This commit is contained in:
2025-11-17 09:26:08 +00:00
parent a8518a360c
commit 679c3f4354
4 changed files with 251 additions and 2 deletions

View File

@@ -0,0 +1,184 @@
{
lib,
pkgs,
config,
...
}:
with lib;
let
cfg = config.services.sentinelone;
customerId =
cfg.customerId or (
if cfg.email != null && cfg.serialNumber != null then "${cfg.email}-${cfg.serialNumber}" else null
);
hasCustomerId = customerId != null;
initScript = pkgs.writeShellScriptBin "sentinelone-init.sh" ''
#!/bin/bash
mkdir -p ${cfg.dataDir}
# initialize the data directory
if [ -z "$(ls -A ${cfg.dataDir} 2>/dev/null)" ]; then
find "${cfg.package}/opt/sentinelone/" -mindepth 1 -maxdepth 1 ! -name "bin" ! -name "ebpfs" ! -name "lib" ! -name "ranger" -exec cp -r {} "${cfg.dataDir}/" \;
cat << EOF > ${cfg.dataDir}/configuration/install_config
S1_AGENT_MANAGEMENT_TOKEN=$(cat ${cfg.sentinelOneManagementTokenPath})
S1_AGENT_DEVICE_TYPE=desktop
S1_AGENT_AUTO_START=true
${optionalString hasCustomerId "S1_AGENT_CUSTOMER_ID=${customerId}"}
EOF
cat << EOF > ${cfg.dataDir}/configuration/installation_params.json
{
"PACKAGE_TYPE": "deb",
"SERVICE_TYPE": "systemd"
}
EOF
siteKey=$(cat ${cfg.sentinelOneManagementTokenPath} | base64 -d | ${getExe pkgs.jq} .site_key)
mgmtUrl=$(cat ${cfg.sentinelOneManagementTokenPath} | base64 -d | ${getExe pkgs.jq} .url)
cat << EOF > ${cfg.dataDir}/configuration/basic.conf
{
"mgmt_device-type": 1,
"mgmt_site-key": $siteKey,
"mgmt_url": $mgmtUrl
}
EOF
chown -R sentinelone:sentinelone ${cfg.dataDir}
chmod -R 0755 $(find ${cfg.dataDir} -group sentinelone)
fi
'';
in
{
options = {
services = {
sentinelone = {
enable = mkEnableOption "SentinelOne Service";
package = mkPackageOption pkgs "sentinelone" { };
customerId = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Set a customer specific identifier for the host. It is common practice to set this as your email and serial number separated by a hyphen.
'';
example = "me@gmail.com-FTXYZWW";
};
email = mkOption {
type = types.nullOr types.str;
default = null;
example = "me@gmail.com";
};
serialNumber = mkOption {
type = types.nullOr types.str;
default = null;
example = "FTXYZWW";
};
sentinelOneManagementTokenPath = mkOption {
type = types.path;
example = "/run/secrets/s1_mgmt_token";
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/sentinelone";
};
};
};
};
config = mkIf cfg.enable {
warnings =
optional (cfg.email != null) "services.sentinelone.email is deprecated in favour of customerId."
++ optional (
cfg.serialNumber != null
) "services.sentinelone.serialNumber is deprecated in favour of customerId.";
assertions = [
{
assertion = (cfg.customerId != null) -> (cfg.email == null && cfg.serialNumber == null);
message = ''
You cannot use services.sentinelone.customerId with the deprecated services.sentinelone.email and services.sentinelone.serialNumber options.
'';
}
{
assertion = (cfg.email != null) -> (cfg.serialNumber != null);
message = ''
services.sentinelone.email requires services.sentinelone.serialNumber to also be set.
'';
}
{
assertion = (cfg.serialNumber != null) -> (cfg.email != null);
message = ''
services.sentinelone.serialNumber requires services.sentinelone.email to also be set.
'';
}
];
users.users.sentinelone = {
isSystemUser = true;
createHome = true;
shell = "${pkgs.shadow}/bin/nologin";
group = "sentinelone";
};
users.groups.sentinelone = { };
systemd.services.sentinelone-init = {
wantedBy = [ "sentinelone.service" ];
before = [ "sentinelone.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${getExe initScript}";
};
};
environment.systemPackages = [
cfg.package
];
systemd.services.sentinelone = {
enable = true;
description = "SentinelOne";
path = [
pkgs.coreutils-full
pkgs.gawk
pkgs.zlib
pkgs.libelf
pkgs.bash
];
unitConfig = {
Description = "SentinelOne";
After = [
"uptrack-prefetch.service"
"uptrack.service"
];
StartLimitInterval = "90";
StartLimitBurst = "4";
};
serviceConfig = {
Type = "forking";
ExecStart = "${cfg.package}/bin/sentinelctl control run";
WorkingDirectory = "/opt/sentinelone/bin";
SyslogIdentifier = "${cfg.dataDir}/log";
WatchdogSec = "5s";
Restart = "always";
RestartSec = "4";
RefuseManualStop = "yes";
MemoryMax = "18446744073709543424";
ExecStop = "${cfg.package}/bin/sentinelctl control shutdown";
NotifyAccess = "all";
KillMode = "process";
TasksMax = "infinity";
BindPaths = [
"${cfg.dataDir}:/opt/sentinelone"
];
BindReadOnlyPaths = [
"${cfg.package}/opt/sentinelone/bin:/opt/sentinelone/bin"
"${cfg.package}/opt/sentinelone/ebpfs:/opt/sentinelone/ebpfs"
"${cfg.package}/opt/sentinelone/lib:/opt/sentinelone/lib"
"${cfg.package}/opt/sentinelone/ranger:/opt/sentinelone/ranger"
];
};
wantedBy = [ "multi-user.target" ];
};
};
}