S/MIME Część 4: Łatwe zbieranie kluczy publicznych odbiorców – z webhookami SparkPost Inbound Relay

Ptak

1 lut 2019

Email

1 min read

S/MIME Część 4: Łatwe zbieranie kluczy publicznych odbiorców – z webhookami SparkPost Inbound Relay

W tej serii widzieliśmy, że dołączenie podpisu S/MIME jest stosunkowo proste. Wysyłanie zaszyfrowanej poczty S/MIME jest bardziej skomplikowane, ponieważ musisz uzyskać klucze publiczne odbiorców. To jedna rzecz, gdy korzystasz z klienta pocztowego dla ludzi, takiego jak Thunderbird – ale jak to może działać w przypadku generowanych przez aplikację strumieni e-mailowych?

W części 1, przeprowadziliśmy szybki przegląd S/MIME, przyglądając się podpisywaniu i szyfrowaniu naszych strumieni wiadomości w różnych klientach pocztowych. Część 2 przeprowadziła nas przez prostą narzędziową linię poleceń do podpisywania i szyfrowania e-maili, a następnie wysyłania ich przez SparkPost. Część 3 pokazała, jak wstrzyknąć bezpieczne strumienie poczty do platform lokalnych, takich jak Port25 PowerMTA i Momentum.

W tej serii widzieliśmy, że dołączenie podpisu S/MIME jest stosunkowo proste. Wysyłanie zaszyfrowanej poczty S/MIME jest bardziej skomplikowane, ponieważ trzeba uzyskać klucze publiczne odbiorców. To inna sprawa, gdy używasz klienta poczty dla ludzi, takiego jak Thunderbird – ale jak to działa w przypadku strumieni e-mail generowanych przez aplikacje? E-maile generowane przez aplikacje, jak te używane przez platformy randkowe, wymagają starannej strategii do maksymalizacji zaangażowania. Zobacz, jak aplikacje randkowe tworzą przyciągające uwagę uruchamiające doświadczenia e-mail.

Ale poczekaj – jest jeszcze inny sposób na dostanie się do Mordor, aby uzyskać te klucze. Twoja usługa może zaprosić Twoich klientów (oczywiście przez e-mail) do przesłania Ci podpisanej wiadomości na znany adres obsługi klienta. Używając magicznych mocy webhooków SparkPost Inbound Relay, wyciągniemy i przechowamy ten klucz publiczny do Twojego użytku.

Możemy to podsumować w prostym przypadku użycia:

  • Jako odbiorca wiadomości, przekazuję twojej usłudze mój osobisty podpis e-mailowy poprzez e-mail, aby w przyszłości wiadomości e-mail mogły być wysyłane do mnie w formie zaszyfrowanej S/MIME.

Na tej podstawie wywiedziemy bardziej szczegółowe wymagania:

  • Potrzebujemy niezawodnej, zawsze włączonej usługi przyjmowania e-maili, aby odbierać te podpisane wiadomości.

  • Nie powinny istnieć specjalne wymagania dotyczące formatu poczty, poza tym, że powinien on zawierać podpis S/MIME.

  • Ponieważ każdy może spróbować wysłać wiadomość do tej usługi, powinna ona być zaprojektowana defensywnie, na przykład aby odrzucać „podrobione” wiadomości od złych aktorów. Będzie potrzeba kilku warstw weryfikacji.

  • Jeśli wszystko się zgadza, usługa zapisze certyfikat w pliku, używając dobrze znanego formatu tekstowego Privacy-Enhanced Mail (PEM).

Istnieją pewne wymagania niefunkcjonalne:

  • Usługi webhook z maszyny do maszyny mogą być trudne do zauważenia tylko z odpowiedzi na to, co dzieje się wewnątrz. Usługa powinna zapewniać obszerne, czytelne dla człowieka logi aplikacji na poziomie aplikacji, w szczególności powinno być prowadzone logowanie weryfikacji i parsowanie certyfikatów.

  • Dodajemy przypadki testowe dla wewnętrznych części aplikacji, używając fajnego frameworka Pytest, a następnie automatycznie uruchamiamy te testy przy zameldowaniu używając integracji Travis CI z GitHub.

OK – zaczynamy!

1. Przegląd rozwiązania

Oto jak będzie wyglądało ogólne rozwiązanie.

Diagram depicting a secure email flow illustrating how emails are verified using certificates for secure transmission.

2. Instalacja, konfiguracja i uruchamianie aplikacji webowej

