Commit Diff


commit - /dev/null
commit + ea6070544db41f53cc89698c1b48d58b454acd11
blob - /dev/null
blob + 02add5e7c7de84db20898836ad5c7eefe516875b (mode 644)
--- /dev/null
+++ LICENSE
@@ -0,0 +1,11 @@
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
blob - /dev/null
blob + 600625bf6e666a010663423ea56f00f3efc0e684 (mode 644)
--- /dev/null
+++ README.md
@@ -0,0 +1,149 @@
+Ansible role for a Mailserver
+=============================
+
+Ansible role to create a Mailserver on OpenBSD (>=6.4 & -current) with OpenSMTPD, Dovecot, DKIMProxy and Rspamd.
+
+Requirements
+------------
+
+OpenBSD, Python 2.7 (on client machine) and 10 minutes.
+
+Notes
+-----
+
+This is still a WIP, so far, you need to create DKIM keys, new users and DNS entrys. Also, you need
+to enable dovecot, smtpd, rspamd and dkimproxy_{in,out} at boot.
+
+You need to adjust your pf.conf (example bellow).
+
+Also, you need to delete examples on /etc/mail/virtuals and /etc/mail/domains
+
+Feedback is welcome.
+
+Example pf.conf
+---------------
+
+For IMAPs I like to keep bruteforce people away with some tweaks on pf.conf, keep in mind that
+lower numbers than that, can couse problems checking emails on huge directories like misc or mailing list.
+
+```
+...
+pass in quick on egress proto tcp from any \
+        to (egress) port imaps \
+        flags S/SA modulate state \
+        (max-src-conn 50, max-src-conn-rate 50/5, overload <bruteforce> flush global)
+...
+```
+
+For SMTP I have pretty the same:
+
+```
+...
+pass in quick log (to pflog1) proto tcp from any \
+        to (egress) port smtp
+
+pass in quick log (to pflog1) proto tcp from any \
+        to (egress) port { submission, smtps } \
+        flags S/SA modulate state \
+        (max-src-conn 50, max-src-conn-rate 25/5, overload <bruteforce> flush global)
+...
+```
+
+Example Ansible
+---------------
+
+This example is for a remote setup, so ,,test'' is your future mailserver, you
+already put your ssh key on ,,test'' and this server already have python2.7 
+installed.
+
+```
+$ doas pkg_add ansible
+...
+$ cd /tmp && mkdir ansible && cd ansible
+$ git clone https://gitlab.com/gonzalo-/ansible-role-mailserver
+Cloning into 'ansible-role-mailserver'...
+warning: redirecting to https://gitlab.com/gonzalo-/ansible-role-mailserver.git/
+remote: Counting objects: 200, done.
+remote: Total 200 (delta 0), reused 0 (delta 0)
+Receiving objects: 100% (200/200), 36.51 KiB | 1.83 MiB/s, done.
+Resolving deltas: 100% (87/87), done.
+$ mv ansible-role-mailserver gonzalo-.mailserver
+$ cat hosts
+test ansible_python_interpreter=/usr/local/bin/python2.7
+$ cat mailserver.yml
+---
+- hosts: test
+  roles:
+     - role: gonzalo-.mailserver
+  become: yes
+  become_method: doas
+
+  vars:
+   domain: 'foobar.com'
+   mail_dir: '/var/vmail'
+   mail_user: 'gonzalo'
+   release: '6.4'
+   arch: 'amd64'
+   installurl_mirror: 'https://fastly.cdn.openbsd.org/pub/OpenBSD/'
+   pkg_path: 'https://fastly.cdn.openbsd.org/pub/OpenBSD/{{ release }}/packages/{{ arch }}/'
+   packages_list:
+    - dovecot
+    - dovecot-pigeonhole
+    - dkimproxy
+    - rspamd
+    - opensmtpd-extras
+$ ansible-playbook -i hosts mailserver.yml
+...MAGIC...
+$
+```
+
+Example Playbook
+----------------
+```
+---
+- hosts: test
+  roles:
+     - role: gonzalo-.mailserver
+  become: yes
+  become_method: doas
+
+  vars:
+   domain: 'foobar.com'
+   mail_dir: '/var/vmail'
+   mail_user: 'gonzalo'
+   release: '6.4'
+   arch: 'amd64'
+   installurl_mirror: 'https://fastly.cdn.openbsd.org/pub/OpenBSD/'
+   pkg_path: 'https://fastly.cdn.openbsd.org/pub/OpenBSD/{{ release }}/packages/{{ arch }}/'
+   packages_list:
+    - dovecot
+    - dovecot-pigeonhole
+    - dkimproxy
+    - rspamd
+    - opensmtpd-extras
+```
+
+Enable Spam Learning with Dovecot Antispam
+------------------------------------------
+The rspamd system can be trained to learn spam (or ham) by checking if users move
+their email from a folder in their Inbox to the Spam folder (to flag as spam), or
+the reverse: move incorrectly flagged spam out of the Spam folder. This will incur
+some overhead when it comes to moving messages, but it can enable the system to learn
+spam/ham more efficiently.
+
+Note: This ONLY works with IMAP
+
+To enable, modify the following line in /etc/dovecot/conf.d/20-imap.conf:
+```
+mail_plugins = $mail_plugins antispam
+```
+
+Also edit /etc/dovecot/conf.d/90-plugin.conf if you want to enable more logging
+or to change the default Spam and Trash folders (if they are different on your system)
+and then restart dovecot with: ```rcctl restart dovecot```
+
+
+Author Information
+------------------
+
+https://x61.sh/
blob - /dev/null
blob + 9c9b0cf20c9fc5e3e90f21361cdae31d368cb642 (mode 644)
--- /dev/null
+++ defaults/main.yml
@@ -0,0 +1,2 @@
+---
+# defaults file for ansible-rol-mailserver
\ No newline at end of file
blob - /dev/null
blob + 651753ea6627a25c70cae899b0163949eb2d7497 (mode 644)
--- /dev/null
+++ handlers/main.yml
@@ -0,0 +1,2 @@
+---
+# handlers file for ansible-rol-mailserver
\ No newline at end of file
blob - /dev/null
blob + 871b6cfe9c6679a53343b7ba0641aaed94cf96c7 (mode 644)
--- /dev/null
+++ meta/main.yml
@@ -0,0 +1,28 @@
+---
+galaxy_info:
+  author: gonzalo-
+  description: Role to setup a mailserver with opensmtpd, dovecot, dkimproxy and rspamd.
+  license: BSD
+  min_ansible_version: 1.9
+  galaxy_tags:
+  - openbsd
+  - system
+  - opensmtpd
+  - opensmtpd-extras
+  - mailserver
+  - rspamd
+  - dovecot
+  - dovecot-pigeonhole
+  - dovecot-antispam
+  - dkimproxy
+  - antispam
+  platforms:
+  - name: OpenBSD
+    versions:
+     - 6.4
+     - 6.3
+     - 6.2
+     - 6.1
+     - 6.0
+     - 5.9
+dependencies: []
blob - /dev/null
blob + 31e2b2bd101b94c481c83b50409c9eb6c9080cc6 (mode 644)
--- /dev/null
+++ tasks/main.yml
@@ -0,0 +1,69 @@
+---
+
+- name: set installurl
+  lineinfile:
+      dest=/etc/installurl
+      line="{{ installurl_mirror }}"
+      insertafter=EOF
+      create=True
+
+- group:
+    name: vmail
+    state: present
+
+- user:
+    name: vmail
+    comment: "Virtual Mail"
+    shell: /sbin/nologin
+    home: "{{ mail_dir }}"
+    group: vmail
+
+- sieve:
+  name: sieve-global
+  file: path=/var/sieve state=directory
+
+- name: Installing packages
+  openbsd_pkg: name={{ item }} state=present
+  with_items: "{{ packages_list }}"
+
+-  template: src=smtpd.conf.j2 dest="/etc/mail/smtpd.conf" owner="root" group="wheel" mode="0644"
+-  template: src=blacklist-recipients.j2 dest="/etc/mail/blacklist-recipients" owner="root" group="wheel" mode="0644"
+-  template: src=domains.j2 dest="/etc/mail/domains" owner="root" group="wheel" mode="0644"
+-  template: src=virtuals.j2 dest="/etc/mail/virtuals" owner="root" group="wheel" mode="0644"
+-  template: src=passwd.j2 dest="/etc/mail/passwd" owner="_dovecot" group="_smtpd" mode="0440"
+-  template: src=dkimproxy_in.conf.j2 dest="/etc/dkimproxy_in.conf" owner="root" group="wheel" mode="0644"
+-  template: src=dkimproxy_out.conf.j2 dest="/etc/dkimproxy_out.conf" owner="root" group="wheel" mode="0644"
+-  template: src=90-plugin.conf.j2 dest="/etc/dovecot/conf.d/90-plugin.conf" owner="root" group="wheel" mode="0644"
+-  template: src=90-sieve.conf.j2 dest="/etc/dovecot/conf.d/90-sieve.conf" owner="root" group="wheel" mode="0644"
+-  template: src=10-auth.conf.j2 dest="/etc/dovecot/conf.d/10-auth.conf" owner="root" group="wheel" mode="0644"
+-  template: src=20-imap.conf.j2 dest="/etc/dovecot/conf.d/20-imap.conf" owner="root" group="wheel" mode="0644"
+-  template: src=15-lda.conf.j2 dest="/etc/dovecot/conf.d/15-lda.conf" owner="root" group="wheel" mode="0644"
+-  template: src=15-mailboxes.conf.j2 dest="/etc/dovecot/conf.d/15-mailboxes.conf.j2" owner="root" group="wheel" mode="0644"
+-  template: src=10-director.conf.j2 dest="/etc/dovecot/conf.d/10-director" owner="root" group="wheel" mode="0644"
+-  template: src=20-managesieve.conf.j2 dest="/etc/dovecot/conf.d/20-managesieve.conf" owner="root" group="wheel" mode="0644"
+-  template: src=10-mail.conf.j2 dest="/etc/dovecot/conf.d/10-mail.conf" owner="root" group="wheel" mode="0644"
+-  template: src=10-master.conf.j2 dest="/etc/dovecot/conf.d/10-master.conf" owner="root" group="wheel" mode="0644"
+-  template: src=auth-passwdfile.conf.ext.j2 dest="/etc/dovecot/conf.d/auth-passwdfile.conf.ext" owner="root" group="wheel" mode="0644"
+-  template: src=dovecot.conf.j2 dest="/etc/dovecot/dovecot.conf" owner="root" group="wheel" mode="0644"
+-  template: src=10-logging.conf.j2 dest="/etc/dovecot/conf.d/10-logging.conf" owner="root" group="wheel" mode="0644"
+-  template: src=10-ssl.conf.j2 dest="/etc/dovecot/conf.d/10-ssl.conf" owner="root" group="wheel" mode="0644"
+-  template: src=auth-static.conf.ext.j2 dest="/etc/dovecot/conf.d/auth-static.conf.ext" owner="root" group="wheel" mode="0644"
+-  template: src=global-default.sieve.j2 dest="/var/sieve/global-default.sieve" owner="root" group="wheel" mode="0644"
+
+- blockinfile: |
+      dest=/etc/login.conf backup=yes
+      content="## Dovecot
+        dovecot:\
+                :openfiles-cur=1024:\
+                :openfiles-max=2048:\
+                :tc=daemon:"
+      insertafter=EOF
+
+- name: Enable smtpd
+  service: name=smtpd state=started enabled=yes
+
+- name: Enable dovecot
+  service: name=dovecot state=started enabled=yes
+
+- name: Enable rspamd
+  service: name=rspamd state=started enabled=yes
blob - /dev/null
blob + 03232c4faeb420538e354cdc9d613dc986898729 (mode 644)
--- /dev/null
+++ templates/10-auth.conf.j2
@@ -0,0 +1,2 @@
+auth_mechanisms = plain
+!include auth-passwdfile.conf.ext
blob - /dev/null
blob + 1853728d40e459edf8c541c865ed78759444afb8 (mode 644)
--- /dev/null
+++ templates/10-director.conf.j2
@@ -0,0 +1,11 @@
+service imap-login {
+	inet_listener imap {
+		port = 0
+	}
+}
+
+service pop3-login {
+	inet_listener pop3 {
+		port = 0
+	}
+}
blob - /dev/null
blob + f8be4f5dcbddc59af9685b527331cf96cbb28c57 (mode 644)
--- /dev/null
+++ templates/10-logging.conf.j2
@@ -0,0 +1,3 @@
+auth_verbose = yes
+#debug_log_path = /var/log/dovecot-debug.log
+mail_debug = yes
blob - /dev/null
blob + 8f9cc58bafaf558193e402a8b7398132f14197a8 (mode 644)
--- /dev/null
+++ templates/10-mail.conf.j2
@@ -0,0 +1,24 @@
+mail_home = {{ mail_dir }}/%d/%n
+mbox_write_locks = fcntl
+namespace inbox {
+	inbox = yes
+	location = maildir:{{ mail_dir }}/%d/%n/Maildir:LAYOUT=fs
+	mailbox Drafts {
+		special_use = \Drafts
+	}
+	mailbox Spam {
+		special_use = \Junk
+	}
+	mailbox Sent {
+		special_use = \Sent
+	}
+	mailbox "Sent Messages" {
+		special_use = \Sent
+	}
+	mailbox Trash {
+		special_use = \Trash
+	}
+	prefix =
+	separator = /
+}
+mmap_disable = yes
blob - /dev/null
blob + fa16913e086a290db6d20f446bd786fcfe3e462d (mode 644)
--- /dev/null
+++ templates/10-master.conf.j2
@@ -0,0 +1,82 @@
+service auth {
+	unix_listener auth-userdb {
+		group = vmail
+		mode = 0666
+		user = vmail
+	}
+}
+
+service imap-login {
+  inet_listener imap {
+    #port = 143
+  }
+  inet_listener imaps {
+    #port = 993
+    #ssl = yes
+  }
+
+  # Number of connections to handle before starting a new process. Typically
+  # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
+  # is faster. <doc/wiki/LoginProcess.txt>
+  #service_count = 1
+
+  # Number of processes to always keep waiting for more connections.
+  #process_min_avail = 0
+
+  # If you set service_count=0, you probably need to grow this.
+  #vsz_limit = $default_vsz_limit
+}
+
+service pop3-login {
+  inet_listener pop3 {
+    #port = 110
+  }
+  inet_listener pop3s {
+    #port = 995
+    #ssl = yes
+  }
+}
+
+service lmtp {
+  unix_listener lmtp {
+    #mode = 0666
+  }
+
+  # Create inet listener only if you can't use the above UNIX socket
+  #inet_listener lmtp {
+    # Avoid making LMTP visible for the entire internet
+    #address =
+    #port = 
+  #}
+}
+
+service imap {
+  # Most of the memory goes to mmap()ing files. You may need to increase this
+  # limit if you have huge mailboxes.
+  #vsz_limit = $default_vsz_limit
+
+  # Max. number of IMAP processes (connections)
+  #process_limit = 1024
+}
+
+service pop3 {
+  # Max. number of POP3 processes (connections)
+  #process_limit = 1024
+}
+
+service auth-worker {
+  # Auth worker process is run as root by default, so that it can access
+  # /etc/shadow. If this isn't necessary, the user should be changed to
+  # $default_internal_user.
+  #user = root
+}
+
+service dict {
+  # If dict proxy is used, mail processes should have access to its socket.
+  # For example: mode=0660, group=vmail and global mail_access_groups=vmail
+  unix_listener dict {
+    #mode = 0600
+    #user = 
+    #group = 
+  }
+}
blob - /dev/null
blob + 811a2f13c5aac64f36b123ecce4f8f437fecec20 (mode 644)
--- /dev/null
+++ templates/10-ssl.conf.j2
@@ -0,0 +1,6 @@
+#ssl = required
+#ssl_cert = </etc/ssl/{{ domain }}_fullchain.pem
+#ssl_key = </etc/ssl/private/{{ domain }}_private.pem
+#ssl_cipher_list = ALL:HIGH:!SSLv2:!MEDIUM:!LOW:!EXP:!RC4:!MD5:!aNULL:@STRENGTH
+#ssl_prefer_server_ciphers = yes
+#ssl_protocols = !SSLv2 !SSLv3 !TLSv1 !TLSv1.1
blob - /dev/null
blob + f9097946d85272d6a9abc06a4ae9b62c7b95cd4a (mode 644)
--- /dev/null
+++ templates/15-lda.conf.j2
@@ -0,0 +1,6 @@
+protocol lda {
+	#info_log_path = /var/log/dovecot-deliver.log
+	#log_path = /var/log/dovecot-deliver-errors.log
+	mail_plugins = $mail_plugins sieve
+	#postmaster_address = postmaster@foobar.org
+}
blob - /dev/null
blob + 94b3294393a6b185ee828a19c8471f0365d86d2c (mode 644)
--- /dev/null
+++ templates/15-mailboxes.conf.j2
@@ -0,0 +1,78 @@
+##
+## Mailbox definitions
+##
+
+# Each mailbox is specified in a separate mailbox section. The section name
+# specifies the mailbox name. If it has spaces, you can put the name
+# "in quotes". These sections can contain the following mailbox settings:
+#
+# auto:
+#   Indicates whether the mailbox with this name is automatically created
+#   implicitly when it is first accessed. The user can also be automatically
+#   subscribed to the mailbox after creation. The following values are
+#   defined for this setting:
+# 
+#     no        - Never created automatically.
+#     create    - Automatically created, but no automatic subscription.
+#     subscribe - Automatically created and subscribed.
+#  
+# special_use:
+#   A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
+#   mailbox. There are no validity checks, so you could specify anything
+#   you want in here, but it's not a good idea to use flags other than the
+#   standard ones specified in the RFC:
+#
+#     \All      - This (virtual) mailbox presents all messages in the
+#                 user's message store. 
+#     \Archive  - This mailbox is used to archive messages.
+#     \Drafts   - This mailbox is used to hold draft messages.
+#     \Flagged  - This (virtual) mailbox presents all messages in the
+#                 user's message store marked with the IMAP \Flagged flag.
+#     \Junk     - This mailbox is where messages deemed to be junk mail
+#                 are held.
+#     \Sent     - This mailbox is used to hold copies of messages that
+#                 have been sent.
+#     \Trash    - This mailbox is used to hold messages that have been
+#                 deleted.
+#
+# comment:
+#   Defines a default comment or note associated with the mailbox. This
+#   value is accessible through the IMAP METADATA mailbox entries
+#   "/shared/comment" and "/private/comment". Users with sufficient
+#   privileges can override the default value for entries with a custom
+#   value.
+
+# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
+namespace inbox {
+  # These mailboxes are widely used and could perhaps be created automatically:
+  mailbox Drafts {
+    special_use = \Drafts
+  }
+  mailbox Spam {
+    special_use = \Junk
+  }
+  mailbox Trash {
+    special_use = \Trash
+  }
+
+  # For \Sent mailboxes there are two widely used names. We'll mark both of
+  # them as \Sent. User typically deletes one of them if duplicates are created.
+  mailbox Sent {
+    special_use = \Sent
+  }
+  mailbox "Sent Messages" {
+    special_use = \Sent
+  }
+
+  # If you have a virtual "All messages" mailbox:
+  #mailbox virtual/All {
+  #  special_use = \All
+  #  comment = All my messages
+  #}
+
+  # If you have a virtual "Flagged" mailbox:
+  #mailbox virtual/Flagged {
+  #  special_use = \Flagged
+  #  comment = All my flagged messages
+  #}
+}
blob - /dev/null
blob + 02d5c531cb7d2399589106b54a3c049b902783d0 (mode 644)
--- /dev/null
+++ templates/20-imap.conf.j2
@@ -0,0 +1,7 @@
+## No need it on new versions
+#imap_client_workarounds = delay-newmail tb-extra-mailbox-sep tb-lsub-flags
+
+protocol imap {
+	mail_plugins = $mail_plugins
+	mail_max_userip_connections = 20
+}
blob - /dev/null
blob + e76a1333cf25692dc8b7723b4ebeffd7368a23b9 (mode 644)
--- /dev/null
+++ templates/20-managesieve.conf.j2
@@ -0,0 +1,15 @@
+protocols = $protocols sieve
+
+service managesieve-login {
+	inet_listener sieve {
+	port = 4190
+	}
+	inet_listener sieve_deprecated {
+	port = 2000
+  }
+}
+
+protocol sieve {
+	managesieve_notify_capability = mailto
+	managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart
+}
blob - /dev/null
blob + b68ab1a89e1e51ecd9559dda8b5c97529a0513fc (mode 644)
--- /dev/null
+++ templates/90-plugin.conf.j2
@@ -0,0 +1,12 @@
+plugin {
+	#antispam_verbose_debug = 1
+	antispam_backend = mailtrain
+	antispam_spam    = Spam
+	antispam_trash   = Trash
+	antispam_mail_sendmail = /usr/local/bin/rspamc
+	antispam_mail_spam     = learn_spam
+	antispam_mail_notspam  = learn_ham
+	antispam_mail_sendmail_args = -h;localhost:11334;-P;q1
+	antispam_pipe_program_spam_arg = learn_spam
+	antispam_pipe_program_notspam_arg = learn_ham
+}
blob - /dev/null
blob + 17dcb77d515dd2ce086dd20e639a826ad56d89c3 (mode 644)
--- /dev/null
+++ templates/90-sieve-extprograms.conf.j2
@@ -0,0 +1,44 @@
+# Sieve Extprograms plugin configuration
+
+# Don't forget to add the sieve_extprograms plugin to the sieve_plugins setting.
+# Also enable the extensions you need (one or more of vnd.dovecot.pipe,
+# vnd.dovecot.filter and vnd.dovecot.execute) by adding these	to the
+# sieve_extensions or sieve_global_extensions settings. Restricting these
+# extensions to a global context using sieve_global_extensions is recommended.
+
+plugin {
+
+  # The directory where the program sockets are located for the
+  # vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension
+  # respectively. The name of each unix socket contained in that directory
+  # directly maps to a program-name referenced from the Sieve script.
+  #sieve_pipe_socket_dir = sieve-pipe
+  #sieve_filter_socket_dir = sieve-filter
+  #sieve_execute_socket_dir = sieve-execute
+
+  # The directory where the scripts are located for direct execution by the
+  # vnd.dovecot.pipe, vnd.dovecot.filter and vnd.dovecot.execute extension
+  # respectively. The name of each script contained in that directory
+  # directly maps to a program-name referenced from the Sieve script.
+  #sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe
+  #sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter
+  #sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute
+}
+
+# An example program service called 'do-something' to pipe messages to
+#service do-something {
+  # Define the executed script as parameter to the sieve service
+  #executable = script /usr/lib/dovecot/sieve-pipe/do-something.sh
+
+  # Use some unprivileged user for executing the program
+  #user = dovenull
+
+  # The unix socket located in the sieve_pipe_socket_dir (as defined in the 
+  # plugin {} section above)
+  #unix_listener sieve-pipe/do-something {
+    # LDA/LMTP must have access
+  #  user = vmail  
+  #  mode = 0600
+  #}
+#}
+
blob - /dev/null
blob + af4039f02ded94a59569a7c89e73d47c142fdc6e (mode 644)
--- /dev/null
+++ templates/90-sieve.conf.j2
@@ -0,0 +1,9 @@
+plugin {
+	sieve = {{ mail_dir }}/%d/%n/%n.sieve
+	sieve_global_dir = /var/sieve
+	sieve_global_path = /var/sieve/global-default.sieve
+	sieve_extensions = +spamtest +spamtestplus
+	sieve_spamtest_status_type = score
+	sieve_spamtest_status_header = X-Spamd-Result: default: [[:alnum:]]+ \[(-?[[:digit:]]+\.[[:digit:]]+) / -?[[:digit:]]+\.[[:digit:]]+\]
+	sieve_spamtest_max_header    = X-Spamd-Result: default: [[:alnum:]]+ \[-?[[:digit:]]+\.[[:digit:]]+ / (-?[[:digit:]]+\.[[:digit:]]+)\]
+}
blob - /dev/null
blob + 5f85b40273f78689bc8704276aff88e2abb90417 (mode 644)
--- /dev/null
+++ templates/auth-passwdfile.conf.ext.j2
@@ -0,0 +1,9 @@
+passdb {
+	args = scheme=blf-crypt /etc/mail/passwd
+	driver = passwd-file
+}
+
+userdb {
+	args = uid=vmail gid=vmail home={{ mail_dir }}/%d/%n
+	driver = static
+}
blob - /dev/null
blob + 7fa0414352cb91928666fe5182f0a23c1c25b631 (mode 644)
--- /dev/null
+++ templates/auth-static.conf.ext.j2
@@ -0,0 +1,4 @@
+userdb {
+	args = uid=vmail gid=vmail home={{ mail_dir }}/%d/%n
+	driver = static
+}
blob - /dev/null
blob + 69e9e6b3005ef82e34092a80197bbd02c91a6bc3 (mode 644)
--- /dev/null
+++ templates/blacklist-recipients.j2
@@ -0,0 +1,271 @@
+1ink.com@cruisses.bid
+AmazingSUV@surafceclen.bid
+AnastasiaBeautiesTeam@mdicare.bid
+Angeline-6354@nicolasruston.co.uk
+AsianGirlsTeam@lastclick.bid
+BionicSteelHose@memoriss.bid
+BreakingOnForbs@cludcomputting.bid
+BulletBottleOpener@smllbusines.bid
+Coconut-Oil-Secret@bestbattry.bid
+ConcealedCarryBraveResponseGunHolster@mortageplan.bid
+CookOnRedCopperSquare@dattingg.bid
+CookOnRedCopperSquare@phonesys.bid
+CopperChefGrill&Bake@lifeinsrance.bid
+DONOTREPLY@CWOH.COM
+DONOTREPLY@FLOKIS.GR
+DiabetesDefeat@ofrbst.bid
+DisasterSurvival@hawaiivac.bid
+DiySmartSaw@reverseplann.bid
+Eco-Windows@callonchp.bid
+ExposeCheaters@phonsysttem.bid
+ForwardHeadPosture@newoffrbest.bid
+ForwordHeadPosture@fittopen.bid
+FreeEdtMiniMultitool@godiupps.bid
+FungusKeyPro@dibterducr.bid
+GoogleSniper@rvrstinntss.bid
+GreenEnergyGenerator@mrtage.bid
+HealthMagazineExclusive@lessfathip.bid
+HealthyGarcinia@heartbrn.bid
+HighBloodPressure@golfdate.bid
+HurricaneSpinScrubberOffer@reehabalchl.bid
+KATHRINE.WHITEROW@VIPSPICS.COM
+Kathrine_64@thesweetenercompany.co.uk
+Loraine.9432@x61.com.ar
+LotteryStrategies@nuttrra.bid
+MarkMorris@gainhair.bid
+MicrosoftFlightSimulator@mypoliccy.bid
+MicrosoftFlightSimulator@reverseoff.bid
+Miranda.bramley@baltecbalancas.com
+NATHANIAL.YAIR@MANOLA.AT
+NTGenerator@christmattch.bid
+Newsletter@selectedinc.com
+NoReply@boutiquerealtyservices.com
+NoReply@grupogas.com.mx
+NoReply@southernoffshoreng.com
+OnlineRoofingQuotes@diabetesys.bid
+OnlineRoofingQuotes@homsalar.us
+OnlineRoofingQuotes@offersrc.bid
+PaleoCookbook@earnfrmeng.bid
+PatrioticParacordBracelet@hvacfree.bid
+PianoForAll@gettnewofrr.bid
+PocketRadio@seniorcare.bid
+Pocketlight@translateearn.bid
+RelationshipMagic@btrycndition.bid
+RestoreBatteriesSystem@amazingption.bid
+RocketLanguages@expertcnctr.bid
+SharkTank@alaskacrsis.bid
+SimpleOff-GridSystem@datinng.bid
+SolarAirLantern@tatticll.bid
+SolarStirlingPlant@callinchep.bid
+Sue-500@alanstrang.worldonline.co.uk
+SurvivalBag@brazildating.bid
+SurvivalBag@legallhlp.bid
+SurvivalTrademate@constption.bid
+Sylvester-31@theheugh.globalnet.co.uk
+TacticalPen@alcohalrah.us
+TacticalPen@hrpsprtcol.bid
+Tasha.mckean@terzake.nu
+Teds-plans@clouddcompting.bid
+The2020VisionSystem@whittenrr.bid
+TheBigdiabeteslie@datesenior.bid
+TheCoconutOilSecret@efaxing.bid
+TheHybeamFlashlight@summerpro.bid
+Tonya@x61.com.ar
+USInsuranceOpportunity@fstdgree.bid
+UltraFX10@alcholdrink.bid
+UltraForeclosurePartner@fasttooffer.bid
+UltraOmegaBurn@ntionalfmily.bid
+Vogenesis@degreeonline.bid
+WindowRemodel@specloffr.host
+WoodworkingBusiness@schlrrsip.bid
+ZZSnore@aqusttic.bid
+ZZSnore@hellthofr.bid
+admin@securenext.trade
+admin@vip.gist-edu.cn
+administracion@planproductivo.com
+advice@hotgadgetdeals.com
+alexander.bluhm@gmx.de
+alfa@redpositiva.info
+alfa@redpositiva.org
+andrea@espacioverde.com.ar
+app@couponstoday.co.uk
+avisos@infoadsnews3.com
+bancarias@planproductivo.com
+bltsigbj@speedy.com.ar
+bonus@teloenviamos.org
+bounceback@smile-magenta.com
+bounceback@weather-gusty.com
+calendario@cursosuba.com
+cambiocheques@cilandrogroup.org
+ccmtl33g@infovia.com.ar
+connected.cars@readwrite.us
+contact@entregador.org
+contact@experts-advice.com
+contact@feelhappybehappy.com
+contact@maile-ar.com
+contact@panel.nuevatendencia.biz
+contact@thehappyradish.com
+contact@tkp2017.net
+contact@vaikra.org
+contact@xtechraiox.com.br
+contacto@mayoristadevinos.com.ar
+cursoenlinea@participacionempresarial.com
+cursos@arizmendi.com
+cv@aliantec.com
+cvdqomtl33g@infovia.com.ar
+cvdqqomtl33g@infovia.com.ar
+danske.bocenter@danskebank.se
+decisiones@participacionempresarial.com
+demo@alunos.sanchoensino.pt
+direccion@nmm01.com
+donotreply@bottlecutting.co.uk
+donotreply@cloudninegiftshop.co.uk
+donotreply@jakemayesracing.co.uk
+dulcec@participacionempresarial.com
+elounlei@formarse.com.ar
+emma@virgil.ilj.trade
+enelformulario@teloenviamos.org
+envios@correoverificado.org
+envios@toocontacto2.com
+epoint@epointmerchandising.com
+ercas@yopmail.com
+escuela@excelencia.com
+estellapangman@score.worldonline.co.uk
+evaluacion@planproductivo.com
+eventosonline@participacionempresarial.com
+events@readwrite.us
+factorwow@participacionempresarial.com
+fekiw@aiaisi.win
+gegewo@aisila.win
+gerencia@participacionempresarial.com
+gerentes@participacionempresarial.com
+gidohufo@hcdmza.gov.ar
+harriett.decon95@serraseed.com.br
+hugo@victimaprotagonista.com
+impactofiscal@participacionempresarial.com
+indicadoresrh@participacionempresarial.com
+info@altosdetinogasta.com.ar
+info@aol.com
+info@emailprobox.com
+info@enjoymailoffer.com
+info@enviosnew.com
+info@europeanquality.es
+info@hrampu.com
+info@inboxar.com
+info@infinmediagroup.com
+info@joyinmailing.net
+info@laaldea.com.ar
+info@latekha.com
+info@lopfieip.com
+info@mailer.navysofaeighteen.xyz
+info@mailer.navysofaone.xyz
+info@mailer.navysofaseventeen.xyz
+info@mktenvios.com
+info@movistarcorporativo.club
+info@negociosconusa.com.ar
+info@okservicios.net
+info@opcionmail.com
+info@pahikai.com
+info@planespersonal.com.ar
+info@planetagone.com
+info@proseguridad.info
+info@quvuni.com
+info@schfdultz.com
+info@sonypictures.net
+info@thfompson.com
+info@tiendanaif.com
+info@totalserviciosuno.com
+info@tuwebsystems.com
+info@unicreditgroup.eu
+info@vivaisara.it
+infohdp@hijosdeprada.com.ar
+infomovistar@cilandrogroup.org
+informatica@sgociudad.gov.ar
+isidaigrai@telectronica.com
+itvadia@info-trans.com.ar
+john.lucas@vacanciesaustralia.com.au
+kim@shane.ufwe.cn
+kodierqo@mgmsa.com.ar
+kpwcqc@uol.com.ar
+ledagrantze8v@o2.pl
+liberman@headhunttalent.au.com
+lili@bbotou.win
+lo.arturo@participacionempresarial.com
+lo@imailmarketing.biz
+lorena.garcia@participacionempresarial.com
+love@imailmarketing.biz
+luosongtan@yeah.net
+majournee2017@gmail.com
+malaris@dinamai.com.ar
+mar@stelead.org
+marketing@cicalifeinc.com
+mconstantini@edee.com.ar
+mconstantini@escueladeejecutivos.com.ar
+meettracker@tracknowls.eu
+miralaweb@teloenviamos.org
+motivacion@participacionempresarial.com
+msf@medicinaysalud.org
+negocios@participacionempresarial.com
+nehelena1@listo.ru
+nei@teloenviamos.org
+net@teloenviamos.org
+neu@teloenviamos.org
+news@credisense.com.ar
+news@crucerosargentina.com
+news@desafio.org
+news@ilikecompras.com
+news@pestelliemails.com.ar
+news@plannacionalautos.com.ar
+news@procreautoargentina.com.ar
+news@superofertasypromos.com
+newspromo@infoautoplan.com
+nick@happyinamail.com
+niet@imailmarketing.biz
+niet@teloenviamos.org
+nigmaifa@trebliner.com.ar
+non@teloenviamos.org
+noreply@argmark.online
+noresponder@cocheras.org
+noresponder@gmail.com
+novedades@infoadsnews1.com
+novedades@infoadsnews2.com
+osorno.patricia@planproductivo.com
+osp65@r75.fssprus.ru
+otake@TELEFONICA.COM.AR
+plr@instastall.com
+pousadapuertoparaiso@gmail.com
+programaventas@participacionempresarial.com
+psiacacmtl33g@infovia.com.ar
+qibi@newlifes.win
+ralph@carrie.ufy.trade
+reifenwechsel@reifen-fechtelhoff.de
+rgemldsgif@gmail.com
+s.osaki@midorinet-shiga.com
+sales4@lr-link.com
+sebastianguillermo.gomez@prosegur.com
+send1@publoprod.com
+send@datoscreativos.info
+send@malenquiweb.info
+send@miawebs.info
+send@nuevatendencia.co
+send@professionasec.com
+send@prosechome.com
+send@rombosur.info
+send@stelead.org
+send@tuwebmart.com
+sender@smartersender.com
+silvia@freda.afq.trade
+soliaw@toothache.win
+staciqlyshodge@o2.pl
+tcljce@0342.com
+telefonica@participacionempresarial.com
+tizadomontevideo@cilandrogroup.org
+tts@news.porviajar.com
+vairbofriegoa@guazunet.com.ar
+ventas@aguablanda.com.ar
+ventas@orlhornos.com.ar
+visahome@mails-ssl.com
+wubiw@bbotou.win
+xiao@ymdlifes.win
+xpoloER@uerLooper.top
+xxlusb03@126.com
blob - /dev/null
blob + f514e2edf843eceefd81e8dcc1b4d490bf1da171 (mode 644)
--- /dev/null
+++ templates/dkimproxy_in.conf.j2
@@ -0,0 +1,5 @@
+# specify what address/port DKIMproxy should listen on
+listen    127.0.0.1:10025
+
+# specify what address/port DKIMproxy forwards mail to
+relay     127.0.0.1:10026
blob - /dev/null
blob + 7c567e61b52f5a003df3157e5cd918f3694f4475 (mode 644)
--- /dev/null
+++ templates/dkimproxy_out.conf.j2
@@ -0,0 +1,28 @@
+# specify what address/port DKIMproxy should listen on
+listen    127.0.0.1:10027
+
+# specify what address/port DKIMproxy forwards mail to
+relay     127.0.0.1:10028
+
+# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
+domain	  {{ domain }}
+
+# specify what signatures to add
+signature dkim(c=relaxed)
+signature domainkeys(c=nofws)
+
+# specify location of the private key
+# mkdir /etc/ssl/dkim && cd /etc/ssl/dkim
+# openssl genrsa -out {{ domain }}.key 1024
+# openssl rsa -in {{ domain }}.key -pubout -out {{ domain }}-public.key
+# 
+keyfile		/etc/ssl/dkim/{{ domain }}.key
+
+# specify the selector (i.e. the name of the key record put in DNS)
+selector  dkim
+
+# control how many processes DKIMproxy uses
+#  - more information on these options (and others) can be found by
+#    running `perldoc Net::Server::PreFork'.
+#min_servers 5
+#min_spare_servers 2
blob - /dev/null
blob + 4ea09476896db97e98fad7316c8d1bf83c6711af (mode 644)
--- /dev/null
+++ templates/domains.j2
@@ -0,0 +1,3 @@
+{{ domain }}
+foobar.com
+foobar.org.ar
blob - /dev/null
blob + 4f57d6641b4afba9f53c20282bf553b1b04ba113 (mode 644)
--- /dev/null
+++ templates/dovecot.conf.j2
@@ -0,0 +1,5 @@
+listen = *
+mail_home = {{ mail_dir }}/%d/%n
+protocols = imap sieve 
+
+!include conf.d/*.conf
blob - /dev/null
blob + 911c6c5cb4ea21837c22c2e07ab793d5b0e65947 (mode 644)
--- /dev/null
+++ templates/global-default.sieve.j2
@@ -0,0 +1,6 @@
+require ["fileinto", "envelope"];
+
+if header :is "X-Spam" "Yes" {
+    fileinto "Spam";
+    stop;
+}
blob - /dev/null
blob + e3d1651b938ad82786ebc0819a3cd734ab6c8a9f (mode 644)
--- /dev/null
+++ templates/passwd.j2
@@ -0,0 +1,3 @@
+## You can create passwords with:
+## doas smtpctl encrypt
+{{ mail_user }}@{{ domain }}:$2b$06$lZBnDxujxORpoNLou37NvDEg2ab2QIP3LN3CR1KUIPZZ8QLm::::::
blob - /dev/null
blob + 7f31f7f9523fdd624a4fdf20faf5e28401ce0ed9 (mode 644)
--- /dev/null
+++ templates/smtpd.conf.j2
@@ -0,0 +1,43 @@
+set queue compression
+
+set bounce warn-interval 1h, 6h, 2d
+set queue ttl 3d
+
+## PKI
+pki {{ domain }} cert		"/etc/ssl/{{ domain }}_fullchain.pem"
+pki {{ domain }} key		"/etc/ssl/private/{{ domain }}_private.pem"
+
+## Tables
+table aliases			file:/etc/mail/aliases
+table domains			file:/etc/mail/domains
+table passwd			passwd:/etc/mail/passwd
+table virtuals			file:/etc/mail/virtuals
+table blacklist-recipients	file:/etc/mail/blacklist-recipients
+
+## Limits
+set smtp max-message-size 50M
+
+## Ports
+listen on lo0
+listen on lo0 port 10028 tag DKIM_OUT
+listen on egress port 25 tls pki {{ domain }}
+listen on egress port 587 tls-require pki {{ domain }} auth <passwd>
+
+action "mda_with_virtuals" mda \
+	"/usr/local/bin/rspamc --mime --exec '/usr/local/libexec/dovecot/dovecot-lda -f %{sender} -d %{dest}'" \
+	virtual <virtuals> user vmail
+action "relay" relay helo {{ domain }}
+action "dkim" relay host smtp://127.0.0.1:10027
+
+## Block spammers
+match from any mail-from <blacklist-recipients> for domain <domains> reject
+
+# Accept mail sent from local server to a local account
+match from local for local action "mda_with_virtuals"
+
+match from any for domain <domains> action "mda_with_virtuals"
+
+match tag DKIM_OUT for any action "relay"
+
+match from local for any action dkim
+match auth from any for any action dkim
blob - /dev/null
blob + 0555bf0ee7df140c20f1e3cde7125c42a8c1dc0c (mode 644)
--- /dev/null
+++ templates/virtuals.j2
@@ -0,0 +1,9 @@
+abuse@{{ domain }}		{{ mail_user }}@{{ domain }}
+postmaster@{{ domain }}		{{ mail_user }}@{{ domain }}
+webmaster@{{ domain }}		{{ mail_user }}@{{ domain }}
+root@{{ domain }}		{{ mail_user }}@{{ domain }}
+{{ mail_user }}@{{ domain }}	vmail
+
+user2@foobar.org		{{ mail_user }}@{{ domain }}
+user2@foobar.org		{{ mail_user }}@{{ domain }}
+root@foobar.org			{{ mail_user }}@{{ domain }}
blob - /dev/null
blob + 878877b0776c44f55fc4e458f70840f31da5bb01 (mode 644)
--- /dev/null
+++ tests/inventory
@@ -0,0 +1,2 @@
+localhost
+
blob - /dev/null
blob + 65be8f9304cffd57d4a4d33ad11e5bc292039e24 (mode 644)
--- /dev/null
+++ tests/test.yml
@@ -0,0 +1,7 @@
+---
+- hosts: localhost
+  gather_facts: true
+  become: True
+  become_method: doas
+  roles:
+    - ansible-rol-mailserver
blob - /dev/null
blob + ed97d539c095cf1413af30cc23dea272095b97dd (mode 644)
--- /dev/null
+++ vars/main.yml
@@ -0,0 +1 @@
+---