diff options
-rw-r--r-- | group_vars/all.yml | 2 | ||||
-rw-r--r-- | roles/MX/files/etc/postfix/reject-unknown-client-hostname.cf | 10 | ||||
-rw-r--r-- | roles/MX/tasks/main.yml | 9 | ||||
-rw-r--r-- | roles/MX/templates/etc/postfix/access-list.cidr.j2 | 16 | ||||
-rw-r--r-- | roles/MX/templates/etc/postfix/main.cf.j2 | 51 | ||||
-rw-r--r-- | roles/common/files/etc/logcheck/ignore.d.server/postfix-local | 5 |
6 files changed, 72 insertions, 21 deletions
diff --git a/group_vars/all.yml b/group_vars/all.yml index 236527e..0406a7e 100644 --- a/group_vars/all.yml +++ b/group_vars/all.yml @@ -35,7 +35,7 @@ postfix_instance: IMAP: { name: mda , addr: "{{ (groups.all | length > 1) | ternary( ipsec[ hostvars[groups.IMAP[0]].inventory_hostname_short ], '127.0.0.1') }}" , port: 2526 } - MX: { name: mx, group: mta, backup: mx3.fripost.org } + MX: { name: mx, group: mta } out: { name: out, group: mta , addr: "{{ (groups.all | length > 1) | ternary( ipsec[ hostvars[groups.out[0]].inventory_hostname_short ], '127.0.0.1') }}" , port: 2525 } diff --git a/roles/MX/files/etc/postfix/reject-unknown-client-hostname.cf b/roles/MX/files/etc/postfix/reject-unknown-client-hostname.cf new file mode 100644 index 0000000..6969f75 --- /dev/null +++ b/roles/MX/files/etc/postfix/reject-unknown-client-hostname.cf @@ -0,0 +1,10 @@ +server_host = ldapi://%2Fvar%2Fspool%2Fpostfix-mx%2Fprivate%2Fldapi/ +version = 3 +search_base = fvd=%d,ou=virtual,dc=fripost,dc=org +domain = static:all +scope = one +bind = sasl +sasl_mechs = EXTERNAL +query_filter = (&(objectClass=FripostVirtualList)(!(objectClass=FripostPendingEntry))(fvl=%u)(fripostIsStatusActive=TRUE)) +result_attribute = fvl +result_format = reject_unknown_client_hostname diff --git a/roles/MX/tasks/main.yml b/roles/MX/tasks/main.yml index bd6f088..78362ca 100644 --- a/roles/MX/tasks/main.yml +++ b/roles/MX/tasks/main.yml @@ -17,6 +17,7 @@ with_items: - main.cf - master.cf + - access-list.cidr notify: - Reload Postfix @@ -61,6 +62,14 @@ owner=root group=root mode=0644 +- name: Copy recipient access(5) map + copy: src=etc/postfix/reject-unknown-client-hostname.cf + dest=/etc/postfix-{{ postfix_instance[inst].name }}/reject-unknown-client-hostname.cf + owner=root group=root + mode=0644 + notify: + - Reload Postfix + - name: Compile the Postfix transport maps # trivial-rewrite(8) is a long-running process, so it's safer to reload postmap: instance={{ postfix_instance[inst].name }} diff --git a/roles/MX/templates/etc/postfix/access-list.cidr.j2 b/roles/MX/templates/etc/postfix/access-list.cidr.j2 new file mode 100644 index 0000000..bd6e3d8 --- /dev/null +++ b/roles/MX/templates/etc/postfix/access-list.cidr.j2 @@ -0,0 +1,16 @@ +######################################################################## +# Access list, see cidr_table(5) +# +# {{ ansible_managed }} +# Do NOT edit this file directly! + +{% if ipsec_subnet is defined %} +{{ ipsec_subnet }} permit +{% endif %} + +{% for ip in lookup('pipe', 'dig +short outgoing.fripost.org A').splitlines() | sort -%} +{{ ip }}/32 permit +{% endfor %} +{% for ip in lookup('pipe', 'dig +short outgoing.fripost.org AAAA').splitlines() | sort -%} +{{ ip }}/128 permit +{% endfor %} diff --git a/roles/MX/templates/etc/postfix/main.cf.j2 b/roles/MX/templates/etc/postfix/main.cf.j2 index 8e6040f..e5792c4 100644 --- a/roles/MX/templates/etc/postfix/main.cf.j2 +++ b/roles/MX/templates/etc/postfix/main.cf.j2 @@ -93,40 +93,44 @@ invalid_hostname_reject_code = 554 multi_recipient_bounce_reject_code = 554 non_fqdn_reject_code = 554 relay_domains_reject_code = 554 -unknown_address_reject_code = 554 -unknown_client_reject_code = 554 -unknown_hostname_reject_code = 554 unknown_local_recipient_reject_code = 554 unknown_relay_recipient_reject_code = 554 unknown_virtual_alias_reject_code = 554 unknown_virtual_mailbox_reject_code = 554 +postscreen_access_list = + permit_mynetworks + cidr:$config_directory/access-list.cidr postscreen_dnsbl_whitelist_threshold = -1 + postscreen_blacklist_action = drop -postscreen_dnsbl_threshold = 3 +postscreen_dnsbl_threshold = 8 postscreen_dnsbl_action = enforce postscreen_dnsbl_sites = - zen.spamhaus.org*2 + zen.spamhaus.org=127.0.0.[10;11]*8 + zen.spamhaus.org=127.0.0.[4..7]*6 + zen.spamhaus.org=127.0.0.3*4 + zen.spamhaus.org=127.0.0.2*3 #swl.spamhaus.org*-4 - b.barracudacentral.org*2 - bl.spameatingmonkey.net*2 - bl.spamcop.net - dnsbl.sorbs.net - psbl.surriel.com - bl.mailspike.net + b.barracudacentral.org=127.0.0.2*7 + bl.mailspike.net=127.0.0.2*5 + bl.mailspike.net=127.0.0.[10..12]*4 + wl.mailspike.net=127.0.0.[18..20]*-2 + bl.spameatingmonkey.net=127.0.0.2*4 + bl.spamcop.net=127.0.0.2*2 + dnsbl.sorbs.net=127.0.0.10*8 + dnsbl.sorbs.net=127.0.0.5*6 + dnsbl.sorbs.net=127.0.0.7*3 + dnsbl.sorbs.net=127.0.0.8*2 + dnsbl.sorbs.net=127.0.0.6*2 + dnsbl.sorbs.net=127.0.0.9*2 list.dnswl.org=127.0.[0..255].0*-2 list.dnswl.org=127.0.[0..255].1*-3 list.dnswl.org=127.0.[0..255].[2..3]*-4 postscreen_greet_action = enforce -postscreen_whitelist_interfaces = -{%- for ip in lookup('pipe', 'dig +short '+ postfix_instance.MX.backup +' A').splitlines() %} - !{{ ip }} -{%- endfor %} -{%- for ip in lookup('pipe', 'dig +short '+ postfix_instance.MX.backup +' AAAA').splitlines() %} - ![{{ ip }}] -{%- endfor %} - static:all +postscreen_whitelist_interfaces = static:all + smtpd_client_restrictions = permit_mynetworks @@ -139,6 +143,7 @@ smtpd_helo_restrictions = smtpd_sender_restrictions = reject_non_fqdn_sender + reject_unknown_sender_domain smtpd_relay_restrictions = reject_non_fqdn_recipient @@ -146,6 +151,14 @@ smtpd_relay_restrictions = reject_unauth_destination reject_unlisted_recipient +smtpd_recipient_restrictions = + check_client_access cidr:$config_directory/access-list.cidr + check_recipient_access ldap:$config_directory/reject-unknown-client-hostname.cf + reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[2..99] + reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[2..99] + defer_if_reject reject_rhsbl_reverse_client dbl.spamhaus.org=127.0.1.[100..254] + defer_if_reject reject_rhsbl_sender dbl.spamhaus.org=127.0.1.[100..254] + smtpd_data_restrictions = reject_unauth_pipelining diff --git a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local index 2ca704d..e32fce6 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local @@ -29,7 +29,10 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: improper command pipelining after (EHLO|HELO|MAIL|QUIT) from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: warning: hostname [._[:alnum:]-]+ does not resolve to address [[:xdigit:].:]{3,39}(: Name or service not known)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: warning: Connection concurrency limit exceeded: [0-9]+ from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\] for service smtpd$ -^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)? +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} <[^>]+>: Helo command rejected: need fully-qualified hostname;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 4[[:digit:]]{2} 4(\.[[:digit:]]){2} <[^>]+>: Sender address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]: 5[[:digit:]]{2} 5(\.[[:digit:]]){2} Service unavailable; (Unverified Client host|Sender address) \[\S+\] blocked using [._[:alnum:]-]+; https?://[^[:blank:];]+; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-mx/smtpd\[[[:digit:]]+\]: NOQUEUE: reject: RCPT from [._[:alnum:]-]+\[([[:xdigit:].:]{3,39})\]: 4[[:digit:]]{2} 4(\.[[:digit:]]){2} Client host rejected: cannot find your hostname, \[\1\]; from=<[^>]*> to=<[^>]+> proto=E?SMTP( helo=<[^>]+>)?$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(msa|mx)/smtpd\[[[:digit:]]+\]: timeout after [-[:upper:]]+( \([[:digit:]]+ bytes\))? from [^[:space:]]+$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-((msa|mx)/smtpd|out/smtp)\[[[:digit:]]+\]: warning: (tls_text_name: [-._[:alnum:]]+\[[[:xdigit:].:]{3,39}\]: )?peer certificate has no (subject CN|issuer Organization)$ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-msa/smtpd\[[[:digit:]]+\]: (NOQUEUE|[[:xdigit:]]+): reject: [[:upper:]]+ from [^[:space:]]+: 450( 4\.1\.2)? <[^>]*>: Recipient address rejected: Domain not found;( from=<[^>]*> to=<[^>]+>)? proto=E?SMTP( helo=<[^[:space:]]+>)?$ |