Changeset - b1d025a9e559
[Not reviewed]
0 7 0
Branko Majic (branko) - 10 months ago 2025-01-22 13:46:13
branko@majic.rs
MAR-233: Add IPv6 connectivity tests for the mail_server role:

- Include an example of IPv6 address in documentation for the
smtp_allow_relay_from role parameter (has to have square brackets to
make it usable with Postfix configuratin).
- Expand the tests and test parameters to ensure IPv6 is properly
covered.
- Reorder the names in /etc/hosts slightly to ensure the ansible_fqdn
and inventory_hostname match-up. Code should be revisited to
probably drop the use of inventory_hostname from both roles and
tests, and instead rely on ansible_fqdn and ansible_hostname.
- Correct the Dovecot SSL DH parameter specification to use
ansible_fqdn for consistency purposes.
7 files changed with 37 insertions and 10 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
@@ -1274,13 +1274,14 @@ Parameters
 
  Mail address to use for the postmaster account in Dovecot.
 

	
 
**smtp_allow_relay_from** (list, optional, [])
 
  List of networks from which mail relaying is allowed even without
 
  authentication. Each item in the list is a string defining a network. The
 
  format must be compatible with Postfix ``mynetworks`` setting (for example:
 
  ``192.168.1.0/24``, ``myhost.example.com`` etc).
 
  ``192.168.1.0/24``, ``myhost.example.com``, ``[fd00::192:168:56:21]/128``
 
  etc).
 

	
 

	
 
Distribution compatibility
 
~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Role is compatible with the following distributions:
roles/mail_server/molecule/default/group_vars/parameters-optional.yml
Show inline comments
 
@@ -28,22 +28,23 @@ smtp_tls_key: "{{ lookup('file', 'tests/data/x509/server/{{ inventory_hostname }
 
imap_folder_separator: "."
 
smtp_rbl:
 
  - bl.spamcop.net
 
  - zen.spamhaus.org
 

	
 
mail_postmaster: "webmaster@parameters-optional"
 
smtp_allow_relay_from:
 
  - "{{ release_based_smtp_allow_relay_from[ansible_distribution_release] }}"
 
smtp_allow_relay_from: "{{ release_based_smtp_allow_relay_from[ansible_distribution_release] }}"
 
mail_message_size_limit: 20480001
 
mail_server_smtp_additional_configuration: |
 
  mail_name = MySMTP
 
  smtp_skip_5xx_greeting = no
 

	
 
# Variables dependant on distribution release.
 
release_based_smtp_allow_relay_from:
 
  bookworm: "192.168.56.21"
 
  bookworm:
 
    - 192.168.56.21
 
    - "[fd00::192:168:56:21]/128"
 

	
 
# common
 
ca_certificates:
 
  testca: "{{ lookup('file', 'tests/data/x509/ca/level1.cert.pem') }}"
 
# Tests can run in quick succession, increase limits to avoid false negatives.
 
incoming_connection_limit: 10/second
roles/mail_server/molecule/default/molecule.yml
Show inline comments
 
@@ -57,12 +57,17 @@ platforms:
 
    cpus: 1
 
    interfaces:
 
      - auto_config: true
 
        ip: 192.168.56.21
 
        network_name: private_network
 
        type: static
 
      - auto_config: true
 
        ip: fd00::192:168:56:21
 
        network_name: private_network
 
        netmask: 116
 
        type: static
 

	
 
  - name: client2-bookworm
 
    groups:
 
      - client
 
      - client-relay-forbidden
 
      - bookworm
 
@@ -72,12 +77,17 @@ platforms:
 
    cpus: 1
 
    interfaces:
 
      - auto_config: true
 
        ip: 192.168.56.22
 
        network_name: private_network
 
        type: static
 
      - auto_config: true
 
        ip: fd00::192:168:56:22
 
        network_name: private_network
 
        netmask: 116
 
        type: static
 

	
 
  - name: parameters-mandatory-bookworm
 
    groups:
 
      - parameters-mandatory
 
      - bookworm
 
    box: debian/bookworm64
 
@@ -85,12 +95,17 @@ platforms:
 
    cpus: 1
 
    interfaces:
 
      - auto_config: true
 
        ip: 192.168.56.31
 
        network_name: private_network
 
        type: static
 
      - auto_config: true
 
        ip: fd00::192:168:56:31
 
        network_name: private_network
 
        netmask: 116
 
        type: static
 

	
 
  - name: parameters-optional-bookworm
 
    groups:
 
      - parameters-optional
 
      - bookworm
 
    box: debian/bookworm64
 
