From 9ddb8ff2d4134516255e9eca86bfb250d5f395d2 Mon Sep 17 00:00:00 2001 From: Son NK <> Date: Sun, 10 May 2020 10:37:56 +0200 Subject: [PATCH] add more info to spf alert email. Set the max number of emails per 24h to 1 --- app/email_utils.py | 2 +- email_handler.py | 21 ++++++++++++++++++-- templates/emails/transactional/spf-fail.html | 10 +++++++++- templates/emails/transactional/spf-fail.txt | 7 ++++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/app/email_utils.py b/app/email_utils.py index 54b9d767..582d1aa1 100644 --- a/app/email_utils.py +++ b/app/email_utils.py @@ -261,7 +261,7 @@ def send_email_with_rate_control( .count() ) - if nb_alert > max_alert_24h: + if nb_alert >= max_alert_24h: LOG.error( "%s emails were sent to %s in the last 24h, alert type %s", nb_alert, diff --git a/email_handler.py b/email_handler.py index 658c6a65..6c76b4db 100644 --- a/email_handler.py +++ b/email_handler.py @@ -32,6 +32,8 @@ It should contain the following info: """ import email import re + +import arrow import spf import time import uuid @@ -480,7 +482,7 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str mailbox: Mailbox = Mailbox.get_by(email=mailbox_email) if ENFORCE_SPF and mailbox.force_spf: ip = msg[_IP_HEADER] - if not spf_pass(ip, envelope, mailbox, user, alias, address): + if not spf_pass(ip, envelope, mailbox, user, alias, contact.website_email, msg): return False, "451 SL E11" delete_header(msg, _IP_HEADER) @@ -554,7 +556,13 @@ def handle_reply(envelope, smtp: SMTP, msg: Message, rcpt_to: str) -> (bool, str def spf_pass( - ip: str, envelope, mailbox: Mailbox, user: User, alias: Alias, contact_email: str + ip: str, + envelope, + mailbox: Mailbox, + user: User, + alias: Alias, + contact_email: str, + msg: Message, ) -> bool: if ip: LOG.d("Enforce SPF") @@ -583,6 +591,9 @@ def spf_pass( alias=alias.email, ip=ip, mailbox_url=URL + f"/dashboard/mailbox/{mailbox.id}#spf", + to_email=contact_email, + subject=msg["Subject"], + time=arrow.now(), ), render( "transactional/spf-fail.html", @@ -590,7 +601,13 @@ def spf_pass( alias=alias.email, ip=ip, mailbox_url=URL + f"/dashboard/mailbox/{mailbox.id}#spf", + to_email=contact_email, + subject=msg["Subject"], + time=arrow.now(), ), + # as the returned error status is 4**, + # the sender will try to resend the email. Send the error message only once + max_alert_24h=1, ) return False diff --git a/templates/emails/transactional/spf-fail.html b/templates/emails/transactional/spf-fail.html index d8de6264..13558c58 100644 --- a/templates/emails/transactional/spf-fail.html +++ b/templates/emails/transactional/spf-fail.html @@ -4,10 +4,18 @@ {{ render_text("Hi " + name) }} {% call text() %} - We have recorded an attempt to send an email from your alias {{ alias }} from an unknown IP address + We have recorded an attempt to send the following email from your alias {{ alias }} from an unknown IP + address {{ ip }}. {% endcall %} + {% call text() %} + - From: {{ alias }}
+ - To: {{ to_email }}
+ - Subject: {{ subject }}
+ - Time: {{ time.humanize() }} + {% endcall %} + {% call text() %} To prevent email-spoofing, SimpleLogin enforces the SPF (Sender Policy Framework). Emails sent from an IP address that is unknown by your email service are refused by default. diff --git a/templates/emails/transactional/spf-fail.txt b/templates/emails/transactional/spf-fail.txt index e7ba08e7..5cee2e6d 100644 --- a/templates/emails/transactional/spf-fail.txt +++ b/templates/emails/transactional/spf-fail.txt @@ -1,6 +1,11 @@ Hi {{name}} -We have recorded an attempt to send an email from your alias {{ alias }} from an unknown IP address {{ ip }}. +We have recorded an attempt to send the following email from your alias {{ alias }} from an unknown IP address {{ ip }}. + +- From: {{alias}} +- To: {{to_email}} +- Subject: {{subject}} +- Time: {{ time.humanize() }} To prevent email-spoofing, SimpleLogin enforces the SPF (Sender Policy Framework). Emails sent from an IP address that is unknown by your email service are refused by default.