summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2014-07-03 04:26:26 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-06-07 02:52:20 +0200
commit1c357b55931a0d4fbd15d51d61ec4e81d4f38aa5 (patch)
treed5f37b52487f75c3ffe40a39c94ea570c32816a5
parentdfe8b222dc5067e1019d7ab5744df55b2c314ce8 (diff)
Install amavisd-new on the outgoing SMTP proxy.
For DKIM signing and virus checking.
-rw-r--r--common.yml7
-rw-r--r--roles/IMAP/files/etc/amavis/conf.d/05-domain_id20
-rw-r--r--roles/IMAP/handlers/main.yml3
-rw-r--r--roles/IMAP/tasks/main.yml1
-rw-r--r--roles/IMAP/tasks/spam.yml3
-rw-r--r--roles/IMAP/templates/etc/amavis/conf.d/15-content_filter_mode.j229
-rw-r--r--roles/IMAP/templates/etc/amavis/conf.d/50-user.j2135
-rw-r--r--roles/amavis/handlers/main.yml10
-rw-r--r--roles/amavis/tasks/main.yml (renamed from roles/IMAP/tasks/amavis.yml)34
-rw-r--r--roles/amavis/templates/etc/amavis/conf.d/50-user.j2182
-rw-r--r--roles/common/files/etc/logcheck/ignore.d.server/postfix-local2
-rw-r--r--roles/common/files/etc/postfix/master.cf27
-rwxr-xr-xroles/common/files/usr/local/bin/genkeypair.sh4
-rw-r--r--roles/out/templates/etc/postfix/main.cf.j24
14 files changed, 255 insertions, 206 deletions
diff --git a/common.yml b/common.yml
index 99628a3..d069ecc 100644
--- a/common.yml
+++ b/common.yml
@@ -39,3 +39,10 @@
tags: nginx,www,web
roles:
- common-web
+
+- name: Configure amavis
+ hosts: MDA:out
+ gather_facts: False
+ tags: amavis
+ roles:
+ - amavis
diff --git a/roles/IMAP/files/etc/amavis/conf.d/05-domain_id b/roles/IMAP/files/etc/amavis/conf.d/05-domain_id
deleted file mode 100644
index 19f10ed..0000000
--- a/roles/IMAP/files/etc/amavis/conf.d/05-domain_id
+++ /dev/null
@@ -1,20 +0,0 @@
-use strict;
-
-# $mydomain is used just for convenience in the config files and it is not
-# used internally by amavisd-new except in the default X_HEADER_LINE (which
-# Debian overrides by default anyway).
-
-$mydomain = "fripost.org";
-
-# amavisd-new needs to know which email domains are to be considered local
-# to the administrative domain. Only emails to "local" domains are subject
-# to certain functionality, such as the addition of spam tags.
-#
-# Default local domains to $mydomain and all subdomains. Remember to
-# override or redefine this if $mydomain is changed later in the config
-# sequence.
-
-@local_domains_acl = ( ".$mydomain" );
-@local_domains_maps = ( ".$mydomain" );
-
-1; # ensure a defined return
diff --git a/roles/IMAP/handlers/main.yml b/roles/IMAP/handlers/main.yml
index bda2ab9..c14468a 100644
--- a/roles/IMAP/handlers/main.yml
+++ b/roles/IMAP/handlers/main.yml
@@ -8,9 +8,6 @@
- name: Reload Postfix
service: name=postfix state=reloaded
-- name: Restart ClamAV
- service: name=clamav-daemon state=restarted
-
- name: Compile Spamassassin rules
sudo_user: debian-spamd
# it might take a while...
diff --git a/roles/IMAP/tasks/main.yml b/roles/IMAP/tasks/main.yml
index b43f9fb..c6fbbd9 100644
--- a/roles/IMAP/tasks/main.yml
+++ b/roles/IMAP/tasks/main.yml
@@ -1,5 +1,4 @@
---
- include: imap.yml tags=imap,dovecot
- include: mda.yml tags=mda,mail,postfix
-- include: amavis.yml tags=amavis
- include: spam.yml tags=spam,spamassassin
diff --git a/roles/IMAP/tasks/spam.yml b/roles/IMAP/tasks/spam.yml
index 51fde4b..a8fbe71 100644
--- a/roles/IMAP/tasks/spam.yml
+++ b/roles/IMAP/tasks/spam.yml
@@ -1,6 +1,9 @@
- name: Install spamassassin
apt: pkg={{ item }}
with_items:
+ # The following two lines are for the policy lookup (made by amavis)
+ - libnet-ldap-perl
+ - libauthen-sasl-perl
- razor
- spamassassin
- spamc
diff --git a/roles/IMAP/templates/etc/amavis/conf.d/15-content_filter_mode.j2 b/roles/IMAP/templates/etc/amavis/conf.d/15-content_filter_mode.j2
deleted file mode 100644
index cde0452..0000000
--- a/roles/IMAP/templates/etc/amavis/conf.d/15-content_filter_mode.j2
+++ /dev/null
@@ -1,29 +0,0 @@
-use strict;
-
-# You can modify this file to re-enable SPAM checking through spamassassin
-# and to re-enable antivirus checking.
-
-#
-# Default antivirus checking mode
-# Please note, that anti-virus checking is DISABLED by
-# default.
-# If You wish to enable it, please uncomment the following lines:
-
-
-@bypass_virus_checks_maps = (
- \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
-
-
-#
-# Default SPAM checking mode
-# Please note, that anti-spam checking is DISABLED by
-# default.
-# If You wish to enable it, please uncomment the following lines:
-
-
-{% if 'MDA' in group_names -%}
-@bypass_spam_checks_maps = (
- \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
-{% endif %}
-
-1; # ensure a defined return
diff --git a/roles/IMAP/templates/etc/amavis/conf.d/50-user.j2 b/roles/IMAP/templates/etc/amavis/conf.d/50-user.j2
deleted file mode 100644
index b3ae7a9..0000000
--- a/roles/IMAP/templates/etc/amavis/conf.d/50-user.j2
+++ /dev/null
@@ -1,135 +0,0 @@
-use strict;
-
-#
-# Place your configuration directives here. They will override those in
-# earlier files.
-#
-# See /usr/share/doc/amavisd-new/ for documentation and examples of
-# the directives you can use in this file
-#
-
-# $max_servers: num of pre-forked children (2..30 is common). It *must*
-# match the number set in /etc/postfix/master.cf "maxproc" column for
-# the amavisfeed service.
-$max_servers = 2;
-
-# list your internal networks
-@mynetworks = qw( 127.0.0.0/8 172.16.0.1/32 );
-
-
-# Always deliver messages (force *_lovers_maps to [1])
-$final_virus_destiny = D_PASS;
-$final_banned_destiny = D_PASS;
-$final_unchecked_destiny = D_PASS;
-$final_spam_destiny = D_PASS;
-$final_bad_header_destiny = D_PASS;
-$final_destiny_by_ccat{&CC_OVERSIZED} = D_PASS;
-
-%lovers_maps_by_ccat = (
- CC_CATCHALL, 1,
-);
-
-
-# Disable quarantine (force *_quarantine_to_maps to [1]; don't forget to
-# disable setting amavisSpamQuarantineCutoffLevel and amavisVirusQuarantine*To,
-# also)
-$QUARANTINEDIR = undef;
-%quarantine_method_by_ccat = (
- CC_CATCHALL, undef,
-);
-%admin_maps_by_ccat = (
- CC_CATCHALL, undef,
-);
-
-undef $undecipherable_subject_tag;
-
-# Defang virus only
-%defang_maps_by_ccat = (
- CC_VIRUS, 1,
- CC_CATCHALL, undef,
-);
-
-# Never BCC / DSN; don't forget to disallow setting amavisSpamDsnCutoffLevel
-# and amavis*Admin, also
-%always_bcc_by_ccat = (
- CC_CATCHALL, undef,
-);
-%dsn_bcc_by_ccat = (
- CC_CATCHALL, undef,
-);
-
-# Never warn sender / recipient; don't forget to disallow setting
-# amavisWarn*Recip, also
-%warnsender_by_ccat = ( # deprecated use, except perhaps for CC_BADH
- CC_CATCHALL, undef,
-);
-%warnrecip_maps_by_ccat = (
- CC_CATCHALL, undef,
-);
-
-@message_size_limit_maps = (); # per-recipient limits
-
-
-%banned_rules = (
- 'NO-MS-EXEC'=> new_RE( qr'^\.exe-ms$' ),
- 'PASSALL' => new_RE( [qr'^' => 0] ),
- 'ALLOW_EXE' => new_RE( qr'.\.(vbs|pif|scr|bat)$'i, [qr'^\.exe$' => 0] ),
- 'ALLOW_VBS' => new_RE( [qr'.\.vbs$' => 0] ),
-);
-
-
-$enable_ldap = 1;
-$default_ldap = {
- hostname => 'ldapi://',
- sasl => 1,
- sasl_mech => 'EXTERNAL',
- deref => 'never',
- timeout => 5,
- scope => 'one',
- base => 'fvd=%d,ou=virtual,o=mailHosting,dc=fripost,dc=org',
- # XXX: ideally we would use %u in the base and the query_filter, but
- # it's not supported as of amavis 2.7 (see the 'lookup_ldap'
- # subroutine in /usr/sbin/amavisd-new)
- query_filter => '(&(objectClass=amavisAccount)(ObjectClass=FripostVirtualUser)(fvl=%m))'
-};
-
-
-$recipient_delimiter = '+';
-$enable_dkim_verification = 1; # enable DKIM signatures verification
-
-
-# Per-recipient Bayes Database.
-@sa_username_maps = (
- new_RE ( [ qr'^(.+@[^@]+)$'i => '$1' ] ),
- 'amavis' # catch-all
-);
-
-# http://www.ijs.si/software/amavisd/amavisd-new-docs.html#pbanks-ex
-
-$inet_socket_port = 10041;
-
-$interface_policy{'10041'} = 'INBOUND';
-
-{% if 'out' in group_names %}
-$notify_method = 'smtp:[127.0.0.1]:{{ postfix_instance.out.port }}';
-{% else %}
-$notify_method = 'smtp:[outgoing.fripost.org]:{{ postfix_instance.out.port }}';
-{% endif %}
-$forward_method = 'lmtp:/var/run/dovecot/lmtp';
-$requeue_method = $forward_method;
-
-$sa_tag_level_deflt = undef;
-$sa_tag2_level_deflt = 5;
-$sa_kill_level_deflt = 5;
-$sa_dsn_cutoff_level = undef;
-$sa_quarantine_cutoff_level = undef;
-
-$policy_bank{'INBOUND'} = {
- originating => 0, # indicates a remote client, allows checking
- smtpd_greeting_banner =>
- '${helo-name} ${protocol} ${product} INBOUND service ready',
- mynetworks_maps => [], # avoids loading MYNETS policy unnecessarily
-};
-
-#------------ Do not modify anything below this line -------------
-1; # ensure a defined return
diff --git a/roles/amavis/handlers/main.yml b/roles/amavis/handlers/main.yml
new file mode 100644
index 0000000..65287e3
--- /dev/null
+++ b/roles/amavis/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart ClamAV
+ service: name=clamav-daemon state=restarted
+
+- name: Publish the public key in the DNS zone
+ # See the output of 'sudo genkeypair.sh dkim --privkey=/var/lib/dkim/outgoing.fripost.org.key'
+ fail: "msg={{ dkim.stdout }}"
+
+- name: Restart Amavis
+ service: name=amavis state=restarted
diff --git a/roles/IMAP/tasks/amavis.yml b/roles/amavis/tasks/main.yml
index 6f47328..354ade8 100644
--- a/roles/IMAP/tasks/amavis.yml
+++ b/roles/amavis/tasks/main.yml
@@ -2,8 +2,8 @@
apt: pkg={{ item }}
with_items:
- amavisd-new
- - libnet-ldap-perl
- - libauthen-sasl-perl
+ # Mail::DKIM
+ - libmail-dkim-perl
- gzip
- bzip2
- xz-utils
@@ -30,27 +30,33 @@
- Restart ClamAV
- Restart Amavis
-- name: Configure Amavis (1)
- copy: src=etc/amavis/conf.d/05-domain_id
- dest=/etc/amavis/conf.d/05-domain_id
+- name: Create directory /var/lib/dkim
+ file: path=/var/lib/dkim
+ state=directory
owner=root group=root
- mode=0644
- register: r2
+ mode=0755
+
+- name: Generate a private key for DKIM signing
+ command: genkeypair.sh dkim --privkey=/var/lib/dkim/outgoing.fripost.org.key --dns=outgoing -t rsa -b 2048
+ register: dkim
+ changed_when: dkim.rc == 0
+ failed_when: dkim.rc > 1
notify:
- Restart Amavis
+ - Publish the public key in the DNS zone
+ tags:
+ - genkey
-- name: Configure Amavis (2)
- template: src=etc/amavis/conf.d/{{ item }}.j2
- dest=/etc/amavis/conf.d/{{ item }}
+- name: Configure Amavis
+ template: src=etc/amavis/conf.d/50-user.j2
+ dest=/etc/amavis/conf.d/50-user
owner=root group=root
mode=0644
register: r3
- with_items:
- - 15-content_filter_mode
- - 50-user
notify:
- Restart Amavis
+- meta: flush_handlers
+
- name: Start Amavis
service: name=amavis state=started
- when: not (r1.changed or r2.changed or r3.changed)
diff --git a/roles/amavis/templates/etc/amavis/conf.d/50-user.j2 b/roles/amavis/templates/etc/amavis/conf.d/50-user.j2
new file mode 100644
index 0000000..adafd7f
--- /dev/null
+++ b/roles/amavis/templates/etc/amavis/conf.d/50-user.j2
@@ -0,0 +1,182 @@
+use strict;
+
+#
+# Place your configuration directives here. They will override those in
+# earlier files.
+#
+# See /usr/share/doc/amavisd-new/ for documentation and examples of
+# the directives you can use in this file
+#
+
+# $max_servers: num of pre-forked children (2..30 is common). It *must*
+# match the number set in /etc/postfix/master.cf "maxproc" column for
+# the amavisfeed service.
+$max_servers = 5;
+$recipient_delimiter = '+';
+
+$mydomain = 'fripost.org';
+$X_HEADER_LINE = "Debian $myproduct_name at $mydomain";
+undef $undecipherable_subject_tag;
+
+@mynetworks_maps = ();
+@remove_existing_spam_headers_maps = ();
+@bypass_virus_checks_maps = (); # load virus checking code
+
+
+$enable_dkim_verification = 1; # load DKIM signing/verifying code
+{% if 'out' not in group_names %}
+undef $enable_dkim_signing;
+@bypass_spam_checks_maps = (); # load spam checking code
+{% else %}
+$enable_dkim_signing = 1;
+# Sign *all* outgoing mails with *our* key (yes, amavis complains, but this is
+# safe as we force our domain with the 'd' tag).
+dkim_key(qr'^', 'outgoing', '/var/lib/dkim/outgoing.'.$mydomain.'.key');
+@dkim_signature_options_bysender_maps = (
+ { '.' => { d => $mydomain
+ , a => 'rsa-sha256'
+ , ttl => 21*24*3600
+ , c => 'relaxed/simple' } } );
+# Conform to RFC 4871 and don't sign Received: headers.
+$signed_header_fields{received} = 0;
+{% endif %}
+
+
+
+# Defang viruses only
+%defang_maps_by_ccat = ( CC_VIRUS, 1
+ , CC_CATCHALL, undef
+ );
+
+# Never BCC / DSN; don't forget to disallow setting amavisSpamDsnCutoffLevel
+# and amavis*Admin, also
+%always_bcc_by_ccat = ( CC_CATCHALL, undef );
+%dsn_bcc_by_ccat = ( CC_CATCHALL, undef );
+
+# Never warn sender or recipient; don't forget to disallow setting
+# amavisWarn*Recip, also
+%warnsender_by_ccat = ( CC_CATCHALL, undef );
+%warnrecip_maps_by_ccat = ( CC_CATCHALL, undef );
+
+
+# A couple of common banned rules one might can refer by their name
+%banned_rules = (
+ 'NO-MS-EXEC'=> new_RE( qr'^\.exe-ms$' ),
+ 'PASSALL' => new_RE( [qr'^' => 0] ),
+ 'ALLOW_EXE' => new_RE( qr'.\.(vbs|pif|scr|bat)$'i, [qr'^\.exe$' => 0] ),
+ 'ALLOW_VBS' => new_RE( [qr'.\.vbs$' => 0] ),
+);
+
+
+{% if 'MDA' in group_names %}
+$enable_ldap = 1; # Load Net::LDAP
+$default_ldap = {
+ hostname => 'ldapi://',
+ sasl => 1,
+ sasl_mech => 'EXTERNAL',
+ deref => 'never',
+ timeout => 5,
+ scope => 'one',
+ base => 'fvd=%d,ou=virtual,o=mailHosting,dc=fripost,dc=org',
+ # XXX: ideally we would use %u in the base and the query_filter, but
+ # it's not supported as of amavis 2.7 (see the 'lookup_ldap'
+ # subroutine in /usr/sbin/amavisd-new)
+ query_filter => '(&(objectClass=amavisAccount)(ObjectClass=FripostVirtualUser)(fvl=%m))'
+};
+{% endif %}
+
+
+# http://www.ijs.si/software/amavisd/amavisd-new-docs.html#pbanks-ex
+
+$protocol = 'LMTP';
+$inet_socket_port = [];
+
+{% if 'out' in group_names %}
+push @$inet_socket_port, 10040;
+$interface_policy{'10040'} = 'OUTGOING';
+{% endif %}
+{% if 'MDA' in group_names %}
+push @$inet_socket_port, 10041;
+$interface_policy{'10041'} = 'INCOMING';
+{% endif %}
+
+$QUARANTINEDIR = "$MYHOME/virusmails";
+$notify_method = 'smtp:[127.0.0.1]:16132'; # notifications
+$forward_method = 'smtp:[127.0.0.1]:10025'; # reinject
+$requeue_method = $notify_method; # requeue after quarantine
+
+# some defaults for spam checking
+$sa_tag_level_deflt = undef;
+$sa_tag2_level_deflt = 5;
+$sa_kill_level_deflt = 5;
+$sa_dsn_cutoff_level = undef;
+$sa_quarantine_cutoff_level = undef;
+
+
+# Here is an overall picture (sequence of events) of how pieces fit together
+#
+# bypass_virus_checks set for all recipients? ==> PASS
+# no viruses? ==> PASS
+# log virus if $log_templ is nonempty
+# quarantine if $virus_quarantine_to is nonempty
+# notify admin if $virus_admin (lookup) nonempty
+# notify recips if $warnvirusrecip and (recipient is local or $warn_offsite)
+# add address extensions for local recipients (when enabled)
+# send (non-)delivery notifications
+# to sender if DSN needed (BOUNCE or ($warnvirussender and D_PASS))
+# virus_lovers or final_destiny==D_PASS ==> PASS
+# DISCARD (2xx) or REJECT (5xx) (depending on final_*_destiny)
+
+
+# Mandatory DKIM signing and virus checking only
+$policy_bank{'OUTGOING'} = {
+ originating => 1,
+ enable_dkim_verification => 0,
+ smtpd_greeting_banner => '${helo-name} ${protocol} ${product} OUTGOING service ready',
+ forward_method => $forward_method,
+
+ # No black or white lists
+ message_size_limit_maps => [],
+ whitelist_sender_maps => [],
+ blacklist_sender_maps => [],
+
+ # Check for viruses (regardless of the recipient), but bypass all other checks
+ bypass_virus_checks_maps => undef,
+ bypass_banned_checks_maps => 1,
+ bypass_header_checks_maps => 1,
+ bypass_spam_checks_maps => 1,
+
+ # If found, notify postmaster, quarantine and discard
+ quarantine_to_maps_by_ccat => { CC_VIRUS, [$virus_quarantine_to], CC_CATCHALL, undef },
+ quarantine_method_by_ccat => { CC_VIRUS, [$virus_quarantine_method], CC_CATCHALL, undef },
+ admin_maps_by_ccat => { CC_VIRUS, ["postmaster\@$mydomain"], CC_CATCHALL, undef },
+ addr_extension_maps_by_ccat=> { CC_CATCHALL, undef },
+ lovers_maps_by_ccat => { CC_VIRUS, undef, CC_CATCHALL, 1 },
+ final_destiny_by_ccat => { CC_VIRUS, D_DISCARD, CC_CATCHALL, D_PASS },
+};
+
+$policy_bank{'INCOMING'} = {
+ originating => 0,
+ enable_dkim_verification => 1,
+ smtpd_greeting_banner => '${helo-name} ${protocol} ${product} INCOMING service ready',
+ forward_method => $forward_method,
+ message_size_limit_maps => [],
+
+ # Per-recipient Bayes Database
+ sa_username_maps => [ new_RE ( [ qr'^(.+@.+)$'i => '$1' ] )
+ , 'amavis' # catch-all
+ ],
+
+ # Never quarantine
+ # (Remember to disallow setting amavisSpamQuarantineCutoffLevel and
+ # amavisVirusQuarantine*To in the LDAP schema.)
+ quarantine_method_by_ccat => { CC_CATCHALL, undef },
+ admin_maps_by_ccat => { CC_CATCHALL, undef },
+
+ # Always deliver messages
+ final_destiny_by_ccat => { CC_CATCHALL, D_PASS },
+ lovers_maps_by_ccat => { CC_CATCHALL, 1 },
+};
+
+#------------ Do not modify anything below this line -------------
+1; # ensure a defined return
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 e153ce0..d3b7fae 100644
--- a/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
+++ b/roles/common/files/etc/logcheck/ignore.d.server/postfix-local
@@ -33,3 +33,5 @@
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-(mda|out)/smtpd\[[[:digit:]]+\]: [[:xdigit:]]{10}: client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\], orig_queue_id=[[:xdigit:]]{10}, orig_client=[._[:alnum:]-]+\[[[:xdigit:].:]{3,39}\]$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [A-Z[:digit:]]+: to=<[^[:space:]]+>,( orig_to=<[^[:space:]]+>,) relay=[^[:space:]]+, delay=[[:digit:]]+, status=deferred \(host [^[:space:]]+ said: [45][[:digit:]]{2} <[^[:space:]]*>: Recipient address rejected: Greylisted for [[:digit:]]+ (seconds|minutes)(\(see http://isg.ee.ethz.ch/tools/postgrey/help/[.[:alnum:]-]+.html\))? \(in reply to (HELO|EHLO|MAIL FROM|RCPT TO|DATA|end of DATA) command\)\)$
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ postfix-out/smtp\[[[:digit:]]+\]: [[:alnum:]]+: to=<.*>,( orig_to=<[^[:space:]]+>,)? relay=[^[:space:]]+\](:[[:digit:]]+)?,( conn_use=[[:digit:]]+,)? delay=[[:digit:].]+,( delays=[[:digit:]./]+,)?( dsn=4\.[[:digit:]]\.[[:digit:]],)? status=deferred \(host [^[:space:]]+\] said: .*$
+#
+^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ amavis\[[[:digit:]]+\]: \([-[:digit:]]+\) Passed CLEAN {RelayedOutbound}, OUTGOING LOCAL \[(IPv6:)?[[:xdigit:].:]{3,39}\]:[[:digit:]]+( \[[[:xdigit:].:]{3,39}\])? <[^>]*> -> <[^>]*>(,<[^>]*>)*,( Queue-ID: [[:xdigit:]]+,)?( Message-ID: <[^>]+>,)? mail_id: [_-+[:alnum:]]+, Hits: -, size: [[:digit:]]+, queued_as: [[:xdigit:]]+, dkim_new=[-.:[:alnum:]]+, [[:digit:]]+ ms$
diff --git a/roles/common/files/etc/postfix/master.cf b/roles/common/files/etc/postfix/master.cf
index 70f7f4e..02e1658 100644
--- a/roles/common/files/etc/postfix/master.cf
+++ b/roles/common/files/etc/postfix/master.cf
@@ -45,7 +45,32 @@ reserved-alias unix - n n - - pipe
flags=Rhu user=nobody argv=/usr/local/sbin/reserved-alias.pl ${sender} ${original_recipient} @fripost.org
mlmmj unix - n n - - pipe
flags=Rhu user=mlmmj argv=/usr/bin/mlmmj-receive -L /var/spool/mlmmj/${domain}/${user}
-amavisfeed unix - - n - 2 lmtp
+
+# Client part (lmtp) - amavis
+amavisfeed unix - - n - 5 lmtp
-o lmtp_destination_recipient_limit=1000
-o lmtp_send_xforward_command=yes
-o lmtp_data_done_timeout=1200s
+ -o disable_dns_lookups=yes
+
+# Server part (smtpd) - amavis (if the MDA and outgoing proxy are on the
+# same machine, we need to create another entry, on another port.)
+127.0.0.1:10025 inet n - n - - smtpd
+ -o content_filter=
+ -o smtpd_delay_reject=no
+ -o smtpd_client_restrictions=permit_mynetworks,reject
+ -o smtpd_helo_restrictions=
+ -o smtpd_sender_restrictions=
+ -o smtpd_recipient_restrictions=permit_mynetworks,reject
+ -o smtpd_data_restrictions=reject_unauth_pipelining
+ -o smtpd_end_of_data_restrictions=
+ -o smtpd_restriction_classes=
+ -o mynetworks_style=host
+ -o smtpd_error_sleep_time=0
+ -o smtpd_soft_error_limit=1001
+ -o smtpd_hard_error_limit=1000
+ -o smtpd_client_connection_count_limit=0
+ -o smtpd_client_connection_rate_limit=0
+ -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks,no_milters
+ -o local_header_rewrite_clients=
+ -o smtpd_authorized_xforward_hosts=127.0.0.0/8
diff --git a/roles/common/files/usr/local/bin/genkeypair.sh b/roles/common/files/usr/local/bin/genkeypair.sh
index 16f9658..c5dfb30 100755
--- a/roles/common/files/usr/local/bin/genkeypair.sh
+++ b/roles/common/files/usr/local/bin/genkeypair.sh
@@ -40,7 +40,7 @@ usage() {
Command:
x509: generate a self-signed X.509 server certificate
csr: generate a Certificate Signing Request
- dkim: generate a DKIM private key
+ dkim: generate a private key (to use for DKIM signing)
Options:
-t type: key type (default: rsa)
@@ -169,7 +169,7 @@ if [ "$cmd" = x509 -o "$cmd" = csr ]; then
[ "$cmd" = x509 ] && x509=-x509 || x509=
openssl req -config "$config" -new $x509 ${hash:+-$hash} -key "$privkey" >"$pubkey" || exit 2
elif [ "$cmd" = dkim ]; then
- echo "Add the following TXT record to your DNS zone:" >&2
+ echo "Add the following TXT record to your DNS zone:"
echo "${dns:-$(date +%Y%m%d)}._domainkey\tIN\tTXT ( "
# See https://tools.ietf.org/html/rfc4871#section-3.6.1
# t=s: the "i=" domain in signature headers MUST NOT be a subdomain of "d="
diff --git a/roles/out/templates/etc/postfix/main.cf.j2 b/roles/out/templates/etc/postfix/main.cf.j2
index 11bcc10..9bf5882 100644
--- a/roles/out/templates/etc/postfix/main.cf.j2
+++ b/roles/out/templates/etc/postfix/main.cf.j2
@@ -19,7 +19,7 @@ append_dot_mydomain = no
# Turn off all TCP/IP listener ports except that necessary for the
# outgoing SMTP proxy.
-master_service_disable = !{{ postfix_instance.out.port }}.inet inet
+master_service_disable = !{{ postfix_instance.out.port }}.inet !127.0.0.1:10025.inet inet
queue_directory = /var/spool/postfix-{{ postfix_instance[inst].name }}
data_directory = /var/lib/postfix-{{ postfix_instance[inst].name }}
@@ -91,3 +91,5 @@ smtpd_recipient_restrictions =
smtpd_data_restrictions =
reject_unauth_pipelining
+
+content_filter = amavisfeed:[127.0.0.1]:10040