Google Workspace: избавляемся от спуфинга адресов

Спуфинг адресов электронной почты это когда кто-то через свой почтовый сервер отправляет спам подменяя свой адрес электронной почты вашим.

Рассмотрим как избавиться от такой напасти, чтобы самим не быть источником фишинговых рассылок и защитить своих клиентов.

SPF

Первым делом надо добавить в DNS-сервер запись типа TXT для свего основного домена (пусть будет example.com). Выглядеть запись должна примерно так:

{'data': 'v=spf1 ip4:x.x.x.x ip4:y.y.y.y include:_spf.google.com ~all', 'name': '@', 'ttl': 3600, 'type': 'TXT'}
# ip4 - тут перечисляем ip-адреса серверов с которых разрешено отправлять электронную почту (например smtp-релеи)
# include - разрешает отправлять электронную почту с серверов google.com
# ~all - это механизм отклонения писем отправленных с серверов. тильда означает мягкий отказ т.е. если письмо не пройдет проверку spf, но пройдет проверку dkim, то письмо дойдет до получателя.

Эта запись определяет политику отправки электронной почты (собственно и переводится как sender policy framework).

DKIM

DKIM подпись нужна чтобы отправляемые письма проходили аутентификацию с помощью ключей. Закрытая часть хранится в гугле, а открытая на DNS-сервере в виде TXT записи. Письма не подписанные dkim ключом будут отфутболены другими почтовыми серверами.
Идем в admin.google.com -> приложения -> google workspace -> gmail -> аутентификация электронной почты -> generate new record (убедитесь что в выпадающем списке стоит основной домен). Далее будут какие-то вопросы и все оставляем с значениями по-умолчанию после чего нам выдадут TXT запись, которую следует прописать на DNS-сервере и выглядит это примерно так:

DNS Host name (TXT record name):
google._domainkey
TXT record value:
v=DKIM1; k=rsa; p=MIIBIjANBgkqhk...

Ну собственно это и прописываем на DNS-сервере:

{'data': 'v=DKIM1; k=rsa; p=MIIBIjANBgkqhk...', 'name': 'google._domainkey', 'ttl': 3600, 'type': 'TXT'}

Далее просто ждем и время от времени проверяем не появилась ли запись:

host -t txt google._domainkey.example.com 8.8.8.8

Вместо dns 8.8.8.8 можно использовать любой другой публичный dns сервер. Как только запись появится на публичном dns сервере нажимаем на кнопку "start authentication".

DMARC

DMARC защита как раз таки отвечает за проверку spf и dkim. Собственно его активация довольно простая. Надо всего лишь создать такую TXT запись на DNS-сервере:

{'data': 'v=DMARC1; p=reject; rua=mailto:admins@example.com; ruf=mailto:admins@example.com; pct=100; adkim=s; aspf=s', 'name': '_dmarc', 'ttl': 3600, 'type': 'TXT'}
# rua - нужен для отправки общих отчетов о сбоях проверок dmarc
# ruf - нужен для отправки подробных отчетов о сбоях проверок dmarc

Собственно rua и ruf нужны в первое время, чтобы видеть все ли нормально настроено ну и в дальнейшем понадобится для профилирования проблем с доставкой писем. После запуска DMARC полезно будет недели 2 последить за отчетами и если все ОК, то убрать их пока не начнут поступать жалобы в работе почты.

ОТЧЕТ ОТЧЕТОВ

Из DMARC отчетов можно сгенерировать общий отчет в формате CSV, чтобы было удобнее читать, Для этого приложу скрипт сгенерированный в gpt:

# создаем директорию куда положим этот скрипт и все распакованные отчеты
import xml.etree.ElementTree as ET
import glob
import pandas as pd

files = glob.glob('*.xml')

records = []
for file in files:
    tree = ET.parse(file)
    root = tree.getroot()
    
    org_name = root.find('report_metadata/org_name').text
    
    for record in root.findall('record'):
        row = record.find('row')
        source_ip = row.find('source_ip').text
        count = int(row.find('count').text)
        disposition = row.find('policy_evaluated/disposition').text
        dkim_result = row.find('policy_evaluated/dkim').text
        spf_result = row.find('policy_evaluated/spf').text
        
        records.append({
            'org_name': org_name,
            'source_ip': source_ip,
            'count': count,
            'disposition': disposition,
            'dkim_result': dkim_result,
            'spf_result': spf_result
        })

for record in records:
    print(record)

df = pd.DataFrame(records)
df.to_csv('dmarc_reports.csv', index=False)

Таким образом мы получим примерно такой отчет:

org_name,source_ip,count,disposition,dkim_result,spf_result
Yahoo,198.2.142.9,1,none,pass,fail
Yahoo,198.2.174.170,1,none,pass,fail
Yahoo,205.201.133.172,2,none,pass,fail
Yahoo,205.201.135.176,1,none,pass,fail
Yahoo,198.2.142.9,2,none,pass,fail
Yahoo,205.201.133.172,1,none,pass,fail
Yahoo,54.240.8.56,1,none,pass,fail
Yahoo,205.201.133.172,1,none,pass,fail
Yahoo,148.105.11.101,1,none,pass,fail
google.com,129.153.182.219,1,none,pass,fail
google.com,209.85.220.41,18,none,pass,fail
google.com,205.201.133.172,4659,none,pass,fail
google.com,2a01:111:f400:7eac::209,1,none,pass,fail
google.com,2001:558:fd01:2bb4::c,1,none,pass,fail
google.com,209.85.220.65,2,none,pass,pass

Тут мы видим названия организаций, которым принадлежат серверы через которые прошли наши письма, ip-адреса этих серверов, количество отправлений и результаты прохождения проверок dkim и spf.
Как видим где-то прошли все тесты, но в большинстве случаев не прошел тест spf. Это потому-что ip-адреса этих серверов не указаны в нашем spf. И нет, не надо добавлять каждый сервер в spf - лучше просто укажите ip-адреса ваших серверов с которых должна уходить почта (если таковых нет, то и указывать ничего не надо).
Тут такое дело, что если прошла только dkim проверка, то письмо все равно будет доставлено адресату. У нас в spf на это дело указывает значение "~all". Поэтому главное чтобы хотя бы одна из двух проверок прошла - это будет означать что все работает.
Дополнительно можно пройти онлайн тесты тут и тут, а за сбоями в отправке писем можно последить в google postmaster.

ИТОГ

Теперь если кто-то захочет заспуфить адреса электронных ящиков с вашего домена, то им придется раздобыть закрытую часть ключа, чтобы им подписывать письма. Другие же сервера смогут проверять легитимность письма используя открытый ключ хранящийся на DNS-сервере (оно же указывается в заголовке письма).
Надеюсь данная статья поможет избежать фишинговой атаки ваших клиентов и сотрудников с вашего же домена и повысить репутацию домена.