Implement the DANE-only lookup policyd

https://github.com/Snawoot/postfix-mta-sts-resolver/issues/67 for
context
master
Florent Daigniere 3 years ago
parent d607ba0ef2
commit a1da4daa4c

@ -7,6 +7,9 @@ import idna
import re import re
import srslib import srslib
@internal.route("/postfix/dane/<domain_name>")
def postfix_dane_map(domain_name):
return flask.jsonify('dane-only') if utils.has_dane_record(domain_name) else flask.abort(404)
@internal.route("/postfix/domain/<domain_name>") @internal.route("/postfix/domain/<domain_name>")
def postfix_mailbox_domain(domain_name): def postfix_mailbox_domain(domain_name):

@ -6,6 +6,9 @@ try:
except ImportError: except ImportError:
import pickle import pickle
import dns
import dns.resolver
import hmac import hmac
import secrets import secrets
import time import time
@ -25,7 +28,6 @@ from itsdangerous.encoding import want_bytes
from werkzeug.datastructures import CallbackDict from werkzeug.datastructures import CallbackDict
from werkzeug.contrib import fixers from werkzeug.contrib import fixers
# Login configuration # Login configuration
login = flask_login.LoginManager() login = flask_login.LoginManager()
login.login_view = "ui.login" login.login_view = "ui.login"
@ -37,6 +39,26 @@ def handle_needs_login():
flask.url_for('ui.login', next=flask.request.endpoint) flask.url_for('ui.login', next=flask.request.endpoint)
) )
# DNS stub configured to do DNSSEC enabled queries
resolver = dns.resolver.Resolver()
resolver.use_edns(0, 0, 1500)
resolver.flags = dns.flags.AD | dns.flags.RD
def has_dane_record(domain, timeout=5):
try:
result = resolver.query(f'_25._tcp.{domain}', dns.rdatatype.TLSA,dns.rdataclass.IN, lifetime=timeout)
if (result.response.flags & dns.flags.AD) == dns.flags.AD:
for record in result:
if isinstance(record, dns.rdtypes.ANY.TLSA.TLSA):
record.validate()
if record.usage in [2,3]: # postfix wants DANE-only
return True
except dns.resolver.NoNameservers:
# this could be an attack / a failed DNSSEC lookup
return True
except:
pass
# Rate limiter # Rate limiter
limiter = limiter.LimitWraperFactory() limiter = limiter.LimitWraperFactory()

@ -60,7 +60,7 @@ smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtp_tls_protocols =!SSLv2,!SSLv3 smtp_tls_protocols =!SSLv2,!SSLv3
smtp_tls_security_level = {{ OUTBOUND_TLS_LEVEL|default('dane') }} smtp_tls_security_level = {{ OUTBOUND_TLS_LEVEL|default('dane') }}
smtp_tls_dane_insecure_mx_policy = {% if DEFER_ON_TLS_ERROR == 'false' %}may{% else %}dane{% endif %} smtp_tls_dane_insecure_mx_policy = {% if DEFER_ON_TLS_ERROR == 'false' %}may{% else %}dane{% endif %}
smtp_tls_policy_maps=hash:/etc/postfix/tls_policy.map, socketmap:unix:/tmp/mta-sts.socket:postfix smtp_tls_policy_maps=hash:/etc/postfix/tls_policy.map, ${podop}dane, socketmap:unix:/tmp/mta-sts.socket:postfix
smtp_tls_CApath = /etc/ssl/certs smtp_tls_CApath = /etc/ssl/certs
smtp_tls_session_cache_database = lmdb:/dev/shm/postfix/smtp_scache smtp_tls_session_cache_database = lmdb:/dev/shm/postfix/smtp_scache
smtpd_tls_session_cache_database = lmdb:/dev/shm/postfix/smtpd_scache smtpd_tls_session_cache_database = lmdb:/dev/shm/postfix/smtpd_scache

@ -21,6 +21,7 @@ def start_podop():
run_server(0, "postfix", "/tmp/podop.socket", [ run_server(0, "postfix", "/tmp/podop.socket", [
("transport", "url", url + "transport/§"), ("transport", "url", url + "transport/§"),
("alias", "url", url + "alias/§"), ("alias", "url", url + "alias/§"),
("dane", "url", url + "dane/§"),
("domain", "url", url + "domain/§"), ("domain", "url", url + "domain/§"),
("mailbox", "url", url + "mailbox/§"), ("mailbox", "url", url + "mailbox/§"),
("recipientmap", "url", url + "recipient/map/§"), ("recipientmap", "url", url + "recipient/map/§"),

Loading…
Cancel
Save