summaryrefslogtreecommitdiff
path: root/roles/mox/templates
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2026-08-13 16:35:47 +0100
committerJoe Carstairs <me@joeac.net>2026-08-13 16:35:47 +0100
commit9f2ebc2cce3af0e685677c23f2098c115e034adf (patch)
treebc6609cf851ee3f0a4f572d762b4ea35a34610f6 /roles/mox/templates
parentf31e65c51681823ade14abad87c742101a1b823d (diff)
move ansible/ dir to root
Diffstat (limited to 'roles/mox/templates')
-rw-r--r--roles/mox/templates/dnssec.conf9
-rw-r--r--roles/mox/templates/domains.conf98
-rw-r--r--roles/mox/templates/mox.conf62
-rw-r--r--roles/mox/templates/openrc/mox77
4 files changed, 246 insertions, 0 deletions
diff --git a/roles/mox/templates/dnssec.conf b/roles/mox/templates/dnssec.conf
new file mode 100644
index 0000000..de6bf8c
--- /dev/null
+++ b/roles/mox/templates/dnssec.conf
@@ -0,0 +1,9 @@
+server:
+ qname-minimisation: yes
+ interface: 0.0.0.0
+ interface: ::0
+ access-control: {{ router.lan.ipv4 }} allow
+ access-control: {{ router.lan.ipv6 }} allow
+
+remote-control:
+ control-enable: yes
diff --git a/roles/mox/templates/domains.conf b/roles/mox/templates/domains.conf
new file mode 100644
index 0000000..bccfab3
--- /dev/null
+++ b/roles/mox/templates/domains.conf
@@ -0,0 +1,98 @@
+Domains:
+ mail.joeac.net:
+ ClientSettingsDomain: mail.joeac.net
+ LocalpartCatchallSeparator: +
+ DKIM:
+ Selectors:
+ 2026a:
+ Expiration: 72h
+ PrivateKeyFile: dkim/2026a._domainkey.mail.joeac.net.20260705T163220.rsa2048.privatekey.pkcs8.pem
+ 2026b:
+ Expiration: 72h
+ PrivateKeyFile: dkim/2026b._domainkey.mail.joeac.net.20260705T163220.rsa2048.privatekey.pkcs8.pem
+ Sign:
+ - 2026a
+ DMARC:
+ Localpart: dmarcreports
+ Account: me
+ Mailbox: DMARC
+ MTASTS:
+ PolicyID: 20260705T153220
+ Mode: enforce
+ MaxAge: 24h0m0s
+ MX:
+ - mail.joeac.net
+ TLSRPT:
+ Localpart: tlsreports
+ Account: me
+ Mailbox: TLSRPT
+
+Accounts:
+{% for account in email_accounts %}
+ {{ account.name }}:
+ Domain: mail.joeac.net
+ Destinations:
+ {{ account.name }}@mail.joeac.net: nil
+ SubjectPass:
+ Period: 12h0m0s
+ RejectsMailbox: Rejects
+ AutomaticJunkFlags:
+ Enabled: true
+ JunkMailboxRegexp: ^(junk|spam)
+ NeutralMailboxRegexp: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects)
+ JunkFilter:
+ Threshold: 0.950000
+ Params:
+ Onegrams: true
+ MaxPower: 0.010000
+ TopWords: 10
+ IgnoreWords: 0.100000
+ RareWords: 2
+ NoCustomPassword: true
+{% endfor %}
+
+MonitorDNSBLs:
+ - zen.spamhaus.org
+ - bl.spamcop.net
+
+WebHandlers:
+
+{% for subdomain in ( subdomains | selectattr("mox_handler", "eq", "static") ) %}
+ -
+ LogName: {{ subdomain.name }}.joeac.net
+ PathRegexp: ^/
+ Compress: true
+ Domain: {{ subdomain.full_domain }}
+ WebStatic:
+ Root: {{ services[subdomain.service].root }}
+ ListFiles: {{ "directory_listing" in services[subdomain.service] and services[subdomain.service].directory_listing | lower }}
+ ContinueNotFound: true
+
+ -
+ LogName: {{ subdomain.name }}.joeac.net
+ PathRegexp: ^.*[^(.html)]$
+ Compress: true
+ Domain: {{ subdomain.full_domain }}
+ WebRedirect:
+ OrigPathRegexp: ^(.*[^(.html)])$
+ ReplacePath: $1/index.html
+
+ -
+ LogName: {{ subdomain.name }}.joeac.net
+ PathRegexp: ^/.*/index.html$
+ Compress: true
+ Domain: {{ subdomain.full_domain }}
+ WebRedirect:
+ OrigPathRegexp: ^(.*)/index.html$
+ ReplacePath: $1.html
+{% endfor %}
+
+{% for subdomain in ( subdomains | selectattr("mox_handler", "eq", "forward") ) %}
+ -
+ LogName: {{ subdomain.name }}.joeac.net
+ PathRegexp: ^/
+ Compress: true
+ Domain: {{ subdomain.full_domain }}
+ WebForward:
+ URL: http://{{ hostvars[services[subdomain.service].host].ansible_host }}:{{ services[subdomain.service].port }}
+{% endfor %}
diff --git a/roles/mox/templates/mox.conf b/roles/mox/templates/mox.conf
new file mode 100644
index 0000000..8cafc25
--- /dev/null
+++ b/roles/mox/templates/mox.conf
@@ -0,0 +1,62 @@
+DataDir: ../data
+LogLevel: debug
+User: mox
+Hostname: mail.joeac.net
+AdminPasswordFile: adminpasswd
+CheckUpdates: true
+Listeners:
+ internal:
+ IPs:
+ - 127.0.0.1
+ - ::1
+ Hostname: localhost
+ MetricsHTTP:
+ Enabled: true
+ public:
+ IPs:
+{% for interface in ansible_facts.interfaces | reject("eq", "lo") %}
+ - {{ ansible_facts[interface].ipv4.address }}
+{% for ipv6 in ansible_facts[interface].ipv6 | selectattr("scope", "eq", "global") %}
+ - {{ ipv6.address }}
+{% endfor %}
+{% endfor %}
+ NATIPs:
+ - {{ router.wan.ipv4 }}
+ - {{ ansible_facts.default_ipv6.address }}
+ AccountHTTPS:
+ Enabled: true
+ AdminHTTPS:
+ Enabled: true
+ WebmailHTTPS:
+ Enabled: true
+ WebAPIHTTPS:
+ Enabled: true
+ AutoconfigHTTPS:
+ Enabled: true
+ MTASTSHTTPS:
+ Enabled: true
+ WebserverHTTP:
+ Enabled: true
+ WebserverHTTPS:
+ Enabled: true
+ TLS:
+ KeyCerts:
+{% for subdomain in ( subdomains | map(attribute='name') ) %}
+ -
+ CertFile: /etc/letsencrypt/live/{{ subdomain }}.joeac.net/fullchain.pem
+ KeyFile: /etc/letsencrypt/live/{{ subdomain }}.joeac.net/privkey.pem
+{% endfor %}
+ SMTP:
+ Enabled: true
+ RequireSTARTTLS: true
+ Submissions:
+ Enabled: true
+ IMAPS:
+ Enabled: true
+Postmaster:
+ Account: me
+ Mailbox: Postmaster
+HostTLSRPT:
+ Account: me
+ Mailbox: TLSRPT
+ Localpart: tlsreports
diff --git a/roles/mox/templates/openrc/mox b/roles/mox/templates/openrc/mox
new file mode 100644
index 0000000..e04d96a
--- /dev/null
+++ b/roles/mox/templates/openrc/mox
@@ -0,0 +1,77 @@
+#!/sbin/openrc-run
+
+description="Run mox email server"
+extra_commands="configtest"
+description_configtest="Check configuration via \"mox config test\""
+
+configtest()
+{
+ if ! [ -f ~mox/config/mox.conf ]; then
+ eerror "The config file ~mox/config/mox.conf does not exist!"
+ return 1
+ fi
+ cd ~mox
+ if mox config test >&/dev/null; then
+ einfo "config: ok"
+ else
+ eerror "config: error"
+ return 1
+ fi
+}
+
+depend()
+{
+ need net unbound
+}
+
+start_pre() {
+ ebegin "Waiting for global IPv6 address {{ ansible_facts.default_ipv6.address }} to be ready"
+
+ local i=0
+ while [ "$i" -lt 30 ]; do
+ if ip -6 addr show scope global | grep -q "{{ ansible_facts.default_ipv6.address }}" && \
+ ! ip -6 addr show scope global | grep -q "{{ ansible_facts.default_ipv6.address }}.*\btentative\b"
+ then
+ eend 0
+ return 0
+ fi
+ sleep 2
+ i=$((i + 2))
+ done
+
+ eend 1 "Global IPv6 address {{ ansible_facts.default_ipv6.address }} not ready after 30 seconds"
+ return 1
+}
+
+start()
+{
+ configtest || return 1
+ ebegin "Starting mox"
+ start-stop-daemon --start \
+ --exec /usr/bin/mox \
+ --background \
+ --chdir ~mox \
+ --stdout /var/log/mox.log \
+ --stderr /var/log/mox.log \
+ --make-pidfile \
+ --pidfile /run/mox.pid \
+ -- serve
+ eend $?
+}
+
+stop()
+{
+ ebegin "Stopping mox"
+ start-stop-daemon --stop \
+ --exec /usr/bin/mox \
+ --pidfile /run/mox.pid
+ eend $?
+}
+
+restart()
+{
+ ebegin "Restarting mox"
+ svc_stop
+ svc_start
+ eend $?
+}