fix(ops/irccat): Avoid permissions issue with LoadCredentials=

The DynamicUser + Group configuration does not work as planned, thus
the systemd LoadCredentials feature is used instead which makes the
file (which itself is only readable by root) available in a
memory-backed location only readable by the service.

The secret is only available to `ExecStart` commands, so units using
this feature can not be used with pre/post units and the like if those
commands need secrets.

To accommodate this, the merge of configuration files has been moved
into the service launch script, which is now the ExecStart= process.

For details take a look at https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LoadCredential=ID:PATH

Change-Id: I693fe5677cc0d63c7aa485c2c7472457c5262166
This commit is contained in:
Vincent Ambo 2021-12-10 17:10:50 +03:00 committed by clbot
parent 67bde5ecc3
commit b8267c261c
2 changed files with 8 additions and 15 deletions

View file

@ -209,6 +209,7 @@ in {
in {
clbot.file = secretFile "clbot";
gerrit-queue.file = secretFile "gerrit-queue";
irccat.file = secretFile "irccat";
owothia.file = secretFile "owothia";
buildkite-agent-token = {
@ -221,12 +222,6 @@ in {
file = secretFile "clbot-ssh";
owner = "clbot";
};
irccat = {
file = secretFile "irccat";
mode = "0440";
group = "irccat";
};
};
# Automatically collect garbage from the Nix store.

View file

@ -11,15 +11,17 @@ let
# then recursively merge it with an on-disk secret using jq on
# service launch.
configJson = pkgs.writeText "irccat.json" (builtins.toJSON cfg.config);
configMerge = pkgs.writeShellScript "merge-irccat-config" ''
if [ ! -f "${cfg.secretsFile}" ]; then
mergeAndLaunch = pkgs.writeShellScript "merge-irccat-config" ''
if [ ! -f "$CREDENTIALS_DIRECTORY/secrets" ]; then
echo "irccat secrets file is missing"
exit 1
fi
# jq's * is the recursive merge operator
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configJson} ${cfg.secretsFile} \
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configJson} "$CREDENTIALS_DIRECTORY/secrets" \
> /var/lib/irccat/irccat.json
exec ${depot.third_party.irccat}/bin/irccat
'';
in {
options.services.depot.irccat = {
@ -40,20 +42,16 @@ in {
config = lib.mkIf cfg.enable {
systemd.services.irccat = {
inherit description;
preStart = "${configMerge}";
script = "${depot.third_party.irccat}/bin/irccat";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${mergeAndLaunch}";
DynamicUser = true;
Group = "irccat";
StateDirectory = "irccat";
WorkingDirectory = "/var/lib/irccat";
LoadCredential = "secrets:${cfg.secretsFile}";
Restart = "always";
};
};
# Create a real group to grant access to secrets to.
users.groups.irccat = {};
};
}