190 lines
6.9 KiB
Nix
190 lines
6.9 KiB
Nix
{ config, pkgs, ... }:
|
|
let
|
|
clientScript = ./orga-agent/client.py;
|
|
previewScript = ./orga-agent/preview.py;
|
|
readServerScript = ./orga-agent/read_server.py;
|
|
writeServerScript = ./orga-agent/write_server.py;
|
|
draftServerScript = ./orga-agent/draft_server.py;
|
|
client = pkgs.writeShellApplication {
|
|
name = "orga-client-internal";
|
|
runtimeInputs = [ pkgs.python3 ];
|
|
text = ''exec ${pkgs.python3}/bin/python3 ${clientScript} "$@"'';
|
|
};
|
|
calendarClient = pkgs.writeShellApplication {
|
|
name = "orga-calendar";
|
|
text = ''exec ${client}/bin/orga-client-internal calendar "$@"'';
|
|
};
|
|
mailClient = pkgs.writeShellApplication {
|
|
name = "orga-mail-read";
|
|
text = ''exec ${client}/bin/orga-client-internal mail "$@"'';
|
|
};
|
|
calendarWriteClient = pkgs.writeShellApplication {
|
|
name = "orga-calendar-write";
|
|
text = ''exec ${client}/bin/orga-client-internal calendar-write "$@"'';
|
|
};
|
|
previewClient = pkgs.writeShellApplication {
|
|
name = "orga-write-preview";
|
|
runtimeInputs = [ pkgs.python3 ];
|
|
text = ''exec ${pkgs.python3}/bin/python3 ${previewScript} "$@"'';
|
|
};
|
|
mailDraftClient = pkgs.writeShellApplication {
|
|
name = "orga-mail-draft";
|
|
text = ''exec ${client}/bin/orga-client-internal mail-draft "$@"'';
|
|
};
|
|
commonServiceConfig = {
|
|
Type = "simple";
|
|
StandardInput = "socket";
|
|
StandardOutput = "journal";
|
|
StandardError = "journal";
|
|
UMask = "0077";
|
|
NoNewPrivileges = true;
|
|
PrivateDevices = true;
|
|
PrivateTmp = true;
|
|
ProtectClock = true;
|
|
ProtectControlGroups = true;
|
|
ProtectHome = true;
|
|
ProtectHostname = true;
|
|
ProtectKernelLogs = true;
|
|
ProtectKernelModules = true;
|
|
ProtectKernelTunables = true;
|
|
ProtectSystem = "strict";
|
|
LockPersonality = true;
|
|
MemoryDenyWriteExecute = true;
|
|
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
|
RestrictRealtime = true;
|
|
RestrictSUIDSGID = true;
|
|
SystemCallArchitectures = "native";
|
|
};
|
|
socketConfig = {
|
|
SocketMode = "0660";
|
|
SocketUser = "root";
|
|
SocketGroup = "orga-agent";
|
|
RemoveOnStop = true;
|
|
};
|
|
in
|
|
{
|
|
users.groups.orga-calendar-read = { };
|
|
users.groups.orga-calendar-write = { };
|
|
users.groups.orga-mail-read = { };
|
|
users.groups.orga-mail-draft = { };
|
|
users.groups.orga-agent = { };
|
|
users.users.drone.extraGroups = [ "orga-agent" ];
|
|
users.users.orga-calendar-read = {
|
|
isSystemUser = true;
|
|
group = "orga-calendar-read";
|
|
};
|
|
users.users.orga-calendar-write = {
|
|
isSystemUser = true;
|
|
group = "orga-calendar-write";
|
|
};
|
|
users.users.orga-mail-read = {
|
|
isSystemUser = true;
|
|
group = "orga-mail-read";
|
|
};
|
|
users.users.orga-mail-draft = {
|
|
isSystemUser = true;
|
|
group = "orga-mail-draft";
|
|
};
|
|
|
|
environment.systemPackages = [ calendarClient calendarWriteClient mailClient mailDraftClient previewClient ];
|
|
|
|
systemd.sockets.orga-calendar-read = {
|
|
description = "Local socket for the read-only Orga CalDAV capability";
|
|
wantedBy = [ "sockets.target" ];
|
|
listenStreams = [ "/run/orga-calendar-read.sock" ];
|
|
inherit socketConfig;
|
|
};
|
|
systemd.services.orga-calendar-read = {
|
|
description = "Read-only, secret-holding Orga CalDAV service";
|
|
requires = [ "orga-calendar-read.socket" ];
|
|
after = [ "network-online.target" "orga-calendar-read.socket" ];
|
|
wants = [ "network-online.target" ];
|
|
environment = {
|
|
ORGA_CALENDAR_URL = "https://calendar.${config.domain}/calendar/public";
|
|
ORGA_CALENDAR_USER = "calendar";
|
|
ORGA_CALENDAR_PASSWORD_FILE = config.age.secrets.orgaCalendarPw.path;
|
|
};
|
|
serviceConfig = commonServiceConfig // {
|
|
User = "orga-calendar-read";
|
|
Group = "orga-calendar-read";
|
|
ExecStart = "${pkgs.python3}/bin/python3 ${readServerScript} --capability calendar";
|
|
};
|
|
};
|
|
|
|
systemd.sockets.orga-calendar-write = {
|
|
description = "Local socket for the write-capable, admin-scope Orga CalDAV capability";
|
|
wantedBy = [ "sockets.target" ];
|
|
listenStreams = [ "/run/orga-calendar-write.sock" ];
|
|
inherit socketConfig;
|
|
};
|
|
systemd.services.orga-calendar-write = {
|
|
description = "Write-capable, secret-holding Orga CalDAV admin service";
|
|
requires = [ "orga-calendar-write.socket" ];
|
|
after = [ "network-online.target" "orga-calendar-write.socket" ];
|
|
wants = [ "network-online.target" ];
|
|
environment = {
|
|
# Root of Radicale, not a single collection -- write_server.py takes
|
|
# the target collection per-request (validated, no path traversal)
|
|
# so this identity can reach any of them, matching the
|
|
# "05-calendar-admin-full-access" rights rule.
|
|
ORGA_CALENDAR_URL = "https://calendar.${config.domain}";
|
|
ORGA_CALENDAR_USER = "calendar";
|
|
ORGA_CALENDAR_PASSWORD_FILE = config.age.secrets.orgaCalendarWritePw.path;
|
|
};
|
|
serviceConfig = commonServiceConfig // {
|
|
User = "orga-calendar-write";
|
|
Group = "orga-calendar-write";
|
|
ExecStart = "${pkgs.python3}/bin/python3 ${writeServerScript}";
|
|
};
|
|
};
|
|
|
|
systemd.sockets.orga-mail-read = {
|
|
description = "Local socket for the read-only Orga IMAP capability";
|
|
wantedBy = [ "sockets.target" ];
|
|
listenStreams = [ "/run/orga-mail-read.sock" ];
|
|
inherit socketConfig;
|
|
};
|
|
systemd.services.orga-mail-read = {
|
|
description = "Read-only, secret-holding Orga IMAP service";
|
|
requires = [ "orga-mail-read.socket" ];
|
|
after = [ "network-online.target" "orga-mail-read.socket" ];
|
|
wants = [ "network-online.target" ];
|
|
environment = {
|
|
ORGA_MAIL_HOST = "imappro.zoho.eu";
|
|
ORGA_MAIL_USER = "mail@lukasrosier.com";
|
|
ORGA_MAIL_PASSWORD_FILE = config.age.secrets.orgaMailPw.path;
|
|
};
|
|
serviceConfig = commonServiceConfig // {
|
|
User = "orga-mail-read";
|
|
Group = "orga-mail-read";
|
|
ExecStart = "${pkgs.python3}/bin/python3 ${readServerScript} --capability mail";
|
|
};
|
|
};
|
|
|
|
systemd.sockets.orga-mail-draft = {
|
|
description = "Local socket for the Orga mail-draft capability (IMAP Drafts folder only)";
|
|
wantedBy = [ "sockets.target" ];
|
|
listenStreams = [ "/run/orga-mail-draft.sock" ];
|
|
inherit socketConfig;
|
|
};
|
|
systemd.services.orga-mail-draft = {
|
|
description = "Write-scoped, secret-holding Orga IMAP mail-draft service (Drafts folder only, no SMTP)";
|
|
requires = [ "orga-mail-draft.socket" ];
|
|
after = [ "network-online.target" "orga-mail-draft.socket" ];
|
|
wants = [ "network-online.target" ];
|
|
environment = {
|
|
# Same account orga-mail-read uses, same host/user -- a separate
|
|
# agenix runtime copy of the same underlying credential, so this
|
|
# service's process/journal never shares a secret path with the
|
|
# read-only one (see secrets.nix, "Separate runtime copies").
|
|
ORGA_MAIL_HOST = "imappro.zoho.eu";
|
|
ORGA_MAIL_USER = "mail@lukasrosier.com";
|
|
ORGA_MAIL_PASSWORD_FILE = config.age.secrets.orgaMailDraftPw.path;
|
|
};
|
|
serviceConfig = commonServiceConfig // {
|
|
User = "orga-mail-draft";
|
|
Group = "orga-mail-draft";
|
|
ExecStart = "${pkgs.python3}/bin/python3 ${draftServerScript}";
|
|
};
|
|
};
|
|
}
|