Zaczniemy od tej części, aby była w pełni przetestowana, zanim podłączymy przekierowania webhooków przychodzących.

Aplikacja internetowa jest uwzględniona w tym samym projekcie GitHub co części 1 – 3, więc jeśli śledziłeś te części, już ją masz. Oto nowe elementy:

  • Program readSMIMEsig.py – odczytuje e-mail i rozbiera na części pośrednie i certyfikaty użytkowników.

  • Program webapp.py – prosta aplikacja internetowa kompatybilna z Flask do użycia z SparkPost Inbound Relay Webhooks.

  • webapp.ini – plik konfiguracyjny dla powyższego. Plik konfiguracyjny umożliwia łatwe przekazanie tych samych wartości zarówno do aplikacji wiersza poleceń, jak i aplikacji webowych.

Musisz upewnić się, że twój host ma odpowiedni numer portu TCP otwarty na przychodzące żądania z zewnątrz, aby SparkPost mógł wysyłać wiadomości do twojej aplikacji. Jeśli hostujesz na przykład na AWS EC2, będziesz musiał skonfigurować Security Group swojej instancji.

Instrukcje dotyczące konfigurowania i uruchamiania aplikacji internetowej są zamieszczone w naszym przewodniku instalacji – to całkiem proste. Aby sprawdzić, czy twoja aplikacja działa i jest dostępna z zewnątrz, możesz wysłać puste żądania z innego hosta, na przykład za pomocą curl:

curl -X POST https://app.trymsys.net:8855/

Powinieneś zobaczyć odpowiedź taką jak:

{"message":"Unknown Content-Type in request headers"}

To dobrze – twoja aplikacja działa!

W webapp.log na twoim hoście zobaczysz wynik podobny do tego:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None
2019-01-15 00:11:07,575,root,INFO,| Unknown Content-Type: None

Aby pomóc ci natychmiast pracować z prawdziwymi danymi w twojej aplikacji, możesz zaimportować to konkretne żądanie Postman z repozytorium projektu. Symuluje ono, co będzie robić twoje konto SparkPost, tzn. wysyła POST https zawierający e-mail ze specyficznym, ważnym certyfikatem (należącym do mojego testowego konta) do twojej aplikacji.

Musisz tylko zmienić adres docelowy w żądaniu (w szarym polu powyżej), aby pasował do twojej instalacji. Jeśli zmieniłeś wartość tokena w webapp.ini, dostosuj wartość nagłówka w Postman, aby pasowała.

Jeśli twoja aplikacja działa, zobaczysz odpowiedź „200 OK” z powrotem w Postman. Twój plik webapp.log na hoście zawierać będzie wynik podobny do tego:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778
2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223
2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed
2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",content-description=S/MIME Cryptographic Signature
2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998
2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'}
2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'}
2019-01-15 00:11:48,616,root,INFO,| written file ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Na szybkie sprawdzenie, spójrz na ostatnią linię – jeśli mówi „written file”, to dobrze. Reszta pokazuje proces sprawdzania DKIM i walidację certyfikatu.

Zaczniemy od tej części, aby była w pełni przetestowana, zanim podłączymy przekierowania webhooków przychodzących.

Aplikacja internetowa jest uwzględniona w tym samym projekcie GitHub co części 1 – 3, więc jeśli śledziłeś te części, już ją masz. Oto nowe elementy:

  • Program readSMIMEsig.py – odczytuje e-mail i rozbiera na części pośrednie i certyfikaty użytkowników.

  • Program webapp.py – prosta aplikacja internetowa kompatybilna z Flask do użycia z SparkPost Inbound Relay Webhooks.

  • webapp.ini – plik konfiguracyjny dla powyższego. Plik konfiguracyjny umożliwia łatwe przekazanie tych samych wartości zarówno do aplikacji wiersza poleceń, jak i aplikacji webowych.

Musisz upewnić się, że twój host ma odpowiedni numer portu TCP otwarty na przychodzące żądania z zewnątrz, aby SparkPost mógł wysyłać wiadomości do twojej aplikacji. Jeśli hostujesz na przykład na AWS EC2, będziesz musiał skonfigurować Security Group swojej instancji.

Instrukcje dotyczące konfigurowania i uruchamiania aplikacji internetowej są zamieszczone w naszym przewodniku instalacji – to całkiem proste. Aby sprawdzić, czy twoja aplikacja działa i jest dostępna z zewnątrz, możesz wysłać puste żądania z innego hosta, na przykład za pomocą curl:

