firebasemail / firebaseapp are domains hosted by Google that are commonly used to send spam.
You could add a regex for firebasemail to /etc/postfix/senderaccess, but that alone is not enough.
Some senders use Firebase with their own custom domains, but you can still block them early: their domain’s TXT SPF record contains _spf.firebasemail.com. You can use this information to reject these emails before the DATA command, saving resources and avoiding spam in your queue.
Create skript: /usr/local/bin/spf-policy.py
Don't forget to set execution bit:
copy templates, if not already done:
cp /var/lib/pmg/templates/master.cf.in /etc/pmg/templates/
cp /var/lib/pmg/templates/main.cf.in /etc/pmg/templates/
Add the policy_service to the existing smtpd_sender_restrictions to main.cf.in:
Add the two lines to the bottom of the master.cf.in
pmgconfig sync --restart
You could add a regex for firebasemail to /etc/postfix/senderaccess, but that alone is not enough.
Some senders use Firebase with their own custom domains, but you can still block them early: their domain’s TXT SPF record contains _spf.firebasemail.com. You can use this information to reject these emails before the DATA command, saving resources and avoiding spam in your queue.
Code:
apt install python3-dnspython
Create skript: /usr/local/bin/spf-policy.py
Python:
#!/usr/bin/env python3
import sys
import time
import dns.resolver
from functools import lru_cache
BLOCK_INCLUDE = "_spf.firebasemail.com"
MAX_SPF_DEPTH = 10
CACHE_SIZE = 4096
resolver = dns.resolver.Resolver()
resolver.timeout = 2
resolver.lifetime = 3
def log(msg):
sys.stderr.write(f"firebase-spf-policy: {msg}\n")
sys.stderr.flush()
@lru_cache(maxsize=CACHE_SIZE)
def get_spf(domain):
try:
answers = resolver.resolve(domain, "TXT")
for r in answers:
txt = "".join([s.decode() for s in r.strings])
if txt.startswith("v=spf1"):
return txt
except Exception:
pass
return None
def spf_contains_block(domain, depth=0, visited=None):
if visited is None:
visited = set()
if depth > MAX_SPF_DEPTH:
return False
if domain in visited:
return False
visited.add(domain)
spf = get_spf(domain)
if not spf:
return False
parts = spf.split()
for p in parts:
if p.startswith("include:"):
include = p.split(":", 1)[1]
if include == BLOCK_INCLUDE:
return True
if spf_contains_block(include, depth + 1, visited):
return True
return False
def handle_request(attrs):
sender = attrs.get("sender", "")
if "@" not in sender:
return "dunno"
domain = sender.split("@", 1)[1].lower()
try:
if spf_contains_block(domain):
log(f"blocked sender domain {domain}")
return "reject reject for policy reason"
except Exception as e:
log(f"error checking {domain}: {e}")
return "dunno"
def main():
while True:
attrs = {}
while True:
line = sys.stdin.readline()
if line == "":
return
line = line.strip()
if not line:
break
if "=" in line:
k, v = line.split("=", 1)
attrs[k] = v
if not attrs:
continue
action = handle_request(attrs)
print(f"action={action}\n")
sys.stdout.flush()
if __name__ == "__main__":
main()
Don't forget to set execution bit:
Code:
chmod +x /usr/local/bin/spf-policy.py
copy templates, if not already done:
cp /var/lib/pmg/templates/master.cf.in /etc/pmg/templates/
cp /var/lib/pmg/templates/main.cf.in /etc/pmg/templates/
Add the policy_service to the existing smtpd_sender_restrictions to main.cf.in:
Code:
smtpd_sender_restrictions =
check_policy_service unix:private/spf-policy
Code:
spf-policy unix - n n - 0 spawn
user=nobody argv=/usr/local/bin/spf_policy.py
pmgconfig sync --restart
Last edited: