Browse Source

Merge branch 'packmail' into unstable

evolinux-users
Victor LABORIE 4 years ago
parent
commit
acf85bfffc
  1. 5
      amavis/handlers/main.yml
  2. 19
      amavis/tasks/main.yml
  3. 57
      amavis/templates/amavis.conf.j2
  4. 4
      apache/tasks/main.yml
  5. 23
      apache/tasks/remount_usr_rw.yml
  6. 5
      clamav/handlers/main.yml
  7. 3
      clamav/meta/main.yml
  8. 111
      clamav/tasks/main.yml
  9. 36
      dovecot/.kitchen.yml
  10. 11
      dovecot/README.md
  11. 2
      dovecot/defaults/main.yml
  12. 126
      dovecot/files/munin_plugin
  13. 10
      dovecot/handlers/main.yml
  14. 68
      dovecot/tasks/main.yml
  15. 20
      dovecot/tasks/munin.yml
  16. 36
      dovecot/templates/z-evolinux-defaults.conf.j2
  17. 1
      fail2ban/defaults/main.yml
  18. 2
      fail2ban/files/roundcube.conf
  19. 18
      fail2ban/tasks/main.yml
  20. 9
      fail2ban/templates/jail.local.j2
  21. 3
      ldap/defaults/main.yml
  22. 74
      ldap/tasks/main.yml
  23. 8
      ldap/templates/config_ldapvi.j2
  24. 30
      ldap/templates/first-entries.ldif.j2
  25. 6
      ldap/templates/ldapvirc.j2
  26. 1
      nagios-nrpe/templates/evolix.cfg.j2
  27. 46
      opendkim/files/opendkim-add.sh
  28. 18
      opendkim/files/opendkim.conf
  29. 10
      opendkim/handlers/main.yml
  30. 95
      opendkim/tasks/main.yml
  31. 5
      postfix/README.md
  32. 4
      postfix/defaults/main.yml
  33. 63
      postfix/files/cn4evolix.ldif
  34. 1
      postfix/files/filter
  35. 87
      postfix/files/spam.sh
  36. 10
      postfix/meta/main.yml
  37. 27
      postfix/tasks/main.yml
  38. 24
      postfix/tasks/minimal.yml
  39. 128
      postfix/tasks/packmail.yml
  40. 27
      postfix/tasks/slow_transport.yml
  41. 16
      postfix/templates/evolinux_main.cf.j2
  42. 423
      postfix/templates/packmail_main.cf.j2
  43. 171
      postfix/templates/packmail_master.cf.j2
  44. 5
      postfix/templates/virtual_aliases.cf.j2
  45. 5
      postfix/templates/virtual_domains.cf.j2
  46. 5
      postfix/templates/virtual_mailboxes.cf.j2
  47. 68
      spamassasin/files/sa-update.sh
  48. 117
      spamassasin/files/spamassassin.cf
  49. 5
      spamassasin/handlers/main.yml
  50. 3
      spamassasin/meta/main.yml
  51. 68
      spamassasin/tasks/main.yml
  52. 23
      webapps/evoadmin-mail/defaults/main.yml
  53. 6
      webapps/evoadmin-mail/handlers/main.yml
  54. 17
      webapps/evoadmin-mail/tasks/config.yml
  55. 19
      webapps/evoadmin-mail/tasks/main.yml
  56. 16
      webapps/evoadmin-mail/tasks/packages.yml
  57. 15
      webapps/evoadmin-mail/tasks/remount_usr_rw.yml
  58. 24
      webapps/evoadmin-mail/tasks/ssl.yml
  59. 113
      webapps/evoadmin-mail/tasks/user.yml
  60. 30
      webapps/evoadmin-mail/tasks/web.yml
  61. 56
      webapps/evoadmin-mail/templates/conf.php.j2
  62. 28
      webapps/evoadmin-mail/templates/connect.php.j2
  63. 12
      webapps/evoadmin-mail/templates/evoadmin.ldif.j2
  64. 58
      webapps/evoadmin-mail/templates/evoadminmail.conf.j2
  65. 3
      webapps/evoadmin-mail/templates/sudoers.j2
  66. 2
      webapps/evoadmin-mail/templates/web-add.conf.j2
  67. 86
      webapps/evoadmin-mail/templates/web-mail.tpl.j2
  68. 4
      webapps/evoadmin-web/tasks/web.yml
  69. 4
      webapps/roundcube/defaults/main.yml
  70. 5
      webapps/roundcube/handlers/main.yml
  71. 104
      webapps/roundcube/tasks/main.yml
  72. 46
      webapps/roundcube/templates/apache2.conf.j2

5
amavis/handlers/main.yml

@ -0,0 +1,5 @@
---
- name: restart amavis
service:
name: amavis
state: restarted

19
amavis/tasks/main.yml

@ -0,0 +1,19 @@
---
- name: install Amavis
apt:
name: "{{ item }}"
state: present
with_items:
- postgrey
- amavisd-new
tags:
- amavis
- name: configure Amavis
template:
src: amavis.conf.j2
dest: /etc/amavis/conf.d/49-evolinux-defaults.conf
mode: "0644"
notify: restart amavis
tags:
- amavis

57
amavis/templates/amavis.conf.j2