curl -X POST https://app.trymsys.net:8855/

Powinieneś zobaczyć odpowiedź taką jak:

{"message":"Unknown Content-Type in request headers"}

To dobrze – twoja aplikacja działa!

W webapp.log na twoim hoście zobaczysz wynik podobny do tego:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None
2019-01-15 00:11:07,575,root,INFO,| Unknown Content-Type: None

Aby pomóc ci natychmiast pracować z prawdziwymi danymi w twojej aplikacji, możesz zaimportować to konkretne żądanie Postman z repozytorium projektu. Symuluje ono, co będzie robić twoje konto SparkPost, tzn. wysyła POST https zawierający e-mail ze specyficznym, ważnym certyfikatem (należącym do mojego testowego konta) do twojej aplikacji.

Musisz tylko zmienić adres docelowy w żądaniu (w szarym polu powyżej), aby pasował do twojej instalacji. Jeśli zmieniłeś wartość tokena w webapp.ini, dostosuj wartość nagłówka w Postman, aby pasowała.

Jeśli twoja aplikacja działa, zobaczysz odpowiedź „200 OK” z powrotem w Postman. Twój plik webapp.log na hoście zawierać będzie wynik podobny do tego:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778
2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223
2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed
2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",content-description=S/MIME Cryptographic Signature
2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998
2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'}
2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'}
2019-01-15 00:11:48,616,root,INFO,| written file ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Na szybkie sprawdzenie, spójrz na ostatnią linię – jeśli mówi „written file”, to dobrze. Reszta pokazuje proces sprawdzania DKIM i walidację certyfikatu.

Zaczniemy od tej części, aby była w pełni przetestowana, zanim podłączymy przekierowania webhooków przychodzących.

Aplikacja internetowa jest uwzględniona w tym samym projekcie GitHub co części 1 – 3, więc jeśli śledziłeś te części, już ją masz. Oto nowe elementy:

  • Program readSMIMEsig.py – odczytuje e-mail i rozbiera na części pośrednie i certyfikaty użytkowników.

  • Program webapp.py – prosta aplikacja internetowa kompatybilna z Flask do użycia z SparkPost Inbound Relay Webhooks.

  • webapp.ini – plik konfiguracyjny dla powyższego. Plik konfiguracyjny umożliwia łatwe przekazanie tych samych wartości zarówno do aplikacji wiersza poleceń, jak i aplikacji webowych.

Musisz upewnić się, że twój host ma odpowiedni numer portu TCP otwarty na przychodzące żądania z zewnątrz, aby SparkPost mógł wysyłać wiadomości do twojej aplikacji. Jeśli hostujesz na przykład na AWS EC2, będziesz musiał skonfigurować Security Group swojej instancji.

Instrukcje dotyczące konfigurowania i uruchamiania aplikacji internetowej są zamieszczone w naszym przewodniku instalacji – to całkiem proste. Aby sprawdzić, czy twoja aplikacja działa i jest dostępna z zewnątrz, możesz wysłać puste żądania z innego hosta, na przykład za pomocą curl:

curl -X POST https://app.trymsys.net:8855/

Powinieneś zobaczyć odpowiedź taką jak:

{"message":"Unknown Content-Type in request headers"}

To dobrze – twoja aplikacja działa!

W webapp.log na twoim hoście zobaczysz wynik podobny do tego:

2019-01-15 00:11:07,575,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None
2019-01-15 00:11:07,575,root,INFO,| Unknown Content-Type: None

Aby pomóc ci natychmiast pracować z prawdziwymi danymi w twojej aplikacji, możesz zaimportować to konkretne żądanie Postman z repozytorium projektu. Symuluje ono, co będzie robić twoje konto SparkPost, tzn. wysyła POST https zawierający e-mail ze specyficznym, ważnym certyfikatem (należącym do mojego testowego konta) do twojej aplikacji.

Musisz tylko zmienić adres docelowy w żądaniu (w szarym polu powyżej), aby pasował do twojej instalacji. Jeśli zmieniłeś wartość tokena w webapp.ini, dostosuj wartość nagłówka w Postman, aby pasowała.

Jeśli twoja aplikacja działa, zobaczysz odpowiedź „200 OK” z powrotem w Postman. Twój plik webapp.log na hoście zawierać będzie wynik podobny do tego:

