2014-04-14 16:26:48 +02:00
{
config ,
lib ,
pkgs ,
. . .
} :
2008-06-30 15:13:02 +00:00
let
2009-10-12 16:36:19 +00:00
2008-06-30 15:13:02 +00:00
cfg = config . services . postfix ;
user = cfg . user ;
group = cfg . group ;
setgidGroup = cfg . setgidGroup ;
2017-07-14 16:55:53 +02:00
haveAliases = cfg . postmasterAlias != " " || cfg . rootAlias != " " || cfg . extraAliases != " " ;
2021-04-04 11:56:31 +00:00
haveCanonical = cfg . canonical != " " ;
2025-06-04 08:15:52 +02:00
haveTransport = cfg . transport != " " ;
2016-01-09 15:48:36 +03:00
haveVirtual = cfg . virtual != " " ;
2019-07-15 13:52:26 +02:00
haveLocalRecipients = cfg . localRecipients != null ;
2016-01-09 15:48:36 +03:00
2016-01-07 22:38:22 -05:00
clientAccess = lib . optional (
2024-08-27 20:57:37 +02:00
cfg . dnsBlacklistOverrides != " "
2018-01-26 14:01:15 +01:00
) " c h e c k _ c l i e n t _ a c c e s s h a s h : / e t c / p o s t f i x / c l i e n t _ a c c e s s " ;
2016-01-07 22:38:22 -05:00
2024-08-27 20:57:37 +02:00
dnsBl = lib . optionals ( cfg . dnsBlacklists != [ ] ) (
2018-01-26 14:01:15 +01:00
map ( s : " r e j e c t _ r b l _ c l i e n t " + s ) cfg . dnsBlacklists
) ;
2016-01-07 22:38:22 -05:00
2024-08-27 20:57:37 +02:00
clientRestrictions = lib . concatStringsSep " , " ( clientAccess ++ dnsBl ) ;
2016-01-07 22:38:22 -05:00
2017-07-14 16:55:53 +02:00
mainCf =
let
2024-08-27 20:57:37 +02:00
escape = lib . replaceStrings [ " $ " ] [ " $ $ " ] ;
mkList = items : " \n " + lib . concatStringsSep " , \n " items ;
2017-07-14 16:55:53 +02:00
mkVal =
value :
2024-08-27 20:57:37 +02:00
if lib . isList value then
mkList value
2017-07-14 16:55:53 +02:00
else
" "
+ (
if value = = true then
" y e s "
else if value = = false then
" n o "
else
toString value
) ;
mkEntry = name : value : " ${ escape name } = ${ mkVal value } " ;
in
2024-08-27 20:57:37 +02:00
lib . concatStringsSep " \n " ( lib . mapAttrsToList mkEntry cfg . config ) + " \n " + cfg . extraConfig ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
masterCfOptions =
{
options ,
config ,
name ,
. . .
} :
{
options = {
2024-08-27 20:57:37 +02:00
name = lib . mkOption {
type = lib . types . str ;
2017-07-14 16:55:53 +02:00
default = name ;
example = " s m t p " ;
description = ''
The name of the service to run . Defaults to the attribute set key .
'' ;
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
type = lib . mkOption {
type = lib . types . enum [
" i n e t "
" u n i x "
" u n i x - d g r a m "
" f i f o "
" p a s s "
] ;
2017-07-14 16:55:53 +02:00
default = " u n i x " ;
example = " i n e t " ;
description = " T h e t y p e o f t h e s e r v i c e " ;
} ;
2009-10-12 16:36:19 +00:00
2024-08-27 20:57:37 +02:00
private = lib . mkOption {
type = lib . types . bool ;
2017-07-14 16:55:53 +02:00
example = false ;
description = ''
Whether the service's sockets and storage directory is restricted to
be only available via the mail system . If ` null ` is
given it uses the postfix default ` true ` .
'' ;
} ;
2009-10-12 16:36:19 +00:00
2024-08-27 20:57:37 +02:00
privileged = lib . mkOption {
type = lib . types . bool ;
2017-07-14 16:55:53 +02:00
example = true ;
2022-08-29 16:57:18 +02:00
description = " " ;
2017-07-14 16:55:53 +02:00
} ;
2009-10-12 16:36:19 +00:00
2024-08-27 20:57:37 +02:00
chroot = lib . mkOption {
type = lib . types . bool ;
2017-07-14 16:55:53 +02:00
example = true ;
description = ''
Whether the service is chrooted to have only access to the
{ option } ` services . postfix . queueDir ` and the closure of
store paths specified by the { option } ` program ` option .
'' ;
} ;
2009-10-12 16:36:19 +00:00
2024-08-27 20:57:37 +02:00
wakeup = lib . mkOption {
type = lib . types . int ;
2017-07-14 16:55:53 +02:00
example = 60 ;
description = ''
Automatically wake up the service after the specified number of
seconds . If ` 0 ` is given , never wake the service
up .
'' ;
} ;
2009-10-12 16:36:19 +00:00
2024-08-27 20:57:37 +02:00
wakeupUnusedComponent = lib . mkOption {
type = lib . types . bool ;
2017-07-14 16:55:53 +02:00
example = false ;
description = ''
If set to ` false ` the component will only be woken
up if it is used . This is equivalent to postfix' notion of adding a
question mark behind the wakeup time in
{ file } ` master . cf `
'' ;
} ;
2024-08-27 20:57:37 +02:00
maxproc = lib . mkOption {
type = lib . types . int ;
2017-07-14 16:55:53 +02:00
example = 1 ;
description = ''
The maximum number of processes to spawn for this service . If the
value is ` 0 ` it doesn't have any limit . If
` null ` is given it uses the postfix default of
` 100 ` .
'' ;
} ;
2024-08-27 20:57:37 +02:00
command = lib . mkOption {
type = lib . types . str ;
2017-07-14 16:55:53 +02:00
default = name ;
example = " s m t p d " ;
description = ''
A program name specifying a Postfix service/daemon process .
By default it's the attribute { option } ` name ` .
'' ;
} ;
2024-08-27 20:57:37 +02:00
args = lib . mkOption {
type = lib . types . listOf lib . types . str ;
2017-07-14 16:55:53 +02:00
default = [ ] ;
example = [
" - o "
" s m t p _ h e l o _ t i m e o u t = 5 "
] ;
description = ''
Arguments to pass to the { option } ` command ` . There is no shell
processing involved and shell syntax is passed verbatim to the
process .
'' ;
} ;
2024-08-27 20:57:37 +02:00
rawEntry = lib . mkOption {
type = lib . types . listOf lib . types . str ;
2017-07-14 16:55:53 +02:00
default = [ ] ;
internal = true ;
description = ''
The raw configuration line for the { file } ` master . cf ` .
'' ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
} ;
config . rawEntry =
let
2024-08-27 20:57:37 +02:00
mkBool = bool : if bool then " y " else " n " ;
mkArg = arg : " ${ lib . optionalString ( lib . hasPrefix " - " arg ) " \n " } ${ arg } " ;
2024-12-10 20:26:33 +01:00
2024-08-27 20:57:37 +02:00
maybeOption = fun : option : if options . ${ option } . isDefined then fun config . ${ option } else " - " ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
# This is special, because we have two options for this value.
2024-12-10 20:26:33 +01:00
wakeup =
2017-07-14 16:55:53 +02:00
let
2024-08-27 20:57:37 +02:00
wakeupDefined = options . wakeup . isDefined ;
wakeupUCDefined = options . wakeupUnusedComponent . isDefined ;
finalValue =
toString config . wakeup + lib . optionalString ( wakeupUCDefined && ! config . wakeupUnusedComponent ) " ? " ;
in
if wakeupDefined then finalValue else " - " ;
2024-12-10 20:26:33 +01:00
in
[
2024-08-27 20:57:37 +02:00
config . name
2017-07-14 16:55:53 +02:00
config . type
2024-08-27 20:57:37 +02:00
( maybeOption mkBool " p r i v a t e " )
2017-07-14 16:55:53 +02:00
( maybeOption ( b : mkBool ( ! b ) ) " p r i v i l e g e d " )
( maybeOption mkBool " c h r o o t " )
2024-12-10 20:26:33 +01:00
wakeup
2024-08-27 20:57:37 +02:00
( maybeOption toString " m a x p r o c " )
( config . command + " " + lib . concatMapStringsSep " " mkArg config . args )
2024-12-10 20:26:33 +01:00
] ;
} ;
2017-07-14 16:55:53 +02:00
masterCfContent =
2024-12-10 20:26:33 +01:00
let
2017-07-14 16:55:53 +02:00
labels = [
" # s e r v i c e "
2024-12-10 20:26:33 +01:00
" t y p e "
2017-07-14 16:55:53 +02:00
" p r i v a t e "
2024-12-10 20:26:33 +01:00
" u n p r i v "
2017-07-14 16:55:53 +02:00
" c h r o o t "
2024-12-10 20:26:33 +01:00
" w a k e u p "
2017-07-14 16:55:53 +02:00
" m a x p r o c "
" c o m m a n d + a r g s "
2024-12-10 20:26:33 +01:00
] ;
2017-07-14 16:55:53 +02:00
labelDefaults = [
2024-12-10 20:26:33 +01:00
" # "
" "
" ( y e s ) "
" ( y e s ) "
" ( n o ) "
2017-07-14 16:55:53 +02:00
" ( n e v e r ) "
2024-12-10 20:26:33 +01:00
" ( 1 0 0 ) "
" "
" "
] ;
2024-08-27 20:57:37 +02:00
masterCf = lib . mapAttrsToList ( lib . const ( lib . getAttr " r a w E n t r y " ) ) cfg . masterConfig ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
# A list of the maximum width of the columns across all lines and labels
maxWidths =
2024-12-10 20:26:33 +01:00
let
2017-07-14 16:55:53 +02:00
foldLine =
line : acc :
2024-12-10 20:26:33 +01:00
let
2024-08-27 20:57:37 +02:00
columnLengths = map lib . stringLength line ;
2024-12-10 20:26:33 +01:00
in
2024-08-27 20:57:37 +02:00
lib . zipListsWith lib . max acc columnLengths ;
2017-07-14 16:55:53 +02:00
# We need to handle the last column specially here, because it's
# open-ended (command + args).
lines = [
2024-12-10 20:26:33 +01:00
labels
2017-07-14 16:55:53 +02:00
labelDefaults
2024-08-27 20:57:37 +02:00
] ++ ( map ( l : lib . init l ++ [ " " ] ) masterCf ) ;
2024-12-10 20:26:33 +01:00
in
2024-08-27 20:57:37 +02:00
lib . foldr foldLine ( lib . genList ( lib . const 0 ) ( lib . length labels ) ) lines ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
# Pad a string with spaces from the right (opposite of fixedWidthString).
2024-12-10 20:26:33 +01:00
pad =
2017-07-14 16:55:53 +02:00
width : str :
2024-12-10 20:26:33 +01:00
let
2024-08-27 20:57:37 +02:00
padWidth = width - lib . stringLength str ;
padding = lib . concatStrings ( lib . genList ( lib . const " " ) padWidth ) ;
2024-12-10 20:26:33 +01:00
in
2017-07-14 16:55:53 +02:00
str + lib . optionalString ( padWidth > 0 ) padding ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
# It's + 2 here, because that's the amount of spacing between columns.
2024-08-27 20:57:37 +02:00
fullWidth = lib . foldr ( width : acc : acc + width + 2 ) 0 maxWidths ;
2024-12-10 20:26:33 +01:00
2024-08-27 20:57:37 +02:00
formatLine = line : lib . concatStringsSep " " ( lib . zipListsWith pad maxWidths line ) ;
2024-12-10 20:26:33 +01:00
2017-07-14 16:55:53 +02:00
formattedLabels =
2024-12-10 20:26:33 +01:00
let
2024-08-27 20:57:37 +02:00
sep = " # " + lib . concatStrings ( lib . genList ( lib . const " = " ) ( fullWidth + 5 ) ) ;
2017-07-14 16:55:53 +02:00
lines = [
2024-12-10 20:26:33 +01:00
sep
2017-07-14 16:55:53 +02:00
( formatLine labels )
( formatLine labelDefaults )
2024-12-10 20:26:33 +01:00
sep
] ;
in
2024-08-27 20:57:37 +02:00
lib . concatStringsSep " \n " lines ;
2024-12-10 20:26:33 +01:00
in
2017-07-14 16:55:53 +02:00
formattedLabels
2024-12-10 20:26:33 +01:00
+ " \n "
2024-08-27 20:57:37 +02:00
+ lib . concatMapStringsSep " \n " formatLine masterCf
2024-12-10 20:26:33 +01:00
+ " \n "
2024-08-27 20:57:37 +02:00
+ cfg . extraMasterConf ;
2024-12-10 20:26:33 +01:00
2024-08-27 20:57:37 +02:00
headerCheckOptions =
2017-07-14 16:55:53 +02:00
{ . . . }:
2024-12-10 20:26:33 +01:00
{
2017-07-14 16:55:53 +02:00
options = {
2024-08-27 20:57:37 +02:00
pattern = lib . mkOption {
type = lib . types . str ;
2017-07-14 16:55:53 +02:00
default = " / ^ . * / " ;
example = " / ^ X - M a i l e r : / " ;
description = " A r e g e x p p a t t e r n m a t c h i n g t h e h e a d e r " ;
} ;
2024-08-27 20:57:37 +02:00
action = lib . mkOption {
type = lib . types . str ;
2017-07-14 16:55:53 +02:00
default = " D U N N O " ;
example = " B C C m a i l @ e x a m p l e . c o m " ;
description = " T h e a c t i o n t o b e e x e c u t e d w h e n t h e p a t t e r n i s m a t c h e d " ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
} ;
} ;
2024-08-27 20:57:37 +02:00
headerChecks =
lib . concatStringsSep " \n " ( map ( x : " ${ x . pattern } ${ x . action } " ) cfg . headerChecks )
+ cfg . extraHeaderChecks ;
2017-07-14 16:55:53 +02:00
2024-08-27 20:57:37 +02:00
aliases =
let
separator = lib . optionalString ( cfg . aliasMapType = = " h a s h " ) " : " ;
in
lib . optionalString ( cfg . postmasterAlias != " " ) ''
2022-12-17 19:31:14 -05:00
postmaster $ { separator } $ { cfg . postmasterAlias }
2009-10-12 16:36:19 +00:00
''
2024-08-27 20:57:37 +02:00
+ lib . optionalString ( cfg . rootAlias != " " ) ''
2022-12-17 19:31:14 -05:00
root $ { separator } $ { cfg . rootAlias }
2009-10-12 16:36:19 +00:00
''
2008-06-30 15:13:02 +00:00
+ cfg . extraAliases ;
aliasesFile = pkgs . writeText " p o s t f i x - a l i a s e s " aliases ;
2021-04-04 11:56:31 +00:00
canonicalFile = pkgs . writeText " p o s t f i x - c a n o n i c a l " cfg . canonical ;
2012-08-24 00:27:07 +02:00
virtualFile = pkgs . writeText " p o s t f i x - v i r t u a l " cfg . virtual ;
2024-08-27 20:57:37 +02:00
localRecipientMapFile = pkgs . writeText " p o s t f i x - l o c a l - r e c i p i e n t - m a p " (
lib . concatMapStrings ( x : x + " A C C E P T \n " ) cfg . localRecipients
) ;
2016-01-07 22:38:22 -05:00
checkClientAccessFile = pkgs . writeText " p o s t f i x - c h e c k - c l i e n t - a c c e s s " cfg . dnsBlacklistOverrides ;
2008-06-30 15:13:02 +00:00
mainCfFile = pkgs . writeText " p o s t f i x - m a i n . c f " mainCf ;
2017-07-14 16:55:53 +02:00
masterCfFile = pkgs . writeText " p o s t f i x - m a s t e r . c f " masterCfContent ;
2025-06-04 08:15:52 +02:00
transportFile = pkgs . writeText " p o s t f i x - t r a n s p o r t " cfg . transport ;
2017-07-14 16:55:53 +02:00
headerChecksFile = pkgs . writeText " p o s t f i x - h e a d e r - c h e c k s " headerChecks ;
2011-09-14 18:20:50 +00:00
2008-06-30 15:13:02 +00:00
in
2009-10-12 16:36:19 +00:00
{
###### interface
options = {
2011-09-14 18:20:50 +00:00
2009-10-12 16:36:19 +00:00
services . postfix = {
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
enable = lib . mkOption {
type = lib . types . bool ;
2009-10-12 16:36:19 +00:00
default = false ;
description = " W h e t h e r t o r u n t h e P o s t f i x m a i l s e r v e r . " ;
} ;
2010-10-10 10:43:28 +00:00
2024-08-27 20:57:37 +02:00
enableSmtp = lib . mkOption {
type = lib . types . bool ;
2016-01-05 02:57:52 -08:00
default = true ;
description = " W h e t h e r t o e n a b l e s m t p i n m a s t e r . c f . " ;
} ;
2017-07-14 16:55:53 +02:00
2024-08-27 20:57:37 +02:00
enableSubmission = lib . mkOption {
type = lib . types . bool ;
2016-06-09 00:15:55 +02:00
default = false ;
2017-07-14 16:55:53 +02:00
description = " W h e t h e r t o e n a b l e s m t p s u b m i s s i o n . " ;
2016-06-09 00:15:55 +02:00
} ;
2024-08-27 20:57:37 +02:00
enableSubmissions = lib . mkOption {
type = lib . types . bool ;
2020-07-06 03:37:56 +02:00
default = false ;
description = ''
Whether to enable smtp submission via smtps .
According to RFC 8314 this should be preferred
over STARTTLS for submission of messages by end user clients .
'' ;
} ;
2024-08-27 20:57:37 +02:00
submissionOptions = lib . mkOption {
type = with lib . types ; attrsOf str ;
2017-07-14 16:55:53 +02:00
default = {
smtpd_tls_security_level = " e n c r y p t " ;
smtpd_sasl_auth_enable = " y e s " ;
smtpd_client_restrictions = " p e r m i t _ s a s l _ a u t h e n t i c a t e d , r e j e c t " ;
milter_macro_daemon_name = " O R I G I N A T I N G " ;
} ;
example = {
smtpd_tls_security_level = " e n c r y p t " ;
smtpd_sasl_auth_enable = " y e s " ;
smtpd_sasl_type = " d o v e c o t " ;
smtpd_client_restrictions = " p e r m i t _ s a s l _ a u t h e n t i c a t e d , r e j e c t " ;
milter_macro_daemon_name = " O R I G I N A T I N G " ;
} ;
2016-06-10 14:51:43 +02:00
description = " O p t i o n s f o r t h e s u b m i s s i o n c o n f i g i n m a s t e r . c f " ;
2016-06-09 00:15:55 +02:00
} ;
2016-01-05 02:57:52 -08:00
2024-08-27 20:57:37 +02:00
submissionsOptions = lib . mkOption {
type = with lib . types ; attrsOf str ;
2020-07-06 03:37:56 +02:00
default = {
smtpd_sasl_auth_enable = " y e s " ;
smtpd_client_restrictions = " p e r m i t _ s a s l _ a u t h e n t i c a t e d , r e j e c t " ;
milter_macro_daemon_name = " O R I G I N A T I N G " ;
} ;
example = {
smtpd_sasl_auth_enable = " y e s " ;
smtpd_sasl_type = " d o v e c o t " ;
smtpd_client_restrictions = " p e r m i t _ s a s l _ a u t h e n t i c a t e d , r e j e c t " ;
milter_macro_daemon_name = " O R I G I N A T I N G " ;
} ;
description = ''
Options for the submission config via smtps in master . cf .
smtpd_tls_security_level will be set to encrypt , if it is missing
or has one of the values " m a y " or " n o n e " .
smtpd_tls_wrappermode with value " y e s " will be added automatically .
'' ;
} ;
2024-08-27 20:57:37 +02:00
setSendmail = lib . mkOption {
type = lib . types . bool ;
2010-10-10 10:43:28 +00:00
default = true ;
description = " W h e t h e r t o s e t t h e s y s t e m s e n d m a i l t o p o s t f i x ' s . " ;
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
user = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " p o s t f i x " ;
description = " W h a t t o c a l l t h e P o s t f i x u s e r ( m u s t b e u s e d o n l y f o r p o s t f i x ) . " ;
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
group = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " p o s t f i x " ;
description = " W h a t t o c a l l t h e P o s t f i x g r o u p ( m u s t b e u s e d o n l y f o r p o s t f i x ) . " ;
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
setgidGroup = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " p o s t d r o p " ;
2022-08-14 05:16:55 +02:00
description = ''
2011-09-14 18:20:50 +00:00
How to call postfix setgid group ( for postdrop ) . Should
2009-10-12 16:36:19 +00:00
be uniquely used group .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
networks = lib . mkOption {
type = lib . types . nullOr ( lib . types . listOf lib . types . str ) ;
2009-10-12 16:36:19 +00:00
default = null ;
example = [ " 1 9 2 . 1 6 8 . 0 . 1 / 2 4 " ] ;
2022-08-14 05:16:55 +02:00
description = ''
2011-09-14 18:20:50 +00:00
Net masks for trusted - allowed to relay mail to third parties -
hosts . Leave empty to use mynetworks_style configuration or use
2009-10-12 16:36:19 +00:00
default ( localhost-only ) .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
networksStyle = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Name of standard way of trusted network specification to use ,
2011-09-14 18:20:50 +00:00
leave blank if you specify it explicitly or if you want to use
2009-10-12 16:36:19 +00:00
default ( localhost-only ) .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
hostname = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Hostname to use . Leave blank to use just the hostname of machine .
It should be FQDN .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
domain = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Domain to use . Leave blank to use hostname minus first component .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
origin = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Origin to use in outgoing e-mail . Leave blank to use hostname .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
destination = lib . mkOption {
type = lib . types . nullOr ( lib . types . listOf lib . types . str ) ;
2009-10-12 16:36:19 +00:00
default = null ;
example = [ " l o c a l h o s t " ] ;
2022-08-14 05:16:55 +02:00
description = ''
2011-09-14 18:20:50 +00:00
Full ( ! ) list of domains we deliver locally . Leave blank for
2009-10-12 16:36:19 +00:00
acceptable Postfix default .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
relayDomains = lib . mkOption {
type = lib . types . nullOr ( lib . types . listOf lib . types . str ) ;
2009-10-12 16:36:19 +00:00
default = null ;
example = [ " l o c a l d o m a i n " ] ;
2022-08-14 05:16:55 +02:00
description = ''
2015-10-25 12:06:56 +01:00
List of domains we agree to relay to . Default is empty .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
relayHost = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Mail relay for outbound mail .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
relayPort = lib . mkOption {
type = lib . types . int ;
2017-11-01 19:06:27 +01:00
default = 25 ;
2022-08-14 05:16:55 +02:00
description = ''
2017-11-01 19:06:27 +01:00
SMTP port for relay mail relay .
2022-08-14 05:16:55 +02:00
'' ;
2017-10-25 10:11:55 -07:00
} ;
2024-08-27 20:57:37 +02:00
lookupMX = lib . mkOption {
type = lib . types . bool ;
2009-10-12 16:36:19 +00:00
default = false ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Whether relay specified is just domain whose MX must be used .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
postmasterAlias = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " r o o t " ;
2022-08-14 05:16:55 +02:00
description = ''
2018-02-11 14:39:19 +01:00
Who should receive postmaster e-mail . Multiple values can be added by
separating values with comma .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
rootAlias = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2009-10-12 16:36:19 +00:00
Who should receive root e-mail . Blank for no redirection .
2018-02-11 14:39:19 +01:00
Multiple values can be added by separating values with comma .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
extraAliases = lib . mkOption {
type = lib . types . lines ;
2009-10-12 16:36:19 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2025-01-27 02:10:23 +01:00
Additional entries to put verbatim into aliases file , cf . man-page { manpage } ` aliases ( 8 ) ` .
2022-08-14 05:16:55 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2024-08-27 20:57:37 +02:00
aliasMapType = lib . mkOption {
type =
with lib . types ;
enum [
" h a s h "
" r e g e x p "
" p c r e "
] ;
2017-07-14 16:55:53 +02:00
default = " h a s h " ;
example = " r e g e x p " ;
description = " T h e f o r m a t t h e a l i a s m a p s h o u l d h a v e . U s e r e g e x p i f y o u w a n t t o u s e r e g u l a r e x p r e s s i o n s . " ;
} ;
2024-08-27 20:57:37 +02:00
config = lib . mkOption {
type =
with lib . types ;
attrsOf ( oneOf [
bool
int
str
( listOf str )
] ) ;
2017-07-14 16:55:53 +02:00
description = ''
The main . cf configuration file as key value set .
'' ;
example = {
mail_owner = " p o s t f i x " ;
2020-06-11 01:59:09 +02:00
smtp_tls_security_level = " m a y " ;
2017-07-14 16:55:53 +02:00
} ;
} ;
2024-08-27 20:57:37 +02:00
extraConfig = lib . mkOption {
type = lib . types . lines ;
2011-01-02 18:49:11 +00:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2012-09-23 12:21:34 +02:00
Extra lines to be added verbatim to the main . cf configuration file .
2022-08-14 05:16:55 +02:00
'' ;
2011-01-02 18:49:11 +00:00
} ;
2024-08-27 20:57:37 +02:00
tlsTrustedAuthorities = lib . mkOption {
type = lib . types . str ;
2025-03-08 00:41:08 -08:00
default = config . security . pki . caBundle ;
defaultText = lib . literalExpression " c o n f i g . s e c u r i t y . p k i . c a B u n d l e " ;
example = lib . literalExpression '' " ''$ { p k g s . c a c e r t } / e t c / s s l / c e r t s / c a - b u n d l e . c r t " '' ;
2020-06-11 03:37:36 +02:00
description = ''
2025-03-08 00:41:08 -08:00
File containing trusted certification authorities ( CA ) to verify certificates of mailservers contacted for mail delivery . This sets [ smtp_tls_CAfile ] ( https://www.postfix.org/postconf.5.html #smtp_tls_CAfile). Defaults to system trusted certificates (see `security.pki.*` options).
2020-06-11 03:37:36 +02:00
'' ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
sslCert = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
2020-06-11 03:37:36 +02:00
description = " S S L c e r t i f i c a t e t o u s e . " ;
2009-10-12 16:36:19 +00:00
} ;
2011-09-14 18:20:50 +00:00
2024-08-27 20:57:37 +02:00
sslKey = lib . mkOption {
type = lib . types . str ;
2009-10-12 16:36:19 +00:00
default = " " ;
description = " S S L k e y t o u s e . " ;
} ;
2024-08-27 20:57:37 +02:00
recipientDelimiter = lib . mkOption {
type = lib . types . str ;
2015-06-26 14:03:21 +02:00
default = " " ;
example = " + " ;
2022-08-14 05:16:55 +02:00
description = ''
2015-06-26 14:03:21 +02:00
Delimiter for address extension : so mail to user + test can be handled by ~ user/.forward+test
2022-08-14 05:16:55 +02:00
'' ;
2015-06-26 14:03:21 +02:00
} ;
2024-08-27 20:57:37 +02:00
canonical = lib . mkOption {
type = lib . types . lines ;
2021-04-04 11:56:31 +00:00
default = " " ;
description = ''
Entries for the { manpage } ` canonical ( 5 ) ` table .
'' ;
} ;
2024-08-27 20:57:37 +02:00
virtual = lib . mkOption {
type = lib . types . lines ;
2012-08-24 00:27:07 +02:00
default = " " ;
2022-08-14 05:16:55 +02:00
description = ''
2025-01-27 02:10:23 +01:00
Entries for the virtual alias map , cf . man-page { manpage } ` virtual ( 5 ) ` .
2022-08-14 05:16:55 +02:00
'' ;
2012-08-24 00:27:07 +02:00
} ;
2024-08-27 20:57:37 +02:00
virtualMapType = lib . mkOption {
type = lib . types . enum [
" h a s h "
" r e g e x p "
" p c r e "
] ;
2017-07-14 16:55:53 +02:00
default = " h a s h " ;
description = ''
What type of virtual alias map file to use . Use ` " r e g e x p " ` for regular expressions .
'' ;
} ;
2024-08-27 20:57:37 +02:00
localRecipients = lib . mkOption {
type = with lib . types ; nullOr ( listOf str ) ;
2019-07-15 13:52:26 +02:00
default = null ;
description = ''
List of accepted local users . Specify a bare username , an
` " @ d o m a i n . t l d " ` wild-card , or a complete
` " u s e r @ d o m a i n . t l d " ` address . If set , these names end
2025-01-27 02:10:23 +01:00
up in the local recipient map - - see the { manpage } ` local ( 8 ) ` man-page - - and
2019-07-15 13:52:26 +02:00
effectively replace the system user database lookup that's otherwise
used by default .
'' ;
} ;
2024-08-27 20:57:37 +02:00
transport = lib . mkOption {
2016-01-05 02:59:16 -08:00
default = " " ;
2024-08-27 20:57:37 +02:00
type = lib . types . lines ;
2022-08-14 05:16:55 +02:00
description = ''
2025-01-27 02:10:23 +01:00
Entries for the transport map , cf . man-page { manpage } ` transport ( 8 ) ` .
2022-08-14 05:16:55 +02:00
'' ;
2016-01-05 02:59:16 -08:00
} ;
2024-08-27 20:57:37 +02:00
dnsBlacklists = lib . mkOption {
2016-01-07 22:38:22 -05:00
default = [ ] ;
2024-08-27 20:57:37 +02:00
type = with lib . types ; listOf str ;
2016-01-07 22:38:22 -05:00
description = " d n s b l a c k l i s t s e r v e r s t o u s e w i t h s m t p d _ c l i e n t _ r e s t r i c t i o n s " ;
} ;
2024-08-27 20:57:37 +02:00
dnsBlacklistOverrides = lib . mkOption {
2016-01-07 22:38:22 -05:00
default = " " ;
2024-08-27 20:57:37 +02:00
type = lib . types . lines ;
2016-01-07 22:38:22 -05:00
description = " c o n t e n t s o f c h e c k _ c l i e n t _ a c c e s s f o r o v e r r i d i n g d n s B l a c k l i s t s " ;
} ;
2024-08-27 20:57:37 +02:00
masterConfig = lib . mkOption {
type = lib . types . attrsOf ( lib . types . submodule masterCfOptions ) ;
2017-07-14 16:55:53 +02:00
default = { } ;
example = {
submission = {
type = " i n e t " ;
args = [
" - o "
" s m t p d _ t l s _ s e c u r i t y _ l e v e l = e n c r y p t "
] ;
} ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
description = ''
An attribute set of service options , which correspond to the service
definitions usually done within the Postfix
{ file } ` master . cf ` file .
'' ;
} ;
2024-08-27 20:57:37 +02:00
extraMasterConf = lib . mkOption {
type = lib . types . lines ;
2012-09-23 12:21:34 +02:00
default = " " ;
example = " s u b m i s s i o n i n e t n - n - - s m t p d " ;
description = " E x t r a l i n e s t o a p p e n d t o t h e g e n e r a t e d m a s t e r . c f f i l e . " ;
} ;
2024-08-27 20:57:37 +02:00
enableHeaderChecks = lib . mkOption {
type = lib . types . bool ;
2017-07-14 16:55:53 +02:00
default = false ;
example = true ;
description = " W h e t h e r t o e n a b l e p o s t f i x h e a d e r c h e c k s " ;
} ;
2024-08-27 20:57:37 +02:00
headerChecks = lib . mkOption {
type = lib . types . listOf ( lib . types . submodule headerCheckOptions ) ;
2017-07-14 16:55:53 +02:00
default = [ ] ;
example = [
{
pattern = " / ^ X - S p a m - F l a g : / " ;
action = " R E D I R E C T s p a m @ e x a m p l e . c o m " ;
}
] ;
description = " P o s t f i x h e a d e r c h e c k s . " ;
} ;
2024-08-27 20:57:37 +02:00
extraHeaderChecks = lib . mkOption {
type = lib . types . lines ;
2017-07-14 16:55:53 +02:00
default = " " ;
example = " / ^ X - S p a m - F l a g : / R E D I R E C T s p a m @ e x a m p l e . c o m " ;
description = " E x t r a l i n e s t o / e t c / p o s t f i x / h e a d e r _ c h e c k s f i l e . " ;
} ;
2024-08-27 20:57:37 +02:00
aliasFiles = lib . mkOption {
type = lib . types . attrsOf lib . types . path ;
2016-01-10 05:39:17 +03:00
default = { } ;
description = " A l i a s e s ' t a b l e s t o b e c o m p i l e d a n d p l a c e d i n t o / v a r / l i b / p o s t f i x / c o n f . " ;
} ;
2024-08-27 20:57:37 +02:00
mapFiles = lib . mkOption {
type = lib . types . attrsOf lib . types . path ;
2016-01-10 05:39:17 +03:00
default = { } ;
description = " M a p s t o b e c o m p i l e d a n d p l a c e d i n t o / v a r / l i b / p o s t f i x / c o n f . " ;
} ;
2024-08-27 20:57:37 +02:00
useSrs = lib . mkOption {
type = lib . types . bool ;
2015-12-24 14:34:43 -05:00
default = false ;
description = " W h e t h e r t o e n a b l e s e n d e r r e w r i t i n g s c h e m e " ;
} ;
2009-10-12 16:36:19 +00:00
} ;
2008-06-30 15:13:02 +00:00
2009-03-06 12:27:07 +00:00
} ;
2009-10-12 16:36:19 +00:00
###### implementation
2024-08-27 20:57:37 +02:00
config = lib . mkIf config . services . postfix . enable (
lib . mkMerge [
2016-01-10 05:39:17 +03:00
{
2009-10-12 16:36:19 +00:00
2016-01-10 05:39:17 +03:00
environment = {
2020-01-11 08:09:56 +01:00
etc . postfix . source = " / v a r / l i b / p o s t f i x / c o n f " ;
2010-10-10 10:43:28 +00:00
2018-10-15 13:12:06 +01:00
# This makes it comfortable to run 'postqueue/postdrop' for example.
2016-01-10 05:39:17 +03:00
systemPackages = [ pkgs . postfix ] ;
2009-10-12 16:36:19 +00:00
} ;
2009-03-06 12:27:07 +00:00
2015-12-24 14:34:43 -05:00
services . pfix-srsd . enable = config . services . postfix . useSrs ;
2024-08-27 20:57:37 +02:00
services . mail . sendmailSetuidWrapper = lib . mkIf config . services . postfix . setSendmail {
2016-01-10 05:39:17 +03:00
program = " s e n d m a i l " ;
source = " ${ pkgs . postfix } / b i n / s e n d m a i l " ;
2021-10-03 11:43:13 +02:00
owner = " r o o t " ;
2016-01-10 05:39:17 +03:00
group = setgidGroup ;
setuid = false ;
setgid = true ;
2016-01-09 03:36:39 +03:00
} ;
2009-03-06 12:27:07 +00:00
2019-11-13 15:25:35 +00:00
security . wrappers . mailq = {
program = " m a i l q " ;
source = " ${ pkgs . postfix } / b i n / m a i l q " ;
2021-10-03 11:43:13 +02:00
owner = " r o o t " ;
2019-11-13 15:25:35 +00:00
group = setgidGroup ;
setuid = false ;
setgid = true ;
} ;
2018-10-15 13:12:06 +01:00
security . wrappers . postqueue = {
program = " p o s t q u e u e " ;
source = " ${ pkgs . postfix } / b i n / p o s t q u e u e " ;
2021-10-03 11:43:13 +02:00
owner = " r o o t " ;
2018-10-15 13:12:06 +01:00
group = setgidGroup ;
setuid = false ;
setgid = true ;
} ;
security . wrappers . postdrop = {
program = " p o s t d r o p " ;
source = " ${ pkgs . postfix } / b i n / p o s t d r o p " ;
2021-10-03 11:43:13 +02:00
owner = " r o o t " ;
2018-10-15 13:12:06 +01:00
group = setgidGroup ;
setuid = false ;
setgid = true ;
} ;
2024-08-27 20:57:37 +02:00
users . users = lib . optionalAttrs ( user = = " p o s t f i x " ) {
2019-09-14 19:51:29 +02:00
postfix = {
description = " P o s t f i x m a i l s e r v e r u s e r " ;
uid = config . ids . uids . postfix ;
group = group ;
} ;
2015-10-25 12:06:56 +01:00
} ;
2010-06-11 21:44:06 +00:00
2018-06-30 01:58:35 +02:00
users . groups =
2024-08-27 20:57:37 +02:00
lib . optionalAttrs ( group = = " p o s t f i x " ) {
2020-01-07 06:05:49 +01:00
$ { group } . gid = config . ids . gids . postfix ;
2016-01-10 05:39:17 +03:00
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs ( setgidGroup = = " p o s t d r o p " ) {
2019-09-14 19:51:29 +02:00
$ { setgidGroup } . gid = config . ids . gids . postdrop ;
2016-01-10 05:39:17 +03:00
} ;
2009-03-06 12:27:07 +00:00
2022-04-05 10:03:25 +00:00
systemd . services . postfix-setup = {
description = " S e t u p f o r P o s t f i x m a i l s e r v e r " ;
2022-05-22 10:33:22 +00:00
serviceConfig . RemainAfterExit = true ;
2022-04-05 10:03:25 +00:00
serviceConfig . Type = " o n e s h o t " ;
script = ''
2016-01-10 15:33:23 +03:00
# Backwards compatibility
if [ ! - d /var/lib/postfix ] && [ - d /var/postfix ] ; then
mkdir - p /var/lib
mv /var/postfix /var/lib/postfix
fi
2016-01-10 05:39:17 +03:00
2016-01-18 23:10:58 +02:00
# All permissions set according ${pkgs.postfix}/etc/postfix/postfix-files script
mkdir - p /var/lib/postfix /var/lib/postfix/queue / { pid , public , maildrop }
chmod 0755 /var/lib/postfix
chown root:root /var/lib/postfix
2016-01-10 05:39:17 +03:00
rm - rf /var/lib/postfix/conf
mkdir - p /var/lib/postfix/conf
2016-01-18 23:10:58 +02:00
chmod 0755 /var/lib/postfix/conf
2016-02-10 02:58:55 +03:00
ln - sf $ { pkgs . postfix } /etc/postfix/postfix-files /var/lib/postfix/conf/postfix-files
2016-01-10 05:39:17 +03:00
ln - sf $ { mainCfFile } /var/lib/postfix/conf/main.cf
ln - sf $ { masterCfFile } /var/lib/postfix/conf/master.cf
2016-01-18 23:10:58 +02:00
2024-08-27 20:57:37 +02:00
$ { lib . concatStringsSep " \n " (
lib . mapAttrsToList ( to : from : ''
2016-01-10 05:39:17 +03:00
ln - sf $ { from } /var/lib/postfix/conf / $ { to }
2023-09-16 07:47:52 -04:00
$ { pkgs . postfix } /bin/postalias - o - p /var/lib/postfix/conf / $ { to }
2016-01-10 05:39:17 +03:00
'' ) c f g . a l i a s F i l e s
) }
2024-08-27 20:57:37 +02:00
$ { lib . concatStringsSep " \n " (
lib . mapAttrsToList ( to : from : ''
2016-01-10 05:39:17 +03:00
ln - sf $ { from } /var/lib/postfix/conf / $ { to }
2016-01-18 23:10:58 +02:00
$ { pkgs . postfix } /bin/postmap /var/lib/postfix/conf / $ { to }
2016-01-10 05:39:17 +03:00
'' ) c f g . m a p F i l e s
) }
mkdir - p /var/spool/mail
chown root:root /var/spool/mail
chmod a + rwxt /var/spool/mail
ln - sf /var/spool/mail /var /
2016-01-18 23:10:58 +02:00
#Finally delegate to postfix checking remain directories in /var/lib/postfix and set permissions on them
$ { pkgs . postfix } /bin/postfix set-permissions config_directory = /var/lib/postfix/conf
2016-01-10 05:39:17 +03:00
'' ;
} ;
2017-07-14 16:55:53 +02:00
2022-04-05 10:03:25 +00:00
systemd . services . postfix = {
description = " P o s t f i x m a i l s e r v e r " ;
2025-03-12 17:59:34 +01:00
documentation = [ " m a n : p o s t f i x ( 1 ) " ] ;
2022-04-05 10:03:25 +00:00
wantedBy = [ " m u l t i - u s e r . t a r g e t " ] ;
after = [
" n e t w o r k . t a r g e t "
" p o s t f i x - s e t u p . s e r v i c e "
] ;
requires = [ " p o s t f i x - s e t u p . s e r v i c e " ] ;
path = [ pkgs . postfix ] ;
serviceConfig = {
Type = " f o r k i n g " ;
Restart = " a l w a y s " ;
PIDFile = " / v a r / l i b / p o s t f i x / q u e u e / p i d / m a s t e r . p i d " ;
ExecStart = " ${ pkgs . postfix } / b i n / p o s t f i x s t a r t " ;
ExecStop = " ${ pkgs . postfix } / b i n / p o s t f i x s t o p " ;
ExecReload = " ${ pkgs . postfix } / b i n / p o s t f i x r e l o a d " ;
2023-09-15 15:06:20 +10:00
# Hardening
PrivateTmp = true ;
PrivateDevices = true ;
ProtectSystem = " f u l l " ;
CapabilityBoundingSet = [ " ~ C A P _ N E T _ A D M I N C A P _ S Y S _ A D M I N C A P _ S Y S _ B O O T C A P _ S Y S _ M O D U L E " ] ;
MemoryDenyWriteExecute = true ;
ProtectKernelModules = true ;
ProtectKernelTunables = true ;
ProtectControlGroups = true ;
RestrictAddressFamilies = [
" A F _ I N E T "
" A F _ I N E T 6 "
" A F _ N E T L I N K "
" A F _ U N I X "
] ;
RestrictNamespaces = true ;
RestrictRealtime = true ;
2022-04-05 10:03:25 +00:00
} ;
} ;
2024-08-27 20:57:37 +02:00
services . postfix . config =
( lib . mapAttrs ( _ : v : lib . mkDefault v ) {
2021-05-02 21:49:33 +00:00
compatibility_level = pkgs . postfix . version ;
2018-01-19 18:32:32 +01:00
mail_owner = cfg . user ;
default_privs = " n o b o d y " ;
2024-12-10 20:26:33 +01:00
2018-01-19 18:32:32 +01:00
# NixOS specific locations
data_directory = " / v a r / l i b / p o s t f i x / d a t a " ;
queue_directory = " / v a r / l i b / p o s t f i x / q u e u e " ;
2024-12-10 20:26:33 +01:00
2018-01-19 18:32:32 +01:00
# Default location of everything in package
meta_directory = " ${ pkgs . postfix } / e t c / p o s t f i x " ;
command_directory = " ${ pkgs . postfix } / b i n " ;
sample_directory = " / e t c / p o s t f i x " ;
newaliases_path = " ${ pkgs . postfix } / b i n / n e w a l i a s e s " ;
mailq_path = " ${ pkgs . postfix } / b i n / m a i l q " ;
readme_directory = false ;
sendmail_path = " ${ pkgs . postfix } / b i n / s e n d m a i l " ;
daemon_directory = " ${ pkgs . postfix } / l i b e x e c / p o s t f i x " ;
manpage_directory = " ${ pkgs . postfix } / s h a r e / m a n " ;
html_directory = " ${ pkgs . postfix } / s h a r e / p o s t f i x / d o c / h t m l " ;
shlib_directory = false ;
mail_spool_directory = " / v a r / s p o o l / m a i l / " ;
setgid_group = cfg . setgidGroup ;
} )
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs ( cfg . relayHost != " " ) {
relayhost =
if cfg . lookupMX then
2018-01-19 18:32:32 +01:00
" ${ cfg . relayHost } : ${ toString cfg . relayPort } "
else
" [ ${ cfg . relayHost } ] : ${ toString cfg . relayPort } " ;
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs ( ! config . networking . enableIPv6 ) { inet_protocols = lib . mkDefault " i p v 4 " ; }
// lib . optionalAttrs ( cfg . networks != null ) { mynetworks = cfg . networks ; }
// lib . optionalAttrs ( cfg . networksStyle != " " ) { mynetworks_style = cfg . networksStyle ; }
// lib . optionalAttrs ( cfg . hostname != " " ) { myhostname = cfg . hostname ; }
// lib . optionalAttrs ( cfg . domain != " " ) { mydomain = cfg . domain ; }
// lib . optionalAttrs ( cfg . origin != " " ) { myorigin = cfg . origin ; }
// lib . optionalAttrs ( cfg . destination != null ) { mydestination = cfg . destination ; }
// lib . optionalAttrs ( cfg . relayDomains != null ) { relay_domains = cfg . relayDomains ; }
// lib . optionalAttrs ( cfg . recipientDelimiter != " " ) {
recipient_delimiter = cfg . recipientDelimiter ;
}
// lib . optionalAttrs haveAliases { alias_maps = [ " ${ cfg . aliasMapType } : / e t c / p o s t f i x / a l i a s e s " ] ; }
// lib . optionalAttrs haveTransport { transport_maps = [ " h a s h : / e t c / p o s t f i x / t r a n s p o r t " ] ; }
// lib . optionalAttrs haveVirtual {
virtual_alias_maps = [ " ${ cfg . virtualMapType } : / e t c / p o s t f i x / v i r t u a l " ] ;
}
// lib . optionalAttrs haveLocalRecipients {
local_recipient_maps = [
" h a s h : / e t c / p o s t f i x / l o c a l _ r e c i p i e n t s "
] ++ lib . optional haveAliases " $ a l i a s _ m a p s " ;
}
// lib . optionalAttrs ( cfg . dnsBlacklists != [ ] ) { smtpd_client_restrictions = clientRestrictions ; }
// lib . optionalAttrs cfg . useSrs {
2018-01-19 18:32:32 +01:00
sender_canonical_maps = [ " t c p : 1 2 7 . 0 . 0 . 1 : 1 0 0 0 1 " ] ;
sender_canonical_classes = [ " e n v e l o p e _ s e n d e r " ] ;
recipient_canonical_maps = [ " t c p : 1 2 7 . 0 . 0 . 1 : 1 0 0 0 2 " ] ;
recipient_canonical_classes = [ " e n v e l o p e _ r e c i p i e n t " ] ;
2024-08-27 20:57:37 +02:00
}
// lib . optionalAttrs cfg . enableHeaderChecks {
header_checks = [ " r e g e x p : / e t c / p o s t f i x / h e a d e r _ c h e c k s " ] ;
2024-12-10 20:26:33 +01:00
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs ( cfg . tlsTrustedAuthorities != " " ) {
2020-06-11 03:37:36 +02:00
smtp_tls_CAfile = cfg . tlsTrustedAuthorities ;
2024-08-27 20:57:37 +02:00
smtp_tls_security_level = lib . mkDefault " m a y " ;
2020-06-11 03:37:36 +02:00
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs ( cfg . sslCert != " " ) {
2018-01-19 18:32:32 +01:00
smtp_tls_cert_file = cfg . sslCert ;
smtp_tls_key_file = cfg . sslKey ;
2024-12-10 20:26:33 +01:00
2024-08-27 20:57:37 +02:00
smtp_tls_security_level = lib . mkDefault " m a y " ;
2024-12-10 20:26:33 +01:00
2018-01-19 18:32:32 +01:00
smtpd_tls_cert_file = cfg . sslCert ;
smtpd_tls_key_file = cfg . sslKey ;
2024-12-10 20:26:33 +01:00
2024-09-22 23:09:55 +02:00
smtpd_tls_security_level = lib . mkDefault " m a y " ;
2025-06-04 08:15:52 +02:00
2018-01-19 18:32:32 +01:00
} ;
2017-07-14 16:55:53 +02:00
services . postfix . masterConfig =
{
pickup = {
private = false ;
wakeup = 60 ;
2020-07-06 03:37:56 +02:00
maxproc = 1 ;
} ;
2017-07-14 16:55:53 +02:00
cleanup = {
2024-08-27 20:57:37 +02:00
private = false ;
maxproc = 0 ;
2024-12-10 20:26:33 +01:00
} ;
qmgr = {
2024-08-27 20:57:37 +02:00
private = false ;
2017-07-14 16:55:53 +02:00
wakeup = 300 ;
maxproc = 1 ;
2024-12-10 20:26:33 +01:00
} ;
2024-08-27 20:57:37 +02:00
tlsmgr = {
2017-07-14 16:55:53 +02:00
wakeup = 1000 ;
2024-08-27 20:57:37 +02:00
wakeupUnusedComponent = false ;
2020-07-06 03:37:56 +02:00
maxproc = 1 ;
2017-07-14 16:55:53 +02:00
} ;
rewrite = {
2024-08-27 20:57:37 +02:00
command = " t r i v i a l - r e w r i t e " ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
bounce = {
maxproc = 0 ;
2024-12-10 20:26:33 +01:00
} ;
defer = {
2017-07-14 16:55:53 +02:00
maxproc = 0 ;
command = " b o u n c e " ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
trace = {
maxproc = 0 ;
command = " b o u n c e " ;
2024-12-10 20:26:33 +01:00
} ;
2024-08-27 20:57:37 +02:00
verify = {
2017-07-14 16:55:53 +02:00
maxproc = 1 ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
flush = {
2019-08-13 21:52:01 +00:00
private = false ;
2017-07-14 16:55:53 +02:00
wakeup = 1000 ;
2019-08-13 21:52:01 +00:00
wakeupUnusedComponent = false ;
2017-07-14 16:55:53 +02:00
maxproc = 0 ;
2016-01-10 05:39:17 +03:00
} ;
2024-08-27 20:57:37 +02:00
proxymap = {
command = " p r o x y m a p " ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
proxywrite = {
maxproc = 1 ;
2021-04-04 11:56:31 +00:00
command = " p r o x y m a p " ;
2024-12-10 20:26:33 +01:00
} ;
2021-04-04 11:56:31 +00:00
showq = {
private = false ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
error = { } ;
retry = {
2021-04-04 11:56:31 +00:00
command = " e r r o r " ;
2024-12-10 20:26:33 +01:00
} ;
2021-04-04 11:56:31 +00:00
discard = { } ;
local = {
privileged = true ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
virtual = {
2021-04-04 11:56:31 +00:00
privileged = true ;
2024-12-10 20:26:33 +01:00
} ;
lmtp = {
} ;
2017-07-14 16:55:53 +02:00
anvil = {
maxproc = 1 ;
2024-12-10 20:26:33 +01:00
} ;
2021-04-04 11:56:31 +00:00
scache = {
2017-07-14 16:55:53 +02:00
maxproc = 1 ;
2024-12-10 20:26:33 +01:00
} ;
}
2021-04-04 11:56:31 +00:00
// lib . optionalAttrs cfg . enableSubmission {
2017-07-14 16:55:53 +02:00
submission = {
2020-07-06 03:37:56 +02:00
type = " i n e t " ;
private = false ;
2017-11-05 09:42:40 -08:00
command = " s m t p d " ;
2024-12-10 20:26:33 +01:00
args =
let
2020-07-06 03:37:56 +02:00
mkKeyVal = opt : val : [
2024-12-10 20:26:33 +01:00
" - o "
2020-07-06 03:37:56 +02:00
( opt + " = " + val )
2024-12-10 20:26:33 +01:00
] ;
in
2021-04-04 11:56:31 +00:00
lib . concatLists ( lib . mapAttrsToList mkKeyVal cfg . submissionOptions ) ;
2019-08-13 21:52:01 +00:00
} ;
2016-01-10 05:39:17 +03:00
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs cfg . enableSmtp {
2019-08-13 21:52:01 +00:00
smtp_inet = {
2017-11-05 09:42:40 -08:00
name = " s m t p " ;
2020-07-06 03:37:56 +02:00
type = " i n e t " ;
2019-08-13 21:52:01 +00:00
private = false ;
2017-11-05 09:42:40 -08:00
command = " s m t p d " ;
2024-12-10 20:26:33 +01:00
} ;
2017-07-14 16:55:53 +02:00
smtp = { } ;
relay = {
2019-08-13 21:52:01 +00:00
command = " s m t p " ;
2024-08-27 20:57:37 +02:00
args = [
2024-12-10 20:26:33 +01:00
" - o "
2024-08-27 20:57:37 +02:00
" s m t p _ f a l l b a c k _ r e l a y = "
2024-12-10 20:26:33 +01:00
] ;
} ;
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs cfg . enableSubmissions {
2020-07-06 03:37:56 +02:00
submissions = {
type = " i n e t " ;
private = false ;
2017-11-05 09:42:40 -08:00
command = " s m t p d " ;
2024-12-10 20:26:33 +01:00
args =
let
2024-08-27 20:57:37 +02:00
mkKeyVal = opt : val : [
2024-12-10 20:26:33 +01:00
" - o "
2024-08-27 20:57:37 +02:00
( opt + " = " + val )
2024-12-10 20:26:33 +01:00
] ;
2024-08-27 20:57:37 +02:00
adjustSmtpTlsSecurityLevel =
! ( cfg . submissionsOptions ? smtpd_tls_security_level )
2019-08-13 21:52:01 +00:00
|| cfg . submissionsOptions . smtpd_tls_security_level = = " n o n e "
|| cfg . submissionsOptions . smtpd_tls_security_level = = " m a y " ;
2020-07-06 03:37:56 +02:00
submissionsOptions =
cfg . submissionsOptions
2024-12-10 20:26:33 +01:00
// {
2019-08-13 21:52:01 +00:00
smtpd_tls_wrappermode = " y e s " ;
2024-12-10 20:26:33 +01:00
}
2024-08-27 20:57:37 +02:00
// lib . optionalAttrs adjustSmtpTlsSecurityLevel {
2019-08-13 21:52:01 +00:00
smtpd_tls_security_level = " e n c r y p t " ;
2024-12-10 20:26:33 +01:00
} ;
in
2019-08-13 21:52:01 +00:00
lib . concatLists ( lib . mapAttrsToList mkKeyVal submissionsOptions ) ;
2024-12-10 20:26:33 +01:00
} ;
} ;
2016-01-07 22:38:22 -05:00
}
2020-06-11 03:37:36 +02:00
2024-08-27 20:57:37 +02:00
( lib . mkIf haveAliases {
2020-06-11 03:37:36 +02:00
services . postfix . aliasFiles . aliases = aliasesFile ;
} )
( lib . mkIf haveCanonical {
services . postfix . mapFiles . canonical = canonicalFile ;
2024-12-10 20:26:33 +01:00
} )
2025-06-04 08:15:52 +02:00
( lib . mkIf haveTransport {
2020-06-11 03:37:36 +02:00
services . postfix . mapFiles . transport = transportFile ;
2024-12-10 20:26:33 +01:00
} )
2024-08-27 20:57:37 +02:00
( lib . mkIf haveVirtual {
2020-06-11 03:37:36 +02:00
services . postfix . mapFiles . virtual = virtualFile ;
2024-12-10 20:26:33 +01:00
} )
2024-08-27 20:57:37 +02:00
( lib . mkIf haveLocalRecipients {
2020-06-11 03:37:36 +02:00
services . postfix . mapFiles . local_recipients = localRecipientMapFile ;
2024-12-10 20:26:33 +01:00
} )
2020-06-11 03:37:36 +02:00
( lib . mkIf cfg . enableHeaderChecks {
2019-08-13 21:52:01 +00:00
services . postfix . mapFiles . header_checks = headerChecksFile ;
2024-12-10 20:26:33 +01:00
} )
2020-06-11 03:37:36 +02:00
( lib . mkIf ( cfg . dnsBlacklists != [ ] ) {
services . postfix . mapFiles . client_access = checkClientAccessFile ;
2024-12-10 20:26:33 +01:00
} )
]
) ;
2021-01-12 15:56:08 +00:00
2020-06-11 03:37:36 +02:00
imports = [
2024-08-27 20:57:37 +02:00
( lib . mkRemovedOptionModule [ " s e r v i c e s " " p o s t f i x " " s s l C A C e r t " ]
2020-06-11 03:37:36 +02:00
" s e r v i c e s . p o s t f i x . s s l C A C e r t w a s r e p l a c e d b y s e r v i c e s . p o s t f i x . t l s T r u s t e d A u t h o r i t i e s . I n c a s e y o u i n t e n d t h a t y o u r s e r v e r s h o u l d v a l i d a t e r e q u e s t e d c l i e n t c e r t i f i c a t e s u s e s e r v i c e s . p o s t f i x . e x t r a C o n f i g . "
2024-12-10 20:26:33 +01:00
)
2024-08-27 20:57:37 +02:00
( lib . mkChangedOptionModule
[ " s e r v i c e s " " p o s t f i x " " u s e D a n e " ]
2021-01-12 15:56:08 +00:00
[ " s e r v i c e s " " p o s t f i x " " c o n f i g " " s m t p _ t l s _ s e c u r i t y _ l e v e l " ]
2024-08-27 20:57:37 +02:00
( config : lib . mkIf config . services . postfix . useDane " d a n e " )
2024-12-10 20:26:33 +01:00
)
2020-06-11 03:37:36 +02:00
] ;
2008-06-30 15:13:02 +00:00
}