commit 76228a0afb830585495164397938e3daec1ef0d8 Author: Denis Knauf Date: Sat Nov 7 20:27:01 2020 +0100 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2c649f --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# ---> Ansible +*.retry + +# ---> Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..388d5b0 --- /dev/null +++ b/README.adoc @@ -0,0 +1,50 @@ +mail - Secure Postfix & Dovecot +=============================== + +Mail is pain. For an easier setup, this role configures a mail-server +with secure default settings. + +Requirements +------------ + +You need to have debian (or compatible, like ubuntu) already installed. + +It will install all dependencies on host-machine: + +* LDAP - Yes, you need a LDAP-server. It can be installed anywhere, but you need one. + +It expects for TLS a PKI in `/etc/postfix/tls/` and `/etc/dovecot/tls/`, +where you have to place `**hostname**.key`, `**hostname**.crt`. + +Role Variables +-------------- + +TODO + +Example Playbook +---------------- + +TODO + +---- +--- +# vim: set expandtab tabstop=2 shiftwidth=2: + +- hosts: mailserver + remote_user: root + become: false + + tasks: + - import_role: + name: mail +---- + +License +------- + +AGPLv3 + +Author Information +------------------ + +Denis Knauf - https://git.denkn.at/deac/ansible-role-mail diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..6c9791f --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# vim: set et sw=2 ts=2 sts=2: + +postfix_tls_policy: [] + diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..86d6a80 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for mail \ No newline at end of file diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..55686cb --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: AGPL-3.0 + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + diff --git a/tasks/dovecot.yml b/tasks/dovecot.yml new file mode 100644 index 0000000..633eca3 --- /dev/null +++ b/tasks/dovecot.yml @@ -0,0 +1,147 @@ +--- +# vim: set et sw=2 ts=2 sts=2: + +- name: dovecot-service.conf set file limit + copy: + dest: /etc/systemd/system/dovecot.service.d/service.conf + content: | + [Service] + LimitNOFILE=16384 + +- name: dovecot-configs + copy: + src: "{{item}}" + dest: /etc/dovecot + owner: root + group: dovecot + mode: 0444 + with_fileglob: + - "dovecot/*" +- name: dovecot-configs in conf.d + copy: + src: "{{item}}" + dest: /etc/dovecot/conf.d + owner: root + group: dovecot + mode: 0444 + with_fileglob: + - "dovecot/conf.d/*" + +- name: 'deactivate auth-system' + lineinfile: + path: /etc/dovecot/conf.d/10-auth.conf + line: "#!include auth-system.conf.ext" + regexp: "^#?!include auth-system\\.conf\\.ext" +- name: 'activate auth-ldap,-passwdfile' + lineinfile: + path: /etc/dovecot/conf.d/10-auth.conf + line: "!include {{item}}.conf.ext" + regexp: "^#?!include {{item}}.conf.ext" + with_items: + - auth-ldap + - auth-passwdfile + +- name: 'dovecot: 10-ssl.conf' + lineinfile: + path: /etc/dovecot/conf.d/10-ssl.conf + insertafter: "^#{{item.key}} *= *" + regexp: "^{{item.key}} *= *" + line: "{{item.key}} = {{item.value}}" + with_dict: + ssl: required + ssl_key: "=TLSv1.2' + smtpd_tls_protocols: '>=TLSv1.2' + # Same for sending mails: :/ + smtp_tls_mandatory_protocols: '>=TLSv1.2' + smtp_tls_protocols: '>=TLSv1.2' + # Internal/Clients must support better crypto: + lmtp_tls_mandatory_protocols: '>=TLSv1.2' + lmtp_tls_protocols: '>=TLSv1.2' + submission_tls_mandatory_protocols: '>=TLSv1.2' + submission_tls_protocols: '>=TLSv1.2' + smtpd_tls_mandatory_ciphers: high + #tls_high_cipherlist: 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA' + smtpd_tls_exclude_ciphers: MD5, DES, eNULL, 3DES, EXP, RC4, DSS, PSK, SEED, IDEA, ECDSA, aNULL + smtpd_tls_eecdh_grade: strong + myhostname: '{{mail_postfix_domain}}' + myorigin: '{{mail_postfix_myorigin}}' + mydestination: '' + relayhost: '' + mynetworks: '{{mynetworks}}' + recipient_delimiter: '+' + inet_interfaces: 'all' + #inet_protocols: 'ipv4' + + alias_maps: 'cdb:/etc/aliases' + alias_database: 'cdb:/etc/aliases' + smtp_generic_maps: cdb:/etc/postfix/generic_map + smtpd_sasl_type: dovecot + smtpd_sasl_path: private/auth + smtpd_sasl_local_domain: '{{domain}}' + smtpd_sasl_security_options: noanonymous + smtpd_sasl_auth_enable: 'no' + strict_rfc821_envelopes: 'yes' + smtpd_reject_unlisted_sender: 'yes' + smtp_tls_policy_maps: 'cdb:/etc/postfix/tls_policy' + + #### Zustellung und Ueberpruefung, ob Server fuer die Domain zustaendig ist und die Adresse existiert: + # domain ist virtuell und nicht lokal! + # zustellung via lmtp and dovecot: + virtual_transport: "lmtp:unix:private/dovecot-lmtp" + # ebenso. eigentlich nicht in verwendung. + local_transport: "lmtp:unix:private/dovecot-lmtp" + # welche domains sind moeglich? + virtual_mailbox_domains: "cdb:/etc/postfix/virtual_endpoint_map" + # aliases fuer virtuelle adressen. + virtual_alias_maps: "cdb:/etc/postfix/virtual_aliases, cdb:/etc/postfix/mailinglists" + sender_canonical_maps: "cdb:/etc/postfix/sender_canonical" + # virtual_mailbox_maps wird nicht gesezt, da virtual_transport die ueberpruefung vornimmt. + smtpd_relay_restrictions: 'permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination' + + address_verify_map: 'lmdb:$data_directory/verify_cache' + unknown_address_reject_code: 550 + + smtpd_recipient_restrictions: 'reject_unknown_reverse_client_hostname, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, reject_invalid_hostname, permit_mynetworks, reject_unauth_destination, reject_unverified_recipient, check_policy_service unix:private/policy-spf' + + # Postscreen + postscreen_greet_banner: 'Loving the dog most, oh human, you say is a sin. The dog stayed true to me during the storm, the human not even during the wind.' + postscreen_cache_map: 'lmdb:$data_directory/postscreen_cache' + postscreen_access_list: 'permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidr' + postscreen_blacklist_action: 'enforce' + postscreen_greet_action: 'enforce' + postscreen_pipelining_enable: 'yes' + postscreen_dnsbl_threshold: '1' + postscreen_dnsbl_sites: 'ix.dnsbl.manitu.net b.barracudacentral.org dnsbl.sorbs.net dnsbl-3.uceprotect.net dnsbl-2.uceprotect.net dnsbl-1.uceprotect.net' + postscreen_dnsbl_action: 'enforce' + postscreen_dnsbl_ttl: '1h' + # TODO: greylisting custom message + + # SPF + policy-spf_time_limit: 3600s + + # DKIM + milter_default_action: accept + milter_protocol: "2" + smtpd_milters: 'unix:milter/opendkim, unix:milter/opendmarc' + non_smtpd_milters: 'unix:milter/opendkim' + +- name: mailinglists-aliases + template: + src: mailinglist-aliases.j2 + dest: /etc/postfix/mailinglists + mode: 0444 + owner: root + group: root + +- name: dummy files if needed + copy: + dest: '{{item.key}}' + content: '{{item.value}}' + force: no + with_dict: '{{postfix_default_file_content}}' + +- name: force TLS for these + lineinfile: + path: /etc/postfix/tls_policy + regexp: '^{{item}}[ \t]' + line: '{{item}} encrypt' + with_items: '{{postfix_tls_policy}}' + +- name: prepare aliases-lookup-tables + command: newaliases +- name: prepare lookup-tables + shell: 'postmap {{item|quote}}' + args: + chdir: /etc/postfix + with_items: '{{postfix_postmap}}' diff --git a/tasks/tls.yml b/tasks/tls.yml new file mode 100644 index 0000000..c7b9c69 --- /dev/null +++ b/tasks/tls.yml @@ -0,0 +1,17 @@ +--- +# vim: set et sw=2 ts=2 sts=2: + +- name: DHs for Postfix + community.crypto.openssl_dhparam: + path: '/etc/postfix/tls/mail_{{item}}.dh' + size: '{{item}}' + owner: postfix + mode: 0400 + with_items: [512,2048,4192] +- name: DHs for Dovecot + community.crypto.openssl_dhparam: + path: '/etc/dovecot/tls/mail_{{item}}.dh' + size: '{{item}}' + owner: dovecot + mode: 0400 + with_items: [512,2048,4192] diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/tests/test.yml b/tests/test.yml new file mode 100644 index 0000000..723dbb4 --- /dev/null +++ b/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - mail \ No newline at end of file diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..b741c50 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,28 @@ +--- +# vim: set et sw=2 ts=2 sts=2: + +postfix_default_file_content: + "/etc/aliases": '' + "/etc/postfix/virtual_aliases": '' + "/etc/postfix/recipient_access": 'public@ REJECT' + "/etc/postfix/relaydomains": '' + "/etc/postfix/access": '' + "/etc/postfix/postscreen_access.cidr": '' + "/etc/postfix/sender_canonical": '' + "/etc/postfix/tls_policy": '' + "/etc/postfix/generic_map": '' + "/etc/postfix/virtual_domain_map": "nfotex.com OK" + "/etc/postfix/virtual_endpoint_map": '' + "/etc/postfix/transport_map": '' +postfix_postmap: +- cdb:access +- cdb:generic_map +- cdb:recipient_access +- cdb:relaydomains +- cdb:sender_canonical +- cdb:tls_policy +- cdb:transport_map +- cdb:virtual_aliases +- cdb:mailinglists +- cdb:virtual_domain_map +- cdb:virtual_endpoint_map