Update Stalwart mailserver to 0.7.3 from 0.6.0.
This commit is contained in:
parent
ceef41b7f5
commit
b544f9a78d
14 changed files with 122 additions and 115 deletions
|
@ -45,11 +45,3 @@ After that, you can create a root cronjob to run this playbook without requiring
|
||||||
```
|
```
|
||||||
|
|
||||||
Here we leave `selected_projects` empty to backup all projects.
|
Here we leave `selected_projects` empty to backup all projects.
|
||||||
|
|
||||||
|
|
||||||
## Mailserver
|
|
||||||
When starting the container for the first time, run the initial setup:
|
|
||||||
```
|
|
||||||
docker exec -it mailserver /bin/sh /usr/local/bin/configure.sh
|
|
||||||
```
|
|
||||||
After that, re-run the setup tasks because `configure.sh` overrides the config files.
|
|
||||||
|
|
3
env.yml
3
env.yml
|
@ -95,7 +95,7 @@ ports:
|
||||||
mailserver_smtp: 1025
|
mailserver_smtp: 1025
|
||||||
mailserver_smtps: 1465
|
mailserver_smtps: 1465
|
||||||
mailserver_imaps: 1993
|
mailserver_imaps: 1993
|
||||||
mailserver_jmap: 1443
|
mailserver_https: 1443
|
||||||
postgres: 5432
|
postgres: 5432
|
||||||
searxng: 8083
|
searxng: 8083
|
||||||
stump: 10801
|
stump: 10801
|
||||||
|
@ -139,7 +139,6 @@ volumes:
|
||||||
etebase_datadir: /mnt/etebasedata
|
etebase_datadir: /mnt/etebasedata
|
||||||
hedgedoc_uploadsdir: /mnt/hedgedocuploads
|
hedgedoc_uploadsdir: /mnt/hedgedocuploads
|
||||||
lldap_datadir: /mnt/lldapdata
|
lldap_datadir: /mnt/lldapdata
|
||||||
mailserver_datadir: /mnt/mailserverdata
|
|
||||||
mailserver_tls_certificate_file: "/etc/letsencrypt/live/mail.{{ domain }}/fullchain.pem"
|
mailserver_tls_certificate_file: "/etc/letsencrypt/live/mail.{{ domain }}/fullchain.pem"
|
||||||
mailserver_tls_certificate_key_file: "/etc/letsencrypt/live/mail.{{ domain }}/privkey.pem"
|
mailserver_tls_certificate_key_file: "/etc/letsencrypt/live/mail.{{ domain }}/privkey.pem"
|
||||||
postgres_datadir: /mnt/postgresdata
|
postgres_datadir: /mnt/postgresdata
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
- name: "Backup PostgreSQL stalwart database & {{ volumes['mailserver_datadir'] }} directory"
|
- name: "Backup PostgreSQL stalwart database"
|
||||||
shell: >
|
shell: >
|
||||||
docker exec postgres
|
docker exec postgres
|
||||||
pg_dump -c {{ role_name }} |
|
pg_dump -c {{ role_name }} |
|
||||||
borg create
|
borg create
|
||||||
--compression lzma
|
--compression lzma
|
||||||
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
"{{ borg_repodir }}::{{ role_name }}-{now:%Y-%m-%d_%H-%M-%S}"
|
||||||
"{{ volumes['mailserver_datadir'] }}"
|
|
||||||
-
|
-
|
||||||
--stdin-name dump_{{ role_name }}.sql
|
--stdin-name dump_{{ role_name }}.sql
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -6,24 +6,16 @@
|
||||||
- absent
|
- absent
|
||||||
- directory
|
- directory
|
||||||
|
|
||||||
- name: Template configuration files to project directory
|
- name: Template docker-compose.yaml & config.toml to project directory
|
||||||
template:
|
template:
|
||||||
src: "{{ item.src }}"
|
src: "{{ item }}"
|
||||||
dest: "{{ project_dir }}/{{ item.path }}"
|
dest: "{{ project_dir }}/{{ item }}"
|
||||||
owner: "{{ host_uid }}"
|
owner: "{{ host_uid }}"
|
||||||
group: "{{ users['mailserver'] + uid_shift }}"
|
group: "{{ users['mailserver'] + uid_shift }}"
|
||||||
mode: '640'
|
mode: '660'
|
||||||
with_filetree: ../templates/
|
loop:
|
||||||
when: item.state == 'file'
|
- docker-compose.yaml
|
||||||
become: true
|
- config.toml
|
||||||
|
|
||||||
- name: "Create (if not exists) directory {{ volumes['mailserver_datadir'] }} & set permissions"
|
|
||||||
file:
|
|
||||||
path: "{{ volumes['mailserver_datadir'] }}"
|
|
||||||
state: directory
|
|
||||||
owner: "{{ users['mailserver'] + uid_shift }}"
|
|
||||||
group: "{{ users['mailserver'] + uid_shift }}"
|
|
||||||
mode: '700'
|
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Set limited permissions on certificate directories
|
- name: Set limited permissions on certificate directories
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
[server]
|
|
||||||
hostname = "%{HOST}%"
|
|
||||||
max-connections = 8192
|
|
||||||
|
|
||||||
[server.security]
|
|
||||||
fail2ban = "100/1d"
|
|
||||||
|
|
||||||
[server.run-as]
|
|
||||||
user = "mail"
|
|
||||||
group = "mail"
|
|
|
@ -1,10 +0,0 @@
|
||||||
[server.tls]
|
|
||||||
enable = true
|
|
||||||
implicit = true
|
|
||||||
timeout = "1m"
|
|
||||||
certificate = "default"
|
|
||||||
ignore-client-order = true
|
|
||||||
|
|
||||||
[certificate."default"]
|
|
||||||
cert = "file:///etc/fullchain.pem"
|
|
||||||
private-key = "file:///etc/privkey.pem"
|
|
|
@ -1,3 +0,0 @@
|
||||||
[global.tracing]
|
|
||||||
method = "stdout"
|
|
||||||
level = "debug"
|
|
105
roles/mailserver/templates/config.toml
Normal file
105
roles/mailserver/templates/config.toml
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
authentication.fallback-admin.secret = "{{ mailserver_secrets['admin_secret'] }}"
|
||||||
|
authentication.fallback-admin.user = "{{ mailserver_secrets['admin_user'] }}"
|
||||||
|
cluster.node-id = 1
|
||||||
|
lookup.default.hostname = "mail.{{ domain }}"
|
||||||
|
|
||||||
|
|
||||||
|
# Server settings
|
||||||
|
server.http.permissive-cors = false
|
||||||
|
server.http.url = "protocol + '://' + key_get('default', 'hostname') + ':' + local_port"
|
||||||
|
server.http.use-x-forwarded = true
|
||||||
|
server.max-connections = 8192
|
||||||
|
server.run-as.group = "mail"
|
||||||
|
server.run-as.user = "mail"
|
||||||
|
server.socket.backlog = 1024
|
||||||
|
server.socket.nodelay = true
|
||||||
|
server.socket.reuse-addr = true
|
||||||
|
server.socket.reuse-port = true
|
||||||
|
|
||||||
|
|
||||||
|
# Listeners
|
||||||
|
server.listener.https.bind = "[::]:443"
|
||||||
|
server.listener.https.protocol = "http"
|
||||||
|
server.listener.https.tls.implicit = true
|
||||||
|
server.listener.imaptls.bind = "[::]:993"
|
||||||
|
server.listener.imaptls.protocol = "imap"
|
||||||
|
server.listener.imaptls.tls.implicit = true
|
||||||
|
server.listener.smtp.bind = "[::]:25"
|
||||||
|
server.listener.smtp.protocol = "smtp"
|
||||||
|
server.listener.smtp.tls.implicit = false
|
||||||
|
server.listener.submissions.bind = "[::]:465"
|
||||||
|
server.listener.submissions.protocol = "smtp"
|
||||||
|
server.listener.submissions.tls.implicit = true
|
||||||
|
|
||||||
|
|
||||||
|
# Certificate settings
|
||||||
|
certificate."default".cert = "%{file:///etc/fullchain.pem}%"
|
||||||
|
certificate."default".default = true
|
||||||
|
certificate."default".private-key = "%{file:///etc/privkey.pem}%"
|
||||||
|
|
||||||
|
|
||||||
|
# Storage settings
|
||||||
|
storage.blob = "postgresql"
|
||||||
|
storage.data = "postgresql"
|
||||||
|
storage.directory = "ldap"
|
||||||
|
storage.fts = "postgresql"
|
||||||
|
storage.lookup = "postgresql"
|
||||||
|
|
||||||
|
|
||||||
|
# Directory settings
|
||||||
|
# Note: 'directory.ldap.attributes.secret' must not be defined
|
||||||
|
# to correctly disable OAuth, if the LDAP server doesn't expose passwords hashes.
|
||||||
|
directory.ldap.attributes.class = "objectClass"
|
||||||
|
directory.ldap.attributes.description = "distinguishedName"
|
||||||
|
directory.ldap.attributes.email = "mail"
|
||||||
|
directory.ldap.attributes.email-alias = "mailAlias"
|
||||||
|
directory.ldap.attributes.groups = "memberOf"
|
||||||
|
directory.ldap.attributes.name = "uid"
|
||||||
|
directory.ldap.attributes.quota = "diskQuota"
|
||||||
|
directory.ldap.base-dn = "{{ ldap_base_dn }}"
|
||||||
|
directory.ldap.bind.auth.dn = "uid=?,ou=people,{{ ldap_base_dn }}"
|
||||||
|
directory.ldap.bind.auth.enable = true
|
||||||
|
directory.ldap.bind.dn = "{{ mailserver_secrets['ldap_user'] }}"
|
||||||
|
directory.ldap.bind.secret = "{{ mailserver_secrets['ldap_password'] }}"
|
||||||
|
directory.ldap.cache.entries = 500
|
||||||
|
directory.ldap.cache.ttl.negative = "10m"
|
||||||
|
directory.ldap.cache.ttl.positive = "1h"
|
||||||
|
directory.ldap.filter.domains = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(|(mail=*@?)(mailAlias=*@?)))"
|
||||||
|
directory.ldap.filter.email = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(|(mail=?)(mailAlias=?)(mailList=?))(mail=*@{{ domain }}))"
|
||||||
|
directory.ldap.filter.expand = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(mailList=?))"
|
||||||
|
directory.ldap.filter.name = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(uid=?))"
|
||||||
|
directory.ldap.filter.verify = "(&(|(objectClass=posixAccount)(objectClass=posixGroup))(|(mail=*?*)(mailAlias=*?*)))"
|
||||||
|
directory.ldap.timeout = "15s"
|
||||||
|
directory.ldap.tls.allow-invalid-certs = false
|
||||||
|
directory.ldap.tls.enable = false
|
||||||
|
directory.ldap.type = "ldap"
|
||||||
|
directory.ldap.url = "ldap://lldap:3890"
|
||||||
|
|
||||||
|
|
||||||
|
# Store settings
|
||||||
|
store.postgresql.compression = "lz4"
|
||||||
|
store.postgresql.database = "stalwart"
|
||||||
|
store.postgresql.host = "postgres.{{ domain }}"
|
||||||
|
store.postgresql.password = "{{ mailserver_secrets['postgres_password'] }}"
|
||||||
|
store.postgresql.pool.max-connections = 10
|
||||||
|
store.postgresql.port = "5432"
|
||||||
|
store.postgresql.purge.frequency = "0 3 *"
|
||||||
|
store.postgresql.query.domains = "SELECT 1 FROM emails WHERE address LIKE '%@' || $1 LIMIT 1"
|
||||||
|
store.postgresql.query.emails = "SELECT address FROM emails WHERE name = $1 AND type != 'list' ORDER BY type DESC, address ASC"
|
||||||
|
store.postgresql.query.expand = "SELECT p.address FROM emails AS p JOIN emails AS l ON p.name = l.name WHERE p.type = 'primary' AND l.address = $1 AND l.type = 'list' ORDER BY p.address LIMIT 50"
|
||||||
|
store.postgresql.query.members = "SELECT member_of FROM group_members WHERE name = $1"
|
||||||
|
store.postgresql.query.name = "SELECT name, type, secret, description, quota FROM accounts WHERE name = $1 AND active = true"
|
||||||
|
store.postgresql.query.recipients = "SELECT name FROM emails WHERE address = $1 ORDER BY name ASC"
|
||||||
|
store.postgresql.query.verify = "SELECT address FROM emails WHERE address LIKE '%' || $1 || '%' AND type = 'primary' ORDER BY address LIMIT 5"
|
||||||
|
store.postgresql.timeout = "15s"
|
||||||
|
store.postgresql.tls.allow-invalid-certs = true
|
||||||
|
store.postgresql.tls.enable = true
|
||||||
|
store.postgresql.type = "postgresql"
|
||||||
|
store.postgresql.user = "{{ mailserver_secrets['postgres_user'] }}"
|
||||||
|
|
||||||
|
|
||||||
|
# Logs settings
|
||||||
|
tracer.stdout.ansi = true
|
||||||
|
tracer.stdout.enable = true
|
||||||
|
tracer.stdout.level = "debug"
|
||||||
|
tracer.stdout.type = "stdout"
|
|
@ -1,28 +0,0 @@
|
||||||
[directory."ldap"]
|
|
||||||
type = "ldap"
|
|
||||||
address = "ldap://lldap:3890"
|
|
||||||
base-dn = "{{ ldap_base_dn }}"
|
|
||||||
timeout = "30s"
|
|
||||||
tls.enable = false
|
|
||||||
|
|
||||||
[directory."ldap".bind]
|
|
||||||
dn = "{{ mailserver_secrets['ldap_user'] }}"
|
|
||||||
secret = "{{ mailserver_secrets['ldap_password'] }}"
|
|
||||||
|
|
||||||
[directory."ldap".bind.auth]
|
|
||||||
enable = true
|
|
||||||
dn = "uid=?,ou=people,{{ ldap_base_dn }}"
|
|
||||||
|
|
||||||
[directory."ldap".filter]
|
|
||||||
name = "(&(|(objectClass=person)(objectClass=posixGroup))(uid=?))"
|
|
||||||
email = "(&(|(objectClass=person)(objectClass=posixGroup))(|(mail=?)(mailAlias=?)(mailList=?))(mail=*@{{ domain }}))"
|
|
||||||
verify = "(&(|(objectClass=person)(objectClass=posixGroup))(|(mail=*?*)(mailAlias=*?*)))"
|
|
||||||
expand = "(&(|(objectClass=person)(objectClass=posixGroup))(mailList=?))"
|
|
||||||
domains = "(&(|(objectClass=person)(objectClass=posixGroup))(|(mail=*@?)(mailAlias=*@?)))"
|
|
||||||
|
|
||||||
[directory."ldap".attributes]
|
|
||||||
name = "uid"
|
|
||||||
type = "objectClass"
|
|
||||||
description = ["distinguishedName"]
|
|
||||||
email = "mail"
|
|
||||||
email-alias = "mailAlias"
|
|
|
@ -1,6 +1,6 @@
|
||||||
services:
|
services:
|
||||||
mailserver:
|
mailserver:
|
||||||
image: docker.io/stalwartlabs/mail-server:v0.6.0
|
image: docker.io/stalwartlabs/mail-server:v0.7.3
|
||||||
container_name: mailserver
|
container_name: mailserver
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
|
@ -9,17 +9,11 @@ services:
|
||||||
- "{{ ports['mailserver_smtp'] }}:25"
|
- "{{ ports['mailserver_smtp'] }}:25"
|
||||||
- {{ ports['mailserver_smtps'] }}:465
|
- {{ ports['mailserver_smtps'] }}:465
|
||||||
- {{ ports['mailserver_imaps'] }}:993
|
- {{ ports['mailserver_imaps'] }}:993
|
||||||
- {{ ports['mailserver_jmap'] }}:443
|
- {{ ports['mailserver_https'] }}:443
|
||||||
volumes:
|
volumes:
|
||||||
- {{ volumes['mailserver_tls_certificate_file'] }}:/etc/fullchain.pem
|
- {{ volumes['mailserver_tls_certificate_file'] }}:/etc/fullchain.pem
|
||||||
- {{ volumes['mailserver_tls_certificate_key_file'] }}:/etc/privkey.pem
|
- {{ volumes['mailserver_tls_certificate_key_file'] }}:/etc/privkey.pem
|
||||||
- {{ volumes['mailserver_datadir' ] }}:/opt/stalwart-mail
|
- ./config.toml:/opt/stalwart-mail/etc/config.toml
|
||||||
- ./common-server.toml:/opt/stalwart-mail/etc/common/server.toml
|
|
||||||
- ./common-tls.toml:/opt/stalwart-mail/etc/common/tls.toml
|
|
||||||
- ./common-tracing.toml:/opt/stalwart-mail/etc/common/tracing.toml
|
|
||||||
- ./directory-ldap.toml:/opt/stalwart-mail/etc/directory/ldap.toml
|
|
||||||
- ./store-postgresql.toml:/opt/stalwart-mail/etc/store/postgresql.toml
|
|
||||||
- ./smtp-listener.toml:/opt/stalwart-mail/etc/smtp/listener.toml
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
mailserver:
|
mailserver:
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
[server.listener."smtp"]
|
|
||||||
bind = ["[::]:25"]
|
|
||||||
protocol = "smtp"
|
|
||||||
tls.implicit = false
|
|
||||||
|
|
||||||
[server.listener."submissions"]
|
|
||||||
bind = ["[::]:465"]
|
|
||||||
protocol = "smtp"
|
|
||||||
tls.implicit = true
|
|
|
@ -1,17 +0,0 @@
|
||||||
[store."postgresql"]
|
|
||||||
type = "postgresql"
|
|
||||||
host = "postgres.{{ domain }}"
|
|
||||||
port = 5432
|
|
||||||
database = "stalwart"
|
|
||||||
user = "{{ mailserver_secrets['postgres_user'] }}"
|
|
||||||
password = "{{ mailserver_secrets['postgres_password'] }}"
|
|
||||||
|
|
||||||
[store."postgresql".timeout]
|
|
||||||
connect = "15s"
|
|
||||||
|
|
||||||
[store."postgresql".tls]
|
|
||||||
enable = false
|
|
||||||
allow-invalid-certs = false
|
|
||||||
|
|
||||||
[store."postgresql".purge]
|
|
||||||
frequency = "0 3 *"
|
|
|
@ -2,10 +2,10 @@ server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
listen [::]:443 ssl;
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
server_name jmap.{{ domain }};
|
server_name mail.{{ domain }};
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass https://127.0.0.1:{{ ports['mailserver_jmap'] }};
|
proxy_pass https://127.0.0.1:{{ ports['mailserver_https'] }};
|
||||||
|
|
||||||
include /etc/nginx/snippets/websocket.conf;
|
include /etc/nginx/snippets/websocket.conf;
|
||||||
include /etc/nginx/snippets/proxy.conf;
|
include /etc/nginx/snippets/proxy.conf;
|
|
@ -36,6 +36,9 @@ lldap_secrets:
|
||||||
postgres_password:
|
postgres_password:
|
||||||
|
|
||||||
mailserver_secrets:
|
mailserver_secrets:
|
||||||
|
admin_user:
|
||||||
|
# Hash obtained with openssl passwd -6
|
||||||
|
admin_secret:
|
||||||
ldap_user:
|
ldap_user:
|
||||||
ldap_password:
|
ldap_password:
|
||||||
postgres_user:
|
postgres_user:
|
||||||
|
|
Loading…
Reference in a new issue