diff options
author | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:23:43 -0500 |
---|---|---|
committer | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:52:13 -0500 |
commit | 0261e875679f1bf63c8d689da7fc7e014597885d (patch) | |
tree | 3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/postfix_server | |
download | selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip |
initial commit
Diffstat (limited to 'roles/postfix_server')
-rw-r--r-- | roles/postfix_server/defaults/main.yml | 13 | ||||
-rw-r--r-- | roles/postfix_server/files/etc/sasl2/smtpd.conf | 2 | ||||
-rw-r--r-- | roles/postfix_server/files/etc/systemd/system/postfix.service.d/override.conf | 6 | ||||
-rw-r--r-- | roles/postfix_server/handlers/main.yml | 9 | ||||
-rw-r--r-- | roles/postfix_server/tasks/freeipa.yml | 95 | ||||
-rw-r--r-- | roles/postfix_server/tasks/main.yml | 61 | ||||
-rw-r--r-- | roles/postfix_server/templates/etc/postfix/main.cf.j2 | 109 | ||||
-rw-r--r-- | roles/postfix_server/templates/etc/postfix/master.cf.j2 | 34 | ||||
-rw-r--r-- | roles/postfix_server/templates/etc/postfix/virtual_aliases.cf.j2 | 8 | ||||
-rw-r--r-- | roles/postfix_server/templates/etc/postfix/virtual_mailboxes.cf.j2 | 7 | ||||
-rw-r--r-- | roles/postfix_server/vars/main.yml | 64 |
11 files changed, 408 insertions, 0 deletions
diff --git a/roles/postfix_server/defaults/main.yml b/roles/postfix_server/defaults/main.yml new file mode 100644 index 0000000..3052a76 --- /dev/null +++ b/roles/postfix_server/defaults/main.yml @@ -0,0 +1,13 @@ +postfix_message_size_limit: 67108864 # 64 MB +postfix_recipient_delimiter: '+' +postfix_lmtp_require_tls: yes +postfix_virtual_domains: ['{{ email_domain }}'] +postfix_myorigin: '{{ email_domain }}' +postfix_mynetworks: "{{ vlans.values() | map(attribute='cidr') }}" +postfix_myhostname: '{{ ansible_fqdn }}' + +postfix_virtual_transport: lmtp:inet:{{ imap_host }}:24 +postfix_mailbox_quota_service: inet:{{ imap_host }}:10993 +postfix_milter: inet:{{ rspamd_host }}:11332 + +postfix_recipient_group: role-imap-access diff --git a/roles/postfix_server/files/etc/sasl2/smtpd.conf b/roles/postfix_server/files/etc/sasl2/smtpd.conf new file mode 100644 index 0000000..cc61713 --- /dev/null +++ b/roles/postfix_server/files/etc/sasl2/smtpd.conf @@ -0,0 +1,2 @@ +pwcheck_method: saslauthd +mech_list: gssapi plain login diff --git a/roles/postfix_server/files/etc/systemd/system/postfix.service.d/override.conf b/roles/postfix_server/files/etc/systemd/system/postfix.service.d/override.conf new file mode 100644 index 0000000..d7d8e76 --- /dev/null +++ b/roles/postfix_server/files/etc/systemd/system/postfix.service.d/override.conf @@ -0,0 +1,6 @@ +[Unit] +Wants=gssproxy.service +After=syslog.target network-online.target gssproxy.service + +[Service] +Environment=GSS_USE_PROXY=yes diff --git a/roles/postfix_server/handlers/main.yml b/roles/postfix_server/handlers/main.yml new file mode 100644 index 0000000..286b942 --- /dev/null +++ b/roles/postfix_server/handlers/main.yml @@ -0,0 +1,9 @@ +- name: restart postfix + systemd: + name: postfix + state: restarted + +- name: restart saslauthd + systemd: + name: saslauthd + state: restarted diff --git a/roles/postfix_server/tasks/freeipa.yml b/roles/postfix_server/tasks/freeipa.yml new file mode 100644 index 0000000..84d7818 --- /dev/null +++ b/roles/postfix_server/tasks/freeipa.yml @@ -0,0 +1,95 @@ +- name: create smtp service principal + ipaservice: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: 'smtp/{{ ansible_fqdn }}' + pac_type: NONE + state: present + +- name: retrieve smtp service keytab + include_role: + name: freeipa_keytab + vars: + keytab_principal: 'smtp/{{ ansible_fqdn }}' + keytab_path: '{{ postfix_keytab }}' + +- name: configure gssproxy + include_role: + name: gssproxy_client + vars: + gssproxy_name: postfix + gssproxy_section: service/postfix + gssproxy_keytab: '{{ postfix_keytab }}' + gssproxy_client_keytab: '{{ postfix_keytab }}' + gssproxy_cred_usage: both + gssproxy_euid: postfix + +- name: create SELinux policy for smtpd to access gssproxy + include_role: + name: selinux_policy + apply: + tags: selinux + vars: + selinux_policy_name: smtpd_gssproxy + selinux_policy_te: '{{ postfix_selinux_policy_te }}' + tags: selinux + +- name: generate PAM configuration for smtp + copy: + content: | + auth required pam_sss.so + account required pam_sss.so + dest: /etc/pam.d/smtp + +- name: create smtp HBAC service + ipahbacsvc: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ postfix_hbac_service }}' + description: Postfix SMTP server + state: present + run_once: True + +- name: create mail-servers hostgroup + ipahostgroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ postfix_hbac_hostgroup }}' + description: Mail Servers + host: "{{ groups[postfix_hbac_hostgroup] | map('regex_replace', '$', '.' ~ ansible_domain) }}" + state: present + run_once: True + +# Note: we explicitly allow all here. SSSD will only be consulted when a user +# performs a PLAIN login, falling back to saslauthd/PAM authentication. +# Users with a valid Kerberos ticket bypass the PAM stack entirely, so a +# restrictive HBAC rule is pointless. +- name: create HBAC rule for smtp + ipahbacrule: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: allow_smtp_on_mail_servers + description: Allow SMTP on mail servers + hostgroup: + - '{{ postfix_hbac_hostgroup }}' + usercategory: all + hbacsvc: + - '{{ postfix_hbac_service }}' + run_once: True + +- name: create systemd override directory + file: + path: /etc/systemd/system/postfix.service.d + state: directory + +- name: create systemd override file + copy: + src: etc/systemd/system/postfix.service.d/override.conf + dest: /etc/systemd/system/postfix.service.d/override.conf + notify: restart postfix + register: postfix_systemd_unit + +- name: reload systemd daemons + systemd: + daemon_reload: yes + when: postfix_systemd_unit.changed diff --git a/roles/postfix_server/tasks/main.yml b/roles/postfix_server/tasks/main.yml new file mode 100644 index 0000000..4f22d49 --- /dev/null +++ b/roles/postfix_server/tasks/main.yml @@ -0,0 +1,61 @@ +- name: install postfix + dnf: + name: '{{ postfix_packages }}' + state: present + +- name: request TLS certificate + include_role: + name: certbot + vars: + certificate_sans: ['{{ postfix_myhostname }}'] + certificate_path: '{{ postfix_certificate_path }}' + certificate_key_path: '{{ postfix_certificate_key_path }}' + certificate_owner: postfix + certificate_hook: systemctl reload postfix + +- import_tasks: freeipa.yml + tags: freeipa + +- name: generate dhparams + openssl_dhparam: + path: '{{ postfix_dhparams_path }}' + size: 2048 + +- name: generate postifx configuration + template: + src: etc/postfix/{{ item }}.j2 + dest: /etc/postfix/{{ item }} + loop: + - main.cf + - master.cf + - virtual_mailboxes.cf + - virtual_aliases.cf + notify: restart postfix + +- name: configure saslauthd for smtpd + copy: + src: etc/sasl2/smtpd.conf + dest: /etc/sasl2/smtpd.conf + notify: restart saslauthd + +- name: enable saslauthd + systemd: + name: saslauthd + enabled: yes + state: started + +- name: enable postfix + systemd: + name: postfix + enabled: yes + state: started + +- name: open firewall ports + firewalld: + service: '{{ item }}' + permanent: yes + immediate: yes + state: enabled + loop: + - smtp + - smtp-submission diff --git a/roles/postfix_server/templates/etc/postfix/main.cf.j2 b/roles/postfix_server/templates/etc/postfix/main.cf.j2 new file mode 100644 index 0000000..9132dff --- /dev/null +++ b/roles/postfix_server/templates/etc/postfix/main.cf.j2 @@ -0,0 +1,109 @@ +compatibility_level = 2 + +### path definitions +queue_directory = /var/spool/postfix +command_directory = /usr/sbin +daemon_directory = /usr/libexec/postfix +data_directory = /var/lib/postfix +mail_owner = postfix + +sendmail_path = /usr/sbin/sendmail.postfix +newaliases_path = /usr/bin/newaliases.postfix +mailq_path = /usr/bin/mailq.postfix +setgid_group = postdrop +html_directory = no +manpage_directory = /usr/share/man +sample_directory = /usr/share/doc/postfix/samples +readme_directory = /usr/share/doc/postfix/README_FILES +meta_directory = /etc/postfix +shlib_directory = /usr/lib64/postfix + +import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C POSTLOG_SERVICE POSTLOG_HOSTNAME GSS_USE_PROXY=yes + +myorigin = {{ postfix_myorigin }} +myhostname = {{ postfix_myhostname }} + +mynetworks = 127.0.0.0/8 {{ postfix_mynetworks | join(' ') }} + +# disable local delivery +mydestination = + +inet_interfaces = all +inet_protocols = all + +# disable open relay +mynetworks_style = host + +alias_database = hash:/etc/aliases + +smtputf8_enable = yes +recipient_delimiter = {{ postfix_recipient_delimiter }} +message_size_limit = {{ postfix_message_size_limit }} + +strict_rfc821_envelopes = yes +allow_percent_hack = no +swap_bangpath = no +disable_vrfy_command = yes +show_user_unknown_table_name = no + +tls_medium_cipherlist = {{ postfix_cipherlist }} +tls_preempt_cipherlist = no + +smtpd_tls_security_level = may +smtpd_tls_auth_only = yes +smtpd_tls_cert_file = {{ postfix_certificate_path }} +smtpd_tls_key_file = {{ postfix_certificate_key_path }} +smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +smtpd_tls_mandatory_ciphers = medium +smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 +smtpd_tls_dh1024_param_file = {{ postfix_dhparams_path }} + +smtpd_sasl_security_options = noanonymous, noplaintext +smtpd_sasl_tls_security_options = noanonymous + +smtpd_helo_required = yes + +smtp_tls_security_level = may +smtp_tls_CAfile = {{ postfix_smtp_ca_file }} + +lmtp_tls_CAfile = {{ postfix_smtp_ca_file }} +lmtp_tls_security_level = {{ 'secure' if postfix_lmtp_require_tls else 'may' }} + +# public mailserver - restrictive policy +smtpd_helo_required = yes +smtpd_client_restrictions = + permit_mynetworks, + reject_unauth_pipelining, + reject_unknown_reverse_client_hostname +smtpd_helo_restrictions = + permit_mynetworks, + reject_invalid_helo_hostname, + reject_non_fqdn_helo_hostname, + reject_unauth_pipelining +smtpd_sender_restrictions = + permit_mynetworks, + reject_non_fqdn_sender, + reject_unknown_sender_domain, + reject_unauth_pipelining +smtpd_relay_restrictions = + permit_mynetworks, + reject_unauth_destination +smtpd_recipient_restrictions = + permit_mynetworks, + reject_non_fqdn_recipient, + reject_unknown_recipient_domain, + reject_unauth_pipelining, + reject_unlisted_recipient, + reject_unauth_destination, + check_policy_service {{ postfix_mailbox_quota_service }} +smtpd_data_restrictions = + permit_mynetworks, + reject_unauth_pipelining + +virtual_transport = {{ postfix_virtual_transport }} +virtual_mailbox_domains = {{ freeipa_realm }} {{ postfix_virtual_domains | join(' ') }} +virtual_mailbox_maps = ldap:$config_directory/virtual_mailboxes.cf +virtual_alias_maps = ldap:$config_directory/virtual_aliases.cf + +milter_default_action = accept +smtpd_milters = {{ postfix_milter }} diff --git a/roles/postfix_server/templates/etc/postfix/master.cf.j2 b/roles/postfix_server/templates/etc/postfix/master.cf.j2 new file mode 100644 index 0000000..1742b7a --- /dev/null +++ b/roles/postfix_server/templates/etc/postfix/master.cf.j2 @@ -0,0 +1,34 @@ +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ========================================================================== +smtp inet n - n - - smtpd +submission inet n - n - - smtpd + -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o smtpd_sasl_auth_enable=yes +pickup unix n - n 60 1 pickup +cleanup unix n - n - 0 cleanup +qmgr unix n - n 300 1 qmgr +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 +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 +postlog unix-dgram n - n - 1 postlogd diff --git a/roles/postfix_server/templates/etc/postfix/virtual_aliases.cf.j2 b/roles/postfix_server/templates/etc/postfix/virtual_aliases.cf.j2 new file mode 100644 index 0000000..9ba32e8 --- /dev/null +++ b/roles/postfix_server/templates/etc/postfix/virtual_aliases.cf.j2 @@ -0,0 +1,8 @@ +version = 3 +bind = sasl +sasl_mechs = gssapi +server_host = {{ freeipa_hosts | join(" ") }} +search_base = {{ freeipa_accounts_basedn }} +query_filter = (|(mail=%s)(mailAlternateAddress=%s)) +special_result_attribute = member +result_attribute = krbprincipalname diff --git a/roles/postfix_server/templates/etc/postfix/virtual_mailboxes.cf.j2 b/roles/postfix_server/templates/etc/postfix/virtual_mailboxes.cf.j2 new file mode 100644 index 0000000..a6fae98 --- /dev/null +++ b/roles/postfix_server/templates/etc/postfix/virtual_mailboxes.cf.j2 @@ -0,0 +1,7 @@ +version = 3 +bind = sasl +sasl_mechs = gssapi +server_host = {{ freeipa_hosts | join(" ") }} +search_base = {{ freeipa_user_basedn }} +query_filter = (&(krbprincipalname=%s)(memberof=cn={{ postfix_recipient_group }},{{ freeipa_group_basedn }})) +result_attribute = krbprincipalname diff --git a/roles/postfix_server/vars/main.yml b/roles/postfix_server/vars/main.yml new file mode 100644 index 0000000..050c880 --- /dev/null +++ b/roles/postfix_server/vars/main.yml @@ -0,0 +1,64 @@ +postfix_packages: + - postfix + - postfix-ldap + - cyrus-sasl + - cyrus-sasl-gssapi + - cyrus-sasl-plain + - s-nail + +postfix_certificate_path: /etc/pki/tls/certs/postfix2.pem +postfix_certificate_key_path: /etc/pki/tls/private/postfix2.key +postfix_dhparams_path: /etc/pki/tls/misc/dhparams-postfix.pem + +postfix_hbac_service: smtp +postfix_hbac_hostgroup: mail_servers + +postfix_smtp_ca_file: /etc/pki/tls/certs/ca-bundle.crt +postfix_cipherlist: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + +postfix_keytab: /var/lib/gssproxy/clients/postfix.keytab + +postfix_selinux_policy_te: | + require { + type postfix_exec_t; + type postfix_smtpd_exec_t; + type postfix_cleanup_t; + type postfix_cleanup_exec_t; + type postfix_master_t; + type postfix_cleanup_t; + type postfix_smtpd_t; + type gssproxy_t; + type gssproxy_var_lib_t; + class file getattr; + class dir search; + class sock_file write; + class unix_stream_socket connectto; + class process noatsecure; + class key { read view write }; + } + + #============= postfix_smtpd_t ============== + allow postfix_smtpd_t gssproxy_t:unix_stream_socket connectto; + allow postfix_smtpd_t gssproxy_var_lib_t:dir search; + allow postfix_smtpd_t gssproxy_var_lib_t:sock_file write; + allow postfix_smtpd_t postfix_master_t:key { read view write }; + + #============= postfix_master_t ============== + allow postfix_master_t postfix_smtpd_t:process noatsecure; + allow postfix_master_t postfix_smtpd_t:key { read write }; + allow postfix_master_t postfix_cleanup_t:process noatsecure; + allow postfix_master_t gssproxy_t:unix_stream_socket connectto; + allow postfix_master_t gssproxy_var_lib_t:dir search; + allow postfix_master_t gssproxy_var_lib_t:sock_file write; + + #============= postfix_cleanup_t ============== + allow postfix_cleanup_t gssproxy_var_lib_t:dir search; + allow postfix_cleanup_t gssproxy_var_lib_t:sock_file write; + allow postfix_cleanup_t gssproxy_t:unix_stream_socket connectto; + allow postfix_cleanup_t postfix_master_t:key read; + allow postfix_cleanup_t postfix_smtpd_t:key read; + + #============= gssproxy_t ============== + allow gssproxy_t postfix_cleanup_exec_t:file getattr; + allow gssproxy_t postfix_smtpd_exec_t:file getattr; + allow gssproxy_t postfix_exec_t:file getattr; |