From 4ae7df074f5a9241c4e2590562efc45defc9f579 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 7 Apr 2018 23:05:20 +0200 Subject: [PATCH] extend postfix: vmail and more --- roles/postfix/tasks/main.yml | 32 +++++++- roles/postfix/templates/main.cf | 80 +++++++++++++++---- roles/postfix/templates/master.cf | 68 +++++++--------- .../postfix/templates/mysql_vmail_aliases.cf | 8 ++ .../postfix/templates/mysql_vmail_senders.cf | 8 ++ roles/postfix/templates/mysql_vmail_users.cf | 6 ++ roles/postfix/vmail.sql | 33 ++++++++ 7 files changed, 177 insertions(+), 58 deletions(-) create mode 100644 roles/postfix/templates/mysql_vmail_aliases.cf create mode 100644 roles/postfix/templates/mysql_vmail_senders.cf create mode 100644 roles/postfix/templates/mysql_vmail_users.cf create mode 100644 roles/postfix/vmail.sql diff --git a/roles/postfix/tasks/main.yml b/roles/postfix/tasks/main.yml index 07c344e..3343f33 100644 --- a/roles/postfix/tasks/main.yml +++ b/roles/postfix/tasks/main.yml @@ -1,20 +1,44 @@ - name: install postfix apt: name=postfix,bsd-mailx state=latest +- name: install postfix-mysql + apt: name=postfix-mysql state=latest + when: postfix.vmail_mysql_password is defined - name: install postfix config - register: config_main + register: postfix_config template: - src: templates/{{ item }} dest: /etc/postfix/{{ item }} + src: templates/{{ item }} with_items: - main.cf - master.cf +- name: install postfix mysql config + register: postfix_mysql + template: + dest: /etc/postfix/{{ item }} + src: templates/{{ item }} + mode: u=rw,g=r,o= + group: postfix + with_items: + - mysql_vmail_aliases.cf + - mysql_vmail_senders.cf + - mysql_vmail_users.cf + when: postfix.vmail_mysql_password is defined +- name: create empty maps + copy: + dest: /etc/postfix/{{ item }} + content: "" + force: no + with_items: + - virtual_alias_map + - transport_map + when: postfix.virtual_mailbox_domains is defined - name: reload postfix service: name=postfix state=restarted enabled=yes - when: config_main.changed + when: postfix_config.changed or postfix_mysql.changed - name: delete old local-mail cronjob file: path=/etc/cron.daily/local-mail state=absent - name: install check-for-local-mail cronjob copy: - src: files/check-for-local-mail dest: /etc/cron.daily/check-for-local-mail + src: files/check-for-local-mail mode: u=rwx,g=rx,o=rx diff --git a/roles/postfix/templates/main.cf b/roles/postfix/templates/main.cf index 4085955..dc56a85 100644 --- a/roles/postfix/templates/main.cf +++ b/roles/postfix/templates/main.cf @@ -1,8 +1,8 @@ +compatibility_level = 2 + # local delivery: aliases only alias_maps = hash:/etc/aliases local_recipient_maps = $alias_maps -# only consider ourselves local -mynetworks_style = host {% if postfix.mynetworks is defined %} mynetworks = {{ postfix.mynetworks }} {% endif %} @@ -27,18 +27,7 @@ smtp_tls_security_level = dane smtp_dns_support_level = dnssec {% endif %} -{% if postfix.relay_host is defined %} -# Relay everything -default_transport = smtp:{{ postfix.relay_host }} -{% if postfix.relay_client_cert is defined %} -# Enforce relay encryption -smtp_tls_cert_file=$config_directory/{{ postfix.relay_client_cert }}.crt -smtp_tls_key_file=$config_directory/{{ postfix.relay_client_cert }}.key -smtp_tls_security_level = encrypt -{% endif %} -{% endif %} - -{% if postfix.postscreen is defined and postfix.postscreen %} +{% if postfix.postscreen | default(False) %} # postscreen config postscreen_dnsbl_threshold = 3 postscreen_dnsbl_whitelist_threshold = -2 @@ -66,10 +55,71 @@ smtpd_recipient_restrictions = permit_mynetworks, permit_tls_clientcerts, reject_non_fqdn_recipient, reject_non_fqdn_sender, +{% if postfix.relay_host is defined %} +# Relay everything +default_transport = smtp:{{ postfix.relay_host }} +{% if postfix.relay_client_cert is defined %} +# Enforce relay encryption +smtp_tls_cert_file=$config_directory/{{ postfix.relay_client_cert }}.crt +smtp_tls_key_file=$config_directory/{{ postfix.relay_client_cert }}.key +smtp_tls_security_level = encrypt +{% endif %} +{% endif %} + +{% if postfix.submission | default(False) %} +# configure SASL +smtpd_sasl_type = dovecot +smtpd_sasl_path = private/auth +{% endif %} + +{% if postfix.relay_client_cert_whitelist is defined %} +# allow relay for some TLS-authenticated clients +smtpd_tls_ask_ccert = yes +smtpd_tls_fingerprint_digest = sha1 +relay_clientcerts = hash:$config_directory/{{ postfix.relay_client_cert_whitelist }} +{% endif %} + +{% if postfix.virtual_mailbox_domains is defined %} +# setup virtual delivery domains, aliases and destinations +virtual_mailbox_domains = {{ postfix.virtual_mailbox_domains }} +virtual_alias_maps = hash:$config_directory/virtual_alias_map + {% if postfix.vmail_mysql_password is defined %} + proxy:mysql:$config_directory/mysql_vmail_aliases.cf + {% endif %} +# +virtual_mailbox_maps = + {% if postfix.vmail_mysql_password is defined %} + proxy:mysql:$config_directory/mysql_vmail_users.cf + {% endif %} + {% if postfix.mailman | default(False) %} + hash:/var/lib/mailman/data/virtual-mailman + {% endif %} +# +smtpd_sender_login_maps = + {% if postfix.vmail_mysql_password is defined %} + proxy:mysql:$config_directory/mysql_vmail_users.cf + proxy:mysql:$config_directory/mysql_vmail_senders.cf + proxy:mysql:$config_directory/mysql_vmail_aliases.cf + {% endif %} +# +proxy_read_maps = $virtual_alias_maps $virtual_mailbox_maps $smtpd_sender_login_maps + +# setup mail routes for virtual mail: all mail ends up being forwarded somewhere +virtual_transport = error +transport_maps = hash:/etc/postfix/transport_map +mailman_destination_recipient_limit = 1 +{% endif %} + +{% if postfix.opendkim | default(False) %} +# DKIM & Milter +milter_default_action = accept +smtpd_milters = unix:opendkim/sock +non_smtpd_milters = $smtpd_milters +{% endif %} + # misc smtpd_delay_reject = yes disable_vrfy_command = yes recipient_delimiter = + delay_warning_time = 4h message_size_limit = 21384000 -append_dot_mydomain = no diff --git a/roles/postfix/templates/master.cf b/roles/postfix/templates/master.cf index 18b8d98..0e9b536 100644 --- a/roles/postfix/templates/master.cf +++ b/roles/postfix/templates/master.cf @@ -10,36 +10,23 @@ # (yes) (yes) (no) (never) (100) # ========================================================================== {% if postfix.postscreen is defined and postfix.postscreen %} -smtp inet n - y - 1 postscreen +smtp inet n - y - 1 postscreen +dnsblog unix - - y - 0 dnsblog +tlsproxy unix - - y - 0 tlsproxy {% else %} smtp inet n - y - - smtpd {% endif %} -#smtpd pass - - y - - smtpd -#dnsblog unix - - y - 0 dnsblog -#tlsproxy unix - - y - 0 tlsproxy -#submission inet n - y - - smtpd -# -o syslog_name=postfix/submission -# -o smtpd_tls_security_level=encrypt -# -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 -#smtps inet n - y - - 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 - y - - qmqpd + +{% if postfix.submission is defined and postfix.submission %} +submission inet n - y - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes + -o smtpd_tls_ask_ccert=no + -o smtpd_relay_restrictions=permit_sasl_authenticated,reject + -o smtpd_recipient_restrictions=reject_sender_login_mismatch +{% endif %} + pickup unix n - y 60 1 pickup cleanup unix n - y - 0 cleanup qmgr unix n - n 300 1 qmgr @@ -61,11 +48,11 @@ error unix - - y - - error retry unix - - y - - error discard unix - - y - - discard local unix - n n - - local -virtual unix - n n - - virtual +#virtual unix - n n - - virtual lmtp unix - - y - - lmtp anvil unix - - y - 1 anvil scache unix - - y - 1 scache -# + # ==================================================================== # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. @@ -78,8 +65,8 @@ scache unix - - y - 1 scache # 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=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} +#maildrop unix - n n - - pipe +# flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} # # ==================================================================== # @@ -110,17 +97,20 @@ maildrop unix - n n - - pipe # # 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) +#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/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient -scalemail-backend unix - n n - 2 pipe - flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} +#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/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient +#scalemail-backend unix - n n - 2 pipe +# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} + +{% if postfix.mailman is defined and postfix.mailman %} mailman unix - n n - - pipe flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user} +{% endif %} diff --git a/roles/postfix/templates/mysql_vmail_aliases.cf b/roles/postfix/templates/mysql_vmail_aliases.cf new file mode 100644 index 0000000..26bae72 --- /dev/null +++ b/roles/postfix/templates/mysql_vmail_aliases.cf @@ -0,0 +1,8 @@ +# Map an email address to the actual username/email address mail should go to. +# I do not think that mapping to an alias here will work properly for the sender check, +# so always map to a username. +user = vmail +password = {{ postfix.vmail_mysql_password }} +hosts = localhost +dbname = vmail +query = SELECT user FROM aliases WHERE mail='%s' diff --git a/roles/postfix/templates/mysql_vmail_senders.cf b/roles/postfix/templates/mysql_vmail_senders.cf new file mode 100644 index 0000000..de5dcd6 --- /dev/null +++ b/roles/postfix/templates/mysql_vmail_senders.cf @@ -0,0 +1,8 @@ +# Map an email address to the actual username/email address mail should go to. +# I do not think that mapping to an alias here will work properly for the sender check, +# so always map to a username. +user = vmail +password = {{ postfix.vmail_mysql_password }} +hosts = localhost +dbname = vmail +query = SELECT user FROM senders WHERE sender='%s' diff --git a/roles/postfix/templates/mysql_vmail_users.cf b/roles/postfix/templates/mysql_vmail_users.cf new file mode 100644 index 0000000..7ddb1f4 --- /dev/null +++ b/roles/postfix/templates/mysql_vmail_users.cf @@ -0,0 +1,6 @@ +# It is also used to check ownership, mapping email addresses to usernames - however, in my setup, the email address is the username. +user = vmail +password = {{ postfix.vmail_mysql_password }} +hosts = localhost +dbname = vmail +query = SELECT username FROM users WHERE username='%s' AND active = '1' diff --git a/roles/postfix/vmail.sql b/roles/postfix/vmail.sql new file mode 100644 index 0000000..72c3e30 --- /dev/null +++ b/roles/postfix/vmail.sql @@ -0,0 +1,33 @@ +CREATE DATABASE IF NOT EXISTS `vmail`; +USE `vmail`; + +-- +-- Table structure for table `aliases` +-- + +CREATE TABLE `aliases` ( + `mail` varchar(255) NOT NULL, + `user` varchar(255) NOT NULL, + PRIMARY KEY (`mail`) +) DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `senders` +-- + +CREATE TABLE `senders` ( + `sender` varchar(255) NOT NULL, + `user` varchar(255) NOT NULL, + PRIMARY KEY (`sender`) +) DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `users` +-- + +CREATE TABLE `users` ( + `username` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `active` tinyint(4) NOT NULL, + PRIMARY KEY (`username`) +) DEFAULT CHARSET=utf8; -- 2.30.2