1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7let
8 cfg = config.services.zeyple;
9 ini = pkgs.formats.ini { };
10
11 gpgHome = pkgs.runCommand "zeyple-gpg-home" { } ''
12 mkdir -p $out
13 for file in ${lib.concatStringsSep " " cfg.keys}; do
14 ${config.programs.gnupg.package}/bin/gpg --homedir="$out" --import "$file"
15 done
16
17 # Remove socket files
18 rm -f $out/S.*
19 '';
20in
21{
22 options.services.zeyple = {
23 enable = lib.mkEnableOption "Zeyple, an utility program to automatically encrypt outgoing emails with GPG";
24
25 user = lib.mkOption {
26 type = lib.types.str;
27 default = "zeyple";
28 description = ''
29 User to run Zeyple as.
30
31 ::: {.note}
32 If left as the default value this user will automatically be created
33 on system activation, otherwise the sysadmin is responsible for
34 ensuring the user exists.
35 :::
36 '';
37 };
38
39 group = lib.mkOption {
40 type = lib.types.str;
41 default = "zeyple";
42 description = ''
43 Group to use to run Zeyple.
44
45 ::: {.note}
46 If left as the default value this group will automatically be created
47 on system activation, otherwise the sysadmin is responsible for
48 ensuring the user exists.
49 :::
50 '';
51 };
52
53 settings = lib.mkOption {
54 type = ini.type;
55 default = { };
56 description = ''
57 Zeyple configuration. refer to
58 <https://github.com/infertux/zeyple/blob/master/zeyple/zeyple.conf.example>
59 for details on supported values.
60 '';
61 };
62
63 keys = lib.mkOption {
64 type = with lib.types; listOf path;
65 description = "List of public key files that will be imported by gpg.";
66 };
67
68 rotateLogs = lib.mkOption {
69 type = lib.types.bool;
70 default = true;
71 description = "Whether to enable rotation of log files.";
72 };
73 };
74
75 config = lib.mkIf cfg.enable {
76 users.groups = lib.optionalAttrs (cfg.group == "zeyple") { "${cfg.group}" = { }; };
77 users.users = lib.optionalAttrs (cfg.user == "zeyple") {
78 "${cfg.user}" = {
79 isSystemUser = true;
80 group = cfg.group;
81 };
82 };
83
84 services.zeyple.settings = {
85 zeyple = lib.mapAttrs (name: lib.mkDefault) {
86 log_file = "/var/log/zeyple/zeyple.log";
87 force_encrypt = true;
88 };
89
90 gpg = lib.mapAttrs (name: lib.mkDefault) { home = "${gpgHome}"; };
91
92 relay = lib.mapAttrs (name: lib.mkDefault) {
93 host = "localhost";
94 port = 10026;
95 };
96 };
97
98 environment.etc."zeyple.conf".source = ini.generate "zeyple.conf" cfg.settings;
99
100 systemd.tmpfiles.settings."10-zeyple".${cfg.settings.zeyple.log_file}.f = {
101 inherit (cfg) user group;
102 mode = "0600";
103 };
104
105 services.logrotate = lib.mkIf cfg.rotateLogs {
106 enable = true;
107 settings.zeyple = {
108 files = cfg.settings.zeyple.log_file;
109 frequency = "weekly";
110 rotate = 5;
111 compress = true;
112 copytruncate = true;
113 };
114 };
115
116 services.postfix.extraMasterConf = ''
117 zeyple unix - n n - - pipe
118 user=${cfg.user} argv=${pkgs.zeyple}/bin/zeyple ''${recipient}
119
120 localhost:${toString cfg.settings.relay.port} inet n - n - 10 smtpd
121 -o content_filter=
122 -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
123 -o smtpd_helo_restrictions=
124 -o smtpd_client_restrictions=
125 -o smtpd_sender_restrictions=
126 -o smtpd_recipient_restrictions=permit_mynetworks,reject
127 -o mynetworks=127.0.0.0/8,[::1]/128
128 -o smtpd_authorized_xforward_hosts=127.0.0.0/8,[::1]/128
129 '';
130
131 services.postfix.extraConfig = "content_filter = zeyple";
132 };
133}