10
flake.nix
10
flake.nix
@@ -104,8 +104,9 @@
|
|||||||
weather = super.callPackage ./pkgs/weather { };
|
weather = super.callPackage ./pkgs/weather { };
|
||||||
nicer = super.callPackage ./pkgs/nicer.nix { };
|
nicer = super.callPackage ./pkgs/nicer.nix { };
|
||||||
tmuxbash = super.callPackage ./pkgs/tmuxbash.nix { };
|
tmuxbash = super.callPackage ./pkgs/tmuxbash.nix { };
|
||||||
vanta-agent = super.callPackage ./pkgs/vanta-agent.nix { };
|
sentinelone = super.callPackage ./pkgs/sentinelone { };
|
||||||
chronoctl = super.callPackage ./pkgs/chronoctl.nix { };
|
chronoctl = super.callPackage ./pkgs/chronoctl.nix { };
|
||||||
|
vanta-agent = super.callPackage ./pkgs/vanta-agent.nix { };
|
||||||
gcloud-wrapped = super.callPackage ./pkgs/gcloud-wrapped { };
|
gcloud-wrapped = super.callPackage ./pkgs/gcloud-wrapped { };
|
||||||
go-raceless = super.callPackage ./pkgs/go-raceless { };
|
go-raceless = super.callPackage ./pkgs/go-raceless { };
|
||||||
|
|
||||||
@@ -359,7 +360,12 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages.x86_64-linux = {
|
packages.x86_64-linux = {
|
||||||
inherit (pkgs) weather gamja chronoctl;
|
inherit (pkgs)
|
||||||
|
weather
|
||||||
|
gamja
|
||||||
|
chronoctl
|
||||||
|
sentinelone
|
||||||
|
;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
./ping_exporter
|
./ping_exporter
|
||||||
./postfix
|
./postfix
|
||||||
./printing
|
./printing
|
||||||
|
./sentinelone
|
||||||
./ssh8022
|
./ssh8022
|
||||||
./syncthing
|
./syncthing
|
||||||
./syncthing-relay
|
./syncthing-relay
|
||||||
|
|||||||
184
modules/services/sentinelone/default.nix
Normal file
184
modules/services/sentinelone/default.nix
Normal 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" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
58
pkgs/sentinelone/default.nix
Normal file
58
pkgs/sentinelone/default.nix
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
fetchurl,
|
||||||
|
dpkg,
|
||||||
|
autoPatchelfHook,
|
||||||
|
zlib,
|
||||||
|
elfutils,
|
||||||
|
dmidecode,
|
||||||
|
jq,
|
||||||
|
gcc-unwrapped,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
sentinelOnePackage = "SentinelAgent_linux_x86_64_v25_2_2_14.deb";
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "sentinelone";
|
||||||
|
version = "25.2.2.14";
|
||||||
|
|
||||||
|
src = fetchurl {
|
||||||
|
url = "http://hdd.jakstys.lt/Motiejaus/${sentinelOnePackage}";
|
||||||
|
hash = "sha256-ZWtuJ/ua2roIz2I/4CicnVXlc1Sj5w/r412pS5KfmOA=";
|
||||||
|
};
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
runHook preUnpack
|
||||||
|
|
||||||
|
dpkg-deb -x $src .
|
||||||
|
|
||||||
|
runHook postUnpack
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
dpkg
|
||||||
|
autoPatchelfHook
|
||||||
|
zlib
|
||||||
|
elfutils
|
||||||
|
dmidecode
|
||||||
|
jq
|
||||||
|
gcc-unwrapped
|
||||||
|
];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/opt/
|
||||||
|
mkdir -p $out/cfg/
|
||||||
|
mkdir -p $out/bin/
|
||||||
|
|
||||||
|
cp -r opt/* $out/opt
|
||||||
|
|
||||||
|
ln -s $out/opt/sentinelone/bin/sentinelctl $out/bin/sentinelctl
|
||||||
|
ln -s $out/opt/sentinelone/bin/sentinelone-agent $out/bin/sentinelone-agent
|
||||||
|
ln -s $out/opt/sentinelone/bin/sentinelone-watchdog $out/bin/sentinelone-watchdog
|
||||||
|
ln -s $out/opt/sentinelone/lib $out/lib
|
||||||
|
'';
|
||||||
|
|
||||||
|
preFixup = ''
|
||||||
|
patchelf --replace-needed libelf.so.0 libelf.so $out/opt/sentinelone/lib/libbpf.so
|
||||||
|
'';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user