@@ -98,12 +113,17 @@ platforms:
 
    cpus: 1
 
    interfaces:
 
      - auto_config: true
 
        ip: 192.168.56.32
 
        network_name: private_network
 
        type: static
 
      - auto_config: true
 
        ip: fd00::192:168:56:32
 
        network_name: private_network
 
        netmask: 116
 
        type: static
 

	
 

	
 
provisioner:
 
  name: ansible
 
  playbooks:
 
    cleanup: cleanup.yml
roles/mail_server/molecule/default/prepare.yml
Show inline comments
 
@@ -194,14 +194,18 @@
 
      with_dict:
 
        # Force mail servers to use local ClamAV database mirror.
 
        192.168.56.11: "db.local.clamav.net database.clamav.net"
 
        192.168.56.12: "ldap-server backup-server"
 
        192.168.56.21: "client1 smtp-server-requiring-tls"
 
        192.168.56.22: "client2 smtp-server-refusing-tls"
 
        192.168.56.31: "parameters-mandatory parameters-mandatory-bookworm"
 
        192.168.56.32: "parameters-optional parameters-optional-bookworm"
 
        192.168.56.31: "parameters-mandatory-bookworm parameters-mandatory"
 
        192.168.56.32: "parameters-optional-bookworm parameters-optional"
 
        fd00::192:168:56:21: "client1 smtp-server-requiring-tls"
 
        fd00::192:168:56:22: "client2 smtp-server-refusing-tls"
 
        fd00::192:168:56:31: "parameters-mandatory-bookworm parameters-mandatory"
 
        fd00::192:168:56:32: "parameters-optional-bookworm parameters-optional"
 

	
 
- name: Prepare, helpers
 
  hosts: client
 
  become: true
 
  tasks:
 

	
roles/mail_server/molecule/default/tests/test_client2.py
Show inline comments
 
@@ -285,19 +285,20 @@ def test_sieve_authentication_requires_tls(host):
 
    27,
 
    587,
 
    143,
 
    993,
 
    4190
 
])
 
def test_connectivity(host, server, port):
 
@pytest.mark.parametrize('ip_protocol', [4, 6])
 
def test_connectivity(host, server, port, ip_protocol):
 
    """
 
    Tests connectivity to the mail server (ports that should be reachable).
 
    """
 

	
 
    with host.sudo():
 
        scan = host.run('nmap -4 -p %s -oG - %s', str(port), server)
 
        scan = host.run('nmap -%s -p %s -oG - %s', str(ip_protocol), str(port), server)
 
        assert scan.rc == 0
 
        assert "Ports: %d/open/tcp//" % port in scan.stdout
 

	
 

	
 
def test_port_forwarding(host):
 
    """
roles/mail_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -38,13 +38,13 @@ def test_postfix_main_cf_file_content(host):
 

	
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 %s" % allow_relay_from_ip in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 %s" % " ".join(allow_relay_from_ip) in config_lines
 
    assert "smtpd_tls_cert_file = /etc/ssl/certs/%s_smtp.pem" % hostname in config_lines
 
    assert "smtpd_tls_key_file = /etc/ssl/private/%s_smtp.key" % hostname in config_lines
 
    assert "  reject_rbl_client bl.spamcop.net" in config_lines
 
    assert "  reject_rbl_client zen.spamhaus.org" in config_lines
 
    assert "smtp_host_lookup = dns, native" in config_lines
 

	
roles/mail_server/templates/99-local.conf.j2
Show inline comments
 
@@ -28,13 +28,13 @@ service auth {
 
  }
 
}
 

	
 
# TLS configuration.
 
ssl_cert = </etc/ssl/certs/{{ ansible_fqdn }}_imap.pem
 
ssl_key = </etc/ssl/private/{{ ansible_fqdn }}_imap.key
 
ssl_dh=</etc/ssl/private/{{ inventory_hostname }}_imap.dh.pem
 
ssl_dh=</etc/ssl/private/{{ ansible_fqdn }}_imap.dh.pem
 
ssl_min_protocol = {{ mail_server_minimum_tls_protocol }}
 
ssl_cipher_list = {{ mail_server_tls_ciphers }}
 
ssl = required
 

	
 
# Mail delivery.
 
protocol lda {
0 comments (0 inline, 0 general)