parent
4dfd89dff1
commit
372f5265d7
12 changed files with 448 additions and 0 deletions
|
@ -1,4 +1,6 @@
|
|||
---
|
||||
dovecot_listen: '[2a01:4f8:150:926f::2], 176.9.59.104'
|
||||
|
||||
haproxy_v4: 176.9.59.104
|
||||
haproxy_v6: 2a01:4f8:150:926f::2
|
||||
|
||||
|
|
14
roles/dovecot/handlers/main.yml
Normal file
14
roles/dovecot/handlers/main.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
- name: Reload s6-rc
|
||||
service:
|
||||
name: s6-rc
|
||||
state: reloaded
|
||||
|
||||
- name: Reload Dovecot
|
||||
command: s6-svc -h /run/service/dovecot
|
||||
|
||||
- name: Restart Dovecot
|
||||
command: s6-svc -wR -T 5000 /run/service/dovecot
|
||||
|
||||
- name: Restart Dovecot log
|
||||
command: s6-svc -wR -T 5000 /run/service/dovecot-log
|
161
roles/dovecot/tasks/main.yml
Normal file
161
roles/dovecot/tasks/main.yml
Normal file
|
@ -0,0 +1,161 @@
|
|||
---
|
||||
- name: Install Dovecot
|
||||
package:
|
||||
name: dovecot dovecot-fts-xapian dovecot-pigeonhole
|
||||
state: present
|
||||
|
||||
- name: Set permissions on /usr/local/etc/dovecot
|
||||
file:
|
||||
path: /usr/local/etc/dovecot
|
||||
state: directory
|
||||
owner: acme
|
||||
group: dovecot
|
||||
mode: 0750
|
||||
|
||||
- name: Generate DH parameters
|
||||
command: openssl dhparam -out /usr/local/etc/dovecot/dh.pem 2048
|
||||
args:
|
||||
creates: /usr/local/etc/dovecot/dh.pem
|
||||
|
||||
- name: Add vmail group
|
||||
group:
|
||||
name: vmail
|
||||
gid: 20002
|
||||
|
||||
- name: Add vmail user
|
||||
user:
|
||||
name: vmail
|
||||
uid: 20002
|
||||
group: vmail
|
||||
home: /var/empty
|
||||
create_home: no
|
||||
login_class: daemon
|
||||
password: '*'
|
||||
|
||||
- name: Add vmail ZFS file system
|
||||
zfs:
|
||||
name: '{{ bhyve_pool }}/var/vmail'
|
||||
state: present
|
||||
|
||||
- name: Set permissions on /var/vmail
|
||||
file:
|
||||
path: /var/vmail
|
||||
state: directory
|
||||
owner: vmail
|
||||
group: vmail
|
||||
mode: 0750
|
||||
|
||||
- name: Create /var/spool/postfix
|
||||
file:
|
||||
path: /var/spool/postfix
|
||||
state: directory
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: 0755
|
||||
|
||||
- name: Add /var/log/dovecot to fstab
|
||||
mount:
|
||||
path: /var/log/dovecot
|
||||
src: tmpfs
|
||||
fstype: tmpfs
|
||||
opts: 'rw,size={{ dovecot_log_size }},mode={{ dovecot_log_mode }},uid={{ dovecot_log_uid }},gid={{ dovecot_log_gid }},late'
|
||||
state: mounted
|
||||
|
||||
- name: Create Dovecot service directories
|
||||
file:
|
||||
path: '/etc/s6-rc/service/{{ item }}'
|
||||
state: directory
|
||||
owner: root
|
||||
group: wheel
|
||||
mode: 0755
|
||||
with_items: '{{ dovecot_service_dirs }}'
|
||||
notify:
|
||||
- Reload s6-rc
|
||||
- Restart Dovecot log
|
||||
- Restart Dovecot
|
||||
|
||||
- name: Generate Dovecot service scripts
|
||||
template:
|
||||
dest: '/etc/s6-rc/service/{{ item }}'
|
||||
src: '{{ item }}.j2'
|
||||
mode: 0555
|
||||
owner: root
|
||||
group: wheel
|
||||
with_items: '{{ dovecot_service_scripts }}'
|
||||
notify:
|
||||
- Reload s6-rc
|
||||
- Restart Dovecot log
|
||||
- Restart Dovecot
|
||||
|
||||
- name: Generate Dovecot service configuration
|
||||
copy:
|
||||
dest: '/etc/s6-rc/service/{{ item.name }}'
|
||||
content: '{{ item.content }}'
|
||||
mode: 0444
|
||||
owner: root
|
||||
group: wheel
|
||||
loop_control:
|
||||
label: '{{ item.name }} = {{ item.content }}'
|
||||
notify:
|
||||
- Reload s6-rc
|
||||
- Restart Dovecot log
|
||||
- Restart Dovecot
|
||||
with_items: '{{ dovecot_service_config }}'
|
||||
|
||||
- name: Configure dovecot
|
||||
template:
|
||||
dest: '/usr/local/etc/dovecot/{{ item }}'
|
||||
src: '{{ item }}.j2'
|
||||
mode: 0440
|
||||
owner: dovecot
|
||||
group: wheel
|
||||
with_items:
|
||||
- dovecot.conf
|
||||
- passwd
|
||||
notify:
|
||||
- Reload Dovecot
|
||||
|
||||
- name: Tell acme.sh where to find Dovecot
|
||||
lineinfile:
|
||||
path: /var/db/acme/account.conf
|
||||
create: yes
|
||||
owner: acme
|
||||
group: acme
|
||||
regexp: '^DEPLOY_DOVECOT_PEM_PATH='
|
||||
state: present
|
||||
line: 'DEPLOY_DOVECOT_RELOAD="sudo s6-svc -h /run/service/dovecot"'
|
||||
|
||||
- name: Flush handlers
|
||||
meta: flush_handlers
|
||||
|
||||
- name: Allow acme.sh to reload Dovecot
|
||||
template:
|
||||
dest: /usr/local/etc/sudoers.d/acme_dovecot
|
||||
src: acme_dovecot.j2
|
||||
mode: 0444
|
||||
owner: root
|
||||
group: wheel
|
||||
|
||||
- name: Deploy X.509 certificate to Dovecot
|
||||
command: 'env sudo -Hu acme acme.sh --debug --home /var/db/acme --install-cert --domain {{ ansible_fqdn }} --cert-file /usr/local/etc/dovecot/cert.pem --key-file /usr/local/etc/dovecot/privkey.pem --fullchain-file /usr/local/etc/dovecot/fullchain.pem --reloadcmd "sudo s6-svc -h /run/service/dovecot"'
|
||||
args:
|
||||
creates: /usr/local/etc/dovecot/fullchain.pem
|
||||
notify:
|
||||
- Reload Dovecot
|
||||
|
||||
- name: Start Dovecot
|
||||
command: fdmove -c 2 1 s6-rc -u -v 2 -t 15000 change dovecot
|
||||
register: change
|
||||
changed_when: change.stdout | length > 0
|
||||
|
||||
- name: Enable Dovecot
|
||||
lineinfile:
|
||||
path: /etc/s6-rc/service/enabled/contents
|
||||
regexp: "^dovecot$"
|
||||
line: dovecot
|
||||
state: present
|
||||
notify:
|
||||
- Reload s6-rc
|
||||
|
||||
- name: Flush handlers (again)
|
||||
meta: flush_handlers
|
1
roles/dovecot/templates/acme_dovecot.j2
Normal file
1
roles/dovecot/templates/acme_dovecot.j2
Normal file
|
@ -0,0 +1 @@
|
|||
acme ALL=NOPASSWD:/usr/local/bin/s6-svc -h /run/service/dovecot
|
13
roles/dovecot/templates/dovecot-log/finish.j2
Normal file
13
roles/dovecot/templates/dovecot-log/finish.j2
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/local/bin/execlineb -S2
|
||||
# {{ ansible_managed }}
|
||||
|
||||
s6-envdir ./env
|
||||
multisubstitute {
|
||||
importas -i -u NAME NAME
|
||||
}
|
||||
|
||||
fdmove -c 1 2
|
||||
ifelse { test "${1}" -eq 0 } {
|
||||
echo "${NAME}-log: Stopped."
|
||||
}
|
||||
echo "${NAME}-log: Failed with exit status (${1}, ${2})."
|
23
roles/dovecot/templates/dovecot-log/run.j2
Normal file
23
roles/dovecot/templates/dovecot-log/run.j2
Normal file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/local/bin/execlineb
|
||||
# {{ ansible_managed }}
|
||||
|
||||
s6-envdir ./env
|
||||
multisubstitute {
|
||||
importas -i -u NAME NAME
|
||||
importas -i -u USER USER
|
||||
importas -i -u GROUP GROUP
|
||||
importas -i -u MODE MODE
|
||||
importas -i -u DIR DIR
|
||||
}
|
||||
|
||||
foreground { fdmove -c 1 2 echo "${NAME} log: Starting." }
|
||||
|
||||
ifelse -n { install -d -o "${USER}" -g "${GROUP}" -m "${MODE}" "$DIR" } {
|
||||
foreground { fdmove -c 1 2 echo "${NAME} log: Failed to create logging directory." }
|
||||
false
|
||||
}
|
||||
|
||||
fdmove -c 2 1
|
||||
|
||||
s6-envuidgid $USER
|
||||
s6-log -d 3 T $DIR
|
124
roles/dovecot/templates/dovecot.conf.j2
Normal file
124
roles/dovecot/templates/dovecot.conf.j2
Normal file
|
@ -0,0 +1,124 @@
|
|||
# {{ ansible_managed }}
|
||||
|
||||
base_dir = /var/run/dovecot
|
||||
import_environment = TZ LC_CTYPE LC_TIME LC_COLLATE LC_NUMERIC LC_MONETARY
|
||||
log_path = /dev/stderr
|
||||
|
||||
default_vsz_limit = 2 G
|
||||
verbose_proctitle = yes
|
||||
doveadm_worker_count = 8
|
||||
|
||||
mail_location = mdbox:~/mdbox
|
||||
mail_plugins = fts fts_xapian
|
||||
|
||||
listen = {{ dovecot_listen }}
|
||||
|
||||
ssl = required
|
||||
ssl_cert = </usr/local/etc/dovecot/fullchain.pem
|
||||
ssl_key = </usr/local/etc/dovecot/privkey.pem
|
||||
ssl_cipher_list = 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA'
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_options = no_compression
|
||||
ssl_dh = </usr/local/etc/dovecot/dh.pem
|
||||
|
||||
|
||||
plugin {
|
||||
fts = xapian
|
||||
fts_xapian = partial=3 full=20 attachments=0 verbose=0
|
||||
fts_autoindex = yes
|
||||
fts_enforced = yes
|
||||
fts_autoindex_exclude = \Trash
|
||||
}
|
||||
|
||||
plugin {
|
||||
sieve = ~/.dovecot.sieve
|
||||
sieve_dir = ~/sieve
|
||||
sieve_extensions = +vacation-seconds
|
||||
sieve_vacation_min_period = 1d
|
||||
sieve_vacation_default_period = 1d
|
||||
sieve_vacation_max_period = 30d
|
||||
}
|
||||
|
||||
namespace inbox {
|
||||
inbox = yes
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
args = /usr/local/etc/dovecot/passwd
|
||||
}
|
||||
|
||||
userdb {
|
||||
driver = passwd-file
|
||||
args = /usr/local/etc/dovecot/passwd
|
||||
default_fields = uid=vmail gid=vmail home=/var/vmail/%d/%n
|
||||
}
|
||||
|
||||
protocols = imap lmtp sieve
|
||||
|
||||
auth_mechanisms = plain login
|
||||
auth_default_realm = %{hostname}
|
||||
service auth {
|
||||
unix_listener /var/spool/postfix/private/dovecot-auth {
|
||||
user = postfix
|
||||
group = postfix
|
||||
mode = 0600
|
||||
}
|
||||
}
|
||||
|
||||
service lmtp {
|
||||
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||
user = postfix
|
||||
group = postfix
|
||||
mode = 0600
|
||||
}
|
||||
}
|
||||
|
||||
service managesieve-login {
|
||||
inet_listener sieve {
|
||||
port = 4190
|
||||
}
|
||||
|
||||
inet_listener sieve_deprecated {
|
||||
port = 2000
|
||||
}
|
||||
|
||||
service_count = 1
|
||||
}
|
||||
|
||||
service imap-login {
|
||||
inet_listener imap {
|
||||
port = 143
|
||||
}
|
||||
|
||||
inet_listener imaps {
|
||||
port = 993
|
||||
ssl = yes
|
||||
}
|
||||
|
||||
process_limit = 128
|
||||
}
|
||||
|
||||
protocol lmtp {
|
||||
mail_plugins = $mail_plugins sieve
|
||||
}
|
18
roles/dovecot/templates/dovecot/data/check.j2
Normal file
18
roles/dovecot/templates/dovecot/data/check.j2
Normal file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/local/bin/execlineb -P
|
||||
# {{ ansible_managed }}
|
||||
|
||||
s6-envdir ./env
|
||||
multisubstitute {
|
||||
importas -i -u NAME NAME
|
||||
}
|
||||
|
||||
ifelse {
|
||||
redirfd -w 1 /dev/null
|
||||
fdmove -c 2 1
|
||||
doveadm who
|
||||
} {
|
||||
foreground { fdmove -c 1 2 echo "${NAME}: Ready." }
|
||||
true
|
||||
}
|
||||
foreground { fdmove -c 1 2 echo "${NAME}: Poll." }
|
||||
false
|
13
roles/dovecot/templates/dovecot/finish.j2
Normal file
13
roles/dovecot/templates/dovecot/finish.j2
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/local/bin/execlineb -S2
|
||||
# {{ ansible_managed }}
|
||||
|
||||
s6-envdir ./env
|
||||
multisubstitute {
|
||||
importas -i -u NAME NAME
|
||||
}
|
||||
|
||||
fdmove -c 1 2
|
||||
ifelse { test "${1}" -eq 0 } {
|
||||
echo "${NAME}: Stopped."
|
||||
}
|
||||
echo "${NAME}: Failed with exit status (${1}, ${2})."
|
13
roles/dovecot/templates/dovecot/run.j2
Normal file
13
roles/dovecot/templates/dovecot/run.j2
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/local/bin/execlineb -P
|
||||
# {{ ansible_managed }}
|
||||
|
||||
s6-envdir ./env
|
||||
multisubstitute {
|
||||
importas -i -u NAME NAME
|
||||
}
|
||||
|
||||
foreground { fdmove -c 1 2 echo "${NAME}: Starting." }
|
||||
s6-notifyoncheck -d -w 100 -n 70
|
||||
|
||||
fdmove -c 2 1
|
||||
dovecot -F
|
5
roles/dovecot/templates/passwd.j2
Normal file
5
roles/dovecot/templates/passwd.j2
Normal file
|
@ -0,0 +1,5 @@
|
|||
{% for domain, users in dovecot_users.items() %}
|
||||
{% for name, password in users.items() %}
|
||||
{{ [[name, domain] | join("@"), password, 20002, 20002, ["/var/vmail", domain, name] | join("/"), ""] | join(":") }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
61
roles/dovecot/vars/main.yml
Normal file
61
roles/dovecot/vars/main.yml
Normal file
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
dovecot_log_size: '32m'
|
||||
dovecot_log_mode: '750'
|
||||
dovecot_log_uid: '20000'
|
||||
dovecot_log_gid: '20000'
|
||||
|
||||
dovecot_service_dirs:
|
||||
- dovecot
|
||||
- dovecot/env
|
||||
- dovecot/data
|
||||
- dovecot-log
|
||||
- dovecot-log/env
|
||||
|
||||
dovecot_service_scripts:
|
||||
- dovecot/run
|
||||
- dovecot/finish
|
||||
- dovecot/data/check
|
||||
- dovecot-log/run
|
||||
- dovecot-log/finish
|
||||
|
||||
dovecot_service_config:
|
||||
- name: dovecot/type
|
||||
content: longrun
|
||||
- name: dovecot/producer-for
|
||||
content: dovecot-log
|
||||
- name: dovecot/notification-fd
|
||||
content: 3
|
||||
- name: dovecot/env/NAME
|
||||
content: dovecot
|
||||
- name: dovecot/env/PATH
|
||||
content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin
|
||||
|
||||
- name: dovecot-log/type
|
||||
content: longrun
|
||||
- name: dovecot-log/notification-fd
|
||||
content: 3
|
||||
- name: dovecot-log/consumer-for
|
||||
content: dovecot
|
||||
- name: dovecot-log/env/NAME
|
||||
content: dovecot
|
||||
- name: dovecot-log/env/PATH
|
||||
content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin
|
||||
- name: dovecot-log/env/MODE
|
||||
content: '750'
|
||||
- name: dovecot-log/env/USER
|
||||
content: s6-log
|
||||
- name: dovecot-log/env/GROUP
|
||||
content: s6-log
|
||||
- name: dovecot-log/env/DIR
|
||||
content: /var/log/dovecot
|
||||
|
||||
dovecot_config:
|
||||
- name: maillog_file
|
||||
value: /var/log/dovecot/fifo
|
||||
state: present
|
||||
- name: inet_protocols
|
||||
value: '{{ dovecot_inet_protocols | default("ipv6, ipv4") }}'
|
||||
state: present
|
||||
- name: inet_interfaces
|
||||
value: '{{ dovecot_inet_interfaces }}'
|
||||
state: present
|
Loading…
Reference in a new issue