Niezgodność hasha treści DKIM oznacza, że treść wiadomości została zmieniona gdzieś pomiędzy serwerem, który ją podpisał, a serwerem, który ją zweryfikował. DKIM przechowuje hash treści w tagu bh= podpisu. Kiedy odbiorca ponownie wylicza ten hash z treści, którą faktycznie otrzymał, i uzyskuje inną wartość, weryfikacja kończy się niepowodzeniem z powodu niezgodności hasha treści, nawet jeśli Twój klucz prywatny i rekord są bez zarzutu. W dziewięciu przypadkach na dziesięć rozwiązaniem nie jest klucz ani rekord DNS. To jakiś etap przekazu, który przepisał treść po podpisaniu.
Odczytujemy wyłącznie publiczny DNS. Nic nie zapisujemy, dopóki nie przypiszesz domeny do konta.
Co tak naprawdę chroni tag bh=
Podpis DKIM ma dwie niezależne kontrole integralności, a ich mylenie sprawia, że awarie hasha treści wydają się tak tajemnicze.
Pierwsza to hash treści. Serwer podpisujący przepuszcza treść wiadomości przez funkcję skrótu (SHA-256 w nowoczesnych konfiguracjach) i zapisuje wynik w tagu bh=. Weryfikator hashuje otrzymaną treść w ten sam sposób i porównuje. Jeśli obie wartości się różnią, otrzymujesz niezgodność hasha treści, a cały podpis jest nieważny, kropka.
Druga to podpis nagłówków, przechowywany w tagu b=. Jest to podpis RSA lub Ed25519 obejmujący wybrane nagłówki oraz wartość bh=. Dowodzi on, że podpisane nagłówki i hash treści nie zostały naruszone i że pochodzą od posiadacza klucza prywatnego.
Oto część, która najbardziej myli. Jeśli odbiorca zgłasza coś w rodzaju dkim=fail (body hash did not verify), Twoja kryptografia jest w porządku. Klucz się zgadzał, nagłówki były nienaruszone, ale treść dotarła inna niż ta, która została podpisana. To zupełnie inny problem niż błąd signature did not verify, który wskazuje na klucz lub podpisane nagłówki. Przeczytaj dokładny opis przyczyny w nagłówku Authentication-Results, zanim czegokolwiek dotkniesz, bo mówi on, która z dwóch kontroli się nie powiodła.
Typowy podpis wygląda tak:
v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=selector1; h=from:to:subject:date; bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=; b=dzX9k...
Wartość bh= to odcisk palca treści. c=relaxed/relaxed kontroluje kanonikalizację, do której jeszcze wrócimy, bo to ona decyduje, jak wyrozumiałe jest porównanie treści.
Typowi winowajcy stojący za awarią bh=
Niemal każda niezgodność hasha treści pochodzi od jednego z niewielkiej grupy pośredników, którzy edytują treść po podpisaniu jej przez Twój serwer.
Dodawanie klauzul i stopek
To najczęstsza przyczyna. Urządzenie zgodności, brama pocztowa lub lista mailingowa dodaje na dole wiadomości klauzulę prawną, stopkę z rezygnacją z subskrypcji albo baner "przeskanowano przez". Ten doklejony tekst zmienia treść, więc hash wyliczony przez nadawcę przestaje pasować. Serwer podpisujący nie miał pojęcia, że stopka nadchodzi, dlatego bh= został obliczony na krótszej, oryginalnej treści.
Menedżery list mailingowych są tu szczególnie agresywne. Dodają stopki, przepisują tematy, a czasem usuwają załączniki, co jest dużym powodem, dla którego poczta przekazywana i listowa psuje uwierzytelnianie. Ta sama klasa problemów dotyka też SPF, co omówiono w dlaczego przekazywanie poczty psuje SPF.
Przepisywanie linków i śledzenie kliknięć
Produkty bezpieczeństwa i platformy marketingowe przepisują każdy URL w treści, tak aby kliknięcia przechodziły przez ich domenę śledzącą lub skanującą. Przepisanie choćby jednego linku zmienia bajty w treści. Jeśli takie przepisanie następuje po podpisaniu, hash treści jest martwy. Zdarza się to często przy funkcjach ochrony URL na bramach przychodzących oraz przy wysyłkach ze śledzeniem, gdzie ESP podpisuje przed przepisaniem przez system śledzący albo odwrotnie.
Ponowne kodowanie MIME
Niektóre przekaźniki normalizują wiadomość: ponownie zawijają długie wiersze, przełączają część z quoted-printable na base64, dodają lub usuwają końcowe ograniczenie MIME albo kodują ponownie z 8bit na 7bit. Nic z tego nie zmienia tego, co czyta człowiek, ale zmienia surowe bajty, a DKIM hashuje surowe bajty. Wiadomość, która przechodzi na jednym etapie, może zawieść jeden przekaźnik dalej wyłącznie z powodu ponownego kodowania w transporcie.
Końcowe białe znaki i puste wiersze
DKIM ma ścisłe reguły dotyczące pustych wierszy na końcu treści. Jeśli serwer doda lub usunie końcowe puste wiersze, hash może się przesunąć. Kanonikalizacja relaxed radzi sobie z częścią tych przypadków, ale nie ze wszystkimi, co jest idealnym przejściem do tematu kanonikalizacji.
Kanonikalizacja simple kontra relaxed
Kanonikalizacja to normalizacja, którą DKIM stosuje przed hashowaniem, a tag c= nazywa dwa algorytmy oddzielone ukośnikiem: najpierw kanonikalizacja nagłówków, potem treści, na przykład relaxed/relaxed albo simple/simple.
Dla treści oba tryby zachowują się bardzo różnie:
- simple nie toleruje niemal niczego. Jedyne, co wybacza, to puste wiersze na samym końcu treści. Każda inna zmiana białych znaków, w tym końcowe spacje w wierszu albo przekonwertowane tabulatory, psuje hash.
- relaxed jest znacznie bardziej wyrozumiały. Redukuje ciągi białych znaków wewnątrz wiersza do pojedynczej spacji, usuwa końcowe białe znaki na końcu każdego wiersza i ignoruje puste wiersze końcowe. Drobne przeformatowanie przez porządny przekaźnik może to przetrwać.
Jeśli obserwujesz sporadyczne awarie hasha treści, a Twój podpis używa kanonikalizacji treści simple, przełączenie na relaxed/relaxed często zatrzymuje krwawienie, bo pochłania nieszkodliwą normalizację białych znaków, którą simple traktuje jak naruszenie. Relaxed to rozsądny domyślny wybór dla niemal każdego nadawcy. Nie uratuje Cię jednak przed dodawaniem stopek ani przepisywaniem linków. One zmieniają prawdziwą treść i żaden tryb kanonikalizacji tego nie wybaczy.
Złota zasada: podpisuj na ostatnim etapie zmieniającym treść
Trwałym rozwiązaniem jest architektura, a nie ustawienie, które przełączasz. DKIM musi być stosowany przez ostatni system, który dotyka treści. Jeśli cokolwiek dalej w łańcuchu edytuje wiadomość, ta edycja musi nastąpić przed podpisaniem albo podpis musi zostać nałożony ponownie po edycji.
W praktyce:
- Jeśli brama dodaje klauzule, podpisuj na tej bramie lub na etapie po niej, a nie przed.
- Jeśli Twój ESP przepisuje linki do śledzenia, pozwól ESP podpisać ostateczną, przepisaną wiadomość, zamiast podpisywać wcześniej i przekazywać mu podpisaną treść, którą potem zmieni.
- Jeśli urządzenie bezpieczeństwa znajduje się między Twoim serwerem pocztowym a internetem i modyfikuje pocztę, musi ono albo być świadome podpisywania, albo być umieszczone przed systemem podpisującym.
Kolejność operacji jest wszystkim. Podpis to migawka treści w jednej chwili. Każda zmiana na poziomie bajtów po tej chwili go unieważnia. Wygrywające konfiguracje podpisują raz, tak późno, jak to możliwe, i niczego potem nie zmieniają.
Metoda porównania surowej treści przed i po
Aby wychwycić dokładnie ten etap, który Cię psuje, porównaj surową treść w dwóch punktach.
- Przechwyć surową wiadomość, którą emituje serwer podpisujący. Na wielu serwerach MTA możesz zapisać kopię do skrzynki debugowania albo odczytać ją z kolejki wychodzącej. Zdobądź surowe źródło, nie widok wyrenderowany, bo Twój klient poczty ukrywa bajty, które mają znaczenie.
- Przechwyć surową wiadomość w postaci otrzymanej w miejscu docelowym. W Gmailu użyj "Pokaż oryginał", w Outlooku użyj "Wyświetl źródło wiadomości", albo pobierz ją z magazynu serwera odbierającego.
- Porównaj obie treści bajt po bajcie. Szukaj konkretnie doklejonej stopki, przepisanych adresów URL, zmienionego
Content-Transfer-Encoding, ponownie zawiniętych długich wierszy albo dodanych końcowych pustych wierszy.
Cokolwiek różni się między dwoma przechwyceniami, to Twój winowajca, a etap, który to wprowadził, to etap, który musi podpisywać albo musi znaleźć się przed systemem podpisującym. To zamienia mgliste "DKIM czasem zawodzi" w konkretną, naprawialną zmianę.
Jeśli po tym wszystkim treść jest naprawdę identyczna, a DKIM nadal zawodzi, problem nie leży już w hashu treści. Przeniósł się na podpis nagłówków albo na wyrównanie, i powinieneś przyjrzeć się wyrównaniu DKIM oraz potwierdzić swój rekord i selektor względem czystej konfiguracji DKIM.
Najczęściej zadawane pytania
Czy niezgodność hasha treści oznacza, że mój klucz DKIM jest błędny?
Nie. Niezgodność hasha treści oznacza, że treść zmieniła się po podpisaniu. Twój klucz prywatny, klucz publiczny i selektor mogą być poprawne, a mimo to zobaczysz tę awarię. Opis przyczyny błędu zwykle mówi "body hash did not verify", co konkretnie wyklucza problem z kluczem i wskazuje na modyfikację wiadomości w transporcie.
Czy mogę naprawić awarię bh=, zmieniając kanonikalizację na relaxed?
Czasami. Kanonikalizacja treści relaxed wybacza normalizację białych znaków i końcowe puste wiersze, więc jeśli przekaźnik jedynie przeformatowuje odstępy, przejście z simple na relaxed/relaxed może to naprawić. Nie pomoże, jeśli stopka, klauzula lub system przepisujący linki dodaje do treści prawdziwą zawartość. W takich przypadkach musisz podpisywać po modyfikacji.
Dlaczego moja poczta przechodzi DKIM u niektórych odbiorców, a u innych zawodzi?
Różne ścieżki odbioru stosują różne modyfikacje. Wiadomość, która dociera do jednego dostawcy bezpośrednio, może przejść, podczas gdy ta sama wiadomość przekierowana przez system przekazujący, listę mailingową albo bramę bezpieczeństwa dostaje stopkę lub przepisany link i zawodzi. Przekazywanie to klasyczny winowajca i psuje SPF z tego samego strukturalnego powodu.
Skąd mam wiedzieć, czy zawiódł hash treści, czy podpis nagłówków?
Przeczytaj nagłówek Authentication-Results w otrzymanej kopii. "Body hash did not verify" to problem z treścią, więc wykonaj porównanie surowej treści przed i po. "Signature did not verify" wskazuje z kolei na klucz albo podpisane nagłówki. Te dwie awarie wymagają różnych rozwiązań, więc ustal, którą masz, zanim wprowadzisz zmiany.