wip
This commit is contained in:
parent
5e96e7df53
commit
c1e37b233c
12 changed files with 375 additions and 30 deletions
5
bundles/dovecot/files/dovecot-sql.conf
Normal file
5
bundles/dovecot/files/dovecot-sql.conf
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
connect = host=${host} dbname=${name} user=${user} password=${password}
|
||||||
|
driver = pgsql
|
||||||
|
default_pass_scheme = MD5-CRYPT
|
||||||
|
password_query = SELECT username as user, password FROM mailbox WHERE username = '%u' AND active = true
|
||||||
|
user_query = SELECT '/var/mail/vmail/' || maildir as home, 65534 as uid, 65534 as gid FROM mailbox WHERE username = '%u' AND active = true
|
139
bundles/dovecot/files/dovecot.conf
Normal file
139
bundles/dovecot/files/dovecot.conf
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
!include conf.d/*.conf
|
||||||
|
|
||||||
|
namespace inbox {
|
||||||
|
separator = .
|
||||||
|
type = private
|
||||||
|
inbox = yes
|
||||||
|
location =
|
||||||
|
mailbox Drafts {
|
||||||
|
auto = subscribe
|
||||||
|
special_use = \Drafts
|
||||||
|
}
|
||||||
|
mailbox Junk {
|
||||||
|
auto = create
|
||||||
|
special_use = \Junk
|
||||||
|
autoexpunge = 30d
|
||||||
|
}
|
||||||
|
mailbox Sent {
|
||||||
|
auto = subscribe
|
||||||
|
special_use = \Sent
|
||||||
|
}
|
||||||
|
mailbox Trash {
|
||||||
|
auto = subscribe
|
||||||
|
special_use = \Trash
|
||||||
|
autoexpunge = 360d
|
||||||
|
}
|
||||||
|
prefix =
|
||||||
|
}
|
||||||
|
|
||||||
|
mail_location = maildir:/var/vmail/%u
|
||||||
|
protocols = imap lmtp sieve
|
||||||
|
|
||||||
|
ssl = yes
|
||||||
|
ssl_cert = </var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/fullchain.pem
|
||||||
|
ssl_key = </var/lib/dehydrated/certs/${node.metadata.get('mailserver/hostname')}/privkey.pem
|
||||||
|
ssl_dh = </etc/dovecot/ssl/dhparam.pem
|
||||||
|
ssl_min_protocol = TLSv1.2
|
||||||
|
ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM
|
||||||
|
ssl_prefer_server_ciphers = yes
|
||||||
|
|
||||||
|
login_greeting = IMAPd ready
|
||||||
|
auth_mechanisms = plain login
|
||||||
|
first_valid_uid = 65534
|
||||||
|
disable_plaintext_auth = yes
|
||||||
|
mail_plugins = $mail_plugins zlib
|
||||||
|
|
||||||
|
plugin {
|
||||||
|
zlib_save_level = 6
|
||||||
|
zlib_save = gz
|
||||||
|
|
||||||
|
sieve_plugins = sieve_imapsieve sieve_extprograms
|
||||||
|
sieve_dir = /var/vmail/sieve/%d/%n/
|
||||||
|
sieve = /var/vmail/sieve/%d/%n.sieve
|
||||||
|
sieve_pipe_bin_dir = /var/vmail/sieve/bin
|
||||||
|
sieve_extensions = +vnd.dovecot.pipe
|
||||||
|
|
||||||
|
old_stats_refresh = 30 secs
|
||||||
|
old_stats_track_cmds = yes
|
||||||
|
|
||||||
|
% if node.has_bundle('rspamd'):
|
||||||
|
sieve_before = /var/vmail/sieve/global/spam-global.sieve
|
||||||
|
|
||||||
|
# From elsewhere to Spam folder
|
||||||
|
imapsieve_mailbox1_name = Junk
|
||||||
|
imapsieve_mailbox1_causes = COPY
|
||||||
|
imapsieve_mailbox1_before = file:/var/vmail/sieve/global/learn-spam.sieve
|
||||||
|
|
||||||
|
# From Spam folder to elsewhere
|
||||||
|
imapsieve_mailbox2_name = *
|
||||||
|
imapsieve_mailbox2_from = Junk
|
||||||
|
imapsieve_mailbox2_causes = COPY
|
||||||
|
imapsieve_mailbox2_before = file:/var/vmail/sieve/global/learn-ham.sieve
|
||||||
|
% endif
|
||||||
|
}
|
||||||
|
|
||||||
|
service auth {
|
||||||
|
unix_listener /var/spool/postfix/private/auth {
|
||||||
|
mode = 0660
|
||||||
|
user = postfix
|
||||||
|
group = postfix
|
||||||
|
}
|
||||||
|
|
||||||
|
unix_listener auth-userdb {
|
||||||
|
mode = 0660
|
||||||
|
user = nobody
|
||||||
|
group = nogroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service lmtp {
|
||||||
|
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||||
|
group = postfix
|
||||||
|
mode = 0600
|
||||||
|
user = postfix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service imap {
|
||||||
|
executable = imap
|
||||||
|
}
|
||||||
|
|
||||||
|
service imap-login {
|
||||||
|
service_count = 1
|
||||||
|
process_min_avail = 8
|
||||||
|
vsz_limit = 64M
|
||||||
|
}
|
||||||
|
|
||||||
|
service managesieve-login {
|
||||||
|
inet_listener sieve {
|
||||||
|
port = 4190
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userdb {
|
||||||
|
driver = sql
|
||||||
|
args = /etc/dovecot/dovecot-sql.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
passdb {
|
||||||
|
driver = sql
|
||||||
|
args = /etc/dovecot/dovecot-sql.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol lmtp {
|
||||||
|
mail_plugins = $mail_plugins sieve
|
||||||
|
postmaster_address = ${admin_email}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol imap {
|
||||||
|
mail_plugins = $mail_plugins imap_zlib imap_sieve imap_old_stats
|
||||||
|
mail_max_userip_connections = 50
|
||||||
|
imap_idle_notify_interval = 29 mins
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol sieve {
|
||||||
|
plugin {
|
||||||
|
sieve = /var/vmail/sieve/%d/%n.sieve
|
||||||
|
sieve_storage = /var/vmail/sieve/%d/%n/
|
||||||
|
}
|
||||||
|
}
|
56
bundles/dovecot/items.py
Normal file
56
bundles/dovecot/items.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
assert node.has_bundle('postfix')
|
||||||
|
assert node.has_bundle('postgresql')
|
||||||
|
assert node.has_bundle('letsencrypt')
|
||||||
|
|
||||||
|
directories = {
|
||||||
|
'/etc/dovecot/ssl': {},
|
||||||
|
}
|
||||||
|
|
||||||
|
files = {
|
||||||
|
'/etc/dovecot/dovecot.conf': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
'context': {
|
||||||
|
'admin_email': node.metadata.get('mailserver/admin_email'),
|
||||||
|
},
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:'
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actions = {
|
||||||
|
'dovecot_generate_dhparam': {
|
||||||
|
'command': 'openssl dhparam -out /etc/dovecot/ssl/dhparam.pem 2048',
|
||||||
|
'unless': 'test -f /etc/dovecot/ssl/dhparam.pem',
|
||||||
|
'cascade_skip': False,
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:'
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:dovecot:restart',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd = {
|
||||||
|
'dovecot': {
|
||||||
|
'needs': {
|
||||||
|
'action:dovecot_generate_dhparam',
|
||||||
|
'file:/etc/dovecot/dovecot.conf',
|
||||||
|
'file:/etc/dovecot/dovecot-sql.conf',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
25
bundles/dovecot/metadata.py
Normal file
25
bundles/dovecot/metadata.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
from bundlewrap.metadata import atomic
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
'apt': {
|
||||||
|
'packages': {
|
||||||
|
'dovecot-imapd': {},
|
||||||
|
'dovecot-lmtpd': {},
|
||||||
|
'dovecot-managesieved': {},
|
||||||
|
'dovecot-pgsql': {},
|
||||||
|
'dovecot-sieve': {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'letsencrypt': {
|
||||||
|
'reload_after': {
|
||||||
|
'dovecot',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'dovecot': {
|
||||||
|
'database': {
|
||||||
|
'dbname': 'mailserver',
|
||||||
|
'dbuser': 'mailserver',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
33
bundles/mailserver/metadata.py
Normal file
33
bundles/mailserver/metadata.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
database_password = repo.vault.password_for(f'{node.name} db mailserver')
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
'mailserver': {
|
||||||
|
'maildir': '/var/vmail',
|
||||||
|
'database': {
|
||||||
|
'host': '127.0.0.1',
|
||||||
|
'name': 'mailserver',
|
||||||
|
'user': 'mailserver',
|
||||||
|
'password': database_password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfs': {
|
||||||
|
'datasets': {
|
||||||
|
'tank/vmail': {
|
||||||
|
'mountpoint': '/var/vmail',
|
||||||
|
'compression': 'on',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'postgresql': {
|
||||||
|
'roles': {
|
||||||
|
'mailserver': {
|
||||||
|
'password': database_password,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'databases': {
|
||||||
|
'mailserver': {
|
||||||
|
'owner': 'mailserver',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
assert node.has_bundle('postgresql')
|
assert node.has_bundle('postgresql')
|
||||||
|
assert node.has_bundle('dovecot')
|
||||||
|
assert node.has_bundle('letsencrypt')
|
||||||
|
|
||||||
file_options = {
|
file_options = {
|
||||||
'triggers': [
|
'triggers': [
|
||||||
|
@ -19,22 +21,22 @@ files = {
|
||||||
},
|
},
|
||||||
'/etc/postfix/virtual_alias_maps.cf': {
|
'/etc/postfix/virtual_alias_maps.cf': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': node.metadata.get('postfix/database'),
|
'context': node.metadata.get('mailserver/database'),
|
||||||
**file_options,
|
**file_options,
|
||||||
},
|
},
|
||||||
'/etc/postfix/virtual_mailbox_domains.cf': {
|
'/etc/postfix/virtual_mailbox_domains.cf': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': node.metadata.get('postfix/database'),
|
'context': node.metadata.get('mailserver/database'),
|
||||||
**file_options,
|
**file_options,
|
||||||
},
|
},
|
||||||
'/etc/postfix/virtual_mailbox_maps.cf': {
|
'/etc/postfix/virtual_mailbox_maps.cf': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': node.metadata.get('postfix/database'),
|
'context': node.metadata.get('mailserver/database'),
|
||||||
**file_options,
|
**file_options,
|
||||||
},
|
},
|
||||||
'/etc/postfix/virtual_redirects.cf': {
|
'/etc/postfix/virtual_redirects.cf': {
|
||||||
'content_type': 'mako',
|
'content_type': 'mako',
|
||||||
'context': node.metadata.get('postfix/database'),
|
'context': node.metadata.get('mailserver/database'),
|
||||||
**file_options,
|
**file_options,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,13 @@
|
||||||
database_password = repo.vault.password_for(f'{node.name} db mailserver')
|
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
'apt': {
|
'apt': {
|
||||||
'packages': {
|
'packages': {
|
||||||
'postfix': {},
|
'postfix': {},
|
||||||
|
'postfix-pgsql': {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'postfix': {
|
'letsencrypt': {
|
||||||
'database': {
|
'reload_after': {
|
||||||
'host': '127.0.0.1',
|
'postfix',
|
||||||
'name': 'mailserver',
|
},
|
||||||
'user': 'mailserver',
|
|
||||||
'password': database_password,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'postgresql': {
|
|
||||||
'roles': {
|
|
||||||
'mailserver': {
|
|
||||||
'password': database_password,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'databases': {
|
|
||||||
'mailserver': {
|
|
||||||
'owner': 'mailserver',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
if node.has_bundle('zfs'):
|
|
||||||
pkg_apt[postgresql]\
|
|
||||||
.setdefault('needs', [])\
|
|
||||||
.append('zfs_dataset:tank/postgresql')
|
|
||||||
|
|
||||||
for user, config in node.metadata.get('postgresql/roles').items():
|
for user, config in node.metadata.get('postgresql/roles').items():
|
||||||
postgres_roles[user] = {
|
postgres_roles[user] = {
|
||||||
'password': config['password'],
|
'password': config['password'],
|
||||||
|
|
41
bundles/zfs/items.py
Normal file
41
bundles/zfs/items.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
from json import dumps
|
||||||
|
from bundlewrap.metadata import MetadataJSONEncoder
|
||||||
|
|
||||||
|
actions = {
|
||||||
|
'modprobe_zfs': {
|
||||||
|
'command': 'modprobe zfs',
|
||||||
|
'unless': 'lsmod | grep ^zfs',
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:zfs-dkms',
|
||||||
|
},
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:zfs-zed',
|
||||||
|
'pkg_apt:zfsutils-linux',
|
||||||
|
'zfs_dataset:',
|
||||||
|
'zfs_pool:',
|
||||||
|
},
|
||||||
|
'comment': 'If this fails, do a dist-upgrade, reinstall zfs-dkms, reboot',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd = {
|
||||||
|
'zfs-zed': {
|
||||||
|
'needs': {
|
||||||
|
'pkg_apt:zfs-zed'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
zfs_datasets = node.metadata.get('zfs/datasets', {})
|
||||||
|
zfs_pools = {}
|
||||||
|
|
||||||
|
# TRIM
|
||||||
|
for name, attrs in node.metadata.get('zfs/pools', {}).items():
|
||||||
|
zfs_pools[name] = attrs
|
||||||
|
actions[f'pool_{name}_enable_trim'] = {
|
||||||
|
'command': f'zpool set autotrim=on {name}',
|
||||||
|
'unless': f'zpool get autotrim -H -o value {name} | grep -q on',
|
||||||
|
'needs': [
|
||||||
|
f'zfs_pool:{name}'
|
||||||
|
]
|
||||||
|
}
|
55
bundles/zfs/metadata.py
Normal file
55
bundles/zfs/metadata.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#import re
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
'apt': {
|
||||||
|
'packages': {
|
||||||
|
'linux-headers-amd64': {
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:zfs-dkms',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfs-dkms': {
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:zfs-zed',
|
||||||
|
'pkg_apt:zfsutils-linux',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfs-zed': {
|
||||||
|
'needed_by': {
|
||||||
|
'zfs_dataset:',
|
||||||
|
'zfs_pool:',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfsutils-linux': {
|
||||||
|
'needed_by': {
|
||||||
|
'pkg_apt:zfs-zed',
|
||||||
|
'zfs_dataset:',
|
||||||
|
'zfs_pool:',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'parted': {
|
||||||
|
'needed_by': {
|
||||||
|
'zfs_pool:',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfs': {
|
||||||
|
'datasets': {},
|
||||||
|
'pools': {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'zfs/datasets'
|
||||||
|
)
|
||||||
|
def dataset_defaults(metadata):
|
||||||
|
return {
|
||||||
|
'zfs': {
|
||||||
|
'datasets': {
|
||||||
|
name: {
|
||||||
|
'compression': 'lz4',
|
||||||
|
} for name, config in metadata.get('zfs/datasets').items()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
'bundles': [
|
'bundles': [
|
||||||
|
'dovecot',
|
||||||
|
'letsencrypt',
|
||||||
|
'mailserver',
|
||||||
'postfix',
|
'postfix',
|
||||||
'postgresql',
|
'postgresql',
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
'mailserver',
|
'mailserver',
|
||||||
'webserver',
|
'webserver',
|
||||||
],
|
],
|
||||||
|
'bundles': [
|
||||||
|
'zfs',
|
||||||
|
],
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'nginx': {
|
'nginx': {
|
||||||
'vhosts': {
|
'vhosts': {
|
||||||
|
@ -24,5 +27,9 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'mailserver': {
|
||||||
|
'admin_email': 'postmaster@sublimity.de',
|
||||||
|
'hostname': 'mail.sublimity.de',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue