1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.services.opensmtpd;
10 conf = pkgs.writeText "smtpd.conf" cfg.serverConfiguration;
11 args = lib.concatStringsSep " " cfg.extraServerArgs;
12
13 sendmail = pkgs.runCommand "opensmtpd-sendmail" { preferLocalBuild = true; } ''
14 mkdir -p $out/bin
15 ln -s ${cfg.package}/sbin/smtpctl $out/bin/sendmail
16 '';
17
18in
19{
20
21 ###### interface
22
23 imports = [
24 (lib.mkRenamedOptionModule
25 [ "services" "opensmtpd" "addSendmailToSystemPath" ]
26 [ "services" "opensmtpd" "setSendmail" ]
27 )
28 ];
29
30 options = {
31
32 services.opensmtpd = {
33
34 enable = lib.mkOption {
35 type = lib.types.bool;
36 default = false;
37 description = "Whether to enable the OpenSMTPD server.";
38 };
39
40 package = lib.mkPackageOption pkgs "opensmtpd" { };
41
42 setSendmail = lib.mkOption {
43 type = lib.types.bool;
44 default = true;
45 description = "Whether to set the system sendmail to OpenSMTPD's.";
46 };
47
48 extraServerArgs = lib.mkOption {
49 type = lib.types.listOf lib.types.str;
50 default = [ ];
51 example = [
52 "-v"
53 "-P mta"
54 ];
55 description = ''
56 Extra command line arguments provided when the smtpd process
57 is started.
58 '';
59 };
60
61 serverConfiguration = lib.mkOption {
62 type = lib.types.lines;
63 example = ''
64 listen on lo
65 accept for any deliver to lmtp localhost:24
66 '';
67 description = ''
68 The contents of the smtpd.conf configuration file. See the
69 OpenSMTPD documentation for syntax information.
70 '';
71 };
72
73 procPackages = lib.mkOption {
74 type = lib.types.listOf lib.types.package;
75 default = [ ];
76 description = ''
77 Packages to search for filters, tables, queues, and schedulers.
78
79 Add packages here if you want to use them as as such, for example
80 from the opensmtpd-table-* packages.
81 '';
82 };
83 };
84
85 };
86
87 ###### implementation
88
89 config = lib.mkIf cfg.enable rec {
90 users.groups = {
91 smtpd.gid = config.ids.gids.smtpd;
92 smtpq.gid = config.ids.gids.smtpq;
93 };
94
95 users.users = {
96 smtpd = {
97 description = "OpenSMTPD process user";
98 uid = config.ids.uids.smtpd;
99 group = "smtpd";
100 };
101 smtpq = {
102 description = "OpenSMTPD queue user";
103 uid = config.ids.uids.smtpq;
104 group = "smtpq";
105 };
106 };
107
108 security.wrappers.smtpctl = {
109 owner = "root";
110 group = "smtpq";
111 setuid = false;
112 setgid = true;
113 source = "${cfg.package}/bin/smtpctl";
114 };
115
116 services.mail.sendmailSetuidWrapper = lib.mkIf cfg.setSendmail (
117 security.wrappers.smtpctl
118 // {
119 source = "${sendmail}/bin/sendmail";
120 program = "sendmail";
121 }
122 );
123
124 systemd.tmpfiles.rules = [
125 "d /var/spool/smtpd 711 root - - -"
126 "d /var/spool/smtpd/offline 770 root smtpq - -"
127 "d /var/spool/smtpd/purge 700 smtpq root - -"
128 ];
129
130 systemd.services.opensmtpd =
131 let
132 procEnv = pkgs.buildEnv {
133 name = "opensmtpd-procs";
134 paths = [ cfg.package ] ++ cfg.procPackages;
135 pathsToLink = [ "/libexec/smtpd" ];
136 };
137 in
138 {
139 wantedBy = [ "multi-user.target" ];
140 after = [ "network.target" ];
141 serviceConfig.ExecStart = "${cfg.package}/sbin/smtpd -d -f ${conf} ${args}";
142 environment.OPENSMTPD_PROC_PATH = "${procEnv}/libexec/smtpd";
143 };
144 };
145}