first import of mailserver config
This commit is contained in:
		
					parent
					
						
							
								d4cdbc8ccd
							
						
					
				
			
			
				commit
				
					
						292215f770
					
				
			
		
					 19 changed files with 811 additions and 0 deletions
				
			
		
							
								
								
									
										20
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								README.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | hamburg.freifunk.net Mailserver | ||||||
|  | =============================== | ||||||
|  | 
 | ||||||
|  | Initiales Setup | ||||||
|  | ----- | ||||||
|  | 1. System starten | ||||||
|  | 2. URL anpassen und aufrufen: http://127.0.0.1/setup.php?lostpw=1 | ||||||
|  | 3. Neues Setup-Passwort vergeben und den Hash generieren. | ||||||
|  | 4. Hash in der Datei variables.nix ersetzen und das System neu bauen und starten. | ||||||
|  | 5. URL anpassen und aufrufen: http://127.0.0.1/setup.php | ||||||
|  | 6. Admin-Account über die Website anlegen | ||||||
|  | 7. URL anpassen und aufrufen: http://127.0.0.1/ | ||||||
|  | 8. Mail konfigurieren. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Development | ||||||
|  | ----- | ||||||
|  | Starten des Systems: | ||||||
|  |     QEMU_NET_OPTS="hostfwd=tcp:127.0.0.1:2222-:22,hostfwd=tcp:127.0.0.1:8080-:80,hostfwd=tcp:127.0.0.1:2525-:25" nixos-shell | ||||||
|  | Zugriff dann per SSH über 127.0.0.1:2222 und HTTP über 127.0.0.1:8080. | ||||||
|  | @ -8,8 +8,51 @@ | ||||||
|   imports = |   imports = | ||||||
|     [ # Include the results of the hardware scan. |     [ # Include the results of the hardware scan. | ||||||
|       ./hardware-configuration.nix |       ./hardware-configuration.nix | ||||||
|  |       ./variables.nix | ||||||
|  |       ./mailserver.nix | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|  |   # Use the staging environment of Let's encrypt and accept their certificates as well... | ||||||
|  |   security.acme.production = false; | ||||||
|  |   security.pki.certificates = [ | ||||||
|  |     '' | ||||||
|  |       -----BEGIN CERTIFICATE----- | ||||||
|  |       MIIFATCCAumgAwIBAgIRAKc9ZKBASymy5TLOEp57N98wDQYJKoZIhvcNAQELBQAw | ||||||
|  |       GjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDMyMzIyNTM0NloXDTM2 | ||||||
|  |       MDMyMzIyNTM0NlowGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMIICIjANBgkq | ||||||
|  |       hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA+pYHvQw5iU3v2b3iNuYNKYgsWD6KU7aJ | ||||||
|  |       diddtZQxSWYzUI3U0I1UsRPTxnhTifs/M9NW4ZlV13ZfB7APwC8oqKOIiwo7IwlP | ||||||
|  |       xg0VKgyz+kT8RJfYr66PPIYP0fpTeu42LpMJ+CKo9sbpgVNDZN2z/qiXrRNX/VtG | ||||||
|  |       TkPV7a44fZ5bHHVruAxvDnylpQxJobtCBWlJSsbIRGFHMc2z88eUz9NmIOWUKGGj | ||||||
|  |       EmP76x8OfRHpIpuxRSCjn0+i9+hR2siIOpcMOGd+40uVJxbRRP5ZXnUFa2fF5FWd | ||||||
|  |       O0u0RPI8HON0ovhrwPJY+4eWKkQzyC611oLPYGQ4EbifRsTsCxUZqyUuStGyp8oa | ||||||
|  |       aoSKfF6X0+KzGgwwnrjRTUpIl19A92KR0Noo6h622OX+4sZiO/JQdkuX5w/HupK0 | ||||||
|  |       A0M0WSMCvU6GOhjGotmh2VTEJwHHY4+TUk0iQYRtv1crONklyZoAQPD76hCrC8Cr | ||||||
|  |       IbgsZLfTMC8TWUoMbyUDgvgYkHKMoPm0VGVVuwpRKJxv7+2wXO+pivrrUl2Q9fPe | ||||||
|  |       Kk055nJLMV9yPUdig8othUKrRfSxli946AEV1eEOhxddfEwBE3Lt2xn0hhiIedbb | ||||||
|  |       Ftf/5kEWFZkXyUmMJK8Ra76Kus2ABueUVEcZ48hrRr1Hf1N9n59VbTUaXgeiZA50 | ||||||
|  |       qXf2bymE6F8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB | ||||||
|  |       Af8wHQYDVR0OBBYEFMEmdKSKRKDm+iAo2FwjmkWIGHngMA0GCSqGSIb3DQEBCwUA | ||||||
|  |       A4ICAQBCPw74M9X/Xx04K1VAES3ypgQYH5bf9FXVDrwhRFSVckria/7dMzoF5wln | ||||||
|  |       uq9NGsjkkkDg17AohcQdr8alH4LvPdxpKr3BjpvEcmbqF8xH+MbbeUEnmbSfLI8H | ||||||
|  |       sefuhXF9AF/9iYvpVNC8FmJ0OhiVv13VgMQw0CRKkbtjZBf8xaEhq/YqxWVsgOjm | ||||||
|  |       dm5CAQ2X0aX7502x8wYRgMnZhA5goC1zVWBVAi8yhhmlhhoDUfg17cXkmaJC5pDd | ||||||
|  |       oenZ9NVhW8eDb03MFCrWNvIh89DDeCGWuWfDltDq0n3owyL0IeSn7RfpSclpxVmV | ||||||
|  |       /53jkYjwIgxIG7Gsv0LKMbsf6QdBcTjhvfZyMIpBRkTe3zuHd2feKzY9lEkbRvRQ | ||||||
|  |       zbh4Ps5YBnG6CKJPTbe2hfi3nhnw/MyEmF3zb0hzvLWNrR9XW3ibb2oL3424XOwc | ||||||
|  |       VjrTSCLzO9Rv6s5wi03qoWvKAQQAElqTYRHhynJ3w6wuvKYF5zcZF3MDnrVGLbh1 | ||||||
|  |       Q9ePRFBCiXOQ6wPLoUhrrbZ8LpFUFYDXHMtYM7P9sc9IAWoONXREJaO08zgFtMp4 | ||||||
|  |       8iyIYUyQAbsvx8oD2M8kRvrIRSrRJSl6L957b4AFiLIQ/GgV2curs0jje7Edx34c | ||||||
|  |       idWw1VrejtwclobqNMVtG3EiPUIpJGpbMcJgbiLSmKkrvQtGng== | ||||||
|  |       -----END CERTIFICATE----- | ||||||
|  |     '' | ||||||
|  |   ]; | ||||||
|  | 
 | ||||||
|  |   # Configuration options for the mailserver | ||||||
|  |   variables = { | ||||||
|  |     mailAdmin = "postmaster@mail2.hamburg.freifunk.net"; | ||||||
|  |     useSSL = true; | ||||||
|  |   }; | ||||||
|   # Use the GRUB 2 boot loader. |   # Use the GRUB 2 boot loader. | ||||||
|   boot.loader.grub.enable = true; |   boot.loader.grub.enable = true; | ||||||
|   boot.loader.grub.version = 2; |   boot.loader.grub.version = 2; | ||||||
|  |  | ||||||
							
								
								
									
										136
									
								
								dovecot.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								dovecot.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | let | ||||||
|  |   dovecotSQL = pkgs.writeText "dovecot-sql.conf" '' | ||||||
|  |     driver = sqlite | ||||||
|  |     connect = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     password_query = SELECT username AS user, password FROM mailbox WHERE username = '%Lu' AND active='1' | ||||||
|  |     user_query = SELECT username AS user FROM mailbox WHERE username = '%Lu' AND active='1' | ||||||
|  |   ''; | ||||||
|  |   dovecotConf = pkgs.writeText "dovecot.conf" '' | ||||||
|  |     default_internal_user = dovecot2 | ||||||
|  |     default_internal_group = dovecot2 | ||||||
|  |     protocols = imap lmtp pop3 sieve | ||||||
|  | 
 | ||||||
|  |     ${lib.optionalString (config.variables.useSSL) '' | ||||||
|  |         ssl = yes | ||||||
|  |         ssl_cert = </var/lib/acme/dovecot2.${config.variables.myFQDN}/fullchain.pem | ||||||
|  |         ssl_key = </var/lib/acme/dovecot2.${config.variables.myFQDN}/key.pem | ||||||
|  |       '' | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     disable_plaintext_auth = no | ||||||
|  |     auth_mechanisms = plain login | ||||||
|  | 
 | ||||||
|  |     userdb { | ||||||
|  |         driver = sql | ||||||
|  |         args = ${dovecotSQL} | ||||||
|  |     } | ||||||
|  |     passdb { | ||||||
|  |         driver = sql | ||||||
|  |         args = ${dovecotSQL} | ||||||
|  |     } | ||||||
|  |     mail_home = ${config.variables.vmailBaseDir}/%Lu/ | ||||||
|  |     mail_location = maildir:${config.variables.vmailBaseDir}/%Lu/Maildir | ||||||
|  |     mail_uid = ${toString config.variables.vmailUID} | ||||||
|  |     mail_gid = ${toString config.variables.vmailGID} | ||||||
|  | 
 | ||||||
|  |     service auth { | ||||||
|  |       unix_listener ${config.variables.dovecotAuthSocket} { | ||||||
|  |         user = ${config.services.postfix.user} | ||||||
|  |         group = ${config.services.postfix.group} | ||||||
|  |         mode = 0600 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     service lmtp { | ||||||
|  |       unix_listener ${config.variables.dovecotLmtpSocket} { | ||||||
|  |         user = ${config.services.postfix.user} | ||||||
|  |         group = ${config.services.postfix.group} | ||||||
|  |         mode = 0600 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protocol lmtp { | ||||||
|  |       mail_plugins = sieve | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protocol imap { | ||||||
|  |       mail_plugins = $mail_plugins imap_sieve | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     namespace inbox { | ||||||
|  |       inbox = yes | ||||||
|  |       location = | ||||||
|  |       mailbox Drafts { | ||||||
|  |         special_use = \Drafts | ||||||
|  |         auto = subscribe | ||||||
|  |       } | ||||||
|  |       mailbox Junk { | ||||||
|  |         special_use = \Junk | ||||||
|  |         auto = subscribe | ||||||
|  |       } | ||||||
|  |       mailbox Sent { | ||||||
|  |         special_use = \Sent | ||||||
|  |         auto = subscribe | ||||||
|  |       } | ||||||
|  |       mailbox Trash { | ||||||
|  |         special_use = \Trash | ||||||
|  |         auto = subscribe | ||||||
|  |       } | ||||||
|  |       mailbox Archive { | ||||||
|  |         special_use = \Archive | ||||||
|  |         auto = subscribe | ||||||
|  |       } | ||||||
|  |       prefix = | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     plugin { | ||||||
|  |       sieve_after = ${(pkgs.callPackage ./sieve-after.nix {}) } | ||||||
|  |       sieve_plugins = sieve_imapsieve sieve_extprograms | ||||||
|  |       # From elsewhere to Spam folder | ||||||
|  |       imapsieve_mailbox1_name = Junk | ||||||
|  |       imapsieve_mailbox1_causes = COPY | ||||||
|  |       imapsieve_mailbox1_before = file:${(pkgs.callPackage ./sieve-report-spam-ham.nix {})}/report-spam.sieve | ||||||
|  |       # From Spam folder to elsewhere | ||||||
|  |       imapsieve_mailbox2_name = * | ||||||
|  |       imapsieve_mailbox2_from = Junk | ||||||
|  |       imapsieve_mailbox2_causes = COPY | ||||||
|  |       imapsieve_mailbox2_before = file:${(pkgs.callPackage ./sieve-report-spam-ham.nix {})}/report-ham.sieve | ||||||
|  |       sieve_pipe_bin_dir = ${(pkgs.callPackage ./sieve-pipe-bin-dir.nix {})} | ||||||
|  |       sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment | ||||||
|  |     } | ||||||
|  |   ''; | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   # Configure certificates... | ||||||
|  |   security = lib.mkIf config.variables.useSSL { | ||||||
|  |     acme.certs."dovecot2.${config.variables.myFQDN}" = { | ||||||
|  |       domain = "${config.variables.myFQDN}"; | ||||||
|  |       user = config.services.nginx.user; | ||||||
|  |       group = config.services.dovecot2.group; | ||||||
|  |       allowKeysForGroup = true; | ||||||
|  |       postRun = "systemctl restart dovecot2.service"; | ||||||
|  |       # cheat by getting the webroot from another certificate configured through nginx. | ||||||
|  |       webroot = config.security.acme.certs."${config.variables.myFQDN}".webroot; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  |   # Make sure at least the self-signed certs are available before trying to start postfix | ||||||
|  |   systemd.services.dovecot2.after = lib.mkIf config.variables.useSSL [ "acme-selfsigned-certificates.target" ]; | ||||||
|  |   # Setup dovecot | ||||||
|  |   networking.firewall.allowedTCPPorts = [ 110 143 993 995 4190 ]; | ||||||
|  |   services.dovecot2 = { | ||||||
|  |     enable = true; | ||||||
|  |     configFile = "${dovecotConf}"; | ||||||
|  |     modules = [ pkgs.dovecot_pigeonhole ]; | ||||||
|  |   }; | ||||||
|  |   systemd.services."vmail-setup" = { | ||||||
|  |     serviceConfig.Type = "oneshot"; | ||||||
|  |     wantedBy = [ "multi-user.target" ]; | ||||||
|  |       script = '' | ||||||
|  |         mkdir -p ${config.variables.vmailBaseDir} | ||||||
|  |         chown -c ${config.variables.vmailUser}:${config.variables.vmailGroup} ${config.variables.vmailBaseDir} | ||||||
|  |         chmod -c 0700 ${config.variables.vmailBaseDir} | ||||||
|  |       ''; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										18
									
								
								mailserver.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								mailserver.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | { config, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  |   # Import some configuration as they are too long to be easily readable here | ||||||
|  |   imports = [  | ||||||
|  |     ./dovecot.nix | ||||||
|  |     ./postfix.nix | ||||||
|  |     ./postfixadmin.nix | ||||||
|  |     ./roundcube.nix | ||||||
|  |     ./rspamd.nix | ||||||
|  |   ]; | ||||||
|  |   users.groups."${config.variables.vmailGroup}" = { gid = config.variables.vmailGID; }; | ||||||
|  |   users.users."${config.variables.vmailUser}" = { | ||||||
|  |     uid = config.variables.vmailUID; | ||||||
|  |     group = config.variables.vmailGroup; | ||||||
|  |     hashedPassword = "!"; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								pkg-postfixadmin.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								pkg-postfixadmin.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | { stdenv, lib, fetchFromGitHub, config ? null, cacheDir ? null }: | ||||||
|  | 
 | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "postfixadmin-${version}"; | ||||||
|  |   version = "3.2.2"; | ||||||
|  |   rev = "${name}"; | ||||||
|  | 
 | ||||||
|  |   src = fetchFromGitHub { | ||||||
|  |     inherit rev; | ||||||
|  |     owner = "postfixadmin"; | ||||||
|  |     repo = "postfixadmin"; | ||||||
|  |     sha256 = "0bkjdmn63yinf217fnn3wq13pc0yklmnsbrgxjv22vpync42f9vh"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   phases = [ "unpackPhase" "installPhase" ]; | ||||||
|  | 
 | ||||||
|  |   installPhase = '' | ||||||
|  |     cp -Rp ./ $out/ | ||||||
|  |     ${lib.optionalString (config != null) '' | ||||||
|  |       ln -s ${config} $out/config.local.php | ||||||
|  |     ''} | ||||||
|  |     ${lib.optionalString (cacheDir != null) '' | ||||||
|  |       ln -s ${cacheDir}/templates_c $out/templates_c | ||||||
|  |     ''} | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   meta = with stdenv.lib; { | ||||||
|  |     description = "Postfix Admin"; | ||||||
|  |     homepage    = http://postfixadmin.sourceforge.net/; | ||||||
|  |     license     = licenses.gpl2; | ||||||
|  |     maintainers = with maintainers; [ tokudan ]; | ||||||
|  |     platforms   = platforms.all; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										32
									
								
								pkg-roundcube.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								pkg-roundcube.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | { stdenv, lib, fetchurl, acl, librsync, ncurses, openssl, zlib, conf ? null, temp ? null, logs ? null }: | ||||||
|  | 
 | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "roundcube-${version}"; | ||||||
|  |   version = "1.3.9"; | ||||||
|  |   url = "https://github.com/roundcube/roundcubemail/releases/download/${version}/roundcubemail-${version}-complete.tar.gz"; | ||||||
|  | 
 | ||||||
|  |   src = fetchurl { | ||||||
|  |     inherit url; | ||||||
|  |     curlOpts = "--location"; | ||||||
|  |     sha256 = "1b91amcpzb7935hpm67iqw92bl5r1a0rkfrc8gfm8w9sngzv8vbj"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   phases = [ "unpackPhase" "installPhase" ]; | ||||||
|  | 
 | ||||||
|  |   installPhase = '' | ||||||
|  |     cp -Rp ./ $out/ | ||||||
|  |     cd "$out" | ||||||
|  |     ${lib.optionalString (conf != null) "ln -s ${conf} $out/config/config.inc.php"} | ||||||
|  |     ${lib.optionalString (temp != null) "mv temp temp.dist; ln -s ${temp} $out/temp"} | ||||||
|  |     ${lib.optionalString (logs != null) "mv logs logs.dist; ln -s ${logs} $out/logs"} | ||||||
|  |   ''; | ||||||
|  | 
 | ||||||
|  |   meta = with stdenv.lib; { | ||||||
|  |     description = "Roundcube"; | ||||||
|  |     homepage    = https://roundcube.net/; | ||||||
|  |     license     = licenses.agpl3; | ||||||
|  |     maintainers = with maintainers; [ tokudan ]; | ||||||
|  |     platforms   = platforms.all; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										80
									
								
								postfix.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								postfix.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,80 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | let | ||||||
|  |   pfvirtual_mailbox_domains = pkgs.writeText "virtual_mailbox_domains.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' | ||||||
|  |   ''; | ||||||
|  |   pfvirtual_alias_maps = pkgs.writeText "virtual_alias_maps.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT goto FROM alias WHERE address='%s' AND active = '1' | ||||||
|  |   ''; | ||||||
|  |   pfvirtual_alias_domain_maps = pkgs.writeText "virtual_alias_domain_maps.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = ('%u' || '@' || alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' | ||||||
|  |   ''; | ||||||
|  |   pfvirtual_alias_domain_catchall_maps = pkgs.writeText "virtual_alias_domain_catchall_maps.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = ('@' || alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' | ||||||
|  |   ''; | ||||||
|  |   pfvirtual_mailbox_maps = pkgs.writeText "virtual_mailbox_maps.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1' | ||||||
|  |   ''; | ||||||
|  |   pfvirtual_alias_domain_mailbox_maps = pkgs.writeText "virtual_alias_domain_mailbox_maps.cf" '' | ||||||
|  |     dbpath = ${config.variables.pfadminDataDir}/postfixadmin.db | ||||||
|  |     query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = ('%u' || '@' || alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1' | ||||||
|  |   ''; | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   # Configure Postfix to support SQLite | ||||||
|  |   nixpkgs.config.packageOverrides = pkgs: { postfix = pkgs.postfix.override { withSQLite = true; }; }; | ||||||
|  |   # SSL/TLS specific configuration | ||||||
|  |   security = lib.mkIf config.variables.useSSL { | ||||||
|  |     # Configure the certificates... | ||||||
|  |     acme.certs."postfix.${config.variables.myFQDN}" = { | ||||||
|  |       domain = "${config.variables.myFQDN}"; | ||||||
|  |       group = config.services.postfix.group; | ||||||
|  |       allowKeysForGroup = true; | ||||||
|  |       postRun = "systemctl restart postfix.service"; | ||||||
|  |       # cheat by getting some settings from another certificate configured through nginx. | ||||||
|  |       user = config.security.acme.certs."${config.variables.myFQDN}".user; | ||||||
|  |       webroot = config.security.acme.certs."${config.variables.myFQDN}".webroot; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  |   systemd = lib.mkIf config.variables.useSSL { | ||||||
|  |     # Make sure at least the self-signed certs are available before trying to start postfix | ||||||
|  |     services.postfix.after = [ "acme-selfsigned-certificates.target" ]; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   # Setup Postfix | ||||||
|  |   networking.firewall.allowedTCPPorts = [ 25 587 ]; | ||||||
|  |   services.postfix = { | ||||||
|  |     enable = true; | ||||||
|  |     enableSmtp = true; | ||||||
|  |     enableSubmission = true; | ||||||
|  |     config = { | ||||||
|  |       myhostname = config.variables.myFQDN; | ||||||
|  |       mynetworks_style = "host"; | ||||||
|  |       recipient_delimiter = "+"; | ||||||
|  |       relay_domains = ""; | ||||||
|  |       smtpd_milters = "unix:${config.variables.rspamdMilterSocket}"; | ||||||
|  |       non_smtpd_milters = "unix:${config.variables.rspamdMilterSocket}"; | ||||||
|  |       smtpd_sasl_path = config.variables.dovecotAuthSocket; | ||||||
|  |       smtpd_sasl_type = "dovecot"; | ||||||
|  |       smtpd_tls_auth_only = "yes"; | ||||||
|  |       smtpd_tls_chain_files = lib.mkIf config.variables.useSSL "/var/lib/acme/postfix.${config.variables.myFQDN}/full.pem"; | ||||||
|  |       smtpd_tls_loglevel = "1"; | ||||||
|  |       smtpd_tls_received_header = "yes"; | ||||||
|  |       smtpd_tls_security_level = "may"; | ||||||
|  |       smtp_tls_loglevel = "1"; | ||||||
|  |       smtp_tls_security_level = "may"; | ||||||
|  |       virtual_alias_maps = "proxy:sqlite:${pfvirtual_alias_maps}, proxy:sqlite:${pfvirtual_alias_domain_maps}, proxy:sqlite:${pfvirtual_alias_domain_catchall_maps}"; | ||||||
|  |       virtual_mailbox_domains = "proxy:sqlite:${pfvirtual_mailbox_domains}"; | ||||||
|  |       virtual_mailbox_maps = "proxy:sqlite:${pfvirtual_mailbox_maps}, proxy:sqlite:${pfvirtual_alias_domain_mailbox_maps}"; | ||||||
|  |       virtual_transport = "lmtp:unix:${config.variables.dovecotLmtpSocket}"; | ||||||
|  |     }; | ||||||
|  |     rootAlias = config.variables.mailAdmin; | ||||||
|  |     postmasterAlias = config.variables.mailAdmin; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										102
									
								
								postfixadmin.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								postfixadmin.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | let | ||||||
|  |   phppoolName = "postfixadmin_pool"; | ||||||
|  |   pfaGroup = config.variables.pfaGroup; | ||||||
|  |   pfaUser = config.variables.pfaUser; | ||||||
|  |   postfixadminpkg = config.variables.postfixadminpkg; | ||||||
|  |   pfadminDataDir = config.variables.pfadminDataDir; | ||||||
|  |   cacheDir = config.variables.postfixadminpkgCacheDir; | ||||||
|  |   phpfpmHostPort = config.variables.pfaPhpfpmHostPort; | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   # Setup the user and group | ||||||
|  |   users.groups."${pfaGroup}" = { }; | ||||||
|  |   users.users."${pfaUser}" = { | ||||||
|  |     isSystemUser = true; | ||||||
|  |     group = "${pfaGroup}"; | ||||||
|  |     description = "PHP User for postfixadmin"; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   # Setup nginx | ||||||
|  |   networking.firewall.allowedTCPPorts = [ 80 443 ]; | ||||||
|  |   services.nginx.enable = true; | ||||||
|  |   services.nginx.virtualHosts."${config.variables.pfaDomain}" = { | ||||||
|  |     forceSSL = config.variables.useSSL; | ||||||
|  |     enableACME = config.variables.useSSL; | ||||||
|  |     default = true; | ||||||
|  |     root = "${postfixadminpkg}/public"; | ||||||
|  |     extraConfig = '' | ||||||
|  |       access_log /tmp/nginx/log/$host combined; | ||||||
|  |       charset utf-8; | ||||||
|  | 
 | ||||||
|  |       etag off; | ||||||
|  |       add_header etag "\"${builtins.substring 11 32 postfixadminpkg}\""; | ||||||
|  | 
 | ||||||
|  |       index index.php; | ||||||
|  | 
 | ||||||
|  |       location ~* \.php$ { | ||||||
|  |         # Zero-day exploit defense. | ||||||
|  |         # http://forum.nginx.org/read.php?2,88845,page=3 | ||||||
|  |         # Won't work properly (404 error) if the file is not stored on this | ||||||
|  |         # server, which is entirely possible with php-fpm/php-fcgi. | ||||||
|  |         # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on | ||||||
|  |         # another machine.  And then cross your fingers that you won't get hacked. | ||||||
|  |         try_files $uri =404; | ||||||
|  |         # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini | ||||||
|  |         fastcgi_split_path_info ^(.+\.php)(/.+)$; | ||||||
|  |         # With php5-cgi alone: | ||||||
|  |         fastcgi_pass ${phpfpmHostPort}; | ||||||
|  |         fastcgi_index index.php; | ||||||
|  |         fastcgi_param  GATEWAY_INTERFACE  CGI/1.1; | ||||||
|  |         fastcgi_param  SERVER_SOFTWARE    nginx; | ||||||
|  |         fastcgi_param  QUERY_STRING       $query_string; | ||||||
|  |         fastcgi_param  REQUEST_METHOD     $request_method; | ||||||
|  |         fastcgi_param  CONTENT_TYPE       $content_type; | ||||||
|  |         fastcgi_param  CONTENT_LENGTH     $content_length; | ||||||
|  |         fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name; | ||||||
|  |         fastcgi_param  SCRIPT_NAME        $fastcgi_script_name; | ||||||
|  |         fastcgi_param  REQUEST_URI        $request_uri; | ||||||
|  |         fastcgi_param  DOCUMENT_URI       $document_uri; | ||||||
|  |         fastcgi_param  DOCUMENT_ROOT      $document_root; | ||||||
|  |         fastcgi_param  SERVER_PROTOCOL    $server_protocol; | ||||||
|  |         fastcgi_param  REMOTE_ADDR        $remote_addr; | ||||||
|  |         fastcgi_param  REMOTE_PORT        $remote_port; | ||||||
|  |         fastcgi_param  SERVER_ADDR        $server_addr; | ||||||
|  |         fastcgi_param  SERVER_PORT        $server_port; | ||||||
|  |         fastcgi_param  SERVER_NAME        $server_name; | ||||||
|  |         fastcgi_param  HTTP_PROXY         ""; | ||||||
|  |       } | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
|  |   systemd.services."postfixadmin-setup" = { | ||||||
|  |     serviceConfig.Type = "oneshot"; | ||||||
|  |     wantedBy = [ "multi-user.target" ]; | ||||||
|  |     script = '' | ||||||
|  |       # Setup the data directory with the database and the cache directory | ||||||
|  |       mkdir -p ${pfadminDataDir} | ||||||
|  |       chmod -c 751 ${pfadminDataDir} | ||||||
|  |       chown -c ${pfaUser}:${pfaGroup} ${pfadminDataDir} | ||||||
|  | 
 | ||||||
|  |       mkdir -p ${cacheDir}/templates_c | ||||||
|  |       chown -Rc ${pfaUser}:${pfaGroup} ${cacheDir}/templates_c | ||||||
|  |       chmod -Rc 751 ${cacheDir}/templates_c | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
|  |   services.phpfpm.pools."${phppoolName}" = { | ||||||
|  |     listen = phpfpmHostPort; | ||||||
|  |     extraConfig = '' | ||||||
|  |       user = ${pfaUser} | ||||||
|  |       pm = dynamic | ||||||
|  |       pm.max_children = 75 | ||||||
|  |       pm.min_spare_servers = 5 | ||||||
|  |       pm.max_spare_servers = 20 | ||||||
|  |       pm.max_requests = 10 | ||||||
|  |       catch_workers_output = 1 | ||||||
|  |       php_admin_value[upload_max_filesize] = 42M | ||||||
|  |       php_admin_value[post_max_size] = 42M | ||||||
|  |       php_admin_value[memory_limit] = 128M | ||||||
|  |       php_admin_value[cgi.fix_pathinfo] = 1 | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										109
									
								
								roundcube.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								roundcube.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,109 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | let | ||||||
|  |   poolName = "roundcube_pool"; | ||||||
|  | 
 | ||||||
|  |   roundcube = (pkgs.callPackage ./pkg-roundcube.nix { | ||||||
|  |     conf = pkgs.writeText "roundcube-config.inc.php" '' | ||||||
|  |       <?php | ||||||
|  |       $config = array(); | ||||||
|  |       $config['db_dsnw'] = 'sqlite:///${config.variables.roundcubeDataDir}/roundcube.sqlite?mode=0600'; | ||||||
|  |       $config['default_host'] = 'tls://${config.variables.myFQDN}'; | ||||||
|  |       $config['smtp_server'] = 'tls://${config.variables.myFQDN}'; | ||||||
|  |       $config['smtp_port'] = 587; | ||||||
|  |       $config['smtp_user'] = '%u'; | ||||||
|  |       $config['smtp_pass'] = '%p'; | ||||||
|  |       $config['product_name'] = 'Webmail'; | ||||||
|  |       $config['des_key'] = 'JQgS7JcnFMNcU3cHKrr880wO'; | ||||||
|  |       $config['plugins'] = array( | ||||||
|  |         'archive', | ||||||
|  |         'managesieve', | ||||||
|  |         'zipdownload', | ||||||
|  |         ); | ||||||
|  |       $config['skin'] = 'larry'; | ||||||
|  |       ''; | ||||||
|  |     temp = "${config.variables.roundcubeDataDir}/temp"; | ||||||
|  |     logs = "${config.variables.roundcubeDataDir}/logs"; | ||||||
|  |   } ); | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   services.nginx.virtualHosts."${config.variables.roundcubeFQDN}" = { | ||||||
|  |     forceSSL = config.variables.useSSL; | ||||||
|  |     enableACME = config.variables.useSSL; | ||||||
|  |     root = "${roundcube}/public_html"; | ||||||
|  |     locations."~ ^/favicon.ico/.*$" = { | ||||||
|  |         extraConfig = "try_files $uri kins/larry/images/$uri;"; | ||||||
|  |     }; | ||||||
|  |     locations."/" = { | ||||||
|  |         extraConfig = '' | ||||||
|  |           index index.php; | ||||||
|  |           try_files $uri /public/$uri /index.php$is_args$args; | ||||||
|  | 
 | ||||||
|  |           etag off; | ||||||
|  |           add_header etag "\"${builtins.substring 11 32 roundcube}\""; | ||||||
|  |         ''; | ||||||
|  |     }; | ||||||
|  |     locations."~ [^/]\.php(/|$)" = { | ||||||
|  |       extraConfig = '' | ||||||
|  |         etag off; | ||||||
|  |         add_header etag "\"${builtins.substring 11 32 roundcube}\""; | ||||||
|  | 
 | ||||||
|  |         fastcgi_split_path_info ^(.+?\.php)(/.*)$; | ||||||
|  |         if (!-f $document_root$fastcgi_script_name) { | ||||||
|  |             return 404; | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |         fastcgi_pass ${config.variables.roundcubePhpfpmHostPort}; | ||||||
|  |         fastcgi_index index.php; | ||||||
|  | 
 | ||||||
|  |         fastcgi_param   QUERY_STRING            $query_string; | ||||||
|  |         fastcgi_param   REQUEST_METHOD          $request_method; | ||||||
|  |         fastcgi_param   CONTENT_TYPE            $content_type; | ||||||
|  |         fastcgi_param   CONTENT_LENGTH          $content_length; | ||||||
|  | 
 | ||||||
|  |         fastcgi_param   SCRIPT_FILENAME         $document_root$fastcgi_script_name; | ||||||
|  |         fastcgi_param   SCRIPT_NAME             $fastcgi_script_name; | ||||||
|  |         fastcgi_param   PATH_INFO               $fastcgi_path_info; | ||||||
|  |         fastcgi_param   PATH_TRANSLATED         $document_root$fastcgi_path_info; | ||||||
|  |         fastcgi_param   REQUEST_URI             $request_uri; | ||||||
|  |         fastcgi_param   DOCUMENT_URI            $document_uri; | ||||||
|  |         fastcgi_param   DOCUMENT_ROOT           $document_root; | ||||||
|  |         fastcgi_param   SERVER_PROTOCOL         $server_protocol; | ||||||
|  | 
 | ||||||
|  |         fastcgi_param   GATEWAY_INTERFACE       CGI/1.1; | ||||||
|  |         fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version; | ||||||
|  | 
 | ||||||
|  |         fastcgi_param   REMOTE_ADDR             $remote_addr; | ||||||
|  |         fastcgi_param   REMOTE_PORT             $remote_port; | ||||||
|  |         fastcgi_param   SERVER_ADDR             $server_addr; | ||||||
|  |         fastcgi_param   SERVER_PORT             $server_port; | ||||||
|  |         fastcgi_param   SERVER_NAME             $server_name; | ||||||
|  | 
 | ||||||
|  |         fastcgi_param   HTTPS                   $https; | ||||||
|  |         fastcgi_param   HTTP_PROXY              ""; | ||||||
|  |       ''; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  |   systemd.services.roundcube-install = { | ||||||
|  |     serviceConfig.Type = "oneshot"; | ||||||
|  |     wantedBy = [ "multi-user.target" ]; | ||||||
|  |     script = '' | ||||||
|  |       mkdir -p ${config.variables.roundcubeDataDir}/temp ${config.variables.roundcubeDataDir}/logs | ||||||
|  |       chown -Rc ${config.variables.roundcubeUser} ${config.variables.roundcubeDataDir} | ||||||
|  |       chmod -c 700 ${config.variables.roundcubeDataDir} | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
|  |   services.phpfpm.pools."${poolName}" = { | ||||||
|  |     listen = config.variables.roundcubePhpfpmHostPort; | ||||||
|  |     extraConfig = '' | ||||||
|  |       user = ${config.variables.roundcubeUser} | ||||||
|  |       pm = dynamic | ||||||
|  |       pm.max_children = 75 | ||||||
|  |       pm.min_spare_servers = 5 | ||||||
|  |       pm.max_spare_servers = 20 | ||||||
|  |       pm.max_requests = 10 | ||||||
|  |       catch_workers_output = 1 | ||||||
|  |     ''; | ||||||
|  |   }; | ||||||
|  |   users.extraUsers."${config.variables.roundcubeUser}" = { }; | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								rspamd.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								rspamd.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | let | ||||||
|  |   rspamdExtraConfig = pkgs.writeText "rspamd-extra.conf" '' | ||||||
|  |     secure_ip = [::1] | ||||||
|  |     actions { | ||||||
|  |       reject = null; | ||||||
|  |     } | ||||||
|  |     options { | ||||||
|  |       filters: "chartable,dkim,dkim_signing,spf,surbl,regexp,fuzzy_check" | ||||||
|  |     } | ||||||
|  |     milter_headers { | ||||||
|  |       extended_spam_headers = true; | ||||||
|  |     } | ||||||
|  |     classifier { | ||||||
|  |       bayes { | ||||||
|  |         autolearn = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     dkim_signing { | ||||||
|  |       path = "/var/lib/rspamd/dkim/$domain.$selector.key"; | ||||||
|  |       check_pubkey = true; | ||||||
|  |     } | ||||||
|  |   ''; | ||||||
|  | in | ||||||
|  | { | ||||||
|  |   #networking.firewall.allowedTCPPorts = [ 110 143 993 995 ]; | ||||||
|  |   environment.systemPackages = [ | ||||||
|  |     (pkgs.writeShellScriptBin "dkim-generate" '' | ||||||
|  |       if [ $# -ne 1 ]; then | ||||||
|  |         echo Usage: dkim-generate DOMAIN >&2 | ||||||
|  |         exit 1 | ||||||
|  |       fi | ||||||
|  |       rspamd=${pkgs.rspamd}/bin/rspamadm | ||||||
|  |       mkdir -p /var/lib/rspamd/dkim | ||||||
|  |       $rspamd dkim_keygen -b 2048 -d "$1" -s dkim | ${pkgs.gawk}/bin/awk '/^-/ {KEY= ! KEY; print; next} KEY {print} !KEY {print > "/dev/stderr"}' >/var/lib/rspamd/dkim/"$1".dkim.key 2>/var/lib/rspamd/dkim/"$1".dkim.dns | ||||||
|  |       ls -l /var/lib/rspamd/dkim/"$1".dkim.key /var/lib/rspamd/dkim/"$1".dkim.dns | ||||||
|  |     '') ]; | ||||||
|  |   services.rspamd = { | ||||||
|  |     enable = true; | ||||||
|  |     # Just shove our own configuration up rspamd's rear end with high prio as the default configuration structure is a mess | ||||||
|  |     extraConfig = '' | ||||||
|  |         .include(try=true,priority=10,duplicate=merge) "${rspamdExtraConfig}" | ||||||
|  |       ''; | ||||||
|  |     workers = { | ||||||
|  |       controller = { | ||||||
|  |         enable = true; | ||||||
|  |         extraConfig = '' | ||||||
|  |           secure_ip = [::1] | ||||||
|  |         ''; | ||||||
|  |         bindSockets = [ | ||||||
|  |           "[::1]:11334" | ||||||
|  |           { mode = "0666"; owner = config.variables.vmailUser; socket = "/run/rspamd/worker-controller.socket"; } | ||||||
|  |         ]; | ||||||
|  |       }; | ||||||
|  |       rspamd_proxy = { | ||||||
|  |         enable = true; | ||||||
|  |         type = "rspamd_proxy"; | ||||||
|  |         count = 5; # TODO: match with postfix limits | ||||||
|  |         extraConfig = '' | ||||||
|  |           upstream "local" { | ||||||
|  |             self_scan = yes; # Enable self-scan | ||||||
|  |           } | ||||||
|  |         ''; | ||||||
|  |         bindSockets = [ | ||||||
|  |           { socket = config.variables.rspamdMilterSocket; mode = "0600"; owner = config.services.postfix.user; group = config.services.rspamd.group; } | ||||||
|  |         ]; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										20
									
								
								sieve-after.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								sieve-after.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | { stdenv, dovecot_pigeonhole}: | ||||||
|  | 
 | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "sieve-after"; | ||||||
|  | 
 | ||||||
|  |   src = ./sieve-after; | ||||||
|  | 
 | ||||||
|  |   phases = [ "copyPhase" "compilePhase" ]; | ||||||
|  | 
 | ||||||
|  |   copyPhase = '' | ||||||
|  |     cd $src | ||||||
|  |     mkdir $out | ||||||
|  |     cp -Rv $src/. $out/ | ||||||
|  |     find $out -type d -exec chmod -c 0755 {} \; | ||||||
|  |     set +x | ||||||
|  |     ''; | ||||||
|  |   compilePhase = '' | ||||||
|  |     find $out -iname '*.sieve' -print0 | xargs -t -0 -n1 ${dovecot_pigeonhole}/bin/sievec -c /dev/null | ||||||
|  |   ''; | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								sieve-after/junk-folder.sieve
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								sieve-after/junk-folder.sieve
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | require ["fileinto","mailbox"]; | ||||||
|  | 
 | ||||||
|  | if header :contains "X-Spam" "Yes" { | ||||||
|  |  fileinto :create "Junk"; | ||||||
|  |  stop; | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								sieve-pipe-bin-dir.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								sieve-pipe-bin-dir.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | { stdenv}: | ||||||
|  | 
 | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "sieve-pipe-bin-dir"; | ||||||
|  | 
 | ||||||
|  |   src = ./sieve-pipe-bin-dir; | ||||||
|  | 
 | ||||||
|  |   phases = [ "copyPhase" "fixupPhase" ]; | ||||||
|  | 
 | ||||||
|  |   copyPhase = '' | ||||||
|  |     mkdir $out | ||||||
|  |     cp -Rv $src/. $out/ | ||||||
|  |     ''; | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								sieve-pipe-bin-dir/learn-ham.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								sieve-pipe-bin-dir/learn-ham.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | #!/usr/bin/env bash | ||||||
|  | set -euo pipefail | ||||||
|  | 
 | ||||||
|  | exec /run/current-system/sw/bin/rspamc -h /run/rspamd/worker-controller.socket learn_ham | ||||||
							
								
								
									
										4
									
								
								sieve-pipe-bin-dir/learn-spam.sh
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								sieve-pipe-bin-dir/learn-spam.sh
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | #!/usr/bin/env bash | ||||||
|  | set -euo pipefail | ||||||
|  | 
 | ||||||
|  | exec /run/current-system/sw/bin/rspamc -h /run/rspamd/worker-controller.socket learn_spam | ||||||
							
								
								
									
										30
									
								
								sieve-report-spam-ham.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								sieve-report-spam-ham.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | { stdenv, dovecot_pigeonhole}: | ||||||
|  | 
 | ||||||
|  | stdenv.mkDerivation rec { | ||||||
|  |   name = "sieve-report-spam-ham"; | ||||||
|  | 
 | ||||||
|  |   src = ./sieve-report-spam-ham; | ||||||
|  | 
 | ||||||
|  |   phases = [ "copyPhase" "compilePhase" ]; | ||||||
|  | 
 | ||||||
|  |   copyPhase = '' | ||||||
|  |     mkdir $out | ||||||
|  |     cp -Rv $src/. $out/ | ||||||
|  |     find $out -type d -exec chmod -c 0755 {} \; | ||||||
|  |     set +x | ||||||
|  |     ''; | ||||||
|  | 
 | ||||||
|  |   # Yeah, need a specific dovecot.conf to enable the necessary plugins... | ||||||
|  |   # taking the one used by the dovecot that actually executes the sieve scripts should | ||||||
|  |   # work as well, but passing it through isn't worth my time. | ||||||
|  |   compilePhase = '' | ||||||
|  |     dc=$(pwd)/dovecot.conf | ||||||
|  |     cat > $dc <<-EOF | ||||||
|  |       plugin { | ||||||
|  |         sieve_plugins = sieve_imapsieve sieve_extprograms | ||||||
|  |         sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment | ||||||
|  |       } | ||||||
|  |     EOF | ||||||
|  |     find $out -iname '*.sieve' -print0 | xargs -t -0 -n1 ${dovecot_pigeonhole}/bin/sievec -c $dc | ||||||
|  |   ''; | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								sieve-report-spam-ham/report-ham.sieve
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								sieve-report-spam-ham/report-ham.sieve
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; | ||||||
|  | 
 | ||||||
|  | if environment :matches "imap.mailbox" "*" { | ||||||
|  |   set "mailbox" "${1}"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | if string "${mailbox}" "Trash" { | ||||||
|  |   stop; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | if environment :matches "imap.user" "*" { | ||||||
|  |   set "username" "${1}"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pipe :copy "learn-ham.sh" [ "${username}" ]; | ||||||
							
								
								
									
										7
									
								
								sieve-report-spam-ham/report-spam.sieve
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								sieve-report-spam-ham/report-spam.sieve
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | ||||||
|  | require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; | ||||||
|  | 
 | ||||||
|  | if environment :matches "imap.user" "*" { | ||||||
|  |   set "username" "${1}"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pipe :copy "learn-spam.sh" [ "${username}" ]; | ||||||
							
								
								
									
										65
									
								
								variables.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								variables.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | ||||||
|  | { config, lib, pkgs, ... }: | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  |   options = { | ||||||
|  |     variables = lib.mkOption { | ||||||
|  |       type = lib.types.attrs; | ||||||
|  |       default = { }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  |   config.variables = { | ||||||
|  |     dovecotGroup = "dovecot2"; | ||||||
|  |     dovecotUser = "dovecot2"; | ||||||
|  |     dovecotAuthSocket = "/run/dovecot2/dovecot-auth"; | ||||||
|  |     dovecotLmtpSocket = "/run/dovecot2/dovecot-lmtp"; | ||||||
|  |     rspamdMilterSocket = "/run/rspamd/milter"; | ||||||
|  |     myFQDN = "${config.networking.hostName}.${config.networking.domain}"; | ||||||
|  |     pfadminDataDir = "/var/lib/postfixadmin"; | ||||||
|  |     pfaGroup = "pfadmin"; | ||||||
|  |     pfaPhpfpmHostPort = "127.0.0.1:9000"; | ||||||
|  |     pfaUser = "pfadmin"; | ||||||
|  |     pfaDomain = "pfa.${config.variables.myFQDN}"; | ||||||
|  |     roundcubeFQDN = config.variables.myFQDN; | ||||||
|  |     roundcubeDataDir = "/var/lib/roundcube"; | ||||||
|  |     roundcubePhpfpmHostPort = "127.0.0.1:9001"; | ||||||
|  |     roundcubeUser = "roundcube"; | ||||||
|  |     useSSL = false; | ||||||
|  |     vmailBaseDir = "/var/vmail"; | ||||||
|  |     vmailGID = 10000; | ||||||
|  |     vmailGroup = "vmail"; | ||||||
|  |     vmailUID = 10000; | ||||||
|  |     vmailUser = "vmail"; | ||||||
|  |     postfixadminpkgCacheDir = "/var/cache/postfixadmin"; | ||||||
|  |     postfixadminpkg = (pkgs.callPackage ./pkg-postfixadmin.nix { | ||||||
|  |       config = (pkgs.writeText "postfixadmin-config.local.php" '' | ||||||
|  |         <?php | ||||||
|  |         $CONF['configured'] = true; | ||||||
|  |         $CONF['setup_password'] = '!'; | ||||||
|  |         $CONF['database_type'] = 'sqlite'; | ||||||
|  |         $CONF['database_name'] = '${config.variables.pfadminDataDir}/postfixadmin.db'; | ||||||
|  |         $CONF['password_expiration'] = 'NO'; | ||||||
|  |         $CONF['encrypt'] = 'dovecot:BLF-CRYPT'; | ||||||
|  |         $CONF['dovecotpw'] = "${pkgs.dovecot}/bin/doveadm pw -r 12"; | ||||||
|  |         $CONF['generate_password'] = 'YES'; | ||||||
|  |         $CONF['show_password'] = 'NO'; | ||||||
|  |         $CONF['quota'] = 'NO'; | ||||||
|  |         $CONF['fetchmail'] = 'NO'; | ||||||
|  |         $CONF['recipient_delimiter'] = "+"; | ||||||
|  |         $CONF['forgotten_user_password_reset'] = false; | ||||||
|  |         $CONF['forgotten_admin_password_reset'] = false; | ||||||
|  |         $CONF['aliases'] = '0'; | ||||||
|  |         $CONF['mailboxes'] = '0'; | ||||||
|  |         $CONF['default_aliases'] = array ( | ||||||
|  |           'abuse' => '${config.variables.mailAdmin}', | ||||||
|  |           'hostmaster' => '${config.variables.mailAdmin}', | ||||||
|  |           'postmaster' => '${config.variables.mailAdmin}', | ||||||
|  |           'webmaster' => '${config.variables.mailAdmin}' | ||||||
|  |         ); | ||||||
|  |         $CONF['footer_text'] = ""; | ||||||
|  |         $CONF['footer_link'] = ""; | ||||||
|  |         ?> | ||||||
|  |       ''); | ||||||
|  |       cacheDir = config.variables.postfixadminpkgCacheDir; | ||||||
|  |     } ); | ||||||
|  |   }; | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Daniel Frank
				Daniel Frank