Many organizations have a requirement to configure a mail transfer agent (MTA) on Red Hat Enterprise Linux (RHEL) servers. This is frequently done to enable servers to send out notifications or reports over email. For example, you might configure a script to email out a notification after an event occurs, or you might have a script to email out a monthly report after it is generated.
RHEL 7, 8 and 9 provide two options for MTAs: Postfix and Sendmail. Sendmail has been deprecated, and this post will be focusing on Postfix.
It is possible to install and configure Postfix on RHEL systems manually, following the documentation, however this can be time-consuming and prone to error. Red Hat introduced the postfix
RHEL System Role to provide an automated solution to install and configure Postfix. The postfix
RHEL System Role was introduced in RHEL 7.6 as a technology preview feature. With the release of RHEL 8.5, the postfix
RHEL System Role is now fully supported.
RHEL System Roles are a collection of Ansible roles and modules that are included in RHEL to help provide consistent workflows and streamline the execution of manual tasks.
Environment overview
In my example environment, I have a control node system named controlnode running RHEL 8 and four managed nodes: rhel8-server1, rhel8-server2, rhel7-server1, and rhel7-server2 (the first two running RHEL 8, and the other two running RHEL 7). I would like to configure Postfix on each of the four managed nodes with the following configuration:
-
rhel8-server1 should be configured with a basic Postfix configuration to accept mail from the local subnet (which contains the other managed nodes).
-
rhel8-server2, rhel7-server1, and rhel7-server2 should be configured as forward-only null clients, and should forward mail to rhel8-server1.
I’ve already set up an Ansible service account on the five servers, named ansible, and have SSH key authentication set up so that the ansible account on controlnode can log in to each of the systems. In addition, the ansible service account has been configured with access to the root account via sudo on each host.
I’ve also installed the rhel-system-roles and ansible packages on controlnode. For more information on these tasks, refer to the Introduction to RHEL System Roles post.
In this environment, I’m using a RHEL 8 control node, but you can also use Ansible automation controller or Red Hat Satellite as your RHEL system roles control node. Ansible automation controller provides many advanced automation features and capabilities that are not available when using a RHEL control node.
For more information on Ansible automation controller and its functionality, refer to this overview page. For more information on using Satellite as your RHEL System Roles control node, refer to Automating host configuration with Red Hat Satellite and RHEL System Roles.
Defining the inventory file and role variables
From the controlnode system, the first step is to create a new directory structure:
[ansible@controlnode ~]$ mkdir -p postfix/group_vars
These directories will be used as follows:
-
The postfix directory will contain the playbook and the inventory file.
-
The postfix/group_vars file will contain variable files for inventory groups that will apply to hosts in the respective Ansible inventory groups.
I need to define an Ansible inventory file to list and group the hosts that I want the postfix
System Role to configure. I’ll create the inventory file at postfix/inventory.yml with the following content:
all: children: postfix_server: hosts: rhel8-server1.example.com: postfix_null_client: hosts: rhel8-server2.example.com: rhel7-server1.example.com: rhel7-server2.example.com:
This inventory defines two inventory groups:
-
postfix_server inventory group contains the rhel8-server1 host.
-
postfix_null_client inventory group contains the rhel8-server2, rhel7-server1 and rhel7-server2 hosts.
If using Ansible automation controller as your control node, this Inventory can be imported into Red Hat Ansible Automation Platform via an SCM project (example GitHub or GitLab) or using the awx-manage Utility as specified in the documentation. |
Next, I’ll define the role variables that will control the behavior of the postfix
System Role when it runs. The README.md file for the postfix
role, available at /usr/share/doc/rhel-system-roles/postfix/README.md, contains important information about the role including a list of available role variables and how to use them.
I’ll create a file that will define variables for my managed node listed in the postfix_server inventory group by creating a file at postfix/group_vars/postfix_server.yml with the following content:
postfix_conf: mydomain: "example.com" myorigin: "$mydomain" myhostname: "{{ inventory_hostname }}" mydestination: "$myhostname, localhost.$mydomain" mynetworks: "192.168.0.0/24" inet_interfaces: "all"
This will cause the postfix
role to configure the host in postfix_server inventory group (rhel8-server1) with a basic Postfix configuration that will accept connections from the 192.168.0.0/24 subnet, which is the network that contains all of the managed nodes.
I’ll also create a file to define variables for my managed nodes listed in the postfix_null_client inventory group by creating a file at postfix/group_vars/postfix_null_client.yml with the following content:
postfix_conf: myhostname: "{{ inventory_hostname }}" myorigin: "$mydomain" relayhost: "rhel8-server1.example.com" inet_interfaces: "loopback-only" mydestination: ""
This will cause the postfix
role to configure the hosts in the postfix_null_client inventory group (rhel8-server2, rhel7-server1, rhel7-server) as forward only null clients which will use rhel8-server1 as their relayhost.
Creating the playbook
The next step is creating the playbook file at postfix/postfix.yml with the following content:
- name: Open firewall for smtp on postfix_server group hosts: postfix_server tasks: - firewalld: service: smtp permanent: yes immediate: yes state: enabled - name: Run postfix role hosts: all roles: - rhel-system-roles.postfix
The first task, Open firewall for smtp on postfix_server group, will only be run on the rhel8-server1 host that is in the postfix_server inventory group, and this task will open the firewall for the smtp service.
The second task, Run postfix role, will run on all four of the managed nodes, and will cause Postfix to be installed and configured on each host, utilizing the previously defined variables.
If you are using Ansible automation controller as your control node, you can import this Ansible playbook into Red Hat Ansible Automation Platform by creating a Project, following the documentation provided here. It is very common to use Git repos to store Ansible playbooks. Ansible Automation Platform stores automation in units called Jobs which contain the playbook, credentials and inventory. Create a Job Template following the documentation here. |
Running the playbook
At this point, everything is in place, and I’m ready to run the playbook. For this demonstration, I’m using a RHEL control node and will run the playbook from the command line. I’ll use the cd command to move into the postfix
directory, and then use the ansible-playbook command to run the playbook.
[ansible@controlnode ~]$ cd postfix [ansible@controlnode postfix]$ ansible-playbook postfix.yml -b -i inventory.yml
I specify that the postfix.yml playbook should be run, that it should escalate to root (the -b flag), and that the inventory.yml file should be used as my Ansible inventory (the -i flag).
After the playbook completes, I verified that there were no failed tasks:
If you are using Ansible automation controller as your control node, you can launch the job from the automation controller web interface. |
Validating the configuration
To validate the configuration, I’ll log in to each of the three forward-only null clients (rhel8-server2, rhel7-server1, rhel7-server2) and send an email to the brian@rhel8-server1.example.com email address. I’ll then verify the emails were received by the brian account on the rhel8-server1.example.com host.
I’ll start on rhel8-server2 by sending the email:
[root@rhel8-server2 ~]# mail brian@rhel8-server1.example.com Subject: Test email from rhel8-server2 EOT Null message body; hope that's ok
Press Ctrl-d
to send the test message. I’ll repeat this step on rhel7-server1 and rhel7-server2 to send emails from them as well.
Next, I’ll login to rhel8-server1 as the brian account and verify the emails were received:
[brian@rhel8-server1 ~]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/brian": 3 messages 3 new >N 1 root Wed Nov 24 10:01 21/870 "Test email from rhel8-server2" N 2 root Wed Nov 24 10:03 21/861 "Test email from rhel7-server1" N 3 root Wed Nov 24 10:03 21/863 "Test email from rhel7-server2" &
Conclusion
The postfix
RHEL System Role can help you quickly and consistently implement the Postfix MTA across your RHEL environment in an automated manner.
We offer many RHEL System Roles that can help automate other important aspects of your RHEL environment. To explore additional roles, review the list of available RHEL System Roles and start managing your RHEL servers in a more efficient, consistent and automated manner today.
关于作者
Brian Smith is a Product Manager at Red Hat focused on RHEL automation and management. He has been at Red Hat since 2018, previously working with Public Sector customers as a Technical Account Manager (TAM).
产品
工具
试用购买与出售
沟通
关于红帽
我们是世界领先的企业开源解决方案供应商,提供包括 Linux、云、容器和 Kubernetes。我们致力于提供经过安全强化的解决方案,从核心数据中心到网络边缘,让企业能够更轻松地跨平台和环境运营。