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.

First 10 of 30 Posts Switch mode

VictorGaiva

VictorGaiva

I had an issue similar to yours, and got it working with the following configuration:

config :messenger, Messenger.Mailer,
    sockopts: [
      cacerts: :public_key.cacerts_get(),
      customize_hostname_check: [
        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      ],
    ],
    adapter: Swoosh.Adapters.SMTP,
    relay: "smtp-relay.gmail.com",
    username: "no-reply@colecao.moda",
    tls: :never,
    ssl: true,
    auth: :always,
    retries: 2,
    no_mx_lookups: false,
    sockopts: [
      versions: [:"tlsv1.2", :"tlsv1.3"],
      verify: :verify_peer,
      depth: 99,
      server_name_indication: 'smtp-relay.gmail.com'
    ]
derek-zhou

derek-zhou

I am assuming you are using STARTTLS on port 465 with a self signed certificate
.
You have 2 ssl keys in the config, and it should be set to false. for details. see the official swoosh doc:

managua1902

managua1902 OP

Yours is different, isn’t it? You use tls: :never

Why sockopts 2 times?

managua1902

managua1902 OP

Where 2 ssl keys? What set to false? Why?

https://hexdocs.pm/swoosh/Swoosh.Adapters.SMTP.html#module-note

With STARTTLS you should omit the ssl configuration or set it to false.

In my case it’s not STARTTLS - it’s SSL/TLS

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

managua1902

managua1902 OP

tls: :never,

Still

[notice] TLS :client: In state :wait_cert_cr at ssl_handshake.erl:2140 generated CLIENT ALERT: Fatal - Handshake Failure
 - {:bad_cert, :max_path_length_reached}

derek-zhou

derek-zhou

You have one line as ssl: true, and one as ssl: [ ...

_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.

distefam

distefam

@LostKobrakai Unfortunately, using cacerts: :public_key.cacerts_get() inside of sockopts does not work when deploying to Fly.io. When I try to deploy with this configuration I get the following:

ERROR! Config provider Config.Reader failed with:
  ** (MatchError) no match of right hand side value: {:error, :enoent}
      pubkey_os_cacerts.erl:38: :pubkey_os_cacerts.get/0
      /app/releases/0.1.0/runtime.exs:65: (file)
      (elixir 1.14.5) src/elixir.erl:312: anonymous fn/4 in :elixir.eval_external_handler/1

It seems that this is expected behavior when no CA cert is found on the OS. However, my understanding is that Fly.io does not place the generated certificates inside its created containers. So, how would one fix this when deploying to Fly.io?

Where Next?

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
silverdr
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated! To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead. Sta...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
michallepicki
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement