| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | with lib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cfg = config.services.postsrsd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### interface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.postsrsd = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = "Whether to enable the postsrsd SRS server for Postfix."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 19:35:02 +02:00
										 |  |  |       secretsFile = mkOption { | 
					
						
							|  |  |  |         type = types.path; | 
					
						
							|  |  |  |         default = "/var/lib/postsrsd/postsrsd.secret"; | 
					
						
							|  |  |  |         description = "Secret keys used for signing and verification"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       domain = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         description = "Domain name for rewrite"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 19:35:02 +02:00
										 |  |  |       separator = mkOption { | 
					
						
							|  |  |  |         type = types.enum ["-" "=" "+"]; | 
					
						
							|  |  |  |         default = "="; | 
					
						
							|  |  |  |         description = "First separator character in generated addresses"; | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 19:35:02 +02:00
										 |  |  |       # bindAddress = mkOption { # uncomment once 1.5 is released | 
					
						
							|  |  |  |       #   type = types.str; | 
					
						
							|  |  |  |       #   default = "127.0.0.1"; | 
					
						
							|  |  |  |       #   description = "Socket listen address"; | 
					
						
							|  |  |  |       # }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       forwardPort = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 10001; | 
					
						
							|  |  |  |         description = "Port for the forward SRS lookup"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       reversePort = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 10002; | 
					
						
							|  |  |  |         description = "Port for the reverse SRS lookup"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 19:35:02 +02:00
										 |  |  |       timeout = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 1800; | 
					
						
							|  |  |  |         description = "Timeout for idle client connections in seconds"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       excludeDomains = mkOption { | 
					
						
							|  |  |  |         type = types.listOf types.str; | 
					
						
							|  |  |  |         default = []; | 
					
						
							|  |  |  |         description = "Origin domains to exclude from rewriting in addition to primary domain"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       user = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "postsrsd"; | 
					
						
							|  |  |  |         description = "User for the daemon"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       group = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = "postsrsd"; | 
					
						
							|  |  |  |         description = "Group for the daemon"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### implementation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   config = mkIf cfg.enable { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.postsrsd.domain = mkDefault config.networking.hostName; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.users = optionalAttrs (cfg.user == "postsrsd") (singleton | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       { name = "postsrsd"; | 
					
						
							|  |  |  |         group = cfg.group; | 
					
						
							|  |  |  |         uid = config.ids.uids.postsrsd; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.groups = optionalAttrs (cfg.group == "postsrsd") (singleton | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |       { name = "postsrsd"; | 
					
						
							|  |  |  |         gid = config.ids.gids.postsrsd; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     systemd.services.postsrsd = { | 
					
						
							|  |  |  |       description = "PostSRSd SRS rewriting server"; | 
					
						
							|  |  |  |       after = [ "network.target" ]; | 
					
						
							|  |  |  |       before = [ "postfix.service" ]; | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       path = [ pkgs.coreutils ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       serviceConfig = { | 
					
						
							| 
									
										
										
										
											2016-10-27 19:35:02 +02:00
										 |  |  |         ExecStart = ''${pkgs.postsrsd}/sbin/postsrsd "-s${cfg.secretsFile}" "-d${cfg.domain}" -a${cfg.separator} -f${toString cfg.forwardPort} -r${toString cfg.reversePort} -t${toString cfg.timeout} "-X${concatStringsSep "," cfg.excludeDomains}"''; | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |         User = cfg.user; | 
					
						
							|  |  |  |         Group = cfg.group; | 
					
						
							|  |  |  |         PermissionsStartOnly = true; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       preStart = ''
 | 
					
						
							|  |  |  |         if [ ! -e "${cfg.secretsFile}" ]; then | 
					
						
							|  |  |  |           echo "WARNING: secrets file not found, autogenerating!" | 
					
						
							| 
									
										
										
										
											2016-02-09 12:57:42 +03:00
										 |  |  |           DIR="$(dirname "${cfg.secretsFile}")" | 
					
						
							|  |  |  |           if [ ! -d "$DIR" ]; then | 
					
						
							|  |  |  |             mkdir -p -m750 "$DIR" | 
					
						
							|  |  |  |             chown "${cfg.user}:${cfg.group}" "$DIR" | 
					
						
							|  |  |  |           fi | 
					
						
							| 
									
										
										
										
											2016-01-06 06:04:50 +03:00
										 |  |  |           dd if=/dev/random bs=18 count=1 | base64 > "${cfg.secretsFile}" | 
					
						
							|  |  |  |           chmod 600 "${cfg.secretsFile}" | 
					
						
							|  |  |  |         fi | 
					
						
							|  |  |  |         chown "${cfg.user}:${cfg.group}" "${cfg.secretsFile}" | 
					
						
							|  |  |  |       '';
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |