Reviewed-on: #2
This commit is contained in:
commit
2861687888
72
README.md
72
README.md
@ -1,2 +1,72 @@
|
||||
# ansible_role_mailserver
|
||||
# **Ansible Role: Postfix**
|
||||
|
||||
An Ansible role to install and configure Postfix on Debian-based systems.
|
||||
|
||||
## **Description**
|
||||
|
||||
This role sets up Postfix to function as a local mail server designed for internal use. Its primary function is to accept mail from local services and relay all outbound messages through a configured **smarthost**.
|
||||
|
||||
This is the perfect setup for environments where internal applications (like cron, monitoring systems, or web applications) need to send email notifications without the complexity of managing a full, internet-facing mail server.
|
||||
|
||||
This role performs the following actions:
|
||||
|
||||
* Installs the Postfix package and necessary SASL modules on Debian/Ubuntu.
|
||||
* Manages the main Postfix configuration file (/etc/postfix/main.cf) via a template.
|
||||
* Manages the /etc/mailname file for defining the mail domain.
|
||||
* Configures Postfix to route all outgoing mail through a specified smarthost.
|
||||
* Securely configures SASL authentication for the smarthost if credentials are provided.
|
||||
|
||||
## **Requirements**
|
||||
|
||||
* **Target OS**: This role is designed exclusively for **Debian-based** distributions (e.g., Debian, Ubuntu).
|
||||
* **Ansible**: Version 2.10 or newer.
|
||||
|
||||
## **Role Variables**
|
||||
|
||||
The role's behavior can be customized using the following variables. The default values are defined in defaults/main.yml.
|
||||
|
||||
| Variable | Default Value | Description |
|
||||
| :---- | :---- | :---- |
|
||||
| postfix_relayhost | "" (empty string) | **Required.** The smarthost for relaying all mail. Use square brackets [] to prevent MX lookups (e.g., \[smtp.sendgrid.net\]:587). |
|
||||
| postfix_relayhost_user | (undefined) | The username for SASL authentication with the smarthost. If defined with a password, SASL auth will be enabled. |
|
||||
| postfix_relayhost_password | (undefined) | The password or API key for the smarthost user. **It** is strongly recommended to store this in Ansible **Vault.** |
|
||||
| postfix_mail_domain | `{{ ansible_domain \| default('internal.local') }}` | The primary mail domain for this server |
|
||||
| postfix_myhostname | `mail.{{ postfix_mail_domain }}` | The fully qualified domain name (FQDN) of the mail server itself (e.g., mail.example.com). |
|
||||
| postfix_mydestination | `$myhostname, localhost.{{ postfix_mail_domain }}, localhost, {{ postfix_mail_domain }}` | A comma-separated list of domains this server will accept mail for. The default is usually sufficient for an internal relay. |
|
||||
| postfix_mynetworks | `"127.0.0.0/8 [::1]/128"` | The list of "trusted" remote SMTP clients that have more privileges than "strangers"|
|
||||
| postfix_inet_interfaces | all | The network interfaces Postfix listens on. Set to loopback-only to only accept mail from the server itself. |
|
||||
| postfix_inet_protocols | all | The IP protocols to use (ipv4, ipv6, or all). |
|
||||
|
||||
### **SASL Authentication**
|
||||
|
||||
SASL authentication for the smarthost is **automatically enabled** if both postfix_relayhost_user and postfix_relayhost_password are defined. If they are not defined, Postfix will attempt to send mail without authentication.
|
||||
|
||||
## **Dependencies**
|
||||
|
||||
This role has no dependencies on other Ansible roles or collections beyond the standard ansible.builtin modules.
|
||||
|
||||
## **Example Playbook**
|
||||
|
||||
Here is a basic example of how to use this role in your playbook. You must define postfix_relayhost. It is also highly recommended to use Ansible Vault to encrypt the smarthost password.
|
||||
|
||||
```
|
||||
---
|
||||
- hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- role: your_username.postfix
|
||||
vars:
|
||||
postfix_relayhost: "[smtp.mailgun.org\]:587"
|
||||
postfix_relayhost_user: "postmaster@mg.example.com"
|
||||
postfix_relayhost_password: "{{ vaulted_mailgun_password }}" # Stored in Ansible Vault
|
||||
postfix_inet_interfaces: "loopback-only"
|
||||
postfix_mail_domain: "example.com"
|
||||
```
|
||||
|
||||
## **License**
|
||||
|
||||
GPL-3.0-only
|
||||
|
||||
## **Author Information**
|
||||
|
||||
This role was created by Giacchetta Networks.
|
37
defaults/main.yml
Normal file
37
defaults/main.yml
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# Default variables for the role. These can be overridden in your inventory
|
||||
# or playbook to customize the deployment.
|
||||
#
|
||||
|
||||
# The Internet protocols Postfix will attempt to use when making or accepting connections. Specify one or more of "ipv4" or "ipv6", separated by whitespace or commas.
|
||||
# The form "all" is equivalent to "ipv4, ipv6" or "ipv4", depending on whether the operating system implements IPv6.
|
||||
postfix_inet_protocols: "all"
|
||||
|
||||
# The local network interface addresses that this mail system receives mail on. Specify "all" to receive mail on all network interfaces (default),
|
||||
# "loopback-only" to receive mail on loopback network interfaces only (Postfix version 2.2 and later), or zero or more IPv4 or IPv6 addresses
|
||||
# (IPv6 is supported in Postfix version 2.2 and later)
|
||||
postfix_inet_interfaces: "all"
|
||||
|
||||
# The primary mail domain for this server.
|
||||
postfix_mail_domain: "{{ ansible_domain | default('internal.local') }}"
|
||||
|
||||
# The Fully Qualified Domain Name of the mail server.
|
||||
postfix_myhostname: "mail.{{ postfix_mail_domain }}"
|
||||
|
||||
# Comma-separated list of domains this server accepts mail for.
|
||||
# It's critical that this includes the server's own hostname and mail domain.
|
||||
postfix_mydestination: "$myhostname, localhost.{{ postfix_mail_domain }}, localhost, {{ postfix_mail_domain }}"
|
||||
|
||||
# The list of "trusted" remote SMTP clients that have more privileges than "strangers".
|
||||
postfix_mynetworks: "127.0.0.0/8 [::1]/128"
|
||||
|
||||
# The relayhost (smarthost) for all outgoing mail.
|
||||
# This variable MUST be set for the role to work as intended.
|
||||
# Example: "[smtp.sendgrid.net]:587"
|
||||
# Note: The square brackets [] are important to prevent MX record lookups.
|
||||
postfix_relayhost: ""
|
||||
|
||||
# Optional credentials for the relayhost. If these are defined,
|
||||
# SASL authentication will be automatically configured.
|
||||
# postfix_relayhost_user: "apikey"
|
||||
# postfix_relayhost_password: "YourVeryLongAndComplexApiKey"
|
0
files/.gitkeep
Normal file
0
files/.gitkeep
Normal file
5
handlers/main.yml
Normal file
5
handlers/main.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Restart Postfix
|
||||
ansible.builtin.service:
|
||||
name: postfix
|
||||
state: restarted
|
21
meta/main.yml
Normal file
21
meta/main.yml
Normal file
@ -0,0 +1,21 @@
|
||||
galaxy_info:
|
||||
role_name: "mailserver"
|
||||
author: "Luciano Giacchetta"
|
||||
description: "Complete Mail Server Role"
|
||||
company: "Giacchetta Networks LLC"
|
||||
issue_tracker_url: "https://gianet.us/engineering/ansible_role_mailserver/issues"
|
||||
license: "GPL-3.0-only"
|
||||
min_ansible_version: "2.12"
|
||||
platforms:
|
||||
- name: "Debian"
|
||||
versions:
|
||||
- "all"
|
||||
- name: "Ubuntu"
|
||||
versions:
|
||||
- "all"
|
||||
galaxy_tags:
|
||||
- "mta"
|
||||
- "mail"
|
||||
- "postfix"
|
||||
|
||||
dependencies: []
|
55
tasks/main.yml
Normal file
55
tasks/main.yml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
- name: "POSTFIX | Install postfix package"
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- postfix
|
||||
- postfix-pcre # Often useful for advanced matching
|
||||
- libsasl2-modules # Required for SASL authentication
|
||||
state: present
|
||||
update_cache: true
|
||||
tags:
|
||||
- postfix_install
|
||||
|
||||
- name: "POSTFIX | Configure /etc/mailname"
|
||||
ansible.builtin.copy:
|
||||
content: "{{ postfix_mail_domain }}\n"
|
||||
dest: /etc/mailname
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
tags:
|
||||
- postfix_config
|
||||
|
||||
- name: "POSTFIX | Configure main.cf"
|
||||
ansible.builtin.template:
|
||||
src: main.cf.j2
|
||||
dest: /etc/postfix/main.cf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
validate: 'postfix check -c %s' # Validates the template before deploying
|
||||
notify: Restart Postfix # Triggers the handler to restart the service
|
||||
tags:
|
||||
- postfix_config
|
||||
|
||||
- name: "POSTFIX | Configure smarthost credentials (if defined)"
|
||||
when: postfix_relayhost_user is defined and postfix_relayhost_password is defined
|
||||
block:
|
||||
- name: "POSTFIX | Template the SASL password file"
|
||||
ansible.builtin.template:
|
||||
src: sasl_passwd.j2
|
||||
dest: /etc/postfix/sasl_passwd
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0600' # Secure permissions for file with credentials
|
||||
no_log: true # Prevents credentials from being displayed in Ansible logs
|
||||
notify: Restart Postfix
|
||||
|
||||
- name: "POSTFIX | Create hash map for SASL password file"
|
||||
ansible.builtin.command:
|
||||
cmd: postmap hash:/etc/postfix/sasl_passwd
|
||||
changed_when: true # The postmap command always updates the .db file
|
||||
notify: Restart Postfix
|
||||
tags:
|
||||
- postfix_config
|
||||
- postfix_smarthost
|
50
templates/main.cf.j2
Normal file
50
templates/main.cf.j2
Normal file
@ -0,0 +1,50 @@
|
||||
# This Jinja2 template is used to generate the /etc/postfix/main.cf file.
|
||||
# It uses variables to make the role reusable.
|
||||
#
|
||||
# See: https://www.postfix.org/postconf.5.html
|
||||
#
|
||||
# Ansible managed: {{ ansible_managed }}
|
||||
#
|
||||
# Basic configuration
|
||||
smtpd_banner = $myhostname ESMTP
|
||||
biff = no
|
||||
append_dot_mydomain = no
|
||||
readme_directory = no
|
||||
compatibility_level = 3.6
|
||||
inet_protocols = {{ postfix_inet_protocols }}
|
||||
inet_interfaces = {{ postfix_inet_interfaces }}
|
||||
recipient_delimiter = +
|
||||
|
||||
# TLS parameters for incoming connections
|
||||
# For a production server, replace snakeoil with real certificates.
|
||||
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||
smtpd_tls_security_level=may
|
||||
smtpd_use_tls=yes
|
||||
|
||||
# Host and domain configuration
|
||||
myhostname = {{ postfix_myhostname }}
|
||||
myorigin = /etc/mailname
|
||||
mydestination = {{ postfix_mydestination }}
|
||||
mynetworks = {{ postfix_mynetworks }}
|
||||
|
||||
# Relayhost (smarthost) configuration
|
||||
# All outgoing mail will be sent through this host. This is the only
|
||||
# supported outbound method in this configuration.
|
||||
relayhost = {{ postfix_relayhost }}
|
||||
|
||||
# SASL configuration for the relayhost (if credentials are provided)
|
||||
{% if postfix_relayhost_user is defined and postfix_relayhost_password is defined %}
|
||||
smtp_sasl_auth_enable = yes
|
||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||
smtp_sasl_security_options = noanonymous
|
||||
# Use 'encrypt' for services like Gmail/O365 that require TLS
|
||||
smtp_tls_security_level = encrypt
|
||||
{% else %}
|
||||
# If no auth, 'may' is a safe default for opportunistic TLS
|
||||
smtp_tls_security_level = may
|
||||
{% endif %}
|
||||
|
||||
# Other settings
|
||||
alias_maps = hash:/etc/aliases
|
||||
alias_database = hash:/etc/aliases
|
5
templates/sasl_passwd.j2
Normal file
5
templates/sasl_passwd.j2
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# This template creates the credential file for the smarthost.
|
||||
#
|
||||
# Ansible managed: {{ ansible_managed }}
|
||||
{{ postfix_relayhost }} {{ postfix_relayhost_user }}:{{ postfix_relayhost_password }}
|
2
tests/inventory
Normal file
2
tests/inventory
Normal file
@ -0,0 +1,2 @@
|
||||
localhost
|
||||
|
5
tests/test.yml
Normal file
5
tests/test.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- ansible_role_mailserver
|
2
vars/main.yml
Normal file
2
vars/main.yml
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
# vars file for ansible_role_mailserver
|
Loading…
x
Reference in New Issue
Block a user