Fix MX and SPF check
- take into account priority in MX check - use EMAIL_DOMAIN in SPF instead of MX server
This commit is contained in:
parent
ef8f87798b
commit
757fff71af
|
@ -49,7 +49,6 @@ POSTFIX_SERVER = os.environ.get("POSTFIX_SERVER", "1.1.1.1")
|
||||||
EMAIL_SERVERS_WITH_PRIORITY = eval(
|
EMAIL_SERVERS_WITH_PRIORITY = eval(
|
||||||
os.environ["EMAIL_SERVERS_WITH_PRIORITY"]
|
os.environ["EMAIL_SERVERS_WITH_PRIORITY"]
|
||||||
) # [(10, "email.hostname.")]
|
) # [(10, "email.hostname.")]
|
||||||
EMAIL_SERVERS = [es for _, es in EMAIL_SERVERS_WITH_PRIORITY]
|
|
||||||
|
|
||||||
# these emails are ignored when computing stats
|
# these emails are ignored when computing stats
|
||||||
if os.environ.get("IGNORED_EMAILS"):
|
if os.environ.get("IGNORED_EMAILS"):
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-2">Add the following MX DNS record to your domain</div>
|
<div class="mb-2">Add the following MX DNS record to your domain.
|
||||||
|
Please note that there's a point (<em>.</em>) at the end of target addresses.
|
||||||
|
</div>
|
||||||
|
|
||||||
{% for priority, email_server in EMAIL_SERVERS_WITH_PRIORITY %}
|
{% for priority, email_server in EMAIL_SERVERS_WITH_PRIORITY %}
|
||||||
<div class="mb-3 p-3" style="background-color: #eee">
|
<div class="mb-3 p-3" style="background-color: #eee">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from flask import render_template, request, redirect, url_for, flash
|
from flask import render_template, request, redirect, url_for, flash
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
|
|
||||||
from app.config import EMAIL_SERVERS_WITH_PRIORITY, EMAIL_SERVERS, DKIM_DNS_VALUE
|
from app.config import EMAIL_SERVERS_WITH_PRIORITY, DKIM_DNS_VALUE, EMAIL_DOMAIN
|
||||||
from app.dashboard.base import dashboard_bp
|
from app.dashboard.base import dashboard_bp
|
||||||
from app.dns_utils import (
|
from app.dns_utils import (
|
||||||
get_mx_domains,
|
get_mx_domains,
|
||||||
|
@ -33,9 +33,12 @@ def domain_detail_dns(custom_domain_id):
|
||||||
if request.form.get("form-name") == "check-mx":
|
if request.form.get("form-name") == "check-mx":
|
||||||
mx_domains = get_mx_domains(custom_domain.domain)
|
mx_domains = get_mx_domains(custom_domain.domain)
|
||||||
|
|
||||||
if mx_domains != EMAIL_SERVERS:
|
if sorted(mx_domains) != sorted(EMAIL_SERVERS_WITH_PRIORITY):
|
||||||
mx_ok = False
|
mx_ok = False
|
||||||
mx_errors = get_mx_domains(custom_domain.domain, keep_priority=True)
|
# build mx_errors to show to user
|
||||||
|
mx_errors = [
|
||||||
|
f"{priority} {domain}" for (priority, domain) in mx_domains
|
||||||
|
]
|
||||||
else:
|
else:
|
||||||
flash(
|
flash(
|
||||||
"Your domain is verified. Now it can be used to create custom alias",
|
"Your domain is verified. Now it can be used to create custom alias",
|
||||||
|
@ -50,15 +53,7 @@ def domain_detail_dns(custom_domain_id):
|
||||||
)
|
)
|
||||||
elif request.form.get("form-name") == "check-spf":
|
elif request.form.get("form-name") == "check-spf":
|
||||||
spf_domains = get_spf_domain(custom_domain.domain)
|
spf_domains = get_spf_domain(custom_domain.domain)
|
||||||
for email_server in EMAIL_SERVERS:
|
if EMAIL_DOMAIN in spf_domains:
|
||||||
email_server = email_server[:-1] # remove the trailing .
|
|
||||||
if email_server not in spf_domains:
|
|
||||||
flash(
|
|
||||||
f"{email_server} is not included in your SPF record.", "warning"
|
|
||||||
)
|
|
||||||
spf_ok = False
|
|
||||||
|
|
||||||
if spf_ok:
|
|
||||||
custom_domain.spf_verified = True
|
custom_domain.spf_verified = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("The SPF is setup correctly", "success")
|
flash("The SPF is setup correctly", "success")
|
||||||
|
@ -68,6 +63,8 @@ def domain_detail_dns(custom_domain_id):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
flash(f"{EMAIL_DOMAIN} is not included in your SPF record.", "warning")
|
||||||
|
spf_ok = False
|
||||||
spf_errors = get_txt_record(custom_domain.domain)
|
spf_errors = get_txt_record(custom_domain.domain)
|
||||||
|
|
||||||
elif request.form.get("form-name") == "check-dkim":
|
elif request.form.get("form-name") == "check-dkim":
|
||||||
|
@ -87,11 +84,7 @@ def domain_detail_dns(custom_domain_id):
|
||||||
dkim_ok = False
|
dkim_ok = False
|
||||||
dkim_errors = get_txt_record(f"dkim._domainkey.{custom_domain.domain}")
|
dkim_errors = get_txt_record(f"dkim._domainkey.{custom_domain.domain}")
|
||||||
|
|
||||||
spf_include_records = []
|
spf_record = f"v=spf1 include:{EMAIL_DOMAIN} -all"
|
||||||
for priority, email_server in EMAIL_SERVERS_WITH_PRIORITY:
|
|
||||||
spf_include_records.append(f"include:{email_server[:-1]}")
|
|
||||||
|
|
||||||
spf_record = f"v=spf1 {' '.join(spf_include_records)} -all"
|
|
||||||
|
|
||||||
dkim_record = f"v=DKIM1; k=rsa; p={DKIM_DNS_VALUE}"
|
dkim_record = f"v=DKIM1; k=rsa; p={DKIM_DNS_VALUE}"
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
|
|
||||||
|
|
||||||
def get_mx_domains(hostname, keep_priority=False) -> [str]:
|
def get_mx_domains(hostname) -> [(int, str)]:
|
||||||
"""return list of (domain name). priority is also included if `keep_priority`
|
"""return list of (priority, domain name).
|
||||||
|
domain name ends with a "." at the end.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
answers = dns.resolver.query(hostname, "MX")
|
answers = dns.resolver.query(hostname, "MX")
|
||||||
|
@ -13,10 +14,9 @@ def get_mx_domains(hostname, keep_priority=False) -> [str]:
|
||||||
|
|
||||||
for a in answers:
|
for a in answers:
|
||||||
record = a.to_text() # for ex '20 alt2.aspmx.l.google.com.'
|
record = a.to_text() # for ex '20 alt2.aspmx.l.google.com.'
|
||||||
if not keep_priority:
|
parts = record.split(" ")
|
||||||
record = record.split(" ")[1] # alt2.aspmx.l.google.com.
|
|
||||||
|
|
||||||
ret.append(record)
|
ret.append((int(parts[0]), parts[1]))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue