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 = | ||||
|     [ # Include the results of the hardware scan. | ||||
|       ./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----- | ||||
|       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 | ||||
|       -----END CERTIFICATE----- | ||||
|     '' | ||||
|   ]; | ||||
| 
 | ||||
|   # Configuration options for the mailserver | ||||
|   variables = { | ||||
|     mailAdmin = "postmaster@mail2.hamburg.freifunk.net"; | ||||
|     useSSL = true; | ||||
|   }; | ||||
|   # Use the GRUB 2 boot loader. | ||||
|   boot.loader.grub.enable = true; | ||||
|   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