Files
nix/modules/nixos/mail-server/mobileconfig.nix
T
2026-04-14 17:53:35 +02:00

90 lines
2.6 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.mailserver;
hasMailDiscoveryConfig = cfg.enable && cfg.fqdn != null && cfg.domains != [ ];
in
lib.mkIf hasMailDiscoveryConfig (
let
domain = builtins.head cfg.domains;
mobileconfigHost = "autoconfig.${domain}";
radicaleHost = "cal.${domain}";
mobileconfigPort = 8426;
safeLegacyPath = email: builtins.replaceStrings [ "@" "+" ] [ "_" "-" ] email;
accountEntries = lib.filter (entry: entry.domain == domain) (
lib.mapAttrsToList (
email: _:
let
parts = lib.splitString "@" email;
username = builtins.head parts;
domainPart = lib.last parts;
in
{
inherit email username;
domain = domainPart;
legacyPath = safeLegacyPath email;
}
) cfg.loginAccounts
);
usernames = map (entry: entry.username) accountEntries;
defaultUsername =
if lib.length accountEntries == 1 then (builtins.head accountEntries).username else null;
generatorScript = ./mobileconfig-generator.py;
accountArgs = lib.concatMapStrings (
entry: " --account ${entry.username}:${entry.email}:${entry.legacyPath}"
) accountEntries;
defaultUsernameArg =
if defaultUsername != null then " --default-username ${defaultUsername}" else "";
in
{
assertions = [
{
assertion = lib.length usernames == lib.length (lib.unique usernames);
message = "Mail mobileconfig usernames must be unique within ${domain}.";
}
];
systemd.services.mobileconfig-generator = {
description = "Apple mobileconfig generator";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
DynamicUser = true;
ExecStart = "${pkgs.python3}/bin/python3 \
${generatorScript} \
--domain ${domain} \
--mail-host ${cfg.fqdn} \
--radicale-host ${radicaleHost} \
--port ${toString mobileconfigPort}${defaultUsernameArg}${accountArgs}";
NoNewPrivileges = true;
PrivateTmp = true;
ProtectHome = true;
ProtectSystem = "strict";
Restart = "always";
};
};
services.nginx.virtualHosts.${mobileconfigHost}.locations = {
"= /mobileconfig".return = "308 /mobileconfig/$is_args$args";
"/mobileconfig/" = {
proxyPass = "http://127.0.0.1:${toString mobileconfigPort}";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
'';
};
};
}
)