Compare commits
No commits in common. "5fd775d855336c8a282b968426bdcccf84bb60bb" and "1f2273d2ab9eee661a30aa41dd0876b3d483db79" have entirely different histories.
5fd775d855
...
1f2273d2ab
10 changed files with 100 additions and 154 deletions
17
bundles/dovecot/files/dovecot-sql.conf
Normal file
17
bundles/dovecot/files/dovecot-sql.conf
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
connect = host=${host} dbname=${name} user=${user} password=${password}
|
||||||
|
driver = pgsql
|
||||||
|
default_pass_scheme = ARGON2ID
|
||||||
|
|
||||||
|
user_query = SELECT '/var/vmail/%u' AS home, 'vmail' AS uid, 'vmail' AS gid
|
||||||
|
|
||||||
|
iterate_query = SELECT CONCAT(users.name, '@', domains.name) AS user \
|
||||||
|
FROM users \
|
||||||
|
LEFT JOIN domains ON users.domain_id = domains.id \
|
||||||
|
WHERE redirect IS NULL
|
||||||
|
|
||||||
|
password_query = SELECT CONCAT(users.name, '@', domains.name) AS user, password \
|
||||||
|
FROM users \
|
||||||
|
LEFT JOIN domains ON users.domain_id = domains.id \
|
||||||
|
WHERE redirect IS NULL \
|
||||||
|
AND users.name = SPLIT_PART('%u', '@', 1) \
|
||||||
|
AND domains.name = SPLIT_PART('%u', '@', 2)
|
|
@ -1,17 +1,13 @@
|
||||||
dovecot_config_version = ${config_version}
|
|
||||||
dovecot_storage_version = ${storage_version}
|
|
||||||
|
|
||||||
protocols = imap lmtp sieve
|
protocols = imap lmtp sieve
|
||||||
auth_mechanisms = plain login
|
auth_mechanisms = plain login
|
||||||
|
mail_privileged_group = mail
|
||||||
ssl = required
|
ssl = required
|
||||||
ssl_server_cert_file = /var/lib/dehydrated/certs/${hostname}/fullchain.pem
|
ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/fullchain.pem
|
||||||
ssl_server_key_file = /var/lib/dehydrated/certs/${hostname}/privkey.pem
|
ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/privkey.pem
|
||||||
ssl_server_dh_file = /etc/dovecot/dhparam.pem
|
ssl_dh = </etc/dovecot/dhparam.pem
|
||||||
ssl_client_ca_dir = /etc/ssl/certs
|
ssl_client_ca_dir = /etc/ssl/certs
|
||||||
mail_driver = maildir
|
mail_location = maildir:${node.metadata.get('mailserver/maildir')}/%u:INDEX=${node.metadata.get('mailserver/maildir')}/index/%u
|
||||||
mail_path = ${maildir}/%{user}
|
mail_plugins = fts fts_xapian
|
||||||
mail_index_path = ${maildir}/index/%{user}
|
|
||||||
mail_plugins = fts fts_flatcurve
|
|
||||||
|
|
||||||
namespace inbox {
|
namespace inbox {
|
||||||
inbox = yes
|
inbox = yes
|
||||||
|
@ -34,46 +30,14 @@ namespace inbox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# postgres passdb userdb
|
passdb {
|
||||||
|
driver = sql
|
||||||
sql_driver = pgsql
|
args = /etc/dovecot/dovecot-sql.conf
|
||||||
|
|
||||||
pgsql main {
|
|
||||||
parameters {
|
|
||||||
host = ${db_host}
|
|
||||||
dbname = ${db_name}
|
|
||||||
user = ${db_user}
|
|
||||||
password = ${db_password}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
# use sql for userdb too, to enable iterate_query
|
||||||
passdb sql {
|
userdb {
|
||||||
passdb_default_password_scheme = ARGON2ID
|
driver = sql
|
||||||
|
args = /etc/dovecot/dovecot-sql.conf
|
||||||
query = SELECT \
|
|
||||||
CONCAT(users.name, '@', domains.name) AS "user", \
|
|
||||||
password \
|
|
||||||
FROM users \
|
|
||||||
LEFT JOIN domains ON users.domain_id = domains.id \
|
|
||||||
WHERE redirect IS NULL \
|
|
||||||
AND users.name = SPLIT_PART('%{user}', '@', 1) \
|
|
||||||
AND domains.name = SPLIT_PART('%{user}', '@', 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
mail_uid = vmail
|
|
||||||
mail_gid = vmail
|
|
||||||
|
|
||||||
userdb sql {
|
|
||||||
query = SELECT \
|
|
||||||
'/var/vmail/%{user}' AS home, \
|
|
||||||
'vmail' AS uid, \
|
|
||||||
'vmail' AS gid
|
|
||||||
|
|
||||||
iterate_query = SELECT \
|
|
||||||
CONCAT(users.name, '@', domains.name) AS username \
|
|
||||||
FROM users \
|
|
||||||
LEFT JOIN domains ON users.domain_id = domains.id \
|
|
||||||
WHERE redirect IS NULL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
service auth {
|
service auth {
|
||||||
|
@ -103,9 +67,10 @@ service stats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service managesieve-login {
|
service managesieve-login {
|
||||||
#inet_listener sieve {}
|
inet_listener sieve {
|
||||||
process_min_avail = 1
|
}
|
||||||
process_limit = 1
|
process_min_avail = 0
|
||||||
|
service_count = 1
|
||||||
vsz_limit = 64 M
|
vsz_limit = 64 M
|
||||||
}
|
}
|
||||||
service managesieve {
|
service managesieve {
|
||||||
|
@ -113,53 +78,31 @@ service managesieve {
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol imap {
|
protocol imap {
|
||||||
mail_plugins = fts fts_flatcurve imap_sieve
|
mail_plugins = $mail_plugins imap_sieve
|
||||||
mail_max_userip_connections = 50
|
mail_max_userip_connections = 50
|
||||||
imap_idle_notify_interval = 29 mins
|
imap_idle_notify_interval = 29 mins
|
||||||
}
|
}
|
||||||
protocol lmtp {
|
protocol lmtp {
|
||||||
mail_plugins = fts fts_flatcurve sieve
|
mail_plugins = $mail_plugins sieve
|
||||||
}
|
}
|
||||||
|
protocol sieve {
|
||||||
# Persönliches Skript (deine alte Datei /var/vmail/sieve/%u.sieve)
|
plugin {
|
||||||
sieve_script personal {
|
sieve = /var/vmail/sieve/%u.sieve
|
||||||
driver = file
|
sieve_storage = /var/vmail/sieve/%u/
|
||||||
# Verzeichnis mit (evtl. mehreren) Sieve-Skripten des Users
|
}
|
||||||
path = /var/vmail/sieve/%{user}/
|
|
||||||
# Aktives Skript (entspricht früher "sieve = /var/vmail/sieve/%u.sieve")
|
|
||||||
active_path = /var/vmail/sieve/%{user}.sieve
|
|
||||||
}
|
|
||||||
|
|
||||||
# Globales After-Skript (dein früheres "sieve_after = …")
|
|
||||||
sieve_script after {
|
|
||||||
type = after
|
|
||||||
driver = file
|
|
||||||
path = /var/vmail/sieve/global/spam-to-folder.sieve
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# fulltext search
|
# fulltext search
|
||||||
language en {
|
plugin {
|
||||||
|
fts = xapian
|
||||||
|
fts_xapian = partial=3 full=20 verbose=0
|
||||||
|
fts_autoindex = yes
|
||||||
|
fts_enforced = yes
|
||||||
|
# Index attachements
|
||||||
|
fts_decoder = decode2text
|
||||||
}
|
}
|
||||||
language de {
|
|
||||||
default = yes
|
|
||||||
}
|
|
||||||
language_tokenizers = generic email-address
|
|
||||||
|
|
||||||
fts flatcurve {
|
|
||||||
substring_search = yes
|
|
||||||
# rotate_count = 5000 # DB-Rotation nach X Mails
|
|
||||||
# rotate_time = 5s # oder zeitbasiert rotieren
|
|
||||||
# optimize_limit = 10
|
|
||||||
# min_term_size = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
fts_autoindex = yes
|
|
||||||
fts_decoder_driver = script
|
|
||||||
fts_decoder_script_socket_path = decode2text
|
|
||||||
|
|
||||||
service indexer-worker {
|
service indexer-worker {
|
||||||
process_limit = ${indexer_cores}
|
vsz_limit = ${indexer_ram}
|
||||||
vsz_limit = ${indexer_ram}M
|
|
||||||
}
|
}
|
||||||
service decode2text {
|
service decode2text {
|
||||||
executable = script /usr/local/libexec/dovecot/decode2text.sh
|
executable = script /usr/local/libexec/dovecot/decode2text.sh
|
||||||
|
@ -169,39 +112,24 @@ service decode2text {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mailbox Junk {
|
# spam filter
|
||||||
sieve_script learn_spam {
|
plugin {
|
||||||
driver = file
|
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||||
type = before
|
sieve_dir = /var/vmail/sieve/%u/
|
||||||
cause = copy
|
sieve = /var/vmail/sieve/%u.sieve
|
||||||
path = /var/vmail/sieve/global/learn-spam.sieve
|
sieve_pipe_bin_dir = /var/vmail/sieve/bin
|
||||||
}
|
sieve_extensions = +vnd.dovecot.pipe
|
||||||
}
|
|
||||||
|
|
||||||
imapsieve_from Junk {
|
sieve_after = /var/vmail/sieve/global/spam-to-folder.sieve
|
||||||
sieve_script learn_ham {
|
|
||||||
driver = file
|
|
||||||
type = before
|
|
||||||
cause = copy
|
|
||||||
path = /var/vmail/sieve/global/learn-ham.sieve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Extprograms-Plugin einschalten
|
# From elsewhere to Spam folder
|
||||||
sieve_plugins {
|
imapsieve_mailbox1_name = Junk
|
||||||
sieve_extprograms = yes
|
imapsieve_mailbox1_causes = COPY
|
||||||
}
|
imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve
|
||||||
|
|
||||||
# Welche Sieve-Erweiterungen dürfen genutzt werden?
|
# From Spam folder to elsewhere
|
||||||
# Empfehlung: nur global erlauben (nicht in User-Skripten):
|
imapsieve_mailbox2_name = *
|
||||||
sieve_global_extensions {
|
imapsieve_mailbox2_from = Junk
|
||||||
vnd.dovecot.pipe = yes
|
imapsieve_mailbox2_causes = COPY
|
||||||
# vnd.dovecot.filter = yes # nur falls gebraucht
|
imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve
|
||||||
# vnd.dovecot.execute = yes # nur falls gebraucht
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Verzeichnis mit deinen Skripten/Binaries für :pipe
|
|
||||||
sieve_pipe_bin_dir = /var/vmail/sieve/bin
|
|
||||||
# (optional, analog für :filter / :execute)
|
|
||||||
# sieve_filter_bin_dir = /var/vmail/sieve/filter
|
|
||||||
# sieve_execute_bin_dir = /var/vmail/sieve/execute
|
|
|
@ -44,16 +44,6 @@ files = {
|
||||||
'context': {
|
'context': {
|
||||||
'admin_email': node.metadata.get('mailserver/admin_email'),
|
'admin_email': node.metadata.get('mailserver/admin_email'),
|
||||||
'indexer_ram': node.metadata.get('dovecot/indexer_ram'),
|
'indexer_ram': node.metadata.get('dovecot/indexer_ram'),
|
||||||
'config_version': node.metadata.get('dovecot/config_version'),
|
|
||||||
'storage_version': node.metadata.get('dovecot/storage_version'),
|
|
||||||
'maildir': node.metadata.get('mailserver/maildir'),
|
|
||||||
'hostname': node.metadata.get('mailserver/hostname'),
|
|
||||||
'db_host': node.metadata.get('mailserver/database/host'),
|
|
||||||
'db_name': node.metadata.get('mailserver/database/name'),
|
|
||||||
'db_user': node.metadata.get('mailserver/database/user'),
|
|
||||||
'db_password': node.metadata.get('mailserver/database/password'),
|
|
||||||
'indexer_cores': node.metadata.get('vm/cores'),
|
|
||||||
'indexer_ram': node.metadata.get('vm/ram')//2,
|
|
||||||
},
|
},
|
||||||
'needs': {
|
'needs': {
|
||||||
'pkg_apt:'
|
'pkg_apt:'
|
||||||
|
@ -62,9 +52,29 @@ files = {
|
||||||
'svc_systemd:dovecot:restart',
|
'svc_systemd:dovecot:restart',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'/etc/dovecot/dovecot-sql.conf': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
'context': node.metadata.get('mailserver/database'),
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:'
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:dovecot:restart',
|
||||||
|
},
|
||||||
|
},
|
||||||
'/etc/dovecot/dhparam.pem': {
|
'/etc/dovecot/dhparam.pem': {
|
||||||
'content_type': 'any',
|
'content_type': 'any',
|
||||||
},
|
},
|
||||||
|
'/etc/dovecot/dovecot-sql.conf': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
'context': node.metadata.get('mailserver/database'),
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:'
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:dovecot:restart',
|
||||||
|
},
|
||||||
|
},
|
||||||
'/var/vmail/sieve/global/spam-to-folder.sieve': {
|
'/var/vmail/sieve/global/spam-to-folder.sieve': {
|
||||||
'owner': 'vmail',
|
'owner': 'vmail',
|
||||||
'group': 'vmail',
|
'group': 'vmail',
|
||||||
|
@ -121,6 +131,7 @@ svc_systemd = {
|
||||||
'action:letsencrypt_update_certificates',
|
'action:letsencrypt_update_certificates',
|
||||||
'action:dovecot_generate_dhparam',
|
'action:dovecot_generate_dhparam',
|
||||||
'file:/etc/dovecot/dovecot.conf',
|
'file:/etc/dovecot/dovecot.conf',
|
||||||
|
'file:/etc/dovecot/dovecot-sql.conf',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ defaults = {
|
||||||
'dovecot-sieve': {},
|
'dovecot-sieve': {},
|
||||||
'dovecot-managesieved': {},
|
'dovecot-managesieved': {},
|
||||||
# fulltext search
|
# fulltext search
|
||||||
'dovecot-flatcurve': {}, # buster-backports
|
'dovecot-fts-xapian': {}, # buster-backports
|
||||||
'poppler-utils': {}, # pdftotext
|
'poppler-utils': {}, # pdftotext
|
||||||
'catdoc': {}, # catdoc, catppt, xls2csv
|
'catdoc': {}, # catdoc, catppt, xls2csv
|
||||||
},
|
},
|
||||||
|
|
|
@ -32,14 +32,10 @@ defaults = {
|
||||||
'tank/vmail': {
|
'tank/vmail': {
|
||||||
'mountpoint': '/var/vmail',
|
'mountpoint': '/var/vmail',
|
||||||
'compression': 'on',
|
'compression': 'on',
|
||||||
'atime': 'off',
|
|
||||||
'recordsize': '16384',
|
|
||||||
},
|
},
|
||||||
'tank/vmail/index': {
|
'tank/vmail/index': {
|
||||||
'mountpoint': '/var/vmail/index',
|
'mountpoint': '/var/vmail/index',
|
||||||
'compression': 'on',
|
'compression': 'on',
|
||||||
'atime': 'off',
|
|
||||||
'recordsize': '4096',
|
|
||||||
'com.sun:auto-snapshot': 'false',
|
'com.sun:auto-snapshot': 'false',
|
||||||
'backup': False,
|
'backup': False,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,6 @@ directories = {
|
||||||
},
|
},
|
||||||
'/var/lib/redis': {
|
'/var/lib/redis': {
|
||||||
'owner': 'redis',
|
'owner': 'redis',
|
||||||
'group': 'redis',
|
|
||||||
'mode': '0750',
|
'mode': '0750',
|
||||||
'needs': [
|
'needs': [
|
||||||
'pkg_apt:redis-server',
|
'pkg_apt:redis-server',
|
||||||
|
|
|
@ -7,16 +7,18 @@ $config['enable_installer'] = true;
|
||||||
/* Local configuration for Roundcube Webmail */
|
/* Local configuration for Roundcube Webmail */
|
||||||
|
|
||||||
$config['db_dsnw'] = '${database['provider']}://${database['user']}:${database['password']}@${database['host']}/${database['name']}';
|
$config['db_dsnw'] = '${database['provider']}://${database['user']}:${database['password']}@${database['host']}/${database['name']}';
|
||||||
$config['imap_host'] = 'ssl://${imap_host}';
|
$config['imap_host'] = 'localhost';
|
||||||
$config['imap_port'] = 993;
|
|
||||||
$config['smtp_host'] = 'tls://localhost';
|
$config['smtp_host'] = 'tls://localhost';
|
||||||
$config['smtp_port'] = 587;
|
|
||||||
$config['smtp_user'] = '%u';
|
$config['smtp_user'] = '%u';
|
||||||
$config['smtp_pass'] = '%p';
|
$config['smtp_pass'] = '%p';
|
||||||
#$config['imap_debug'] = true;
|
|
||||||
#$config['smtp_debug'] = true;
|
|
||||||
$config['support_url'] = '';
|
$config['support_url'] = '';
|
||||||
$config['des_key'] = '${des_key}';
|
$config['des_key'] = '${des_key}';
|
||||||
$config['product_name'] = '${product_name}';
|
$config['product_name'] = '${product_name}';
|
||||||
$config['plugins'] = array(${', '.join(f'"{plugin}"' for plugin in plugins)});
|
$config['plugins'] = array(${', '.join(f'"{plugin}"' for plugin in plugins)});
|
||||||
$config['language'] = 'de_DE';
|
$config['language'] = 'de_DE';
|
||||||
|
$config['smtp_conn_options'] = array(
|
||||||
|
'ssl' => array(
|
||||||
|
'verify_peer' => false,
|
||||||
|
'verify_peer_name' => false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
|
@ -61,7 +61,6 @@ files['/opt/roundcube/config/config.inc.php'] = {
|
||||||
'des_key': node.metadata.get('roundcube/des_key'),
|
'des_key': node.metadata.get('roundcube/des_key'),
|
||||||
'database': node.metadata.get('roundcube/database'),
|
'database': node.metadata.get('roundcube/database'),
|
||||||
'plugins': node.metadata.get('roundcube/plugins'),
|
'plugins': node.metadata.get('roundcube/plugins'),
|
||||||
'imap_host': node.metadata.get('mailserver/hostname'),
|
|
||||||
},
|
},
|
||||||
'needs': [
|
'needs': [
|
||||||
'action:chown_roundcube',
|
'action:chown_roundcube',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
defaults = {
|
defaults = {
|
||||||
'systemd-swap': 2*(2**30), # 2GiB
|
'systemd-swap': 2*10**9,
|
||||||
'systemd': {
|
'systemd': {
|
||||||
'units': {
|
'units': {
|
||||||
'swapfile.swap': {
|
'swapfile.swap': {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
'hostname': '49.12.184.229',
|
'hostname': '49.12.184.229',
|
||||||
'groups': [
|
'groups': [
|
||||||
'backup',
|
'backup',
|
||||||
'debian-13',
|
'debian-12',
|
||||||
'hetzner-cloud',
|
'hetzner-cloud',
|
||||||
'mailserver',
|
'mailserver',
|
||||||
'monitored',
|
'monitored',
|
||||||
|
@ -18,7 +18,6 @@
|
||||||
#'nginx-rtmps',
|
#'nginx-rtmps',
|
||||||
'wireguard',
|
'wireguard',
|
||||||
'zfs',
|
'zfs',
|
||||||
'systemd-swap',
|
|
||||||
],
|
],
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'id': 'ea29bdf0-0b47-4bf4-8346-67d60c9dc4ae',
|
'id': 'ea29bdf0-0b47-4bf4-8346-67d60c9dc4ae',
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
'gateway6': 'fe80::1',
|
'gateway6': 'fe80::1',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'systemd-swap': 4*2**30, # clamav alleine braucht 1,3G
|
|
||||||
'bind': {
|
'bind': {
|
||||||
'hostname': 'resolver.name',
|
'hostname': 'resolver.name',
|
||||||
'acme_zone': 'acme.sublimity.de',
|
'acme_zone': 'acme.sublimity.de',
|
||||||
|
@ -110,10 +108,6 @@
|
||||||
'elimu-kwanza.de',
|
'elimu-kwanza.de',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'dovecot': {
|
|
||||||
'config_version': '2.4.1',
|
|
||||||
'storage_version': '2.4.1',
|
|
||||||
},
|
|
||||||
'rspamd': {
|
'rspamd': {
|
||||||
'hostname': 'rspamd.sublimity.de',
|
'hostname': 'rspamd.sublimity.de',
|
||||||
},
|
},
|
||||||
|
@ -168,7 +162,7 @@
|
||||||
},
|
},
|
||||||
'roundcube': {
|
'roundcube': {
|
||||||
'product_name': 'Sublimity Mail',
|
'product_name': 'Sublimity Mail',
|
||||||
'version': '1.6.11',
|
'version': '1.6.7',
|
||||||
'installer': False,
|
'installer': False,
|
||||||
},
|
},
|
||||||
'vm': {
|
'vm': {
|
||||||
|
|
Loading…
Reference in a new issue