managua1902

managua1902

Unable to send an email via my SMTP server via SSL/TLS. But my local email client works well

I have my own SMTP server. It’s behind SSL/TLS - port 465

In my phoenix I use Swoosh to send emails. Since recently I’ve been facing this error:

delivery error:
{:retries_exceeded, {:network_failure, ~c"mail.my_mail_server.com", {:error, {:options, :incompatible, [verify: :verify_peer, cacerts: :undefined]}}}}

My config:

adapter: Swoosh.Adapters.SMTP,
    relay: host,
    username: user,
    password: password,
    port: port,

    ssl: true,
    tls: :always,

    # allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2", :"tlsv1.3"],
    auth: :always,
    retries: 5,
    no_mx_lookups: true,


    ssl: [
    # ssl_opts: [
    # ssl_options: [

        verify: :verify_none,
      # verify: :verify_peer,

      # cacerts: :public_key.cacerts_get(),
      # versions: [:"tlsv1.2"],
      # versions: [:"tlsv1.3"],
      #   customize_hostname_check: [
      #     match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      #   ]
    ],

    tls_options: [
        # verify: :verify_peer,
        verify: :verify_none,

        # cacerts: :certifi.cacerts(),
        # cacerts: :public_key.cacerts_get(),
        #   server_name_indication: ~c"#{host}",
    ]

An interesting thing is that all the options that have to do with tls and ssl will be ignored.

Meaning, the error will always contain

<...> { verify: :verify_peer, cacerts: :undefined}...

There’s never been an error with verify: :verify_none and cacerts: <something_else>, even though I’ve set it up.

Why? I’ve set different values in the config. Why will they remain verify: :verify_peer, cacerts: :undefined ?

And it’s unclear wether I should used ssl_opts, ssl or ssl_options – I’ve tried dozens of combinations. The same goes for the tls_options.

What’s the matter?


The emails I’ll send from an email-client from my local computer via the same email server get sent with no issue, and under the same settings: port 465, SSL/TLS, same relay.

P.S.

OTP 26.

I’m aware of this - Erlang/OTP 26 Highlights - Erlang/OTP

But, as I’ve mentioned, it’ll ignore my verify: <...> variables in the first place.

Most Liked

_jonas

_jonas

I was also struggling with this issue for a good while until I used almost the exact configuration mentioned here by @LostKobrakai SSL connection options · Issue #298 · gen-smtp/gen_smtp · GitHub

Here is my config which now (finally) works (using this smtp server)

  config :backend, Backend.Mailer,
    adapter: Swoosh.Adapters.SMTP,
    relay: System.get_env("EMAIL_SMTP_HOST"),
    username: System.get_env("EMAIL_SMTP_USER"),
    password: System.get_env("EMAIL_SMTP_PASSWORD"),
    port: String.to_integer(System.get_env("EMAIL_SMTP_PORT") || "465"),
    ssl: true,
    tls: :never,
    auth: :always,
    retries: 2,
    no_mx_lookups: false,
    sockopts: [
      versions: [:"tlsv1.2", :"tlsv1.3"],
      verify: :verify_peer,
      cacerts: :public_key.cacerts_get(),
      depth: 3,
      customize_hostname_check: [
        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      ],
      server_name_indication: 'mail.privateemail.com'
    ]

It was pretty tough to figure this out as someone very new to Elixir, especially since I couldn’t find this sockopts key documented anywhere in Swoosh or the gen_smtp Readme and I still don’t really understand why this is necessary, but maybe it helps someone.
What was also really tripping me up for a bit was the fact that server_name_indication apparently needs to be a charlist (single quoted) and I was trying to set it as a string with System.get_env("EMAIL_SMTP_HOST").

Perhaps someone who understands this better than me could add a note about it to the Swoosh SMTP adapter docs, since without these settings it doesn’t seem to be possible to get it to work?

LostKobrakai

LostKobrakai

I might be able to give some insight around the why here: Erlangs SSL handling is a lot more explicit (and hence complicated) than in many other places. Given nowadays emails usually use SSL over starttls you’re running into that explicitness. That’s most of the reason for the sockopts. More info can be found here: Erlang standard library: ssl | EEF Security WG

server_name_indication is additional required because by default (no_mx_lookup: false) gen_smtp doesn’t connect to the smtp server using the provided hostname, but rather it looks up the IP address for the hostname using the MX dns entry and uses that IP to connect to the server. Usually SSL certificates are supplied for a given hostname though, not an IP address. Therefore one needs to supply the hostname as SNI value, so the certificate can be validated against that hostname instead.

Disabling MX lookup does remove the need for the SNI value.

LostKobrakai

LostKobrakai

The :tls setting is for STARTTLS. If you’re not using starttls you should disable it. You can find a bit more context about that here: SSL connection options · Issue #298 · gen-smtp/gen_smtp · GitHub

Where Next?

Popular in Questions Top

chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39467 209
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement