--- - set_fact: pmg_smtpd_milters_int={{ [] }} tags: pmg - set_fact: pmg_smtpd_milters_ext={{ [] }} tags: pmg - name: Enable dkim signing for outgoing messages set_fact: pmg_smtpd_milters_int={{ pmg_smtpd_milters_int + ['unix:/var/run/opendkim/signer.sock'] }} when: pmg_dkim_sign | length > 0 tags: pmg - name: Enable dkim checks for incoming messages set_fact: pmg_smtpd_milters_ext={{ pmg_smtpd_milters_ext + ['unix:/var/run/opendkim/verifier.sock'] }} when: pmg_check_dkim == True tags: pmg - name: Enable dmarc checks for incoming messages set_fact: pmg_smtpd_milters_ext={{ pmg_smtpd_milters_ext + ['unix:/var/run/opendmarc/opendmarc.sock'] }} when: pmg_check_dkim and pmg_check_dmarc tags: pmg - name: Add PMG repository APT key apt_key: url: http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg state: present environment: - http_proxy: "{{ system_proxy | default('') }}" tags: pmg - name: Remove the paid repository apt_repository: repo: deb https://enterprise.proxmox.com/debian/pmg stretch pmg-enterprise state: absent filename: pmg-enterprise tags: pmg - name: Configure the no-subscription PMG repository apt_repository: repo: deb http://download.proxmox.com/debian/pmg {{ ansible_distribution_release }} pmg-no-subscription state: present filename: pmg-enterprise tags: pmg - name: Install PMG apt: name: - proxmox-mailgateway - sasl2-bin - libsasl2-modules-ldap - opendkim - opendkim-tools - opendmarc - python-mysqldb # Needed to manage the db for dmarc reports - mariadb-client # Needed to inject the schema - patch # Needed to remove the subscription nag screen - libmail-imapclient-perl # For the sa-learn script update_cache: True tags: pmg - name: Remove registration nag patch: src=remove_nag.patch dest=/usr/share/perl5/PMG/API2/Subscription.pm notify: restart pmgproxy tags: pmg # The tracking center uses mails.{info,err,log} - name: Ensure syslog daemon is enabled and running service: name=rsyslog state=started enabled=True tags: pmg - name: Add postfix to the sasl group user: name: postfix groups: sasl,opendkim,opendmarc append: True notify: restart postfix tags: pmg - name: Deploy saslauth configuration template: src={{ item.src }}.j2 dest={{ item.dest }} mode={{ item.mode | default(omit) }} with_items: - src: saslauthd dest: /etc/default/saslauthd - src: smtpd.conf dest: /etc/postfix/sasl/smtpd.conf - src: saslauthd.conf dest: /etc/saslauthd.conf mode: 600 when: pmg_ldap_auth == True notify: - restart saslauthd - restart postfix tags: pmg - name: Handle saslauthd daemon service: name=saslauthd state={{ pmg_ldap_auth | ternary('started','stopped') }} enabled={{ pmg_ldap_auth | ternary(True,False) }} tags: pmg - name: Create custom templates directory file: path=/etc/pmg/templates state=directory tags: pmg - name: Copy custom templates template: src={{ item }}.j2 dest=/etc/pmg/templates/{{ item }} with_items: - master.cf.in - main.cf.in notify: pmgconfig sync tags: pmg - name: Check if pmg backup dir exists stat: path=/var/lib/pmg/backup register: pmg_backup tags: pmg - name: Move backup dir command: mv /var/lib/pmg/backup /home/lbkp/pmg when: pmg_backup.stat.isdir is defined and pmg_backup.stat.isdir tags: pmg - name: Link backup dir file: src=/home/lbkp/pmg dest=/var/lib/pmg/backup state=link tags: pmg - name: Create pre/post backup scripts dir file: path=/etc/backup/{{ item }}.d state=directory with_items: - pre - post tags: pmg - name: Deploy pre/post backup scripts template: src={{ item.src }}.j2 dest=/etc/backup/{{ item.type }}.d/pmg.sh mode=755 with_items: - src: pmg_pre_backup.sh type: pre - src: pmg_post_backup.sh type: post tags: pmg - name: Create dehydrated hook dir file: path=/etc/dehydrated/hooks_deploy_cert.d/ state=directory tags: pmg - name: Deploy dehydrated hook template: src=dehydrated_deploy_hook.j2 dest=/etc/dehydrated/hooks_deploy_cert.d/pmg mode=755 tags: pmg - name: Create directories for opendkim file: path={{ item.dir }} owner={{ item.owner | default(omit) }} mode={{ item.mode | default(omit) }} state=directory with_items: - dir: /etc/opendkim - dir: /etc/opendkim/keys owner: opendkim mode: 700 tags: pmg - name: Deploy opendkim signing template: src={{ item }}.j2 dest=/etc/opendkim/{{ item }} with_items: - keytable - signingtable notify: restart opendkim-signer tags: pmg - name: Deploy opendkim daemon config template: src=opendkim.conf.j2 dest=/etc/opendkim/{{ item }}.conf with_items: - signer - verifier notify: - restart opendkim-signer - restart opendkim-verifier tags: pmg - name: Create DKIM dir file: path=/etc/opendkim/keys/{{ (item.domain == '*') | ternary('default',item.domain) }} state=directory owner=opendkim group=opendkim mode=700 with_items: "{{ pmg_dkim_sign }}" tags: pmg - name: Create DKIM keys command: opendkim-genkey -D /etc/opendkim/keys/{{ (item.domain == '*') | ternary('default',item.domain) }}/ -s {{ item.selector | default('default') }} args: creates: /etc/opendkim/keys/{{ (item.domain == '*') | ternary('default',item.domain) }}/{{ item.selector | default('default') }}.private become_user: opendkim with_items: "{{ pmg_dkim_sign }}" tags: pmg - name: Deploy opendkim service unit template: src=opendkim.service.j2 dest=/etc/systemd/system/opendkim-{{ item }}.service with_items: - signer - verifier register: pmg_opendkim_unit tags: pmg - name: Deploy opendmarc service unit template: src=opendmarc.service.j2 dest=/etc/systemd/system/opendmarc.service register: pmg_opendmarc_unit tags: pmg - name: Reload systemd systemd: daemon_reload=True when: pmg_opendkim_unit.results | selectattr('changed','equalto',True) | list | length > 0 or pmg_opendmarc_unit.changed tags: pmg - name: Check if /etc/pmg/mynetworks exists stat: path=/etc/pmg/mynetworks register: pmg_mynetworks tags: pmg - name: Deploy opendmarc config template: src=opendmarc.conf.j2 dest=/etc/opendmarc.conf tags: pmg - name: Handle opendkim and opendmarc services service: name={{ item.service }} state={{ item.enabled | ternary('started','stopped') }} enabled={{ item.enabled }} with_items: - service: opendkim enabled: False - service: opendkim-signer enabled: "{{ pmg_dkim_sign | length > 0 }}" - service: opendkim-verifier enabled: "{{ pmg_check_dkim }}" - service: opendmarc enabled: "{{ pmg_check_dkim and pmg_check_dmarc }}" tags: pmg - import_tasks: ../includes/get_rand_pass.yml vars: - pass_file: "/etc/opendmarc.dbpass" when: pmg_dmarc_db_pass is not defined tags: pmg - set_fact: pmg_dmarc_db_pass={{ rand_pass }} when: pmg_dmarc_db_pass is not defined tags: pmg - import_tasks: ../includes/webapps_create_mysql_db.yml vars: - db_name: "{{ pmg_dmarc_db_name }}" - db_user: "{{ pmg_dmarc_db_user }}" - db_server: "{{ pmg_dmarc_db_server }}" - db_pass: "{{ pmg_dmarc_db_pass }}" when: pmg_dmarc_report == True tags: pmg - name: Inject DMARC report SQL structure mysql_db: name: "{{ pmg_dmarc_db_name }}" state: import target: /usr/share/dbconfig-common/data/opendmarc/install/mysql login_host: "{{ pmg_dmarc_db_server }}" login_user: sqladmin login_password: "{{ mysql_admin_pass }}" when: pmg_dmarc_report and db_created.changed tags: pmg - name: Deploy dmarc_reports script template: src=dmarc_reports.j2 dest=/usr/local/bin/dmarc_reports mode=700 when: pmg_dmarc_report == True tags: pmg - name: Handle dmarc report cron job cron: name: dmarc_reports cron_file: opendmarc user: root job: systemd-cat /usr/local/bin/dmarc_reports special_time: daily state: "{{ pmg_dmarc_report | ternary('present','absent') }}" tags: pmg - name: Install imap-sa-learn script copy: src=imap-sa-learn dest=/usr/local/bin/imap-sa-learn mode=755 tags: pmg - name: Deploy imap-sa-learn config template: src=imap-sa-learn.j2 dest=/etc/default/imap-sa-learn mode=600 tags: pmg - name: Deploy imap-sa-learn systemd units template: src=imap-sa-learn.{{ item }}.j2 dest=/etc/systemd/system/imap-sa-learn.{{ item }} loop: - service - timer register: pmg_imap_sa_learn_unit tags: pmg - name: Reload systemd systemd: daemon_reload=True when: pmg_imap_sa_learn_unit.results | selectattr('changed','equalto',True) | list | length > 0 tags: pmg - name: Handle imap-sa-learn timer systemd: name: imap-sa-learn.timer state: "{{ (pmg_bayes_imap_server is defined and pmg_bayes_imap_user is defined and pmg_bayes_imap_pass is defined) | ternary('started','stopped') }}" enabled: "{{ (pmg_bayes_imap_server is defined and pmg_bayes_imap_user is defined and pmg_bayes_imap_pass is defined) | ternary(True,False) }}" tags: pmg - name: Remove imap-sa-learn wrapper file: path={{ item }} state=absent loop: - /usr/local/bin/imap-sa-learn.sh - /etc/cron.d/imap_sa_learn tags: pmg - name: Configure log retention template: src=logrotate.d/{{ item }}.j2 dest=/etc/logrotate.d/{{ item }} with_items: - rsyslog tags: pmg - name: Configure additional spamassassin plugins template: src=spamassassin/{{ item }}.j2 dest=/etc/mail/spamassassin/{{ item }} with_items: - hashbl.pre - hashbl.cf - fromnamespoof.pre - fromnamespoof.cf - phishing.pre - phishing.cf - scores.cf notify: reload pmg-smtp-filter tags: pmg - name: Create spamassassin data dir file: path=/var/lib/spamassassin state=directory tags: pmg - name: Download fishtank feed get_url: url: https://data.phishtank.com/data/online-valid.csv dest: /var/lib/spamassassin/phishtank.txt notify: reload pmg-smtp-filter environment: - https_proxy: "{{ system_proxy | default('') }}" tags: pmg - name: Download openphish feed get_url: url: https://openphish.com/feed.txt dest: /var/lib/spamassassin/openphish.txt notify: reload pmg-smtp-filter environment: - https_proxy: "{{ system_proxy | default('') }}" when: pmg_use_openphish tags: pmg - name: Deploy a script to update phishing feeds template: src=update-phishing-feeds.j2 dest=/usr/local/bin/update-phishing-feeds mode=755 tags: pmg - name: Add a cron job to update phishing feeds cron: name: phishing_feeds cron_file: phishing_feeds user: root job: systemd-cat /usr/local/bin/update-phishing-feeds minute: 1 hour: '*/3' state: present tags: pmg - name: Handle ports in the firewall iptables_raw: name: "{{ item.name }}" state: "{{ (item.src | length > 0) | ternary('present','absent') }}" rules: "{% if 'tcp' in item.proto | default(['tcp']) or item.proto | default('tcp') == 'tcp' %}-A INPUT -m state --state NEW -p tcp -m multiport --dports {{ item.ports | join(',') }} -s {{ item.src | join(',') }} -j ACCEPT\n{% endif %} {% if 'udp' in item.proto | default(['tcp']) or item.proto | default('tcp') == 'udp' %}-A INPUT -m state --state NEW -p udp -m multiport --dports {{ item.ports | join(',') }} -s {{ item.src | join(',') }} -j ACCEPT{% endif %}" when: iptables_manage | default(True) with_items: - ports: "{{ pmg_api_ports }}" name: pmg_api_ports src: "{{ pmg_api_src_ip }}" - ports: "{{ pmg_smtp_ext_ports }}" name: pmg_smtp_ext_ports src: "{{ pmg_smtp_ext_src_ip }}" - ports: "{{ pmg_smtp_int_ports }}" name: pmg_smtp_int_ports src: "{{ pmg_smtp_int_src_ip }}" tags: pmg,firewall - name: Remove obsolete firewall rules iptables_raw: name: "{{ item }}" state: absent loop: - pmg_imap_ports - pmg_pop_ports tags: pmg,firewall - include: filebeat.yml