1 { config, pkgs, lib, ... }: with lib; let
2 cfg = config.services.sogo;
4 preStart = pkgs.writeShellScriptBin "sogo-prestart" ''
5 ${if (cfg.configReplaces != {}) then ''
7 ${concatStringsSep "\n" (mapAttrsToList (k: v: ''export ${k}="$(cat "${v}" | tr -d '\n')"'') cfg.configReplaces)}
9 ${pkgs.perl}/bin/perl -p ${concatStringsSep " " (mapAttrsToList (k: v: '' -e 's/${k}/''${ENV{"${k}"}}/g;' '') cfg.configReplaces)} /etc/sogo/sogo.conf.raw | install -m 640 -o sogo -g sogo /dev/stdin /etc/sogo/sogo.conf
11 install -m 640 -o sogo -g sogo /etc/sogo/sogo.conf.raw /etc/sogo/sogo.conf
16 options.services.sogo = with types; {
17 enable = mkEnableOption "SOGo groupware";
19 vhostName = mkOption {
20 description = "Name of the nginx vhost";
26 description = "Timezone of your SOGo instance";
28 example = "America/Montreal";
32 description = "Language of SOGo";
37 ealarmsCredFile = mkOption {
38 description = "Optional path to a credentials file for email alarms";
43 configReplaces = mkOption {
45 Replacement-filepath mapping for sogo.conf.
46 Every key is replaced with the contents of the file specified as value.
48 In the example, every occurrence of LDAP_BINDPW will be replaced with the text of the
54 LDAP_BINDPW = "/var/lib/secrets/sogo/ldappw";
58 extraConfig = mkOption {
59 description = "Extra sogo.conf configuration lines";
65 config = mkIf cfg.enable {
66 environment.systemPackages = [ pkgs.sogo ];
68 environment.etc."sogo/sogo.conf.raw".text = ''
70 // Mandatory parameters
71 SOGoTimeZone = "${cfg.timezone}";
72 SOGoLanguage = "${cfg.language}";
74 WOSendMail = "/run/wrappers/bin/sendmail";
75 SOGoMailSpoolPath = "/var/lib/sogo/spool";
76 // Enable CSRF protection
77 SOGoXSRFValidationEnabled = YES;
78 // Remove dates from log (jornald does that)
79 NGLogDefaultLogEventFormatterClass = "NGLogEventFormatter";
85 systemd.services.sogo = {
86 description = "SOGo groupware";
87 after = [ "postgresql.service" "mysql.service" "memcached.service" "openldap.service" "dovecot2.service" ];
88 wantedBy = [ "multi-user.target" ];
89 restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
91 environment.LDAPTLS_CACERT = "/etc/ssl/certs/ca-certificates.crt";
95 ExecStartPre = "+" + preStart + "/bin/sogo-prestart";
96 ExecStart = "${pkgs.sogo}/bin/sogod -WOLogFile - -WOPidFile /run/sogo/sogo.pid";
98 ProtectSystem = "strict";
101 PrivateDevices = true;
102 ProtectKernelTunables = true;
103 ProtectKernelModules = true;
104 ProtectControlGroups = true;
105 RuntimeDirectory = "sogo";
106 StateDirectory = "sogo/spool";
111 CapabilityBoundingSet = "";
112 NoNewPrivileges = true;
114 LockPersonality = true;
115 RestrictRealtime = true;
116 PrivateMounts = true;
118 MemoryDenyWriteExecute = true;
119 SystemCallFilter = "@basic-io @file-system @network-io @system-service @timer";
120 SystemCallArchitectures = "native";
121 RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
125 systemd.services.sogo-tmpwatch = {
126 description = "SOGo tmpwatch";
128 startAt = [ "hourly" ];
130 SOGOSPOOL=/var/lib/sogo/spool
132 find "$SOGOSPOOL" -type f -user sogo -atime +23 -delete > /dev/null
133 find "$SOGOSPOOL" -mindepth 1 -type d -user sogo -empty -delete > /dev/null
139 ProtectSystem = "strict";
142 PrivateDevices = true;
143 ProtectKernelTunables = true;
144 ProtectKernelModules = true;
145 ProtectControlGroups = true;
146 StateDirectory = "sogo/spool";
151 CapabilityBoundingSet = "";
152 NoNewPrivileges = true;
154 LockPersonality = true;
155 RestrictRealtime = true;
156 PrivateMounts = true;
158 PrivateNetwork = true;
159 SystemCallFilter = "@basic-io @file-system @system-service";
160 SystemCallArchitectures = "native";
161 RestrictAddressFamilies = "";
165 systemd.services.sogo-ealarms = {
166 description = "SOGo email alarms";
168 after = [ "postgresql.service" "mysqld.service" "memcached.service" "openldap.service" "dovecot2.service" "sogo.service" ];
169 restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
171 startAt = [ "minutely" ];
175 ExecStart = "${pkgs.sogo}/bin/sogo-ealarms-notify${optionalString (cfg.ealarmsCredFile != null) " -p ${cfg.ealarmsCredFile}"}";
177 ProtectSystem = "strict";
180 PrivateDevices = true;
181 ProtectKernelTunables = true;
182 ProtectKernelModules = true;
183 ProtectControlGroups = true;
184 StateDirectory = "sogo/spool";
189 CapabilityBoundingSet = "";
190 NoNewPrivileges = true;
192 LockPersonality = true;
193 RestrictRealtime = true;
194 PrivateMounts = true;
196 MemoryDenyWriteExecute = true;
197 SystemCallFilter = "@basic-io @file-system @network-io @system-service";
198 SystemCallArchitectures = "native";
199 RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
204 services.nginx.virtualHosts."${cfg.vhostName}" = {
205 locations."/".extraConfig = ''
206 rewrite ^ https://$server_name/SOGo;
211 locations."/principals/".extraConfig = ''
212 rewrite ^ https://$server_name/SOGo/dav;
216 locations."^~/SOGo".extraConfig = ''
217 proxy_pass http://127.0.0.1:20000;
218 proxy_redirect http://127.0.0.1:20000 default;
220 proxy_set_header X-Real-IP $remote_addr;
221 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
222 proxy_set_header Host $host;
223 proxy_set_header x-webobjects-server-protocol HTTP/1.0;
224 proxy_set_header x-webobjects-remote-host 127.0.0.1;
225 proxy_set_header x-webobjects-server-port $server_port;
226 proxy_set_header x-webobjects-server-name $server_name;
227 proxy_set_header x-webobjects-server-url $scheme://$host;
228 proxy_connect_timeout 90;
229 proxy_send_timeout 90;
230 proxy_read_timeout 90;
231 proxy_buffer_size 64k;
233 proxy_busy_buffers_size 64k;
234 proxy_temp_file_write_size 64k;
235 client_max_body_size 50m;
236 client_body_buffer_size 128k;
240 locations."/SOGo.woa/WebServerResources/".extraConfig = ''
241 alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
245 locations."/SOGo/WebServerResources/".extraConfig = ''
246 alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
250 locations."~ ^/SOGo/so/ControlPanel/Products/([^/]*)/Resources/(.*)$".extraConfig = ''
251 alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
254 locations."~ ^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\\.(jpg|png|gif|css|js)$".extraConfig = ''
255 alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
260 users.groups.sogo = {};
264 description = "SOGo service user";