nixpkgs/modules/services/mail/postfix.nix
Lluís Batlle i Rossell b25771532a Fixing the postfix start/stop (through an upstart job script code that will
monitor the life of postfix)

Adding an assert to upstart jobs, so those with preStop will always need an exec or
script, otherwise the preStop will not be run.


svn path=/nixos/trunk/; revision=22225
2010-06-11 21:44:06 +00:00

331 lines
8.4 KiB
Nix

{ config, pkgs, ... }:
with pkgs.lib;
let
startingDependency = if config.services.gw6c.enable then "gw6c" else "network-interfaces";
cfg = config.services.postfix;
user = cfg.user;
group = cfg.group;
setgidGroup = cfg.setgidGroup;
mainCf =
''
queue_directory = /var/postfix/queue
command_directory = ${pkgs.postfix}/sbin
daemon_directory = ${pkgs.postfix}/libexec/postfix
mail_owner = ${user}
default_privs = nobody
''
+ optionalString (config.services.gw6c.enable || config.networking.nativeIPv6) (''
inet_protocols = all
'')
+ (if cfg.networks != null then
''
mynetworks = ${concatStringsSep ", " cfg.networks}
''
else if cfg.networksStyle != "" then
''
mynetworks_style = ${cfg.networksStyle}
''
else
# Postfix default is subnet, but let's play safe
''
mynetworks_style = host
'')
+ optionalString (cfg.hostname != "") ''
myhostname = ${cfg.hostname}
''
+ optionalString (cfg.domain != "") ''
mydomain = ${cfg.domain}
''
+ optionalString (cfg.origin != "") ''
myorigin = ${cfg.origin}
''
+ optionalString (cfg.destination != null) ''
mydestination = ${concatStringsSep ", " cfg.destination}
''
+ optionalString (cfg.relayDomains != null) ''
relay_domains = ${concatStringsSep ", " cfg.relayDomains}
''
+ ''
local_recipient_maps =
relayhost = ${if cfg.lookupMX || cfg.relayHost == "" then
cfg.relayHost
else
"[" + cfg.relayHost + "]"}
alias_maps = hash:/var/postfix/conf/aliases
mail_spool_directory = /var/spool/mail/
setgid_group = ${setgidGroup}
''
+ optionalString (cfg.sslCert != "") ''
smtp_tls_CAfile = ${cfg.sslCACert}
smtp_tls_cert_file = ${cfg.sslCert}
smtp_tls_key_file = ${cfg.sslKey}
smtp_use_tls = yes
smtpd_tls_CAfile = ${cfg.sslCACert}
smtpd_tls_cert_file = ${cfg.sslCert}
smtpd_tls_key_file = ${cfg.sslKey}
smtpd_use_tls = yes
recipientDelimiter = ${cfg.recipientDelimiter}
'';
aliases =
optionalString (cfg.postmasterAlias != "") ''
postmaster: ${cfg.postmasterAlias}
''
+ optionalString (cfg.rootAlias != "") ''
root: ${cfg.rootAlias}
''
+ cfg.extraAliases
;
aliasesFile = pkgs.writeText "postfix-aliases" aliases;
mainCfFile = pkgs.writeText "postfix-main.cf" mainCf;
in
{
###### interface
options = {
services.postfix = {
enable = mkOption {
default = false;
description = "Whether to run the Postfix mail server.";
};
user = mkOption {
default = "postfix";
description = "What to call the Postfix user (must be used only for postfix).";
};
group = mkOption {
default = "postfix";
description = "What to call the Postfix group (must be used only for postfix).";
};
setgidGroup = mkOption {
default = "postdrop";
description = "
How to call postfix setgid group (for postdrop). Should
be uniquely used group.
";
};
networks = mkOption {
default = null;
example = ["192.168.0.1/24"];
description = "
Net masks for trusted - allowed to relay mail to third parties -
hosts. Leave empty to use mynetworks_style configuration or use
default (localhost-only).
";
};
networksStyle = mkOption {
default = "";
description = "
Name of standard way of trusted network specification to use,
leave blank if you specify it explicitly or if you want to use
default (localhost-only).
";
};
hostname = mkOption {
default = "";
description ="
Hostname to use. Leave blank to use just the hostname of machine.
It should be FQDN.
";
};
domain = mkOption {
default = "";
description ="
Domain to use. Leave blank to use hostname minus first component.
";
};
origin = mkOption {
default = "";
description ="
Origin to use in outgoing e-mail. Leave blank to use hostname.
";
};
destination = mkOption {
default = null;
example = ["localhost"];
description = "
Full (!) list of domains we deliver locally. Leave blank for
acceptable Postfix default.
";
};
relayDomains = mkOption {
default = null;
example = ["localdomain"];
description = "
List of domains we agree to relay to. Default is the same as
destination.
";
};
relayHost = mkOption {
default = "";
description = "
Mail relay for outbound mail.
";
};
lookupMX = mkOption {
default = false;
description = "
Whether relay specified is just domain whose MX must be used.
";
};
postmasterAlias = mkOption {
default = "root";
description = "Who should receive postmaster e-mail.";
};
rootAlias = mkOption {
default = "";
description = "
Who should receive root e-mail. Blank for no redirection.
";
};
extraAliases = mkOption {
default = "";
description = "
Additional entries to put verbatim into aliases file.
";
};
sslCert = mkOption {
default = "";
description = "SSL certificate to use.";
};
sslCACert = mkOption {
default = "";
description = "SSL certificate of CA.";
};
sslKey = mkOption {
default = "";
description = "SSL key to use.";
};
recipientDelimiter = mkOption {
default = "";
example = "+";
description = "
Delimiter for address extension: so mail to user+test can be handled by ~user/.forward+test
";
};
};
};
###### implementation
config = mkIf config.services.postfix.enable {
environment.etc = singleton
{ source = "/var/postfix/conf";
target = "postfix";
};
users.extraUsers = singleton
{ name = user;
description = "Postfix mail server user";
uid = config.ids.uids.postfix;
group = group;
};
users.extraGroups =
[ { name = group;
gid = config.ids.gids.postfix;
}
{ name = setgidGroup;
gid = config.ids.gids.postdrop;
}
];
jobs.postfix =
# I copy _lots_ of shipped configuration filed
# that can be left as is. I am afraid the exact
# will list slightly change in next Postfix
# release, so listing them all one-by-one in an
# accurate way is unlikely to be better.
{ description = "Postfix mail server";
startOn = "started ${startingDependency}";
daemonType = "none";
respawn = true;
script = ''
while ${pkgs.procps}/bin/ps `${pkgs.coreutils}/bin/cat /var/postfix/queue/pid/master.pid` |
grep -q postfix
do
${pkgs.coreutils}/bin/sleep 1m
done
'';
preStart =
''
if ! [ -d /var/spool/postfix ]; then
${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue
fi
${pkgs.coreutils}/bin/chown -R ${user}.${group} /var/postfix
${pkgs.coreutils}/bin/chown -R ${user}.${setgidGroup} /var/postfix/queue
${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue
${pkgs.coreutils}/bin/chown root.root /var/spool/mail
${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail
ln -sf ${pkgs.postfix}/share/postfix/conf/* /var/postfix/conf
ln -sf ${aliasesFile} /var/postfix/conf/aliases
ln -sf ${mainCfFile} /var/postfix/conf/main.cf
${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases
exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start
''; # */
preStop = ''
exec ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop
'';
};
};
}