diff --git a/defaults/main.yml b/defaults/main.yml index 3c472f0..c628223 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -3,6 +3,8 @@ mailserver_mail_domain: "sum7.eu" mailserver_mx_domain: "{{ inventory_hostname }}" mailserver_cert_domains: "{{ mailserver_mx_domain }} mail.{{ mailserver_mail_domain }}" +mailserver_dovecot_enabled: true # would not install postfixadmn either + mailserver_db_type: "pgsql" mailserver_db_host: "localhost" mailserver_db_name: "mailserver" @@ -23,3 +25,5 @@ mailserver_rspamd_enabled: true mailserver_rspamd_domain: "" #mailserver_rspamd_webui_password: "" # run `rspamadm pw` for it mailserver_rspamd_dkim_selector: "2020" + +mailserver_mailman_enabled: true diff --git a/handlers/main.yml b/handlers/main.yml index ea724d3..ef46014 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -13,3 +13,8 @@ systemd: name: rspamd state: restarted + +- name: reload postfix + systemd: + name: postfix + state: reloaded diff --git a/tasks/main.yml b/tasks/main.yml index 2cd1220..323429a 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -23,12 +23,15 @@ line: "{{ mailserver_cert_domains }}" - name: Run userdatabase + when: mailserver_dovecot_enabled import_tasks: db.yml - name: Run postfixadmin + when: mailserver_dovecot_enabled import_tasks: postfixadmin.yml - name: Run dovecot + when: mailserver_dovecot_enabled import_tasks: dovecot.yml - name: Run rspamd @@ -36,6 +39,7 @@ when: mailserver_rspamd_enabled - name: Run mailman + when: mailserver_mailman_enabled import_tasks: mailman.yml - name: Run postfix diff --git a/tasks/postfix.yml b/tasks/postfix.yml index 28388ef..3d67146 100644 --- a/tasks/postfix.yml +++ b/tasks/postfix.yml @@ -1,5 +1,40 @@ -- name: Install Postfix +- name: postfix - install package: state: latest name: - postfix + +- name: postfix - generate DH + notify: reload postfix + openssl_dhparam: + path: /etc/postfix/dh.pem + size: 4096 + +- name: postfix - create sql folder + notify: reload postfix + file: + path: /etc/postfix/sql + state: directory + +- name: postfix - config + notify: reload postfix + template: + src: "postfix/{{ item }}" + dest: "/etc/postfix/{{ item }}" + with_items: + - main.cf + - master.cf + - sql/smtpd-sender-login-maps.cf + - sql/tls-policy.cf + - sql/virtual-sender-maps.cf + - sql/virtual-alias-domains.cf + - sql/virtual-alias-domains-maps.cf + - sql/virtual-alias-maps.cf + - sql/virtual-mailbox-domains.cf + - sql/virtual-mailbox-maps.cf + +- name: postfix - start and enable on boot + systemd: + name: postfix + enabled: yes + state: started diff --git a/templates/postfix/main.cf b/templates/postfix/main.cf new file mode 100644 index 0000000..a3c549e --- /dev/null +++ b/templates/postfix/main.cf @@ -0,0 +1,195 @@ +## +## Network settings +## + +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 +inet_interfaces = all +smtp_address_preference = ipv6 +myhostname = {{ mailserver_mx_domain }} + + +## +## Mail queue settings +## + +maximal_queue_lifetime = 1h +bounce_queue_lifetime = 1h +maximal_backoff_time = 15m +minimal_backoff_time = 5m +queue_run_delay = 5m + + +## +## TLS settings +### + +tls_preempt_cipherlist = yes +tls_ssl_options = NO_COMPRESSION +tls_high_cipherlist = 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 + + +### Outbound SMTP connections (Postfix as sender) + +{% if mailserver_dovecot_enabled %} +smtp_tls_security_level = may +{% else %} +smtp_tls_security_level = dane +smtp_dns_support_level = dnssec +smtp_tls_policy_maps = proxy:{{ mailserver_db_type }}:/etc/postfix/sql/tls-policy.cf +{% endif %} +smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache +smtp_tls_protocols = !SSLv2, !SSLv3 +smtp_tls_ciphers = high +smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt + + +### Inbound SMTP connections +smtpd_tls_security_level = may +smtpd_tls_protocols = !SSLv2, !SSLv3 +smtpd_tls_ciphers = high +smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache + +smtpd_tls_key_file = /etc/dehydrated/certs/{{ mailserver_cert_domains.split(' ')[0] }}/privkey.pem +smtpd_tls_cert_file = /etc/dehydrated/certs/{{ mailserver_cert_domains.split(' ')[0] }}/fullchain.pem +smtpd_tls_dh1024_param_file = ${config_directory}/dh.pem + +## +## Local mail delivery to Dovecot via LMTP +## + +virtual_transport = lmtp:unix:private/dovecot-lmtp + +{% if mailserver_rspamd_enabled %} +## +## Spam filter and DKIM signatures via Rspamd +## + +smtpd_milters = inet:127.0.0.1:11332 +non_smtpd_milters = inet:127.0.0.1:11332 +milter_protocol = 6 +milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen} +milter_default_action = accept +{% endif %} + + +## +## Server Restrictions for clients, cecipients and relaying +## (concerning S2S-connections. Mailclient-connections are configured in submission-section in master.cf) +## + +### Conditions in which Postfix works as a relay. (for mail user clients) +smtpd_relay_restrictions = reject_non_fqdn_recipient +# reject_unknown_recipient_domain + permit_mynetworks + reject_unauth_destination + + +### Conditions in which Postfix accepts e-mails as recipient (additional to relay conditions) +### check_recipient_access checks if an account is "sendonly" +#smtpd_recipient_restrictions = check_recipient_access proxy:{{ mailserver_db_type }}:/etc/postfix/sql/recipient-access.cf + + +### Restrictions for all sending foreign servers ("SMTP clients") +smtpd_client_restrictions = permit_mynetworks + check_client_access hash:/etc/postfix/without_ptr +# reject_unknown_client_hostname + + +### Foreign mail servers must present a valid "HELO" +# Recipient address rejected: Domain not found; +smtpd_helo_required = yes +smtpd_helo_restrictions = permit_mynetworks + reject_invalid_helo_hostname + reject_non_fqdn_helo_hostname +# reject_unknown_helo_hostname + +# Block clients, which start sending too early +smtpd_data_restrictions = reject_unauth_pipelining + + +## +## Restrictions for MUAs (Mail user agents) +## + +mua_relay_restrictions = reject_non_fqdn_recipient,reject_unknown_recipient_domain,permit_mynetworks,permit_sasl_authenticated,reject +mua_sender_restrictions = permit_mynetworks,reject_non_fqdn_sender,reject_sender_login_mismatch,permit_sasl_authenticated,reject +mua_client_restrictions = permit_mynetworks,permit_sasl_authenticated,reject + + +## +## Postscreen Filter +## + +### Postscreen Whitelist / Blocklist +postscreen_access_list = permit_mynetworks + cidr:/etc/postfix/postscreen_access +postscreen_blacklist_action = drop + + +# Drop connections if other server is sending too quickly +postscreen_greet_action = drop + + +### DNS blocklists +postscreen_dnsbl_threshold = 2 +postscreen_dnsbl_sites = ix.dnsbl.manitu.net*2 + zen.spamhaus.org*2 +postscreen_dnsbl_action = drop + + +## +## MySQL queries +## +alias_maps = + hash:/etc/postfix/aliases +{% if mailserver_mailman_enabled %} + hash:/var/lib/mailman/data/aliases +{% endif %} +alias_database = $alias_maps + +virtual_alias_maps = +{% if mailserver_dovecot_enabled %} + proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-alias-maps.cf + proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-alias-domains-maps.cf +{% endif %} +{% if mailserver_mailman_enabled %} + hash:/var/lib/mailman/data/virtual-mailman +{% endif %} +{% if mailserver_dovecot_enabled %} +virtual_alias_domains = proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-alias-domains.cf +virtual_mailbox_maps = proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-mailbox-maps.cf +virtual_mailbox_domains = proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-mailbox-domains.cf + +# List of authorized senders +smtpd_sender_login_maps = + proxy:{{ mailserver_db_type }}:/etc/postfix/sql/smtpd-sender-login-maps.cf + proxy:{{ mailserver_db_type }}:/etc/postfix/sql/virtual-sender-maps.cf +{% endif %} +local_recipient_maps = $smtpd_sender_login_maps + +{% if mailserver_mailman_enabled %} +relay_domains = + hash:/var/lib/mailman/data/relay-domains +{% endif %} + +## +## Miscellaneous +## + +### Maximum mailbox size (0=unlimited - is already limited by Dovecot quota) +mailbox_size_limit = 0 + +### Maximum size of inbound e-mails (50 MB) +message_size_limit = 52428800 + +### Do not notify system users on new e-mail +biff = no + +### Users always have to provide full e-mail addresses +append_dot_mydomain = no + +### Delimiter for "Address Tagging" +recipient_delimiter = + + +#------------------------------ +compatibility_level = 2 diff --git a/templates/postfix/master.cf b/templates/postfix/master.cf new file mode 100644 index 0000000..9ab9e16 --- /dev/null +++ b/templates/postfix/master.cf @@ -0,0 +1,146 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master" or +# on-line: http://www.postfix.org/master.5.html). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== +#smtp inet n - n - - smtpd +smtp inet n - n - 1 postscreen + -o smtpd_sasl_auth_enable=no +smtpd pass - - n - - smtpd +dnsblog unix - - n - 0 dnsblog +tlsproxy unix - - n - 0 tlsproxy +submission inet n - n - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_sasl_type=dovecot + -o smtpd_sasl_path=private/auth + -o smtpd_sasl_security_options=noanonymous +# -o smtpd_tls_auth_only=yes +# -o smtpd_reject_unlisted_recipient=no + -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions + -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o smtpd_relay_restrictions=$mua_relay_restrictions + -o milter_macro_daemon_name=ORIGINATING +{# if mailserver_dovecot_enabled %} + -o smtpd_sender_login_maps=mysql:/etc/postfix/sql/sender-login-maps.cf +{% endif #} + -o smtpd_helo_required=no + -o smtpd_helo_restrictions= + -o cleanup_service_name=submission-header-cleanup +#smtps inet n - n - - smtpd +# -o syslog_name=postfix/smtps +# -o smtpd_tls_wrappermode=yes +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_reject_unlisted_recipient=no +# -o smtpd_client_restrictions=$mua_client_restrictions +# -o smtpd_helo_restrictions=$mua_helo_restrictions +# -o smtpd_sender_restrictions=$mua_sender_restrictions +# -o smtpd_recipient_restrictions= +# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#628 inet n - n - - qmqpd +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr unix n - n 300 1 qmgr +#qmgr unix n - n 300 1 oqmgr +tlsmgr unix - - n 1000? 1 tlsmgr +rewrite unix - - n - - trivial-rewrite +bounce unix - - n - 0 bounce +defer unix - - n - 0 bounce +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +flush unix n - n 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - n - - smtp +relay unix - - n - - smtp + -o syslog_name=postfix/$service_name +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - n - - showq +error unix - - n - - error +retry unix - - n - - error +discard unix - - n - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - n - - lmtp +anvil unix - - n - 1 anvil +scache unix - - n - 1 scache +submission-header-cleanup unix n - n - 0 cleanup + -o header_checks=regexp:/etc/postfix/header_checks +postlog unix-dgram n - n - 1 postlogd +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +#maildrop unix - n n - - pipe +# flags=DRXhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +#uucp unix - n n - - pipe +# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# ==================================================================== +# +# Other external delivery methods. +# +#ifmail unix - n n - - pipe +# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +# +#bsmtp unix - n n - - pipe +# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient +# +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store +# ${nexthop} ${user} ${extension} +# +#mailman unix - n n - - pipe +# flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py +# ${nexthop} ${user} diff --git a/templates/postfix/sql/smtpd-sender-login-maps.cf b/templates/postfix/sql/smtpd-sender-login-maps.cf new file mode 100644 index 0000000..cb17936 --- /dev/null +++ b/templates/postfix/sql/smtpd-sender-login-maps.cf @@ -0,0 +1,6 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +query = select username from mailbox where username='%s' diff --git a/templates/postfix/sql/tls-policy.cf b/templates/postfix/sql/tls-policy.cf new file mode 100644 index 0000000..fb928a5 --- /dev/null +++ b/templates/postfix/sql/tls-policy.cf @@ -0,0 +1,6 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +query = SELECT policy, params FROM tlspolicies WHERE domain = '%s' diff --git a/templates/postfix/sql/virtual-alias-domains-maps.cf b/templates/postfix/sql/virtual-alias-domains-maps.cf new file mode 100644 index 0000000..449761c --- /dev/null +++ b/templates/postfix/sql/virtual-alias-domains-maps.cf @@ -0,0 +1,6 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' diff --git a/templates/postfix/sql/virtual-alias-domains.cf b/templates/postfix/sql/virtual-alias-domains.cf new file mode 100644 index 0000000..e7e543b --- /dev/null +++ b/templates/postfix/sql/virtual-alias-domains.cf @@ -0,0 +1,6 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +query = SELECT alias_domain FROM alias_domain WHERE alias_domain='%s' AND active = '1' diff --git a/templates/postfix/sql/virtual-alias-maps.cf b/templates/postfix/sql/virtual-alias-maps.cf new file mode 100644 index 0000000..af82a5d --- /dev/null +++ b/templates/postfix/sql/virtual-alias-maps.cf @@ -0,0 +1,8 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +table = alias +select_field = goto +where_field = address diff --git a/templates/postfix/sql/virtual-mailbox-domains.cf b/templates/postfix/sql/virtual-mailbox-domains.cf new file mode 100644 index 0000000..5d7bc9e --- /dev/null +++ b/templates/postfix/sql/virtual-mailbox-domains.cf @@ -0,0 +1,8 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +table = domain +select_field = domain +where_field = domain diff --git a/templates/postfix/sql/virtual-mailbox-maps.cf b/templates/postfix/sql/virtual-mailbox-maps.cf new file mode 100644 index 0000000..3f8b9a6 --- /dev/null +++ b/templates/postfix/sql/virtual-mailbox-maps.cf @@ -0,0 +1,8 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +table = mailbox +select_field = maildir +where_field = username diff --git a/templates/postfix/sql/virtual-sender-maps.cf b/templates/postfix/sql/virtual-sender-maps.cf new file mode 100644 index 0000000..607f621 --- /dev/null +++ b/templates/postfix/sql/virtual-sender-maps.cf @@ -0,0 +1,6 @@ +user = {{ mailserver_db_user }} +password = {{ mailserver_db_password }} +hosts = {{ mailserver_db_host }} +dbname = {{ mailserver_db_name }} + +query = SELECT goto FROM alias WHERE address='%s'