Migrate the mail config to the nixos module
This commit is contained in:
parent
ad0ab2e843
commit
5dcbb4e2dc
|
@ -10,7 +10,6 @@
|
|||
./hardware-configuration.nix
|
||||
./acme.nix
|
||||
./sshusers.nix
|
||||
./variables.nix
|
||||
./mailserver.nix
|
||||
./borgbackup.nix
|
||||
./nginx.nix
|
||||
|
|
164
dovecot.nix
164
dovecot.nix
|
@ -1,164 +0,0 @@
|
|||
{ 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'
|
||||
'';
|
||||
dovecotConfSSL = pkgs.writeText "dovecot.conf" ''
|
||||
${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
|
||||
''
|
||||
}
|
||||
'';
|
||||
dovecotConf = pkgs.writeText "dovecot.conf" ''
|
||||
sendmail_path = /run/wrappers/bin/sendmail
|
||||
default_internal_user = dovecot2
|
||||
default_internal_group = dovecot2
|
||||
protocols = imap lmtp pop3 sieve
|
||||
|
||||
# commented out due to a dovecot but in the most recent release
|
||||
#$ {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
|
||||
# '#'
|
||||
#}
|
||||
!include_try /var/lib/dovecot/ssl-keys.conf
|
||||
|
||||
disable_plaintext_auth = yes
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
service stats {
|
||||
unix_listener stats-reader {
|
||||
user = dovecot2
|
||||
group = dovecot2
|
||||
mode = 0660
|
||||
}
|
||||
unix_listener stats-writer {
|
||||
user = dovecot2
|
||||
group = dovecot2
|
||||
mode = 0660
|
||||
}
|
||||
}
|
||||
|
||||
protocol lmtp {
|
||||
mail_plugins = sieve
|
||||
}
|
||||
|
||||
protocol imap {
|
||||
mail_plugins = $mail_plugins imap_sieve
|
||||
}
|
||||
imap_idle_notify_interval = 29 mins
|
||||
|
||||
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}";
|
||||
group = "certs";
|
||||
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") "vmail-setup.service" ];
|
||||
# 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}
|
||||
# SSL workaround for dovecot...
|
||||
mkdir -p /var/lib/dovecot
|
||||
cat ${dovecotConfSSL} > /var/lib/dovecot/ssl-keys.conf
|
||||
chown root:root /var/lib/dovecot/ssl-keys.conf
|
||||
chmod 400 /var/lib/dovecot/ssl-keys.conf
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,14 +1,28 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
let mymailserver = (import <nixpkgs> {}).pkgs.fetchgit {
|
||||
url = "https://codeberg.org/tokudan/nixos-mailserver.git";
|
||||
rev = "15c419d488d1f4148f268d62fce0975f5a88a464";
|
||||
sha256 = "111xjmcvr7gq4406yxdj87wvi8psq3dhb7shkdsj5d4bdr9kr13q";
|
||||
};
|
||||
in
|
||||
|
||||
{
|
||||
# Import some configuration as they are too long to be easily readable here
|
||||
imports = [
|
||||
./dovecot.nix
|
||||
./postfix.nix
|
||||
./postfixadmin.nix
|
||||
./roundcube.nix
|
||||
./rspamd.nix
|
||||
#./dovecot.nix
|
||||
#./postfix.nix
|
||||
#./postfixadmin.nix
|
||||
#./roundcube.nix
|
||||
#./rspamd.nix
|
||||
"${mymailserver}/default.nix"
|
||||
];
|
||||
networking.domain = "hamburg.freifunk.net";
|
||||
services.mymailserver = {
|
||||
enable = true;
|
||||
adminAddress = "kontakt@hamburg.freifunk.net";
|
||||
mailFQDN = "mail2.hamburg.freifunk.net";
|
||||
};
|
||||
users.groups."${config.variables.vmailGroup}" = { gid = config.variables.vmailGID; };
|
||||
users.users."${config.variables.vmailUser}" = {
|
||||
uid = config.variables.vmailUID;
|
||||
|
|
89
postfix.nix
89
postfix.nix
|
@ -1,89 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
submission_header_cleanup_regex = pkgs.writeText "submission_header_cleanup_regex" ''
|
||||
/^Received:.*by ${config.variables.myFQDN} \(Postfix/ IGNORE
|
||||
'';
|
||||
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 = "certs";
|
||||
postRun = "systemctl restart postfix.service";
|
||||
# cheat by getting some settings from another certificate configured through nginx.
|
||||
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 = {
|
||||
mydestination = "";
|
||||
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}";
|
||||
};
|
||||
masterConfig.submission.args = [ "-o" "cleanup_service_name=submission_cleanup" ];
|
||||
masterConfig."submission_cleanup" = {
|
||||
command = "cleanup";
|
||||
args = [ "-o" "header_checks=regexp:${submission_header_cleanup_regex}" ];
|
||||
private = false;
|
||||
maxproc = 0;
|
||||
};
|
||||
rootAlias = config.variables.mailAdmin;
|
||||
postmasterAlias = config.variables.mailAdmin;
|
||||
};
|
||||
}
|
101
postfixadmin.nix
101
postfixadmin.nix
|
@ -1,101 +0,0 @@
|
|||
{ 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}";
|
||||
extraGroups = [ "dovecot2" ];
|
||||
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;
|
||||
root = "${postfixadminpkg}/public";
|
||||
extraConfig = ''
|
||||
charset utf-8;
|
||||
|
||||
etag off;
|
||||
add_header etag "\"${builtins.substring 11 32 postfixadminpkg}\"";
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
|
||||
index index.php;
|
||||
|
||||
location ~* \.php$ {
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
# 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 unix:${config.services.phpfpm.pools."${phppoolName}".socket};
|
||||
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}" = {
|
||||
user = "${pfaUser}";
|
||||
group = "${pfaGroup}";
|
||||
settings = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 75;
|
||||
"pm.min_spare_servers" = 5;
|
||||
"pm.max_spare_servers" = 20;
|
||||
"pm.max_requests" = 10;
|
||||
"catch_workers_output" = 1;
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
};
|
||||
};
|
||||
}
|
136
roundcube.nix
136
roundcube.nix
|
@ -1,136 +0,0 @@
|
|||
{ 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'] = file_get_contents("${config.variables.roundcubeDataDir}/des_key");;
|
||||
$config['cipher_method'] = 'AES-256-CBC';
|
||||
$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";
|
||||
extraConfig = ''
|
||||
access_log off;
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
'';
|
||||
locations."~ ^/favicon.ico/.*$" = {
|
||||
extraConfig = ''
|
||||
try_files $uri kins/larry/images/$uri;
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
'';
|
||||
};
|
||||
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}\"";
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
'';
|
||||
};
|
||||
locations."~ [^/]\.php(/|$)" = {
|
||||
extraConfig = ''
|
||||
etag off;
|
||||
add_header etag "\"${builtins.substring 11 32 roundcube}\"";
|
||||
add_header Permissions-Policy "interest-cohort=()" always;
|
||||
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) {
|
||||
return 404;
|
||||
}
|
||||
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools."${poolName}".socket};
|
||||
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.roundcubeGroup} ${config.variables.roundcubeDataDir}
|
||||
chmod -c 700 ${config.variables.roundcubeDataDir}
|
||||
# Regenerate the key every now and then. This invalidates all sessions, but during reboot should be good enough.
|
||||
[ -f "${config.variables.roundcubeDataDir}/des_key" ] && ${pkgs.coreutils}/bin/shred "${config.variables.roundcubeDataDir}/des_key"
|
||||
${pkgs.coreutils}/bin/dd if=/dev/urandom bs=32 count=1 2>/dev/null | ${pkgs.coreutils}/bin/base64 > "${config.variables.roundcubeDataDir}/des_key"
|
||||
chown -c "${config.variables.roundcubeUser}":${config.variables.roundcubeGroup} "${config.variables.roundcubeDataDir}/des_key"
|
||||
chmod -c 400 "${config.variables.roundcubeDataDir}/des_key"
|
||||
if [ -s "${config.variables.roundcubeDataDir}/roundcube.sqlite" ]; then
|
||||
# Just go ahead and remove the sessions, the key to decrypt them has just been destroyed anyway.
|
||||
${pkgs.sqlite}/bin/sqlite3 "${config.variables.roundcubeDataDir}/roundcube.sqlite" "DELETE FROM session;"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
services.phpfpm.pools."${poolName}" = {
|
||||
user = "${config.variables.roundcubeUser}";
|
||||
group = "${config.variables.roundcubeUser}";
|
||||
settings = {
|
||||
"pm" = "dynamic";
|
||||
"pm.max_children" = 75;
|
||||
"pm.min_spare_servers" = 5;
|
||||
"pm.max_spare_servers" = 20;
|
||||
"pm.max_requests" = 10;
|
||||
"catch_workers_output" = 1;
|
||||
"listen.owner" = "nginx";
|
||||
"listen.group" = "nginx";
|
||||
};
|
||||
};
|
||||
users.extraUsers."${config.variables.roundcubeUser}" = { };
|
||||
users.extraGroups."${config.variables.roundcubeUser}" = { };
|
||||
users.groups."${config.variables.roundcubeGroup}" = { };
|
||||
users.users."${config.variables.roundcubeUser}" = {
|
||||
isSystemUser = true;
|
||||
group = "${config.variables.roundcubeGroup}";
|
||||
description = "PHP User for roundcube";
|
||||
};
|
||||
}
|
68
rspamd.nix
68
rspamd.nix
|
@ -1,68 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
rspamdExtraConfig = pkgs.writeText "rspamd-extra.conf" ''
|
||||
secure_ip = [::1]
|
||||
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; }
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue