From 379fe18f7a08050a6465c2909e4604a61a807136 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 5 Jan 2022 18:49:30 +0100 Subject: [PATCH 01/10] test dns resolvers at startup --- core/admin/start.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/core/admin/start.py b/core/admin/start.py index 0eff3bbe..5e573fd6 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -18,6 +18,36 @@ if account is not None and domain is not None and password is not None: log.info("Creating initial admin accout %s@%s with mode %s",account,domain,mode) os.system("flask mailu admin %s %s '%s' --mode %s" % (account, domain, password, mode)) +def test_DNS(): + import dns.resolver + import dns.exception + import dns.flags + import dns.rdtypes + import dns.rdatatype + import dns.rdataclass + import time + # DNS stub configured to do DNSSEC enabled queries + resolver = dns.resolver.Resolver() + resolver.use_edns(0, 0, 1232) + resolver.flags = dns.flags.AD | dns.flags.RD + nameservers = resolver.nameservers + for ns in nameservers: + resolver.nameservers=[ns] + error = True + while error: + try: + result = resolver.query('example.org', dns.rdatatype.A, dns.rdataclass.IN, lifetime=10) + if not result.response.flags & dns.flags.AD: + log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please install unbound.", ns) + else: + error = False + continue + except Exception as e: + log.critical("Your DNS resolver at %s is not working (%s). Please install unbound.", ns, e); + time.sleep(5) + +test_DNS() + start_command="".join([ "gunicorn --threads ", str(os.cpu_count()), " -b :80 ", From 984ae8b2d3976cda197aaa298d143c956964d5f5 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 5 Jan 2022 18:53:15 +0100 Subject: [PATCH 02/10] enable unbound by default --- setup/templates/steps/compose/03_expose.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/templates/steps/compose/03_expose.html b/setup/templates/steps/compose/03_expose.html index c9238f5a..80340f05 100644 --- a/setup/templates/steps/compose/03_expose.html +++ b/setup/templates/steps/compose/03_expose.html @@ -40,10 +40,10 @@ avoid generic all-interfaces addresses like 0.0.0.0 or :: -

The unbound resolver enables Mailu to do DNSsec verification, DNS root lookups and caching. This also helps the antispam service not to get blocked by the public or ISP DNS servers.

+

The unbound resolver enables Mailu to do DNSSEC verification, DNS root lookups and caching. This also helps the antispam service not to get blocked by the public or ISP DNS servers.

From 0e9880f2894c9b64280f26beb2adb2453db36a87 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 5 Jan 2022 18:55:10 +0100 Subject: [PATCH 03/10] towncrier --- towncrier/newsfragments/2135.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/2135.bugfix diff --git a/towncrier/newsfragments/2135.bugfix b/towncrier/newsfragments/2135.bugfix new file mode 100644 index 00000000..3062c09f --- /dev/null +++ b/towncrier/newsfragments/2135.bugfix @@ -0,0 +1 @@ +Enable unbound by default. Mailu now requires a DNSSEC validating DNS resolver and experience has shown that this may not be the default everywhere yet. From 0f25075fa38f18ced06603a1716357517bc407e6 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 6 Jan 2022 09:40:24 +0100 Subject: [PATCH 04/10] fix test --- tests/compose/core/docker-compose.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/compose/core/docker-compose.yml b/tests/compose/core/docker-compose.yml index 195d8a59..06f91f73 100644 --- a/tests/compose/core/docker-compose.yml +++ b/tests/compose/core/docker-compose.yml @@ -40,8 +40,11 @@ services: volumes: - "/mailu/data:/data" - "/mailu/dkim:/dkim" + dns: + - 192.168.203.254 depends_on: - redis + - resolver imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -75,7 +78,13 @@ services: # Optional services - + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 # Webmail From f4cb9de460c2088fff726c85e227f2d377ccb485 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 6 Jan 2022 09:42:59 +0100 Subject: [PATCH 05/10] enable the resolver everywhere --- setup/flavors/compose/docker-compose.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index efaa46f0..c114ec87 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -33,8 +33,11 @@ services: volumes: - "{{ root }}/certs:/certs" - "{{ root }}/overrides/nginx:/overrides:ro" + {% if resolver_enabled %} + - resolver + dns: + - {{ dns }} - {% if resolver_enabled %} resolver: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-{{ version }}} env_file: {{ env }} @@ -42,7 +45,7 @@ services: networks: default: ipv4_address: {{ dns }} - {% endif %} + {% endif %} admin: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-{{ version }}} @@ -57,6 +60,11 @@ services: - "{{ root }}/dkim:/dkim" depends_on: - redis + {% if resolver_enabled %} + - resolver + dns: + - {{ dns }} + {% endif %} imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-{{ version }}} From 8595893af9c94f463923ba2aa8413fde0f432a3d Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 6 Jan 2022 11:37:18 +0100 Subject: [PATCH 06/10] doh --- tests/compose/fetchmail/docker-compose.yml | 12 ++++++++++++ tests/compose/filters/docker-compose.yml | 11 ++++++++++- tests/compose/rainloop/docker-compose.yml | 11 ++++++++++- tests/compose/roundcube/docker-compose.yml | 11 ++++++++++- tests/compose/webdav/docker-compose.yml | 10 ++++++++++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/tests/compose/fetchmail/docker-compose.yml b/tests/compose/fetchmail/docker-compose.yml index d31479d4..ed296d3e 100644 --- a/tests/compose/fetchmail/docker-compose.yml +++ b/tests/compose/fetchmail/docker-compose.yml @@ -42,6 +42,9 @@ services: - "/mailu/dkim:/dkim" depends_on: - redis + - resolver + dns: + - 192.168.203.254 imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -81,6 +84,15 @@ services: restart: always env_file: mailu.env + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 + + # Webmail diff --git a/tests/compose/filters/docker-compose.yml b/tests/compose/filters/docker-compose.yml index 381d3683..09d948df 100644 --- a/tests/compose/filters/docker-compose.yml +++ b/tests/compose/filters/docker-compose.yml @@ -40,8 +40,11 @@ services: volumes: - "/mailu/data:/data" - "/mailu/dkim:/dkim" + dns: + - 192.168.203.254 depends_on: - redis + - resolver imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -81,7 +84,13 @@ services: volumes: - "/mailu/filter:/data" - + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 # Webmail diff --git a/tests/compose/rainloop/docker-compose.yml b/tests/compose/rainloop/docker-compose.yml index 62d5890f..ca8d70ba 100644 --- a/tests/compose/rainloop/docker-compose.yml +++ b/tests/compose/rainloop/docker-compose.yml @@ -42,6 +42,9 @@ services: - "/mailu/dkim:/dkim" depends_on: - redis + - resolver + dns: + - 192.168.203.254 imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -75,7 +78,13 @@ services: # Optional services - + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 # Webmail webmail: diff --git a/tests/compose/roundcube/docker-compose.yml b/tests/compose/roundcube/docker-compose.yml index 0bb54e8c..7ac94810 100644 --- a/tests/compose/roundcube/docker-compose.yml +++ b/tests/compose/roundcube/docker-compose.yml @@ -42,6 +42,9 @@ services: - "/mailu/dkim:/dkim" depends_on: - redis + - resolver + dns: + - 192.168.203.254 imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -75,7 +78,13 @@ services: # Optional services - + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 # Webmail webmail: diff --git a/tests/compose/webdav/docker-compose.yml b/tests/compose/webdav/docker-compose.yml index a597b2d2..7c62c90a 100644 --- a/tests/compose/webdav/docker-compose.yml +++ b/tests/compose/webdav/docker-compose.yml @@ -40,8 +40,11 @@ services: volumes: - "/mailu/data:/data" - "/mailu/dkim:/dkim" + dns: + - 192.168.203.254 depends_on: - redis + - resolver imap: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${PINNED_MAILU_VERSION:-local} @@ -82,6 +85,13 @@ services: volumes: - "/mailu/dav:/data" + resolver: + image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-local} + env_file: mailu.env + restart: always + networks: + default: + ipv4_address: 192.168.203.254 # Webmail From 70ea2a5be09c4b72d461f70782e1aeacd733cefa Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Thu, 6 Jan 2022 12:48:35 +0100 Subject: [PATCH 07/10] all containers --- setup/flavors/compose/docker-compose.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index c114ec87..6dac166b 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -13,6 +13,12 @@ services: restart: always volumes: - "{{ root }}/redis:/data" + {% if resolver_enabled %} + depends_on: + - resolver + dns: + - {{ dns }} + {% endif %} # Core services front: @@ -34,6 +40,7 @@ services: - "{{ root }}/certs:/certs" - "{{ root }}/overrides/nginx:/overrides:ro" {% if resolver_enabled %} + depends_on: - resolver dns: - {{ dns }} @@ -75,6 +82,11 @@ services: - "{{ root }}/overrides/dovecot:/overrides:ro" depends_on: - front + {% if resolver_enabled %} + - resolver + dns: + - {{ dns }} + {% endif %} smtp: image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-{{ version }}} @@ -130,6 +142,12 @@ services: env_file: {{ env }} volumes: - "{{ root }}/dav:/data" + {% if resolver_enabled %} + depends_on: + - resolver + dns: + - {{ dns }} + {% endif %} {% endif %} {% if fetchmail_enabled %} @@ -158,6 +176,11 @@ services: - "{{ root }}/overrides/{{ webmail_type }}:/overrides:ro" depends_on: - imap + {% if resolver_enabled %} + - resolver + dns: + - {{ dns }} + {% endif %} {% endif %} networks: From b12616b93f6a4df23fe24d7f34ed7feb5b8ee4cb Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 12 Jan 2022 09:55:14 +0100 Subject: [PATCH 08/10] Make the recommendation clearer --- core/admin/start.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/start.py b/core/admin/start.py index 5e573fd6..9a958c4a 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -38,12 +38,12 @@ def test_DNS(): try: result = resolver.query('example.org', dns.rdatatype.A, dns.rdataclass.IN, lifetime=10) if not result.response.flags & dns.flags.AD: - log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please install unbound.", ns) + log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please use another resolver or enable unbound via https://setup.mailu.io.", ns) else: error = False continue except Exception as e: - log.critical("Your DNS resolver at %s is not working (%s). Please install unbound.", ns, e); + log.critical("Your DNS resolver at %s is not working (%s). Please use another resolver or enable unbound via https://setup.mailu.io.", ns, e); time.sleep(5) test_DNS() From a2f624338289d8dc6887457f346b79e254e9394f Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 12 Jan 2022 13:34:18 +0100 Subject: [PATCH 09/10] remove the error variable --- core/admin/start.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/core/admin/start.py b/core/admin/start.py index 9a958c4a..f3e153f5 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -33,17 +33,15 @@ def test_DNS(): nameservers = resolver.nameservers for ns in nameservers: resolver.nameservers=[ns] - error = True - while error: + while True: try: result = resolver.query('example.org', dns.rdatatype.A, dns.rdataclass.IN, lifetime=10) - if not result.response.flags & dns.flags.AD: - log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please use another resolver or enable unbound via https://setup.mailu.io.", ns) - else: - error = False - continue except Exception as e: log.critical("Your DNS resolver at %s is not working (%s). Please use another resolver or enable unbound via https://setup.mailu.io.", ns, e); + elif result.response.flags & dns.flags.AD: + break + else: + log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please use another resolver or enable unbound via https://setup.mailu.io.", ns) time.sleep(5) test_DNS() From a9da0c084a4d40078f706772c420db15a57df993 Mon Sep 17 00:00:00 2001 From: Florent Daigniere Date: Wed, 12 Jan 2022 13:44:17 +0100 Subject: [PATCH 10/10] syntax error --- core/admin/start.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/start.py b/core/admin/start.py index f3e153f5..529f62d6 100755 --- a/core/admin/start.py +++ b/core/admin/start.py @@ -38,9 +38,9 @@ def test_DNS(): result = resolver.query('example.org', dns.rdatatype.A, dns.rdataclass.IN, lifetime=10) except Exception as e: log.critical("Your DNS resolver at %s is not working (%s). Please use another resolver or enable unbound via https://setup.mailu.io.", ns, e); - elif result.response.flags & dns.flags.AD: - break else: + if result.response.flags & dns.flags.AD: + break log.critical("Your DNS resolver at %s isn't doing DNSSEC validation; Please use another resolver or enable unbound via https://setup.mailu.io.", ns) time.sleep(5)