From 48c35a4b7123ab787e4aae3c74b060f751b7ef5c Mon Sep 17 00:00:00 2001 From: Antonio Terceiro Date: Mon, 23 Feb 2015 12:40:36 -0300 Subject: [PATCH] email relay configuration --- config/roles/email_server.rb | 4 ++-- config/roles/server.rb | 2 +- config/roles/social_server.rb | 2 +- cookbooks/email/recipes/client.rb | 9 +++++++++ cookbooks/email/recipes/default.rb | 9 +++++++++ cookbooks/email/recipes/relay.rb | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ cookbooks/mailman/recipes/default.rb | 15 +++++++-------- nodes.yaml | 1 + test/bin/clear-email-queue | 5 +++++ test/bin/curl-host | 8 ++++++++ test/bin/wait-for-email-to | 21 +++++++++++++++++++++ test/mail_relay_test.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 cookbooks/email/recipes/client.rb create mode 100644 cookbooks/email/recipes/default.rb create mode 100644 cookbooks/email/recipes/relay.rb create mode 100755 test/bin/clear-email-queue create mode 100755 test/bin/curl-host create mode 100755 test/bin/wait-for-email-to create mode 100644 test/mail_relay_test.sh diff --git a/config/roles/email_server.rb b/config/roles/email_server.rb index 4da627e..9f3ca46 100644 --- a/config/roles/email_server.rb +++ b/config/roles/email_server.rb @@ -1,3 +1,3 @@ -name 'database_server' +name 'email_server' description 'E-mail server' -run_list 'recipe[postfix]' +run_list 'recipe[email::relay]' diff --git a/config/roles/server.rb b/config/roles/server.rb index 2abd5b8..42fcec6 100644 --- a/config/roles/server.rb +++ b/config/roles/server.rb @@ -1,3 +1,3 @@ name 'server' description 'Common configuration for all servers' -run_list 'recipe[basics]' +run_list 'recipe[basics]', 'recipe[email::client]' diff --git a/config/roles/social_server.rb b/config/roles/social_server.rb index 1a5e11c..1dda53f 100644 --- a/config/roles/social_server.rb +++ b/config/roles/social_server.rb @@ -1,3 +1,3 @@ name 'database_server' description 'Social networking server' -run_list 'recipe[noosfero]' +#run_list 'recipe[noosfero]' diff --git a/cookbooks/email/recipes/client.rb b/cookbooks/email/recipes/client.rb new file mode 100644 index 0000000..3770e5e --- /dev/null +++ b/cookbooks/email/recipes/client.rb @@ -0,0 +1,9 @@ +include_recipe 'email' + +execute 'postfix:configrelay' do + command "postconf relayhost=[#{node['peers']['email']}]" + notifies :reload, 'service[postfix]' + + # not on the relay host itself + not_if { node.hostname == 'email' } +end diff --git a/cookbooks/email/recipes/default.rb b/cookbooks/email/recipes/default.rb new file mode 100644 index 0000000..347aece --- /dev/null +++ b/cookbooks/email/recipes/default.rb @@ -0,0 +1,9 @@ +include_recipe 'email' + +package 'postfix' +package 'mailx' # for testing, etc + +service 'postfix' do + action [:enable, :start] + supports :reload => true +end diff --git a/cookbooks/email/recipes/relay.rb b/cookbooks/email/recipes/relay.rb new file mode 100644 index 0000000..cd3c615 --- /dev/null +++ b/cookbooks/email/recipes/relay.rb @@ -0,0 +1,48 @@ +include_recipe 'email' + +# smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem +# smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key + +postfix_config = { + + myhostname: node['config']['relay_hostname'], + + relay_domains: [ + node['config']['lists_hostname'], + node['config']['external_hostname'], + ].join(', '), + + transport_maps: 'hash:/etc/postfix/transport', + + mynetworks: '127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 ' + node['peers'].values.sort.join(' '), + +} + +execute 'postfix:relay:config' do + command postfix_config.map { |k,v| "postconf #{k}='#{v}'" }.join(' ; ') + notifies :reload, 'service[postfix]' +end + +execute 'postfix:interfaces:all' do + command "postconf inet_interfaces=all" + notifies :restart, 'service[postfix]' + not_if { system('grep -q "inet_interfaces\s*=\s*all" /etc/postfix/main.cf') } +end + +transport = { + node['config']['lists_hostname'] => node['peers']['integration'], + node['config']['external_hostname'] => node['peers']['integration'], +} + +file '/etc/postfix/transport' do + owner 'root' + group 'root' + mode 0644 + content transport.map { |domain,ip| "#{domain}\tsmtp:[#{ip}]\n" }.join + notifies :run, 'execute[transport:postmap]' +end + +execute 'transport:postmap' do + command "postmap /etc/postfix/transport" + action :nothing +end diff --git a/cookbooks/mailman/recipes/default.rb b/cookbooks/mailman/recipes/default.rb index 1386833..86eb297 100644 --- a/cookbooks/mailman/recipes/default.rb +++ b/cookbooks/mailman/recipes/default.rb @@ -22,15 +22,17 @@ service 'mailman' do supports :restart => true end -package 'postfix' -package 'mailx' # for testing, etc - -execute 'postfix-config' do +execute 'postfix:config' do command [ "postconf relay_domains=#{node['config']['lists_hostname']}", "postconf transport_maps=hash:/etc/postfix/transport", ].join(' && ') - only_if { !system('grep', node['config']['lists_hostname'], '/etc/postfix/main.cf') } + notifies :reload, 'service[postfix]' +end + +execute 'postfix:interfaces' do + command "postconf inet_interfaces=\"$(cat /etc/hostname), localhost\"" + not_if { system('postconf inet_interfaces | grep -q \'=\s*localhost\s*$\'') } notifies :restart, 'service[postfix]' end @@ -69,6 +71,3 @@ ruby_block 'configure-mailman-transport' do only_if { !system('grep', '^mailman', '/etc/postfix/master.cf')} end -service 'postfix' do - action [:enable, :reload] -end diff --git a/nodes.yaml b/nodes.yaml index eb5e75d..df9edab 100644 --- a/nodes.yaml +++ b/nodes.yaml @@ -14,6 +14,7 @@ vagrant@integration: email_subject_prefix: '[spb]' lists_hostname: listas.softwarepublico.dev lists_admin: paulo@softwarelivre.org + relay_hostname: relay.softwarepublico.dev peers: &PEERS integration: 10.10.10.2 email: 10.10.10.3 diff --git a/test/bin/clear-email-queue b/test/bin/clear-email-queue new file mode 100755 index 0000000..66e0756 --- /dev/null +++ b/test/bin/clear-email-queue @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +sudo postsuper -d ALL >/dev/null 2>&1 diff --git a/test/bin/curl-host b/test/bin/curl-host new file mode 100755 index 0000000..d329a06 --- /dev/null +++ b/test/bin/curl-host @@ -0,0 +1,8 @@ +#!/bin/sh + +set -eu + +host="$1" +shift + +$(dirname $0)/curl --header "Host: $host" "$@" diff --git a/test/bin/wait-for-email-to b/test/bin/wait-for-email-to new file mode 100755 index 0000000..56eb34e --- /dev/null +++ b/test/bin/wait-for-email-to @@ -0,0 +1,21 @@ +#!/bin/sh + +set -eu + +to="$1" + +waited=0 + +while [ $waited -lt 10 ]; do + if (sudo postqueue -p | grep -q "$to"); then + sudo postqueue -p | grep -c "$to" + exit + fi + sleep 1 + waited=$(($waited + 1)) +done + +echo "E: no message for $to arrived at the mail realy" >&2 +echo 0 +exit 1 + diff --git a/test/mail_relay_test.sh b/test/mail_relay_test.sh new file mode 100644 index 0000000..707e042 --- /dev/null +++ b/test/mail_relay_test.sh @@ -0,0 +1,44 @@ +. $(dirname $0)/test_helper.sh + +test_inbound_mail() { + run_on integration create-list mylist foo@example.com + + # sending FROM EMAIL RELAY HOST + run_on email send-email foo@example.com mylist@listas.softwarepublico.dev + + messages=$(run_on integration wait-for-messages mylist) + + run_on integration remove-list mylist + + assertEquals 'Message arrives at the mailing list' '1' "$messages" +} + +_test_outbound_email() { + machine="$1" + + run_on email clear-email-queue + + run_on $machine send-email sender@example.com receiver@example.com + + messages=$(run_on email wait-for-email-to receiver@example.com) + + run_on email clear-email-queue + + assertEquals 'Message delivered through relay' 1 "$messages" +} + +test_outbound_email_integration() { + _test_outbound_email integration +} +test_outbound_email_database() { + _test_outbound_email database +} +test_outbound_email_social() { + _test_outbound_email social +} +test_outbound_email_reverseproxy() { + _test_outbound_email reverseproxy +} + +. shunit2 + -- libgit2 0.21.2