commit ea6070544db41f53cc89698c1b48d58b454acd11 from: gonzalo date: Wed Jul 25 23:43:31 2018 UTC initial ansible-role-mailserver 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 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 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. + #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 = + +action "mda_with_virtuals" mda \ + "/usr/local/bin/rspamc --mime --exec '/usr/local/libexec/dovecot/dovecot-lda -f %{sender} -d %{dest}'" \ + virtual user vmail +action "relay" relay helo {{ domain }} +action "dkim" relay host smtp://127.0.0.1:10027 + +## Block spammers +match from any mail-from for domain 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 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 @@ +---