2019-01-15 00:11:48,554,root,INFO,Request from 38.96.5.10,scheme=https,path=/
2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778
2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223
2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM passed
2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,content-description=None
2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",content-description=S/MIME Cryptographic Signature
2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998
2019-01-15 00:11:48,601,root,INFO,| Certificate: subject email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'}
2019-01-15 00:11:48,602,root,INFO,| Certificate: subject email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'}
2019-01-15 00:11:48,616,root,INFO,| written file ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True

Na szybkie sprawdzenie, spójrz na ostatnią linię – jeśli mówi „written file”, to dobrze. Reszta pokazuje proces sprawdzania DKIM i walidację certyfikatu.

3. SparkPost inbound relay webhooks konfiguracja

Po pierwsze, wybieramy domenę do użycia jako nasz adres wiadomości przychodzącej –  tutaj będzie to inbound.thetucks.com. Skonfiguruj swoją domenę zgodnie z tym przewodnikiem. Oto kroki, które użyłem szczegółowo:

3.1 Dodaj rekordy MX

Będziesz potrzebować dostępu do swojego konkretnego konta dostawcy usług internetowych. Po zakończeniu możesz sprawdzić je za pomocą dig – oto polecenie dla mojej domeny.

dig +short MX inbound.thetucks.com

Powinieneś zobaczyć:

10 rx3.sparkpostmail.com. 10 rx1.sparkpostmail.com. 10 rx2.sparkpostmail.com

3.2 Utwórz domenę przychodzącą

Użyj SparkPost Postman API collection, wybierając domeny przychodzące / Create .. call. Treść żądania POST zawiera Twoją domenę, na przykład:

{ "domain": "inbound.thetucks.com" }
Postman desktop application with an open tab displaying a 'Create an Inbound Domain' API request, featuring fields such as domain input, several header options, and a JSON payload, aimed at testing and automating API workflows.


3.3 Utwórz Relay Webhook

Utwórz webhook przekaźnika przychodzącego, używając odpowiedniego wywołania Postman. Treść wiadomości w moim przypadku zawiera:

{
  "name": "Certificate Collection Webhook",
  "target": "https://app.trymsys.net:8855/",
  "auth_token": "t0p s3cr3t t0k3n",
  "match": {
    "protocol": "SMTP",
    "domain": "inbound.thetucks.com"
  }
}

Jak wspomniano wcześniej, polecam ustawienie auth_token na własną tajną wartość, jak ustawiono w pliku webapp.ini na Twoim hoście.

Twój „target” musi pasować do adresu hosta i portu TCP, gdzie będziesz prowadzić aplikację internetową.

Twój „domain” musi pasować do rekordów MX skonfigurowanych w kroku 1.

Postman interface, showing the process of creating a relay webhook with detailed JSON configuration, with sections including request method, parameters, and code snippet.


To wszystko! Instalacja jest zakończona. Teraz powinieneś być w stanie wysyłać certyfikaty na swój adres przychodzący, będą one przetworzone i pojawią się na Twoim hoście aplikacji internetowej – w tym przypadku, plik o nazwie bob.lumreeker@gmail.com.crt.

Teraz możesz wysyłać zaszyfrowane e-maile do Bob, używając narzędzi opisanych w częściach 2 i 3 tej serii.

Możesz przeanalizować zawartość certyfikatu używając:

openssl x509 -inform PEM -in bob.lumreeker\@gmail.com.crt -text -noout

4. Wewnętrzności: sprawdzanie DKIM, walidacja certyfikatu

Aplikacja sprawdza, czy otrzymane e-maile mają ważny DKIM i czy same certyfikaty są ważne, jak opisano tutaj. Znajdują się tam również notatki dotyczące wdrożenia oraz pomysły na dalsze działania.

Podsumowując…

Widzieliśmy, jak klucze publiczne odbiorców mogą być łatwo gromadzone za pomocą wiadomości e-mail na adres webhooks dla przychodzącej wiadomości. Po wykonaniu tego, ci odbiorcy mogą otrzymywać swoje wiadomości w szyfrowanej formie S/MIME.

To wszystko na teraz! Udanych wysyłek.

Inne wiadomości

Czytaj więcej z tej kategorii

A person is standing at a desk while typing on a laptop.

Kompletna, AI-native platforma, która skaluje się wraz z Twoim business.

Produkt

Rozwiązania

Zasoby

Company

Ustawienia prywatności

Już wkrótce

Social

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Zarejestruj się

A person is standing at a desk while typing on a laptop.

Kompletna, AI-native platforma, która skaluje się wraz z Twoim business.

Produkt

Rozwiązania

Zasoby

Company

Ustawienia prywatności

Social

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Zarejestruj się