@ -0,0 +1,57 @@
use strict;
## Liste des domaines considérés comme locaux
#@local_domains_acl = qw(.);
@local_domains_acl = (".example.net","example.com");
# On customise la ligne ajoutée dans les entêtes
$X_HEADER_LINE = "by Amavis at $mydomain";
# On precise les FROM pour etre (bugs dans certaines version d'Amavis)
$mailfrom_notify_admin = "postmaster\@$mydomain";
$mailfrom_notify_recip = "postmaster\@$mydomain";
$mailfrom_notify_spamadmin = "postmaster\@$mydomain";
# Notifications de fichiers bannis / virus
$virus_admin = "postmaster\@$mydomain";
# Ne pas recevoir des notifications pour les mails UNCHECKED
delete $admin_maps_by_ccat{&CC_UNCHECKED};
# Que faire avec les messages détectés
$final_virus_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_BOUNCE;
$final_bad_header_destiny = D_PASS;
# Pour recevoir des bounces (mails originals) des fichiers bloqués / virus
#$banned_quarantine_to = "banned\@$mydomain";
#$virus_quarantine_to = "virus\@$mydomain";
# Note tueuse
$sa_tag2_level_deflt = 6.31;
# Pour un comportement "normal" de SA
$sa_tag_level_deflt = -1999;
$sa_kill_level_deflt = 1999;
$sa_dsn_cutoff_level = -99;
$sa_spam_subject_tag = '[SPAM]';
# log
$log_level = 2;
# En fonction besoin/ressources, on a juste le nbre de process
$max_servers = 2;
$enable_ldap = 1;
$default_ldap = {
hostname => '127.0.0.1', tls => 0,
base => '{{ ldap_suffix }}', scope => 'sub',
query_filter => '(&(mailacceptinggeneralid=%m)(isActive=TRUE))'
};
# Activer l'antivirus et antivirus
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
@bypass_spam_checks_maps = (
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
1; # ensure a defined return

4
apache/tasks/main.yml

@ -38,6 +38,10 @@
- expires
- headers
- cgi
- ssl
- include
- negotiation
- alias
notify: reload apache
tags:
- apache

23
apache/tasks/remount_usr_rw.yml

@ -1,19 +1,12 @@
---
- name: Get mount options for partitions
shell: "mount | grep 'on /usr type'"
args:
warn: no
register: mount
changed_when: False
failed_when: False
when: not ansible_check_mode
- name: update ansible_mounts facts
setup:
filter: ansible_mounts
- name: Remount /usr if it is a partition and it is not mounted in rw
command: "mount -o remount,rw /usr"
when:
- not ansible_check_mode
- mount.rc == 0
- not mount.stdout_lines.0 | search("rw")
check_mode: yes
- name: mount /usr in rw
command: mount -o remount,rw /usr
args:
warn: no
changed_when: false
when: item.mount == '/usr' and item.options | match(".*ro.*")
with_items: "{{ ansible_mounts }}"

5
clamav/handlers/main.yml

@ -0,0 +1,5 @@
---
- name: restart clamav
service:
name: clamav-daemon
state: restarted

3
clamav/meta/main.yml

@ -0,0 +1,3 @@
---
dependencies:
- { role: amavis }

111
clamav/tasks/main.yml

@ -0,0 +1,111 @@
---
- name: configure clamav-daemon
debconf:
name: clamav-daemon
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
with_items:
- { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' }
- { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/FollowDirectorySymlinks', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/StreamMaxLength', type: 'string', value: '25' }
- { key: 'clamav-daemon/ReadTimeout', type: 'string', value: '180' }
- { key: 'clamav-daemon/StatsEnabled', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '15' }
- { key: 'clamav-daemon/LogRotate', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/AllowAllMatchScan', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/ScanOnAccess', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/LogFile', type: 'string', value: '/var/log/clamav/clamav.log' }
- { key: 'clamav-daemon/ScanMail', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/BytecodeTimeout', type: 'string', value: '60000' }
- { key: 'clamav-daemon/LogTime', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/OnAccessMaxFileSize', type: 'string', value: '5M' }
- { key: 'clamav-daemon/TcpOrLocal', type: 'select', value: 'UNIX' }
- { key: 'clamav-daemon/MaxEmbeddedPE', type: 'string', value: '10M' }
- { key: 'clamav-daemon/FixStaleSocket', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/User', type: 'string', value: 'clamav' }
- { key: 'clamav-daemon/BytecodeSecurity', type: 'select', value: 'TrustSigned' }
- { key: 'clamav-daemon/ScanSWF', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/MaxDirectoryRecursion', type: 'string', value: '0' }
- { key: 'clamav-daemon/MaxThreads', type: 'string', value: '12' }
- { key: 'clamav-daemon/LocalSocketGroup', type: 'string', value: 'clamav' }
- { key: 'clamav-daemon/MaxScriptNormalize', type: 'string', value: '5M' }
- { key: 'clamav-daemon/ForceToDisk', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/StatsHostID', type: 'string', value: 'auto' }
- { key: 'clamav-daemon/FollowFileSymlinks', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/TCPSocket', type: 'string', value: '3310' }
- { key: 'clamav-daemon/TCPAddr', type: 'string', value: 'any' }
- { key: 'clamav-daemon/DisableCertCheck', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/SelfCheck', type: 'string', value: '3600' }
- { key: 'clamav-daemon/LocalSocket', type: 'string', value: '/var/run/clamav/clamd.ctl' }
- { key: 'clamav-daemon/LocalSocketMode', type: 'string', value: '666' }
- { key: 'clamav-daemon/StatsTimeout', type: 'string', value: '10' }
- { key: 'clamav-daemon/MaxZipTypeRcg', type: 'string', value: '1M' }
- { key: 'clamav-daemon/MaxHTMLNoTags', type: 'string', value: '2M' }
- { key: 'clamav-daemon/LogSyslog', type: 'boolean', value: 'false' }
- { key: 'clamav-daemon/AddGroups', type: 'string', value: '' }
- { key: 'clamav-daemon/Bytecode', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/ScanArchive', type: 'boolean', value: 'true' }
tags:
- clamav
- name: configure clamav-freshclam
debconf:
name: clamav-freshclam
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
with_items:
- { key: 'clamav-freshclam/autoupdate_freshclam', type: 'select', value: 'daemon' }
- { key: 'clamav-freshclam/proxy_user', type: 'string', value: '' }
- { key: 'clamav-freshclam/NotifyClamd', type: 'boolean', value: 'true' }
- { key: 'clamav-freshclam/local_mirror', type: 'select', value: 'db.fr.clamav.net' }
- { key: 'clamav-freshclam/http_proxy', type: 'string', value: '' }
- { key: 'clamav-freshclam/LogRotate', type: 'boolean', value: 'true' }
- { key: 'clamav-freshclam/Bytecode', type: 'boolean', value: 'true' }
- { key: 'clamav-freshclam/update_interval', type: 'string', value: '24' }
- { key: 'clamav-freshclam/SafeBrowsing', type: 'boolean', value: 'false' }
- { key: 'clamav-freshclam/PrivateMirror', type: 'string', value: '' }
- { key: 'clamav-freshclam/internet_interface', type: 'string', value: '' }
tags:
- clamav
- name: install ClamAV
apt:
name: "{{ item }}"
state: present
with_items:
- clamav-daemon
- clamav
- clamdscan
- clamav-freshclam
- arc
- arj
- zoo
- pax
- bzip2
- cabextract
- rpm
- lzop
- razor
tags:
- clamav
- name: add clamav user to amavis group
user:
name: clamav
groups: amavis
append: True
tags:
- clamav
- name: allow supplementary groups
replace:
dest: /etc/clamav/clamd.conf
regexp: 'AllowSupplementaryGroups false'
replace: 'AllowSupplementaryGroups true'
notify: restart clamav
tags:
- clamav

36
dovecot/.kitchen.yml

@ -0,0 +1,36 @@
---
driver:
name: docker
privileged: true
use_sudo: false
provisioner:
name: ansible_playbook
hosts: test-kitchen
roles_path: ../
ansible_verbose: true
require_ansible_source: false
require_chef_for_busser: false
idempotency_test: true
platforms:
- name: debian
driver_config:
image: evolix/ansible:2.2.1
verifier:
name: serverspec
suites:
- name: default
provisioner:
name: ansible_playbook
playbook: ./tests/test.yml
verifier:
patterns:
- nginx/tests/spec/memcached_spec.rb
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
transport:
max_ssh_sessions: 6

11
dovecot/README.md

@ -0,0 +1,11 @@
# Dovecot
Installation and basic configuration of dovecot
## Tasks
Minimal configuration is in `tasks/main.yml`
## Available variables
The full list of variables (with default values) can be found in `defaults/main.yml`.

2
dovecot/defaults/main.yml

@ -0,0 +1,2 @@
---
dovecot_foo: bar

126
dovecot/files/munin_plugin

@ -0,0 +1,126 @@
#! /bin/bash
#
# Munin Plugin
# to count logins to your dovecot mailserver
#
# Created by Dominik Schulz <lkml@ds.gauner.org>
# http://developer.gauner.org/munin/
# Contributions by:
# - Stephane Enten <tuf@delyth.net>
# - Steve Schnepp <steve.schnepp@pwkf.org>
#
# Parameters understood:
#
# config (required)
# autoconf (optional - used by munin-config)
#
# Config variables:
#
# logfile - Where to find the syslog file
#
# Add the following line to a file in /etc/munin/plugin-conf.d:
# env.logfile /var/log/your/logfile.log
#
# Magic markers (optional - used by munin-config and installation scripts):
#
#%# family=auto
#%# capabilities=autoconf
######################
# Configuration
######################
EXPR_BIN=/usr/bin/expr
LOGFILE=${logfile:-/var/log/mail.log}
######################
if [ "$1" = "autoconf" ]; then
echo yes
exit 0
fi
if [ "$1" = "config" ]; then
echo 'graph_title Dovecot Logins'
echo 'graph_category Mail'
echo 'graph_args --base 1000 -l 0'
echo 'graph_vlabel Login Counters'
for t in Total TLS SSL IMAP POP3
do
field=$(echo $t | tr '[:upper:]' '[:lower:]')
echo "login_$field.label $t Logins"
echo "login_$field.type DERIVE"
echo "login_$field.min 0"
done
echo 'connected.label Connected Users'
exit 0
fi
######################
# Total Logins
######################
echo -en "login_total.value "
VALUE=$(egrep -c '[dovecot]?.*Login' $LOGFILE)
if [ ! -z "$VALUE" ]; then
echo "$VALUE"
else
echo "0"
fi
echo -n
######################
# Connected Users
######################
DISCONNECTS=$(egrep -c '[dovecot]?.*Disconnected' $LOGFILE)
CONNECTS=$(egrep -c '[dovecot]?.*Login' $LOGFILE)
VALUE=$($EXPR_BIN $CONNECTS - $DISCONNECTS)
if [ -z "$VALUE" ] || [ "$VALUE" -lt 0 ]; then
VALUE=0
fi
echo -en "connected.value "
echo $VALUE
echo -n
######################
# TLS Logins
######################
echo -en "login_tls.value "
VALUE=$(egrep -c '[dovecot]?.*Login.*TLS' $LOGFILE)
if [ ! -z "$VALUE" ]; then
echo "$VALUE"
else
echo "0"
fi
echo -n
######################
# SSL Logins
######################
echo -en "login_ssl.value "
VALUE=$(egrep -c '[dovecot]?.*Login.*SSL' $LOGFILE)
if [ ! -z "$VALUE" ]; then
echo "$VALUE"
else
echo "0"
fi
echo -n
######################
# IMAP Logins
######################
echo -en "login_imap.value "
VALUE=$(egrep -c '[dovecot]?.*imap.*Login' $LOGFILE)
if [ ! -z "$VALUE" ]; then
echo "$VALUE"
else
echo "0"
fi
echo -n
######################
# POP3 Logins
######################
echo -en "login_pop3.value "
VALUE=$(egrep -c '[dovecot]?.*pop3.*Login' $LOGFILE)
if [ ! -z "$VALUE" ]; then
echo "$VALUE"
else
echo "0"
fi
echo -n

10
dovecot/handlers/main.yml

@ -0,0 +1,10 @@
---
- name: restart dovecot
service:
name: dovecot
state: restarted
- name: reload dovecot
service:
name: dovecot
state: reloaded

68
dovecot/tasks/main.yml

@ -0,0 +1,68 @@
- name: ensure packages are installed
apt:
name: '{{ item }}'
state: present
with_items:
- dovecot-ldap
- dovecot-imapd
- dovecot-pop3d
- dovecot-sieve
- dovecot-managesieved
tags:
- dovecot
- name: disable pam auth
replace:
dest: /etc/dovecot/conf.d/10-auth.conf
regexp: "[^#]!include auth-system.conf.ext"
replace: "#!include auth-system.conf.ext"
tags:
- dovecot
- name: update ldap auth
lineinfile:
dest: /etc/dovecot/dovecot-ldap.conf.ext
line: "{{ item.key }} = {{ item.value }}"
regexp: "^#*{{ item.key }}"
state: present
with_items:
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }
- { key: 'base', value: "{{ ldap_suffix }}" }
- { key: 'user_attrs', value: 'homeDirectory=home' }
- { key: 'user_filter', value: '(&(isActive=TRUE)(uid=%u))' }
- { key: 'pass_attrs', value: 'uid=user,userPassword=password' }
when: ldap_suffix is defined
notify: reload dovecot
tags:
- dovecot
- name: create vmail group
group:
name: vmail
gid: 5000
tags:
- dovecot
- name: create vmail user
user:
name: vmail
group: vmail
uid: 5000
shell: /bin/false
tags:
- dovecot
- name: deploy evolix config
template:
src: z-evolinux-defaults.conf.j2
dest: /etc/dovecot/conf.d/z-evolinux-defaults.conf
mode: "0644"
notify: reload dovecot
tags:
- dovecot
- include: munin.yml
tags:
- dovecot

20
dovecot/tasks/munin.yml

@ -0,0 +1,20 @@
---
- name: is Munin present ?
stat:
path: /etc/munin/plugin-conf.d/munin-node
check_mode: no
register: munin_node_plugins_config
- block:
- name: Install munin plugin
copy:
src: munin_plugin
dest: /etc/munin/plugins/dovecot
mode: "0755"
# TODO : add in /etc/munin/plugin-conf.d/munin-node
# [dovecot]
# group adm
when: munin_node_plugins_config.stat.exists

36
dovecot/templates/z-evolinux-defaults.conf.j2

@ -0,0 +1,36 @@
# {{ ansible_managed }}
# Autorise les mécanismes PLAIN/LOGIN même sans SSL/TLS
disable_plaintext_auth = no
auth_mechanisms = plain login
# Authentification LDAP + intégration avec Postfix pour l'auth SMTP
!include auth-ldap.conf.ext
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
group = vmail
}
unix_listener /var/spool/postfix/private/auth-client {
mode = 0666
user = postfix
group = postfix
}
}
# Stockage des emails dans /home/mail avec UID/GID 5000/5000
mail_location = maildir:/home/vmail/%d/%n
mail_uid = 5000
mail_gid = 5000
# Activation Sieve
protocol lda {
mail_plugins = sieve
}
# Optimisations
service login {
process_limit = 256
}
mail_max_userip_connections = 42

1
fail2ban/defaults/main.yml

@ -3,3 +3,4 @@ general_alert_email: "root@localhost"
fail2ban_alert_email: Null
fail2ban_ignore_ips: []
fail2ban_wordpress: False
fail2ban_roundcube: False

2
fail2ban/files/roundcube.conf

@ -0,0 +1,2 @@
[Definition]
failregex = Login failed for .*. from <HOST>

18
fail2ban/tasks/main.yml

@ -22,14 +22,6 @@
tags:
- fail2ban
- name: package is installed
apt:
name: fail2ban
state: present
tags:
- fail2ban
- packages
- name: custom filters are installed
copy:
src: "{{ item }}"
@ -40,6 +32,16 @@
- sasl-evolix.conf
- wordpress-soft.conf
- wordpress-hard.conf
- roundcube.conf
notify: restart fail2ban
tags:
- fail2ban
- name: package is installed
apt:
name: fail2ban
state: present
tags:
- fail2ban
- packages

9
fail2ban/templates/jail.local.j2

@ -44,3 +44,12 @@ logpath = /var/log/auth.log
maxretry = 5
findtime = 300
{% endif %}
{% if fail2ban_roundcube %}
[roundcube]
enabled = true
port = http,https
filter = roundcube
logpath = /var/lib/roundcube/logs/errors
maxretry = 5
{% endif %}

3
ldap/defaults/main.yml

@ -1,4 +1,5 @@
---
ldap_domain: "{{ ansible_fqdn }}"
ldap_organization: "{{ ansible_domain }}"
#ldap_password=$(apg -n1 -m 12 -c cl_seed)
ldap_suffix: "dc=example,dc=com"
ldap_suffix_dc: "example"

74
ldap/tasks/main.yml

@ -6,8 +6,82 @@
- slapd
- ldap-utils
- ldapvi
- shelldap
- name: "Is /root/.ldapvirc present ?"
stat:
path: /root/.ldapvirc
check_mode: no
register: root_ldapvirc_path
- name: apg package is installed
apt:
name: apg
state: present
when: not root_ldapvirc_path.stat.exists
- name: create a password for cn=admin
command: "apg -n 1 -m 16 -M lcN"
register: ldap_admin_password
changed_when: False
when: not root_ldapvirc_path.stat.exists
- name: create a password for cn=nagios
command: "apg -n 1 -m 16 -M lcN"
register: ldap_nagios_password
changed_when: False
when: not root_ldapvirc_path.stat.exists
- name: hash password for cn=admin
command: "slappasswd -s {{ ldap_admin_password.stdout }}"
register: ldap_admin_password_ssha
changed_when: False
when: not root_ldapvirc_path.stat.exists
- name: hash password for cn=nagios
command: "slappasswd -s {{ ldap_nagios_password.stdout }}"
register: ldap_nagios_password_ssha
changed_when: False
when: not root_ldapvirc_path.stat.exists
- name: create ldapvirc config
template:
src: ldapvirc.j2
dest: /root/.ldapvirc
mode: "0640"
when: not root_ldapvirc_path.stat.exists
- name: upload ldap initial config
template:
src: config_ldapvi.j2
dest: /root/evolinux_ldap_config.ldapvi
mode: "0640"
when: not root_ldapvirc_path.stat.exists
- name: upload ldap initial entries
template:
src: first-entries.ldif.j2
dest: /root/evolinux_ldap_first-entries.ldif
mode: "0640"
when: not root_ldapvirc_path.stat.exists
- name: inject config
command: ldapvi -Y EXTERNAL -h ldapi:// --ldapmodify /root/evolinux_ldap_config.ldapvi
environment:
TERM: xterm
when: not root_ldapvirc_path.stat.exists
- name: inject first entries
command: slapadd -l /root/evolinux_ldap_first-entries.ldif
when: not root_ldapvirc_path.stat.exists
- name: upload custom schema
copy:
src: "{{ ldap_schema }}"
dest: "/root/{{ ldap_schema }}"
mode: "0640"
when: not root_ldapvirc_path.stat.exists and ldap_schema is defined
- name: inject custom schema
command: "ldapadd -Y EXTERNAL -H ldapi:/// -f /root/{{ ldap_schema }}"
when: not root_ldapvirc_path.stat.exists and ldap_schema is defined

8
ldap/templates/config_ldapvi.j2

@ -0,0 +1,8 @@
modify: olcDatabase={1}mdb,cn=config
olcSuffix: {{ ldap_suffix }}
olcRootDN: cn=admin,{{ ldap_suffix }}
olcRootPW: {{ ldap_admin_password_ssha.stdout }}
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
olcAccess: {1}to attrs=userPassword by self write by anonymous auth by dn="cn=admin,{{ ldap_suffix }}" write by dn="cn=perl,ou=ldapusers,{{ ldap_suffix }}" write by * none
olcAccess: {2}to attrs=shadowLastChange by self write by dn="cn=admin,{{ ldap_suffix }}" write by dn="cn=perl,ou=ldapusers,{{ ldap_suffix }}" write by * read
olcAccess: {3}to * by self write by dn="cn=admin,{{ ldap_suffix }}" write by dn="cn=perl,ou=ldapusers,{{ ldap_suffix }}" write by * read

30
ldap/templates/first-entries.ldif.j2

@ -0,0 +1,30 @@
dn: {{ ldap_suffix }}
objectClass: top
objectClass: dcObject
objectClass: organization
o: {{ ldap_suffix_dc }}
dc: {{ ldap_suffix_dc }}
dn: cn=admin,{{ ldap_suffix }}
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: {{ ldap_admin_password_ssha.stdout }}
dn: ou=ldapusers,{{ ldap_suffix }}
objectClass: top
objectClass: organizationalUnit
ou: ldapusers
dn: cn=perl,ou=ldapusers,{{ ldap_suffix }}
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: perl
userPassword: {{ ldap_admin_password_ssha.stdout }}
dn: cn=nagios,ou=ldapusers,{{ ldap_suffix }}
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: nagios
userPassword: {{ ldap_nagios_password_ssha.stdout }}

6
ldap/templates/ldapvirc.j2

@ -0,0 +1,6 @@
profile default
host: ldap://127.0.0.1
base: {{ ldap_suffix }}
user: cn=admin,{{ ldap_suffix }}
bind: simple
password: {{ ldap_admin_password.stdout }}

1
nagios-nrpe/templates/evolix.cfg.j2

@ -28,6 +28,7 @@ command[check_ldap]=/usr/lib/nagios/plugins/check_ldap -3 -H localhost -D cn=nag
command[check_ldaps]=/usr/lib/nagios/plugins/check_ldaps -3 -H localhost -b {{ nagios_nrpe_ldap_dc }}
command[check_imap]=/usr/lib/nagios/plugins/check_imap -H localhost
command[check_imaps]=/usr/lib/nagios/plugins/check_imap -S -H localhost -p 993
command[check_imapproxy]=/usr/lib/nagios/plugins/check_imap -H localhost -p 1143
command[check_pop]=/usr/lib/nagios/plugins/check_pop -H localhost
command[check_pops]=/usr/lib/nagios/plugins/check_pop -S -H localhost -p 995
command[check_ftp]=/usr/lib/nagios/plugins/check_ftp -H localhost

46
opendkim/files/opendkim-add.sh

@ -0,0 +1,46 @@
#!/bin/sh
if [ "$#" -ne 1 ]; then
echo "Usage : $0 example.com" >&2
exit 1
fi
domain="$(echo "$1"|xargs)"
mkdir -pm 0750 "/etc/opendkim/keys/${domain}"
chown opendkim:opendkim "/etc/opendkim/keys/${domain}"
if [ ! -f "/etc/opendkim/keys/${domain}/default.private" ]; then
cd "/etc/opendkim/keys/${domain}"
echo "Generate DKIM keys ..."
sudo -u opendkim opendkim-genkey -r -d "${domain}"
chmod 640 /etc/opendkim/keys/${domain}/*
fi
grep -q "${domain}" /etc/opendkim/TrustedHosts
if [ "$?" -ne 0 ]; then
echo "Add ${domain} to TrustedHosts ..."
echo "${domain}" >> /etc/opendkim/TrustedHosts
fi
grep -q "${domain}" /etc/opendkim/KeyTable
if [ "$?" -ne 0 ]; then
echo "Add ${domain} to KeyTable ..."
echo "default._domainkey.${domain} ${domain}:default:/etc/opendkim/keys/${domain}/default.private" >> /etc/opendkim/KeyTable
fi
grep -q "${domain}" /etc/opendkim/SigningTable
if [ "$?" -ne 0 ]; then
echo "Add ${domain} to SigningTable ..."
echo "*@${domain} default._domainkey.${domain}" >> /etc/opendkim/SigningTable
fi
systemctl reload opendkim
if [ "$?" -eq 0 ]; then
echo "OpenDKIM successfully reloaded"
echo "Public key is in : /etc/opendkim/keys/${domain}/default.txt"
exit 0
else
echo "An error has occurred while opendkim reload, please FIX configuration !" >&2
exit 1
fi

18
opendkim/files/opendkim.conf

@ -0,0 +1,18 @@
UserID opendkim:opendkim
Socket inet:54321@127.0.0.1
PidFile /var/run/opendkim/opendkim.pid
OversignHeaders From
TrustAnchorFile /usr/share/dns/root.key
Selector default
Canonicalization relaxed/relaxed
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
LogResults Yes
LogWhy Yes
Mode sv
SigningTable refile:/etc/opendkim/SigningTable
Syslog Yes
SyslogSuccess Yes
TemporaryDirectory /var/tmp
UMask 007

10
opendkim/handlers/main.yml

@ -0,0 +1,10 @@
---
- name: reload opendkim
systemd:
name: opendkim
state: reloaded
- name: restart opendkim
systemd:
name: opendkim
state: restarted

95
opendkim/tasks/main.yml

@ -0,0 +1,95 @@
---
- name: install OpenDKIM
apt:
name: "{{ item }}"
state: present
with_items:
- opendkim
- opendkim-tools
tags:
- opendkim
- name: create keys directory
file:
name: "{{ item }}"
state: directory
owner: opendkim
group: opendkim
mode: "0750"
with_items:
- '/etc/opendkim'
- '/etc/opendkim/keys'
tags:
- opendkim
- name: add 127.0.0.1 to TrustedHosts
lineinfile:
dest: '/etc/opendkim/TrustedHosts'
line: '127.0.0.1'
create: True
owner: opendkim
group: opendkim
mode: "0640"
notify: reload opendkim
tags:
- opendkim
- name: create config files
file:
name: "/etc/opendkim/{{ item }}"
state: touch
owner: opendkim
group: opendkim
mode: "0640"
with_items:
- 'KeyTable'
- 'SigningTable'
changed_when: False
tags:
- opendkim
- name: copy OpenDKIM config
copy:
src: opendkim.conf
dest: /etc/opendkim.conf
mode: "0644"
force: yes
notify: restart opendkim
tags:
- opendkim
- name: ensure opendkim is started and enabled
systemd:
name: opendkim
state: started
enabled: True
tags:
- opendkim
- name: check if /usr is a partition
shell: "mount | grep 'on /usr type'"
args:
warn: no
changed_when: False
failed_when: False
register: usr_partition
check_mode: no
tags:
- opendkim
- name: mount /usr in rw
command: mount -o remount,rw /usr
args:
warn: no
changed_when: False
when: usr_partition.rc == 0
tags:
- opendkim
- name: deploy opendkim-add.sh script
copy:
src: opendkim-add.sh
dest: /usr/share/scripts/opendkim-add.sh
mode: "0750"
tags:
- opendkim

5
postfix/README.md

@ -4,9 +4,10 @@ Installation and basic configuration of Postfix.
## Tasks
Minimal configuration is in `tasks/main.yml` and optional customization in :
Minimal configuration is in `tasks/minimal.yml` and optional customization in :
* `slow_transport.yml` : slow transport to specific destination.
* `packmail.yml` : config for virtual mail accounts with OpenLDAP
## Available variables
@ -14,5 +15,7 @@ Main variables are :
* `postfix_hostname` : hostname for Postfix ;
* `postfix_slow_transport` : enable customization for delivrability.
* `postfix_force_main_cf` : force copy of main.cf
* `postfix_packmail` : install an Evolix Packmail instead of lite postfix config
The full list of variables (with default values) can be found in `defaults/main.yml`.

4
postfix/defaults/main.yml

@ -1,3 +1,5 @@
---
postfix_hostname: "{{ ansible_fqdn }}"
postfix_slow_transport_include: False
postfix_force_main_cf: False
postfix_packmail: False
postfix_slow_transport_include: "{{ postfix_packmail }}"

63
postfix/files/cn4evolix.ldif

@ -0,0 +1,63 @@
dn: cn={4}evolix,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: {4}evolix
olcAttributeTypes: {0}( 1.3.6.1.4.1.24331.22.1.1 NAME 'maildrop' DESC 'mail fo
rward' SUP mail )
olcAttributeTypes: {1}( 1.3.6.1.4.1.24331.22.1.2 NAME 'mailacceptinggeneralid'
DESC 'mail alias' SUP mail )
olcAttributeTypes: {2}( 1.3.6.1.4.1.24331.22.1.3 NAME 'isActive' DESC 'boolean
to verify an global account is active or not' EQUALITY booleanMatch SYNTAX 1
.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {3}( 1.3.6.1.4.1.24331.22.1.4 NAME 'accountActive' DESC 'bo
olean to verify if an mail account is active' EQUALITY booleanMatch SYNTAX 1.
3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {4}( 1.3.6.1.4.1.24331.22.1.5 NAME 'authsmtpActive' DESC 'b
oolean to verify if SMTP-AUTH is enabled for entry' EQUALITY booleanMatch SYN
TAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {5}( 1.3.6.1.4.1.24331.22.1.6 NAME 'courierActive' DESC 'bo
olean to verify if Courier POP/IMAP is enabled for entry' EQUALITY booleanMat
ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {6}( 1.3.6.1.4.1.24331.22.1.7 NAME 'webmailActive' DESC 'bo
olean to verify if webmail is enabled for entry' EQUALITY booleanMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {7}( 1.3.6.1.4.1.24331.22.1.8 NAME 'isAdmin' DESC 'boolean
to verify if entry is admin for entry' EQUALITY booleanMatch SYNTAX 1.3.6.1.4
.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {8}( 1.3.6.1.4.1.24331.22.1.9 NAME 'postfixTransport' DESC
'transport for Postfix' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.11
5.121.1.26{20} SINGLE-VALUE )
olcAttributeTypes: {9}( 1.3.6.1.4.1.24331.22.1.10 NAME 'domain' DESC 'Postfix
domain' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTA
X 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {10}( 1.3.6.1.4.1.24331.22.1.11 NAME 'quota' DESC 'Courier
maildir quota' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.
26 SINGLE-VALUE )
olcAttributeTypes: {11}( 1.3.6.1.4.1.24331.22.1.16 NAME 'vacationActive' DESC
'A flag, for marking the user as being away' EQUALITY booleanMatch SYNTAX 1.3
.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcAttributeTypes: {12}( 1.3.6.1.4.1.24331.22.1.17 NAME 'vacationInfo' DESC 'A
bsentee note to leave behind, while on vacation' EQUALITY octetStringMatch SY
NTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE )
olcAttributeTypes: {13}( 1.3.6.1.4.1.24331.22.1.18 NAME 'vacationStart' DESC '
Beginning of vacation' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.
121.1.40 SINGLE-VALUE )
olcAttributeTypes: {14}( 1.3.6.1.4.1.24331.22.1.19 NAME 'vacationEnd' DESC 'En
d of vacation' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
SINGLE-VALUE )
olcAttributeTypes: {15}( 1.3.6.1.4.1.24331.22.1.20 NAME 'vacationForward' DESC
'Where to forward mails to, while on vacation' EQUALITY caseIgnoreIA5Match S
UBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
)
olcAttributeTypes: {16}( 1.3.6.1.4.1.24331.22.1.21 NAME 'smbActive' DESC 'bool
ean to verify if an Samba account is active' EQUALITY booleanMatch SYNTAX 1.3
.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
olcObjectClasses: {0}( 1.3.6.1.4.1.24331.22.2.1 NAME 'mailAccount' DESC 'LDAP/
Unix mail account or virtual account' SUP top AUXILIARY MUST ( uid $ mailacce
ptinggeneralid ) MAY ( accountActive $ authsmtpActive $ quota $ isActive $ co
urierActive $ webmailActive $ isAdmin $ vacationActive $ vacationInfo $ vacat
ionStart $ vacationEnd $ vacationForward $ maildrop ) )
olcObjectClasses: {1}( 1.3.6.1.4.1.24331.22.2.2 NAME 'mailAlias' DESC 'Mail al
iasing/forwarding entry' SUP top STRUCTURAL MUST ( mailacceptinggeneralid $ m
aildrop ) MAY ( cn $ isActive ) )
olcObjectClasses: {2}( 1.3.6.1.4.1.24331.22.2.4 NAME 'postfixDomain' DESC 'Pos
tfix domain' SUP posixGroup STRUCTURAL MAY ( postfixTransport $ isActive ) )

1
postfix/files/filter

@ -0,0 +1 @@
# Default empty file

87
postfix/files/spam.sh

@ -0,0 +1,87 @@
#!/bin/bash
#set -x
umask 022
tmp_file=$(mktemp)
tmp=$(mktemp -d)
if [ -f $tmp_file ] ;
then rm $tmp_file ;
fi
sleep $[ $RANDOM / 1024 ]
# Postfix
cd $tmp
wget -q -t 3 http://antispam00.evolix.org/spam/client.access -O $tmp_file
cp $tmp_file /etc/postfix/client.access
rm $tmp_file
wget -q -t 3 http://antispam00.evolix.org/spam/sender.access -O $tmp_file
cp $tmp_file /etc/postfix/sender.access
rm $tmp_file
wget -q -t 3 http://antispam00.evolix.org/spam/recipient.access -O $tmp_file
cp $tmp_file /etc/postfix/recipient.access
rm $tmp_file
wget -q -t 3 http://antispam00.evolix.org/spam/header_kill -O $tmp_file
cp $tmp_file /etc/postfix/header_kill
rm $tmp_file
wget -q -t 3 http://antispam00.evolix.org/spam/sa-blacklist.access -O sa-blacklist.access
wget -q -t 3 http://antispam00.evolix.org/spam/sa-blacklist.access.md5 -O $tmp_file
if md5sum -c $tmp_file > /dev/null && [ -s sa-blacklist.access ] ; then
cp sa-blacklist.access /etc/postfix/sa-blacklist.access
fi
rm sa-blacklist.access
rm $tmp_file
/usr/sbin/postmap hash:/etc/postfix/client.access
/usr/sbin/postmap hash:/etc/postfix/sender.access
/usr/sbin/postmap hash:/etc/postfix/recipient.access
/usr/sbin/postmap -r hash:/etc/postfix/sa-blacklist.access
wget -q -t 3 http://antispam00.evolix.org/spam/spamd.cidr -O spamd.cidr
wget -q -t 3 http://antispam00.evolix.org/spam/spamd.cidr.md5 -O $tmp_file
if md5sum -c $tmp_file > /dev/null && [ -s spamd.cidr ] ; then
cp spamd.cidr /etc/postfix/spamd.cidr
fi
rm spamd.cidr
rm $tmp_file
# SpamAssassin
cd $tmp
wget -q -t 3 http://antispam00.evolix.org/spam/evolix_rules.cf -O evolix_rules.cf
wget -q -t 3 http://antispam00.evolix.org/spam/evolix_rules.cf.md5 -O $tmp_file
if md5sum -c $tmp_file > /dev/null && [ -s evolix_rules.cf ] ; then
dpkg -l spamassassin 2>&1 | grep -v "no packages found matching" | grep -q ^ii && cp evolix_rules.cf /etc/spamassassin
dpkg -l spamassassin 2>&1 | grep -v "no packages found matching" | grep -q ^ii && /etc/init.d/spamassassin reload > /dev/null
if [ -d /etc/spamassassin/sa-update-hooks.d ]; then
run-parts --lsbsysinit /etc/spamassassin/sa-update-hooks.d
fi
fi
# ClamAV
cd $tmp
wget -q -t 3 http://antispam00.evolix.org/spam/evolix.ndb -O evolix.ndb
wget -q -t 3 http://antispam00.evolix.org/spam/evolix.ndb.md5 -O $tmp_file
dpkg -l clamav-daemon 2>&1 | grep -v "no packages found matching" | grep -q ^ii && chown clamav: evolix.ndb
if md5sum -c $tmp_file > /dev/null && [ -s evolix.ndb ] ; then
dpkg -l clamav-daemon 2>&1 | grep -v "no packages found matching" | grep -q ^ii && cp -a evolix.ndb /var/lib/clamav/
fi
wget -q -t 3 http://antispam00.evolix.org/spam/evolix.hsb -O evolix.hsb
wget -q -t 3 http://antispam00.evolix.org/spam/evolix.hsb.md5 -O $tmp_file
dpkg -l clamav-daemon 2>&1 | grep -v "no packages found matching" | grep -q ^ii && chown clamav: evolix.hsb
if md5sum -c $tmp_file > /dev/null && [ -s evolix.hsb ] ; then
dpkg -l clamav-daemon 2>&1 | grep -v "no packages found matching" | grep -q ^ii && cp -a evolix.hsb /var/lib/clamav/
fi
dpkg -l clamav-daemon 2>&1 | grep -v "no packages found matching" | grep -q ^ii && /etc/init.d/clamav-daemon reload-database > /dev/null
rm $tmp_file
rm -rf $tmp

10
postfix/meta/main.yml

@ -13,7 +13,9 @@ galaxy_info:
versions:
- jessie
dependencies: []
# List your role dependencies here, one per line.
# Be sure to remove the '[]' above if you add dependencies
# to this list.
dependencies:
- { role: ldap, ldap_schema: 'cn4evolix.ldif', when: postfix_packmail == True }
- { role: spamassasin, when: postfix_packmail == True }
- { role: clamav, when: postfix_packmail == True }
- { role: opendkim, when: postfix_packmail == True }
- { role: dovecot, when: postfix_packmail == True }

27
postfix/tasks/main.yml

@ -1,30 +1,17 @@
- name: ensure packages are installed
apt:
name: '{{ item }}'
state: present
with_items:
- postfix
- mailgraph
---
- name: check if main.cf is default
shell: grep -v -E "^(myhostname|mydestination|mailbox_command)" /etc/postfix/main.cf | md5sum -
changed_when: False
check_mode: no
register: default_main_cf
tags:
- postfix
- name: create minimal main.cf
template:
src: evolinux_main.cf.j2
dest: /etc/postfix/main.cf
owner: root
group: root
mode: "0644"
force: yes
when: default_main_cf.stdout == "5450c05d65878e99dad696c7c722e511 -" or
default_main_cf.stdout == "30022953f1f61f002bfb72e163ecb27e -"
notify: restart postfix
- include: minimal.yml
when: postfix_packmail == False
- meta: flush_handlers
- include: packmail.yml
when: postfix_packmail == True
- include: slow_transport.yml
when: postfix_slow_transport_include

24
postfix/tasks/minimal.yml

@ -0,0 +1,24 @@
---
- name: ensure packages are installed
apt:
name: '{{ item }}'
state: present
with_items:
- postfix
tags:
- postfix
- name: create minimal main.cf
template:
src: evolinux_main.cf.j2
dest: /etc/postfix/main.cf
owner: root
group: root
mode: "0644"
force: yes
notify: restart postfix
when: postfix_force_main_cf == True or
default_main_cf.stdout == "5450c05d65878e99dad696c7c722e511 -" or
default_main_cf.stdout == "30022953f1f61f002bfb72e163ecb27e -"
tags:
- postfix

128
postfix/tasks/packmail.yml

@ -0,0 +1,128 @@
---
- name: ensure packages are installed
apt:
name: '{{ item }}'
state: present
with_items:
- postfix
- postfix-ldap
- postfix-policyd-spf-python
- mailgraph
tags:
- postfix
- name: create packmail main.cf
template:
src: packmail_main.cf.j2
dest: /etc/postfix/main.cf
owner: root
group: root
mode: "0644"
force: yes
notify: restart postfix
when: postfix_force_main_cf == True or
default_main_cf.stdout == "5450c05d65878e99dad696c7c722e511 -" or
default_main_cf.stdout == "30022953f1f61f002bfb72e163ecb27e -"
tags:
- postfix
- name: deploy packmail master.cf
template:
src: packmail_master.cf.j2
dest: /etc/postfix/master.cf
mode: "0644"
notify: restart postfix
tags:
- postfix
- name: copy default filter files
copy:
src: filter
dest: "/etc/postfix/{{ item }}"
force: no
with_items:
- virtual
- client.access
- client.access_local
- header_kill
- header_kill_local
- recipient.access
- recipient.access_local
- sa-blacklist.access
- sender.access
- sender.access_local
- spamd.cidr
register: postfix_copy_filter
tags:
- postfix
- name: postmap filter files
command: "postmap /etc/postfix/{{ item }}"
with_items:
- virtual
- client.access
- client.access_local
- header_kill
- header_kill_local
- recipient.access
- recipient.access_local
- sa-blacklist.access
- sender.access
- sender.access_local
- spamd.cidr
when: postfix_copy_filter.changed
tags:
- postfix
- name: deploy ldap postfix config
template:
src: "{{ item }}.j2"
dest: "/etc/postfix/{{ item }}"
mode: "0644"
with_items:
- virtual_aliases.cf
- virtual_domains.cf
- virtual_mailboxes.cf
notify: restart postfix
tags:
- postfix
- name: update ansible_mounts facts
setup:
filter: ansible_mounts
tags:
- postfix
- name: mount /usr in rw
command: mount -o remount,rw /usr
args:
warn: no
changed_when: false
when: item.mount == '/usr' and item.options | match(".*ro.*")
with_items: "{{ ansible_mounts }}"
tags:
- postfix
- name: copy spam.sh script
copy:
src: spam.sh
dest: /usr/share/scripts/spam.sh
mode: "0700"
tags:
- postfix
- name: enable spam.sh cron
lineinfile:
dest: /etc/cron.d/spam
line: "42 * * * * /usr/share/scripts/spam.sh"
create: yes
state: present
mode: "0640"
tags:
- postfix
- name: update antispam list
command: /usr/share/scripts/spam.sh
changed_when: false
tags:
- postfix

27
postfix/tasks/slow_transport.yml

@ -1,10 +1,12 @@
---
- name: slow transport is defined in master.cf
lineinfile:
dest: /etc/postfix/master.cf
regexp: "^slow "
line: "slow unix - - n - - smtp"
notify: restart postfix
tags:
- postfix
- name: list of providers for slow transport
lineinfile:
@ -21,24 +23,5 @@
- "hotmail.fr slow:"
- "hotmail.com slow:"
notify: postmap transport
- name: main.cf is configured for slow transports
blockinfile:
dest: /etc/postfix/main.cf
marker: "# {mark} Slow transports configuration (installed by Ansible)"
block: |
minimal_backoff_time = 2h
maximal_backoff_time = 6h
maximal_queue_lifetime = 4d
queue_run_delay = 100s
bounce_queue_lifetime = 1d
initial_destination_concurrency = 5
default_destination_concurrency_limit = 20
slow_destination_rate_delay = 0
slow_destination_concurrency_limit = 1
slow_destination_concurrency_failed_cohort_limit = 100
slow_destination_recipient_limit = 25
transport_maps = hash:$config_directory/transport
notify: restart postfix
- meta: flush_handlers
tags:
- postfix

16
postfix/templates/evolinux_main.cf.j2

@ -13,3 +13,19 @@ recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
disable_vrfy_command = yes
{% if postfix_slow_transport_include == True %}
# Slow transports configuration
minimal_backoff_time = 2h
maximal_backoff_time = 6h
maximal_queue_lifetime = 4d
queue_run_delay = 100s
bounce_queue_lifetime = 1d
initial_destination_concurrency = 5
default_destination_concurrency_limit = 20
slow_destination_rate_delay = 0
slow_destination_concurrency_limit = 1
slow_destination_concurrency_failed_cohort_limit = 100
slow_destination_recipient_limit = 25
transport_maps = hash:$config_directory/transport
{% endif %}

423
postfix/templates/packmail_main.cf.j2

@ -0,0 +1,423 @@
## fichier principal de configuration de Postfix
## commentaires de Gregory Colpart reg AT evolix DOT fr
## version 1.0 : 1ere version publique (05.04.2010)
########################
# Section : Emplacements
########################
# Repertoire ou se trouvent les commandes de postfix [OBLIGATOIRE]
#par defaut, = $program_directory
command_directory = /usr/sbin
# Repertoire ou se trouvent les demons de postfix [OBLIGATOIRE]
#par defaut, = $program_directory
daemon_directory = /usr/lib/postfix/sbin
# Variable pour indiquer les emplacements des commandes et demons de postfix
#program_directory = /usr/lib/postfix
# Repertoire contenant les fichiers de boites aux lettres
#par defaut, = /var/mail
#mail_spool_directory =
# Repertoire de la file d'attente de postfix
#par defaut, = /var/spool/postfix
#queue_directory =
# Boites aux lettres
#par defaut, =
home_mailbox = Maildir/
# Transmettre les mails a un MDA
#par defaut, =
#mailbox_command = /usr/bin/procmail
# Separateur entre noms d'utilisateur et extensions d'adresse
# mettre + pour integration avec amavis
#par defaut, =
recipient_delimiter = +
# Controle si le repertoire existe (souvent pour les systemes de fichiers montes)
#par defaut, = no
#require_home_directory =
# Commande pour transmettre le courrier a un MDA
#par defaut, =
#mailbox_command = /usr/bin/procmail
# Banniere SMTP affichee
#par default, = $myhostname ESMTP $mail_name
smtpd_banner = $myhostname ESMTP mail server
# Groupe des commandes set-gid ayant des acces en ecriture
#par defaut, = postdrop
# setgid_group = postdrop
# Produire des "biff notifications" aux utilisateurs pour
# prevenir de l'arrivee de nouveaux mails
# par default, = yes
#biff = no
####################
# Section : domaines
####################
# Indique le nom d'hote pleinement qualifie ou se trouve postfix [OBLIGATOIRE]
#par defaut, = [retour de la commande Unix hostname]
myhostname = {{ ansible_fqdn }}
# Variable indiquant le domaine dans lequel se trouve la machine
#par defaut, = [partie domain de la variable $myhostname]
#mydomain =
# Liste des noms de domaine (ou IP) consideres comme local
#par defaut, = $myhostname, localhost.$mydomain, localhost
mydestination = $myhostname
# Indique le domaine apparaissant dans le courrier envoye
#par defaut, = $myhostname
myorigin = {{ ansible_fqdn }}
# Liste de domaine fonctionnant UNIQUEMENT avec des alias virtuels
#par defaut, = $virtual_alias_maps
#virtual_alias_domains = [ domaines avec alias virtuels ]
# Liste de domaine fonctionnant avec des comptes virtuels
#par defaut, = $virtual_mailbox_maps
virtual_mailbox_domains = ldap:$config_directory/virtual_domains.cf
# Repertoire de base de l'espace de stockage
#par defaut, =
virtual_mailbox_base = /
# Ajoute $mydomain aux adresse ne compoirtant que la partie hote sans le domaine
#par defaut, = yes
#append_dot_mydomain = no
# Ajoute $myorigin aux adresses ne comportant pas de composante de domaine
#par defaut, = yes
#append_at_myorigin = no
# Liste de domaines cachant des sous-domaines internes
#par defaut, =
#masquerade_domains =
# A l'exception de certains comptes :
#par defaut, =
#masquerade_exceptions = root, admin
# Champs d'application de la reecriture des sous-domaines caches
#par defaut, = envelope_sender, header_sender, header_recipient
#masquerade_classes =
# Sites eligibles pour un vidage rapide (postqueue -s [domain.tld])
#par defaut, = $relay_domains
#fast_flush_domains =
# Interfaces sur lesquelles ecoutent postfix
#par defaut, = all
#inet_interfaces = all
# Adresse IP externe du firewall/proxy si derriere NAT ou proxy
# evite principalement les boucles si MX secondaire et MX primaire indisponible
#par defaut, =
#proxy_interfaces = [adresse IP]
# Domaines acceptes pour faire relai (MX 2aire)
#relay_domains = [domaine a relayer]
###########################
# Section : base de donnees
###########################
# Liste des bases de donnees utilisees par l'agent de distribution locale
# Pour regenerer une base de donnees : postalias /etc/aliases (par ex)
#par defaut, = hash:/etc/aliases, nis:mail.aliases
alias_maps = hash:/etc/aliases
# Liste des bases de donnees locales
# Pour regenerer avec newaliases
#par defaut, = hash:/etc/aliases
alias_database = hash:/etc/aliases
# Chemin vers la commande newaliases
#par defaut, = /usr/bin/newaliases
#newaliases_path =
# Base de donnes d'alias virtuels
# ne pas oublier : postmap /etc/postfix/virtual
#par defaut, = $virtual_maps
virtual_alias_maps = hash:$config_directory/virtual, ldap:$config_directory/virtual_aliases.cf
# Base de donners des boites virtuelles
# ne pas oublier : postmap /etc/postfix/vmailbox
#par defaut, =
virtual_mailbox_maps = ldap:$config_directory/virtual_mailboxes.cf
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
# Reecriture des adresses
#par defaut, =
#canonical_maps = hash:/etc/postfix/canonical
# Reecriture des adresses a l'arrivee (ecrase $canonical_maps)
#par defaut, =
#recipient_canonical_maps = hash:/etc/postfix/canonical
# Reecriture des adresses au depart
#par defaut, =
#sender_canonical_maps = hash:/etc/postfix/canonical
# Adresses changees
#relocated_maps = hash:/etc/postfix/relocated
# Boite pour receptionner tous les utilisateurs inconnus
#luser_relay = spam
# Liste de base de donnees contenant les adresses locales permettant de rejeter les messages aux utilisateurs inconnus
# (sera nulle pour recuperer les courriels vers les utilisateurs inconnus)
#par defaut, = proxy:unix:passwd.byname $alias_maps
#local_recipient_maps =
# MAILING-LIST nommee xx
# dans le fichier /etc/aliases :
# xx: user1@domain1 user2@domain2 etc.
# owner-xx: admin@domain
# Utiliser ou non l'alias xx-owner comme adresse d'enveloppe d'expedition
#par defaut, = yes
#owner_request_special =
# Utiliser l'adresse relle de l'admin au lieu de xx-owner
#par defaut, = no
#expand_owner_alias =
###########################################
# Section : parametres de la file d'attente
###########################################
# Lorsqu'un message n'a pas ete delivre, Postfix adjoint une marque indiquant le moment ou la prochaine tentaive pourra avoir lieu
# Delai au-dela duquel les messages non delivres seront renvoyes a l'expediteur
#par defaut, = 5d
#maximal_queue_lifetime =
# Delai au-dela duquel les *bounces* non delivres ne seront plus envoyes
#par defaut, = 5d
bounce_queue_lifetime = 1d
# Intervalle de temps ou postfix examinera la file
# Il examine notamment la file deferred pour voir si de NOUVEAUX messages sont arrives
# Il faut aussi que la marque indique qu'ils soient prets
#par defaut, = 1000s
#queue_run_delay =
# A chaque echec, le delai de la prochaine distribution double, avec les restrictions suivantes :
# Delai minimal
#par defaut, = 1000s
#minimal_backoff_time =
# Delai maximal
#par defaut, = 4000s
#maximal_backoff_time =
# Si maxproc est vide (master.cf), nombre maximal est :
#par defaut, = 100
#default_process_limit =
# Nombre maximal de destinataires stockes en memoire par qmgr pour un transport particulier
#par defaut, = 10000
#default_recipient_limit =
# Nombre limitant de messages envoyes simultanement INITIALEMENT pour une destination particuliere
# (forcement majoree par maxproc du master.cf ou $default_process_limit)
#par defaut, = 5
#initial_destination_concurrency =
# Une fois ces messages distribues, si il reste des messages dans la file d'attente pour cette destination
# particuliere, postfix augmente le nombre de tentative tant qu'il ne detecte pas de probleme avec
# la destination, avec la limite suivante :
#par defaut, = 20
#default_destination_concurrency_limit =
# Cette limite peut etre differente selon le type de transport utilise :
#par defaut, = $default_destination_concurrency_limit
#lmtp_destination_concurrency_limit =
#par defaut, = 2
#local_destination_concurrency_limit =
#par defaut, = $default_destination_concurrency_limit
#relay_destination_concurrency_limit =
#par defaut, = $default_destination_concurrency_limit
#smtp_destination_concurrency_limit =
#par defaut, = $default_destination_concurrency_limit
#virtual_destination_concurrency_limit =
# On peut aussi limiter le nombre maximum de destinataire pour un meme message
# Si le nombre de destinataire depasse la limite, postfix divise en groupe d'adresses plus petites et envoie des copies distinctes du message
#par defaut, = 10000
#default_destination_recipient_limit =
#par defaut, = $default_destination_recipient_limit
#lmtp_destination_recipient_limit =
#par defaut, = 1
#local_destination_recipient_limit =
#par defaut, = 20000
#qmgr_message_recipient_limit =