Closed beeb closed 7 months ago
Could you share the configuration options you’ve chosen for your SMTP sender? The most likely reason for an error like this is that there’s an issue with the TLS/SSL settings.
Yes absolutely! I used the same settings in Thunderbird and it worked:
Could you try if STARTTLS on 587 is working?
Also, I’ve just tried with one of my SMTP servers that both TLS and STARTTLS are working in a recent Keila version (there were some issues in older versions). Are you running Keila from the official Docker image?
Thanks, I can't try STARTTLS until later today, but I can already confirm that I'm using the latest official image
pentacent/keila@sha256:4c5cb50f9a5d228141c1133d7d6e767ccdeccd370a85ab5556a4ca4ef18229f9
I just noticed that interestingly, the two errors (for the two recipients) don't show the same IP address. Maybe totally unrelated but interesting nonetheless. The domain resolves to 83.166.143.44
at the moment. Could there be something related to IPv6? When I ping the mail.infomaniak.com
domain by default it uses IPv6.
I report that STARTTLS does not work for me:
16:24:48.239 [notice] TLS :client: In state :hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message
- {:unsupported_record_type, 50}
16:24:48.287 [notice] TLS :client: In state :hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message
- {:unsupported_record_type, 50}
16:24:48.332 [notice] TLS :client: In state :hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message
- {:unsupported_record_type, 50}
16:24:48.377 [notice] TLS :client: In state :hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message
- {:unsupported_record_type, 50}
16:24:48.383 [warning] Failed sending email to [redacted]@gmail.com for campaign nmc_d8rKBL4w: {:retries_exceeded, {:network_failure, ~c"83.166.143.45", {:error, {:tls_alert, {:unexpected_message, ~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}
That’s very odd. If you’d feel comfortable privately sharing credentials to an account on that server with me,I can try to debug it further.
Unfortunately that domain is on a starter plan with only 1 address allowance, and I'd rather not share the credentials for it :/ Happy to try other things as instructed however! Sorry...
As far as I can tell without an account, the server’s TLS seems to be fine and Keila should be able to connect. Could you try ssh-ing into your container and start an Elixir console with ./bin/keila remote
? Then try the following line by line:
import Swoosh.Email
sender = Keila.Mailings.get_sender("YOUR SENDER ID [starts with nms_]")
conf = Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(sender)
email = new() |> from("test@example.com") |> to("test@example.com") |> subject("test") |> text_body("test")
Keila.Mailer.deliver(email, conf)
And then to verify you're getting the same results as I am with invalid credentials:
conf = conf |> Keyword.replace(:username, "invalid") |> Keyword.replace(:password, "invalid")
Keila.Mailer.deliver(email, conf)
That's extremely helpful! I tried the commands above and in both cases I got {:error, {:retries_exceeded, {:network_failure, ~c"83.166.143.44", {:error, :timeout}}}}
.
Here's the sender info:
%Keila.Mailings.Sender{
__meta__: #Ecto.Schema.Metadata<:loaded, "mailings_senders">,
id: "nms_2yLDNVbQ",
name: "Infomaniak",
from_email: "[redacted]",
from_name: "[redacted]",
reply_to_email: "[redacted]",
reply_to_name: nil,
config: %Keila.Mailings.Sender.Config{
id: "fe68753c-cd50-4a16-9c00-c7087565b6b4",
type: "smtp",
rate_limit_per_hour: nil,
rate_limit_per_minute: nil,
rate_limit_per_second: nil,
smtp_relay: "mail.infomaniak.com",
smtp_username: "[redacted]",
smtp_password: "[redacted]",
smtp_tls_mode: "tls",
smtp_port: 465,
smtp_tls: nil,
sendgrid_api_key: nil,
ses_region: nil,
ses_access_key: nil,
ses_secret: nil,
ses_configuration_set: nil,
mailgun_api_key: nil,
mailgun_domain: nil,
postmark_api_key: nil,
shared_ses_verified_at: nil,
shared_ses_verification_requested_for: nil
},
project_id: "np_weLJnLY5",
project: #Ecto.Association.NotLoaded<association :project is not loaded>,
shared_sender_id: nil,
shared_sender: nil,
inserted_at: ~U[2024-04-01 19:43:14Z],
updated_at: ~U[2024-04-02 16:26:41Z]
}
And here's the config (remove the cert data for brevity):
[
sockopts: [
verify: :verify_peer,
depth: 100,
cacerts: [...],
verify_fun: {&:ssl_verify_hostname.verify_fun/3,
[check_hostname: ~c"mail.infomaniak.com"]},
partial_chain: &:tls_certificate_check_shared_state.find_trusted_authority/1,
customize_hostname_check: [
match_fun: #Function<6.117093159/2 in :public_key.pkix_verify_hostname_match_fun/1>
],
server_name_indication: ~c"mail.infomaniak.com"
],
ssl: true,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.infomaniak.com",
username: "[redacted]",
password: "[redacted]",
auth: :always,
port: 465
]
Ohh wait.. I should check my firewall shouldn't I... Do I need to open a specific port? I have the following rules in UFW rn:
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
22 (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
Although I don't think outgoing requests are blocked
Can you try running this on your server to verify you can connect outside Keila?
openssl s_client -connect mail.infomaniak.com:587 -starttls smtp
Yep, I ran this on the VPS outside the container and all is good. Excerpt below.
CONNECTED(00000003)
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
verify return:1
depth=0 CN = mail.infomaniak.com
verify return:1
---
Certificate chain
0 s:CN = mail.infomaniak.com
i:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Sep 23 00:00:00 2023 GMT; NotAfter: Oct 6 23:59:59 2024 GMT
1 s:C = GB, ST = Greater Manchester, L = Salford, O = Sectigo Limited, CN = Sectigo RSA Domain Validation Secure Server CA
i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384
v:NotBefore: Nov 2 00:00:00 2018 GMT; NotAfter: Dec 31 23:59:59 2030 GMT
2 s:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
i:C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority
a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384
v:NotBefore: Feb 1 00:00:00 2010 GMT; NotAfter: Jan 18 23:59:59 2038 GMT
---
...
SSL handshake has read 6106 bytes and written 434 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
250 STARTTLS
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
...
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
...
Does it also work from inside the container? You can install openssl with apk add openssl
Yep, same result from inside the container. Thanks for taking the time to help me!
Upon taking another look, I finally figured out what the issue was:
Keila used :tls_certificate_check.options/1
to specify the :tls_options
in the SMTP Swoosh config.
Swoosh normally defaults :tls_options
to [versions: [:"tlsv1", :"tlsv1.1", :"tlsv1.2"]]
- and the :versions
keyword was missing from what tls_certificate_check.options/1
produced.
This caused the error TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50
Since tls_options
and sockopts
are eventually merged by Swoosh/gen_smtp, we now put the results of :tls_certificate_check:options/1
into sockopts
, thus keeping the default tls_options
with the versions
keyword intact.
Thanks again @beeb for reporting! The fix is now available in Keila 0.14.1.
Hey @wmnnd thanks for getting back to this issue.
I updated the docker image to the latest tag and checked that it matched the 0.14.1 tag on docker hub:
$ sudo docker inspect --format='{{index .RepoDigests 0}}' pentacent/keila:latest
pentacent/keila@sha256:f34d81ce04b707f1266ad8ad6fa587fa04f19c090a7bdb1495be73df4bc518a3
Unfortunately, neither the SSL/TLS
setting nor the STARTTLS
setting for the sender work with for me in that version either.
With SSL/TLS
I still get the infamous [warning] Failed sending email to [redacted]@gmail.com for campaign nmc_9xLeJrBv: {:retries_exceeded, {:network_failure, ~c"83.166.143.44", {:error, :timeout}}}
.
With STARTTLS
I get the error: [warning] Failed sending email to [redacted]@gmail.com for campaign nmc_4vLj9gdQ: {:retries_exceeded, {:network_failure, ~c"83.166.143.45", {:error, {:tls_alert, {:unexpected_message, ~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}
Do I need to create a new sender? For now I just modified my existing sender by just changing the "Connection security" parameter.
EDIT: created a new sender and a new campaign to no avail
No, you shouldn’t need to create a new sender. I just went back to testing and I can confirm the fix in 0.14.1 still didn’t work properly. Can you give 0.14.2 another try?
Unfortunately no change with 0.14.2. Still get the timeout for SSL and unsupported_record_type,50
for STARTTLS
Are these your settings?
Server: mail.infomaniak.com
Connection security: STARTTLS
Port: 587
Correct!
Could you double-check if you are running 0.14.2? I just installed it locally and your server is giving me the correct response with it (i.e. :auth_failed
).
You can once again try to test the sending via the console:
Run ./bin/keila remote
in the container. Then:
import Swoosh.Email
s = Keila.Mailings.get_sender("YOUR_SENDER_ID")
cfg = Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(s)
email = new() |> from(s.from_email) |> to(s.from_email) |> subject("Test") |> text_body("test")
Keila.Mailer.deliver(email, cfg)
And if you’re getting an error, please share the error and the output you got after the cfg = ...
line.
Yes, I pulled the new image version, stopped and restarted the service (in docker compose) making sure to completely remove the container, then checked the running container which shows keila:latest
as the image, then checked the image digest which matches with the 0.14.2 version published on docker hub.
Running the code in the REPL gives the same error, i.e.
iex(keila@76e9ee975b7d)5> Keila.Mailer.deliver(email, cfg)
{:error,
{:retries_exceeded,
{:network_failure, ~c"83.166.143.45",
{:error,
{:tls_alert,
{:unexpected_message,
~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}}
Not sure what the problem could be.. When I try to connect with openssl
, even from inside the container, everything works as expected.
Could you share the result of this line Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(s)
?
iex(keila@76e9ee975b7d)3> cfg = Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(s)
[
tls_options: [
versions: [:"tlsv1.2", :"tlsv1.3"],
verify: :verify_peer,
depth: 100,
cacerts: [
(abbreviated)
...
],
verify_fun: {&:ssl_verify_hostname.verify_fun/3,
[check_hostname: ~c"mail.infomaniak.com"]},
partial_chain: &:tls_certificate_check_shared_state.find_trusted_authority/1,
customize_hostname_check: [
match_fun: #Function<6.80064207/2 in :public_key.pkix_verify_hostname_match_fun/1>
],
server_name_indication: ~c"mail.infomaniak.com"
],
tls: :always,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.infomaniak.com",
username: "[redacted]",
password: "[redacted]",
auth: :always,
port: 587
]
How about this?
cfg = [
tls_options: [
versions: [:"tlsv1.2", :"tlsv1.3"],
verify: :verify_none,
depth: 100,
server_name_indication: ~c"mail.infomaniak.com"
],
tls: :always,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.infomaniak.com",
username: "[redacted]",
password: "[redacted]",
auth: :always,
port: 587
]
Keila.Mailer.deliver(email, cfg)
You can try it both with username/password literally being "[redacted]" and with the actual values.
iex(keila@8f95c3b51d20)5> cfg
[
tls_options: [
versions: [:"tlsv1.2", :"tlsv1.3"],
verify: :verify_none,
depth: 100,
server_name_indication: ~c"mail.infomaniak.com"
],
tls: :always,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.infomaniak.com",
username: "[redacted]",
password: "[redacted]",
auth: :always,
port: 587
]
iex(keila@8f95c3b51d20)6> email = new() |> from(s.from_email) |> to("my@email.com") |> subject("Test") |> text_body("test")
%Swoosh.Email{
subject: "Test",
from: {"", "login@email.com"},
to: [{"", "my@email.com"}],
cc: [],
bcc: [],
text_body: "test",
html_body: nil,
attachments: [],
reply_to: nil,
headers: %{},
private: %{},
assigns: %{},
provider_options: %{}
}
iex(keila@8f95c3b51d20)7> Keila.Mailer.deliver(email, cfg)
{:error,
{:retries_exceeded,
{:network_failure, ~c"83.166.143.45",
{:error,
{:tls_alert,
{:unexpected_message,
~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}}
No change. I put my personal email as the "to" and kept "[redacted]" as the login and password for the cfg
object.
I also tried with the real credentials but same result.
EDIT: definitely confirmed the version by running a shell inside the running container and navigating to ~/releases
where I can see a 0.14.2
folder.
Now this is getting mysterious. If I run this fully-self contained bit of code:
import Swoosh.Email
cfg = [
tls_options: [
versions: [:"tlsv1.2", :"tlsv1.3"],
verify: :verify_none,
],
tls: :always,
adapter: Swoosh.Adapters.SMTP,
relay: "mail.infomaniak.com",
username: "invalid",
password: "invalid",
auth: :always,
port: 587
]
email = new() |> from("test@example.com") |> to("test@example.com") |> subject("Test") |> text_body("test")
Keila.Mailer.deliver(email, cfg)
Here is what I get:
iex(keila@b52f046ea3ea)6> Keila.Mailer.deliver(email, cfg)
{:error,
{:no_more_hosts, {:permanent_failure, ~c"83.166.143.45", :auth_failed}}}
Agreed, I ran the exact same bit of code and get a different result. Could it somehow come from the fact that I'm in docker? Did you try it on your side?
I’m running this in the 0.14.2 Docker container :exploding_head:
Then maybe networking over at hetzner where the VPS is hosted? It's running out of their eu-central
datacenter in Nurenberg, Germany
So the image you currently have has the hash pentacent/keila@sha256:0d6c28ccecf5c8388a4691d5802421325c653bebc7d5c6bd09f8e41f89d91159
?
Yep, triple-checked and also and like I said, I also opened a shell into the running container to find the correct folder in ~/releases
This is so weird, but you’re not the only one with this issue, @CodeOfTim reported the same problem today.
How about with a different server. Does this give you a different result?
import Swoosh.Email
cfg = [
tls_options: [
versions: [:"tlsv1.2", :"tlsv1.3"],
verify: :verify_none,
depth: 100,
server_name_indication: ~c"sslout.df.eu"
],
tls: :always,
adapter: Swoosh.Adapters.SMTP,
relay: "sslout.df.eu",
username: "[redacted]",
password: "[redacted]",
auth: :always,
port: 25
]
email = new() |> from("test@example.com") |> to("test@example.com") |> subject("Test") |> text_body("test")
Keila.Mailer.deliver(email, cfg)
I just set up a completely fresh Ubuntu server in Hetzner’s Nuremberg datacenter, installed Docker CI, and then ran the unmodified docker compose file at ops/docker-compose.yml. For both your hostname and sslout.df.eu, I get the expected auth_failed
error.
Hmm okay, so to try and isolate some variables I tried with the same docker file locally (ops/docker.compose.yml
from this repo), with a fresh database.
I used URL_HOST: "localhost"
and generated a new SECRET_KEY_BASE
, and setup the SMTP sender just like on the live instance.
With SSL/TLS
security I get the following error:
keila-1 | 18:57:17.193 [notice] TLS :client: In state :wait_cert_cr at ssl_handshake.erl:2125 generated CLIENT ALERT: Fatal - Unknown CA
keila-1 |
keila-1 | 18:57:17.195 [warning] Failed sending email to [redacted] for campaign nmc_weLJnLY5: {:retries_exceeded, {:network_failure, ~c"83.166.143.45", {:error, {:tls_alert, {:unknown_ca, ~c"TLS client: In state wait_cert_cr at ssl_handshake.erl:2125 generated CLIENT ALERT: Fatal - Unknown CA\n"}}}}}
With STARTTLS
security, I get:
keila-1 | 19:00:42.140 [notice] TLS :client: In state :wait_cert_cr at ssl_handshake.erl:2125 generated CLIENT ALERT: Fatal - Unknown CA
keila-1 |
keila-1 | 19:00:42.142 [warning] Failed sending email to [redacted] for campaign nmc_BzLMaLXv: {:retries_exceeded, {:temporary_failure, ~c"83.166.143.45", :tls_failed}}
Note that this is running docker on my Windows machine, but being docker, it shouldn't matter.
How about with a different server. Does this give you a different result?
With this exact config I get (on the hetzner vps):
{:error,
{:retries_exceeded, {:network_failure, ~c"134.119.18.24", {:error, :timeout}}}}
Let’s try to exclude connectivity issues from within Elixir:
:hackney.get("https://www.keila.io")
# => {:ok, 200, …}
:hackney.get("https://sslout.df.eu:465")
# => {:error, :bad_request}
And let’s also try to go down one more level:
:gen_smtp_client.open([relay: "mail.infomaniak.com", username: "user", password: "password", auth: :always, tls: :always, ssl: false, tls_options: :tls_certificate_check.options("mail.infomaniak.com")])
# => {:error, :no_more_hosts, {:permanent_failure, "mail.infomaniak.com", :auth_failed}}
And finally, let’s take a look at the cert chain:
:tls_certificate_check.options("mail.infomaniak.com")
# =>
# [
# verify: :verify_peer,
# depth: 100,
# cacerts: [
# <<48, 130, 5, 86, 48, 130, 3, 62, 160, 3, 2, 1, 2, 2, 20, 67, 227, 113, 19,
# 216, 179, 89, 20, 93, 183, 206, 140, 253, 53, 253, 111, 188, 5, 141, 69,
# 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, ...>>,
# <<48, 130, 2, 15, 48, 130, 1, 149, 160, 3, 2, 1, 2, 2, 20, 110, 106, 188,
# 89, 170, 83, 190, 152, 57, 103, 162, 210, 107, 164, 59, 230, 109, 28, 214,
# 218, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, ...>>,
# <<48, 130, 3, 148, 48, 130, 2, 124, 160, 3, 2, 1, 2, 2, 10, 49, 245, 228,
# 98, 12, 108, 88, 237, 214, 216, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13,
# 1, 1, 11, 5, 0, 48, 103, 49, 11, ...>>,
# <<48, 130, 3, 115, 48, 130, 2, 91, 160, 3, 2, 1, 2, 2, 11, 0, 174, 207, 0,
# 186, 196, 207, 50, 248, 67, 178, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13,
# 1, 1, 11, 5, 0, 48, 86, ...>>,
# <<48, 130, 2, 78, 48, 130, 1, 211, 160, 3, 2, 1, 2, 2, 10, 60, 246, 7, 169,
# 104, 112, 14, 218, 139, 132, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, 3, 3,
# 48, 107, 49, 11, 48, ...>>,
# <<48, 130, 2, 43, 48, 130, 1, 177, 160, 3, 2, 1, 2, 2, 10, 123, 113, 182,
# 130, 86, 184, 18, 124, 156, 168, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, 3,
# 3, 48, 90, 49, 11, ...>>,
# <<48, 130, 5, 176, 48, 130, 3, 152, 160, 3, 2, 1, 2, 2, 16, 21, 200, 189,
# 101, 71, 92, 175, 184, 151, 0, 94, 228, 6, 210, 188, 157, 48, 13, 6, 9,
# 42, 134, 72, 134, 247, ...>>,
# <<48, 130, 2, 64, 48, 130, 1, 229, 160, 3, 2, 1, 2, 2, 12, 1, 84, 72, 239,
# 33, 253, 151, 89, 13, 245, 4, 10, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4,
# 3, 2, ...>>,
# <<48, 130, 5, 71, 48, 130, 3, 47, 160, 3, 2, 1, 2, 2, 9, 17, 0, 52, 182, 78,
# 198, 54, 45, 54, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5,
# ...>>,
# <<48, 130, 3, 56, 48, 130, 2, 32, 160, 3, 2, 1, 2, 2, 6, 32, 6, 5, 22, 112,
# 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, ...>>,
# <<48, 130, 4, 48, 48, 130, 3, 24, 160, 3, 2, 1, 2, 2, 16, 80, 148, 108, 236,
# 24, 234, 213, 156, 77, 213, 151, 239, 117, 143, 160, 173, 48, 13, 6, 9,
# 42, ...>>,
# <<48, 130, 5, 222, 48, 130, 3, 198, 160, 3, 2, 1, 2, 2, 16, 1, 253, 109, 48,
# 252, 163, 202, 81, 168, 27, 188, 100, 14, 53, 3, 45, 48, 13, 6, 9, ...>>,
# <<48, 130, 2, 143, 48, 130, 2, 21, 160, 3, 2, 1, 2, 2, 16, 92, 139, 153,
# 197, 90, 148, 197, 210, 113, 86, 222, 205, 137, 128, 204, 38, 48, 10, 6,
# ...>>,
# <<48, 130, 5, 70, 48, 130, 3, 46, 160, 3, 2, 1, 2, 2, 16, 93, 223, 177, 218,
# 90, 163, 237, 93, 190, 90, 101, 32, 101, 3, 144, 239, 48, 13, ...>>,
# <<48, 130, 5, 90, 48, 130, 3, 66, 160, 3, 2, 1, 2, 2, 16, 79, 210, 43, 143,
# 245, 100, 200, 51, 158, 79, 52, 88, 102, 35, 112, 96, 48, ...>>,
# <<48, 130, 5, 179, 48, 130, 3, 155, 160, 3, 2, 1, 2, 2, 20, 19, 2, 213, 226,
# 64, 76, 146, 70, 134, 22, 103, 93, 180, 187, 187, 178, ...>>,
# <<48, 130, 2, 157, 48, 130, 2, 36, 160, 3, 2, 1, 2, 2, 12, 8, 189, 133, 151,
# 108, 153, 39, 164, 128, 104, 71, 59, 48, 10, 6, ...>>,
# <<48, 130, 2, 96, 48, 130, 2, 7, 160, 3, 2, 1, 2, 2, 12, 13, 106, 95, 8, 63,
# 40, 92, 62, 81, 149, 223, 93, 48, 10, ...>>,
# <<48, 130, 5, 218, 48, 130, 3, 194, 160, 3, 2, 1, 2, 2, 12, 5, 247, 14, 134,
# 218, 73, 243, 70, 53, 46, 186, 178, 48, ...>>,
# <<48, 130, 2, 85, 48, 130, 1, 220, 160, 3, 2, 1, 2, 2, 20, 79, 35, 100, 184,
# 142, 151, 99, 158, 198, 83, 129, 193, ...>>,
# <<48, 130, 5, 165, 48, 130, 3, 141, 160, 3, 2, 1, 2, 2, 20, 100, 246, 14,
# 101, 119, 97, 106, 171, 59, 180, 234, ...>>,
# <<48, 130, 5, 116, 48, 130, 3, 92, 160, 3, 2, 1, 2, 2, 15, 1, 103, 95, 39,
# 214, 254, 122, 227, 228, 172, ...>>,
# <<48, 130, 5, 56, 48, 130, 3, 32, 160, 3, 2, 1, 2, 2, 17, 0, 149, 190, 22,
# 160, 247, 46, 70, 241, ...>>,
# <<48, 130, 5, 179, 48, 130, 3, 155, 160, 3, 2, 1, 2, 2, 16, 33, 156, 84, 45,
# 232, 246, 236, 113, ...>>,
# <<48, 130, 2, 66, 48, 130, 1, 201, 160, 3, 2, 1, 2, 2, 16, 54, 58, 150, 140,
# 201, 92, 178, ...>>,
# <<48, 130, 3, 123, 48, 130, 2, 99, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, 6, 9,
# 42, ...>>,
# <<48, 130, 5, 65, 48, 130, 3, 41, 160, 3, 2, 1, 2, 2, 2, 12, 190, 48, 13, 6,
# ...>>,
# <<48, 130, 4, 99, 48, 130, 3, 75, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, 6, ...>>,
# <<48, 130, 3, 195, 48, 130, 2, 171, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, ...>>,
# <<48, 130, 3, 195, 48, 130, 2, 171, 160, 3, 2, 1, 2, 2, 1, 1, 48, ...>>,
# <<48, 130, 5, 189, 48, 130, 3, 165, 160, 3, 2, 1, 2, 2, 8, 79, ...>>,
# <<48, 130, 5, 186, 48, 130, 3, 162, 160, 3, 2, 1, 2, 2, 9, ...>>,
# <<48, 130, 3, 239, 48, 130, 2, 215, 160, 3, 2, 1, 2, 2, ...>>,
# <<48, 130, 3, 221, 48, 130, 2, 197, 160, 3, 2, 1, 2, ...>>,
# <<48, 130, 4, 15, 48, 130, 2, 247, 160, 3, 2, 1, ...>>,
# <<48, 130, 5, 127, 48, 130, 3, 103, 160, 3, 2, ...>>,
# <<48, 130, 3, 119, 48, 130, 2, 95, 160, 3, ...>>,
# <<48, 130, 2, 56, 48, 130, 1, 190, 160, ...>>,
# <<48, 130, 3, 188, 48, 130, 2, 164, ...>>,
# <<48, 130, 3, 184, 48, 130, 2, ...>>,
# <<48, 130, 3, 109, 48, 130, ...>>,
# <<48, 130, 5, 138, 48, ...>>,
# <<48, 130, 2, 58, ...>>,
# <<48, 130, 3, ...>>,
# <<48, 130, ...>>,
# <<48, ...>>,
# <<...>>,
# ...
# ],
# verify_fun: {&:ssl_verify_hostname.verify_fun/3,
# [check_hostname: ~c"mail.infomaniak.com"]},
# partial_chain: &:tls_certificate_check_shared_state.find_trusted_authority/1,
# customize_hostname_check: [
# match_fun: #Function<6.80064207/2 in :public_key.pkix_verify_hostname_match_fun/1>
# ],
# server_name_indication: ~c"mail.infomaniak.com"
# ]
Here’s another attempt: Try it with Keila 0.14.3 :see_no_evil:
Really appreciate your patience with this! Here are the results from the tests above (from the VPS - live keila container on 0.14.2):
:hackney.get("https://www.keila.io")
# {:ok, 200, ...}
:hackney.get("https://sslout.df.eu:465")
# already a difference here:
# {:error, :connect_timeout}
Also different result for the next test:
:gen_smtp_client.open([relay: "mail.infomaniak.com", username: "user", password: "password", auth: :always, tls: :always, ssl: false, tls_options: :tls_certificate_check.options("mail.infomaniak.com")])
# {:error, :retries_exceeded, {:network_failure, "mail.infomaniak.com", {:error, :timeout}}}
And finally the certs:
iex(keila@8f95c3b51d20)5> :tls_certificate_check.options("mail.infomaniak.com")
# [
# verify: :verify_peer,
# depth: 100,
# cacerts: [
# <<48, 130, 5, 86, 48, 130, 3, 62, 160, 3, 2, 1, 2, 2, 20, 67, 227, 113, 19,
# 216, 179, 89, 20, 93, 183, 206, 140, 253, 53, 253, 111, 188, 5, 141, 69,
# 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, ...>>,
# <<48, 130, 2, 15, 48, 130, 1, 149, 160, 3, 2, 1, 2, 2, 20, 110, 106, 188,
# 89, 170, 83, 190, 152, 57, 103, 162, 210, 107, 164, 59, 230, 109, 28, 214,
# 218, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, ...>>,
# <<48, 130, 3, 148, 48, 130, 2, 124, 160, 3, 2, 1, 2, 2, 10, 49, 245, 228,
# 98, 12, 108, 88, 237, 214, 216, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13,
# 1, 1, 11, 5, 0, 48, 103, 49, 11, ...>>,
# <<48, 130, 3, 115, 48, 130, 2, 91, 160, 3, 2, 1, 2, 2, 11, 0, 174, 207, 0,
# 186, 196, 207, 50, 248, 67, 178, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13,
# 1, 1, 11, 5, 0, 48, 86, ...>>,
# <<48, 130, 2, 78, 48, 130, 1, 211, 160, 3, 2, 1, 2, 2, 10, 60, 246, 7, 169,
# 104, 112, 14, 218, 139, 132, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, 3, 3,
# 48, 107, 49, 11, 48, ...>>,
# <<48, 130, 2, 43, 48, 130, 1, 177, 160, 3, 2, 1, 2, 2, 10, 123, 113, 182,
# 130, 86, 184, 18, 124, 156, 168, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4, 3,
# 3, 48, 90, 49, 11, ...>>,
# <<48, 130, 5, 176, 48, 130, 3, 152, 160, 3, 2, 1, 2, 2, 16, 21, 200, 189,
# 101, 71, 92, 175, 184, 151, 0, 94, 228, 6, 210, 188, 157, 48, 13, 6, 9,
# 42, 134, 72, 134, 247, ...>>,
# <<48, 130, 2, 64, 48, 130, 1, 229, 160, 3, 2, 1, 2, 2, 12, 1, 84, 72, 239,
# 33, 253, 151, 89, 13, 245, 4, 10, 48, 10, 6, 8, 42, 134, 72, 206, 61, 4,
# 3, 2, ...>>,
# <<48, 130, 5, 71, 48, 130, 3, 47, 160, 3, 2, 1, 2, 2, 9, 17, 0, 52, 182, 78,
# 198, 54, 45, 54, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5,
# ...>>,
# <<48, 130, 3, 56, 48, 130, 2, 32, 160, 3, 2, 1, 2, 2, 6, 32, 6, 5, 22, 112,
# 2, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 5, 5, 0, 48, ...>>,
# <<48, 130, 4, 48, 48, 130, 3, 24, 160, 3, 2, 1, 2, 2, 16, 80, 148, 108, 236,
# 24, 234, 213, 156, 77, 213, 151, 239, 117, 143, 160, 173, 48, 13, 6, 9,
# 42, ...>>,
# <<48, 130, 5, 222, 48, 130, 3, 198, 160, 3, 2, 1, 2, 2, 16, 1, 253, 109, 48,
# 252, 163, 202, 81, 168, 27, 188, 100, 14, 53, 3, 45, 48, 13, 6, 9, ...>>,
# <<48, 130, 2, 143, 48, 130, 2, 21, 160, 3, 2, 1, 2, 2, 16, 92, 139, 153,
# 197, 90, 148, 197, 210, 113, 86, 222, 205, 137, 128, 204, 38, 48, 10, 6,
# ...>>,
# <<48, 130, 5, 70, 48, 130, 3, 46, 160, 3, 2, 1, 2, 2, 16, 93, 223, 177, 218,
# 90, 163, 237, 93, 190, 90, 101, 32, 101, 3, 144, 239, 48, 13, ...>>,
# <<48, 130, 5, 90, 48, 130, 3, 66, 160, 3, 2, 1, 2, 2, 16, 79, 210, 43, 143,
# 245, 100, 200, 51, 158, 79, 52, 88, 102, 35, 112, 96, 48, ...>>,
# <<48, 130, 5, 179, 48, 130, 3, 155, 160, 3, 2, 1, 2, 2, 20, 19, 2, 213, 226,
# 64, 76, 146, 70, 134, 22, 103, 93, 180, 187, 187, 178, ...>>,
# <<48, 130, 2, 157, 48, 130, 2, 36, 160, 3, 2, 1, 2, 2, 12, 8, 189, 133, 151,
# 108, 153, 39, 164, 128, 104, 71, 59, 48, 10, 6, ...>>,
# <<48, 130, 2, 96, 48, 130, 2, 7, 160, 3, 2, 1, 2, 2, 12, 13, 106, 95, 8, 63,
# 40, 92, 62, 81, 149, 223, 93, 48, 10, ...>>,
# <<48, 130, 5, 218, 48, 130, 3, 194, 160, 3, 2, 1, 2, 2, 12, 5, 247, 14, 134,
# 218, 73, 243, 70, 53, 46, 186, 178, 48, ...>>,
# <<48, 130, 2, 85, 48, 130, 1, 220, 160, 3, 2, 1, 2, 2, 20, 79, 35, 100, 184,
# 142, 151, 99, 158, 198, 83, 129, 193, ...>>,
# <<48, 130, 5, 165, 48, 130, 3, 141, 160, 3, 2, 1, 2, 2, 20, 100, 246, 14,
# 101, 119, 97, 106, 171, 59, 180, 234, ...>>,
# <<48, 130, 5, 116, 48, 130, 3, 92, 160, 3, 2, 1, 2, 2, 15, 1, 103, 95, 39,
# 214, 254, 122, 227, 228, 172, ...>>,
# <<48, 130, 5, 56, 48, 130, 3, 32, 160, 3, 2, 1, 2, 2, 17, 0, 149, 190, 22,
# 160, 247, 46, 70, 241, ...>>,
# <<48, 130, 5, 179, 48, 130, 3, 155, 160, 3, 2, 1, 2, 2, 16, 33, 156, 84, 45,
# 232, 246, 236, 113, ...>>,
# <<48, 130, 2, 66, 48, 130, 1, 201, 160, 3, 2, 1, 2, 2, 16, 54, 58, 150, 140,
# 201, 92, 178, ...>>,
# <<48, 130, 3, 123, 48, 130, 2, 99, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, 6, 9,
# 42, ...>>,
# <<48, 130, 5, 65, 48, 130, 3, 41, 160, 3, 2, 1, 2, 2, 2, 12, 190, 48, 13, 6,
# ...>>,
# <<48, 130, 4, 99, 48, 130, 3, 75, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, 6, ...>>,
# <<48, 130, 3, 195, 48, 130, 2, 171, 160, 3, 2, 1, 2, 2, 1, 1, 48, 13, ...>>,
# <<48, 130, 3, 195, 48, 130, 2, 171, 160, 3, 2, 1, 2, 2, 1, 1, 48, ...>>,
# <<48, 130, 5, 189, 48, 130, 3, 165, 160, 3, 2, 1, 2, 2, 8, 79, ...>>,
# <<48, 130, 5, 186, 48, 130, 3, 162, 160, 3, 2, 1, 2, 2, 9, ...>>,
# <<48, 130, 3, 239, 48, 130, 2, 215, 160, 3, 2, 1, 2, 2, ...>>,
# <<48, 130, 3, 221, 48, 130, 2, 197, 160, 3, 2, 1, 2, ...>>,
# <<48, 130, 4, 15, 48, 130, 2, 247, 160, 3, 2, 1, ...>>,
# <<48, 130, 5, 127, 48, 130, 3, 103, 160, 3, 2, ...>>,
# <<48, 130, 3, 119, 48, 130, 2, 95, 160, 3, ...>>,
# <<48, 130, 2, 56, 48, 130, 1, 190, 160, ...>>,
# <<48, 130, 3, 188, 48, 130, 2, 164, ...>>,
# <<48, 130, 3, 184, 48, 130, 2, ...>>,
# <<48, 130, 3, 109, 48, 130, ...>>,
# <<48, 130, 5, 138, 48, ...>>,
# <<48, 130, 2, 58, ...>>,
# <<48, 130, 3, ...>>,
# <<48, 130, ...>>,
# <<48, ...>>,
# <<...>>,
# ...
# ],
# verify_fun: {&:ssl_verify_hostname.verify_fun/3,
# [check_hostname: ~c"mail.infomaniak.com"]},
# partial_chain: &:tls_certificate_check_shared_state.find_trusted_authority/1,
# customize_hostname_check: [
# match_fun: #Function<6.80064207/2 in :public_key.pkix_verify_hostname_match_fun/1>
# ],
# server_name_indication: ~c"mail.infomaniak.com"
# ]
Result for a container running locally on my home computer (same base docker-compose file as ops/docker-compose.yml
):
:hackney.get("https://www.keila.io")
{:ok, 200, ...}
:hackney.get("https://sslout.df.eu:465")
#{:error,
# {:tls_alert,
# {:unknown_ca,
# ~c"TLS client: In state certify at ssl_handshake.erl:2125 generated CLIENT ALERT: Fatal - Unknown CA\n"}}}
:gen_smtp_client.open([relay: "mail.infomaniak.com", username: "user", password: "password", auth: :always, tls: :always, ssl: false, tls_options: :tls_certificate_check.options("mail.infomaniak.com")])
#{:error, :retries_exceeded,
# {:network_failure, "mail.infomaniak.com", {:error, :closed}}}
Certs result is identical to the above
How about this on 0.14.3?
s = Keila.Mailings.get_sender("YOUR_SENDER_ID")
cfg = Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(s)
:gen_smtp_client.open(cfg)
Here's the result of that last line on 0.14.3 with STARTTLS security:
{:ok,
{:smtp_client_socket,
{:sslsocket, {:gen_tcp, #Port<0.49>, :tls_connection, :undefined},
[#PID<0.3891.0>, #PID<0.3890.0>]}, "mail.infomaniak.com",
[
{"PIPELINING", true},
{"SIZE", true},
{"ETRN", true},
{"ENHANCEDSTATUSCODES", true},
{"8BITMIME", true},
{"DSN", true},
{"AUTH", "PLAIN LOGIN"},
{"STARTTLS", true}
],
[
adapter: Swoosh.Adapters.SMTP,
auth: :always,
hostname: ~c"15007975ac37",
on_transaction_error: :quit,
password: "[redacted]",
port: 587,
relay: "mail.infomaniak.com",
retries: 1,
ssl: false,
tls: :always,
tls_options: [
versions: [:"tlsv1.2"],
verify: :verify_peer,
depth: 100,
cacerts: [
<<48, 130, 5, 86, 48, 130, 3, 62, 160, 3, 2, 1, 2, 2, 20, 67, 227, 113,
19, 216, 179, 89, 20, 93, 183, 206, 140, ...>>,
<<48, 130, 2, 15, 48, 130, 1, 149, 160, 3, 2, 1, 2, 2, 20, 110, 106,
188, 89, 170, 83, 190, 152, 57, 103, 162, ...>>,
<<48, 130, 3, 148, 48, 130, 2, 124, 160, 3, 2, 1, 2, 2, 10, 49, 245,
228, 98, 12, 108, 88, 237, 214, 216, ...>>,
<<48, 130, 3, 115, 48, 130, 2, 91, 160, 3, 2, 1, 2, 2, 11, 0, 174, 207,
0, 186, 196, 207, 50, 248, ...>>,
<<48, 130, 2, 78, 48, 130, 1, 211, 160, 3, 2, 1, 2, 2, 10, 60, 246, 7,
169, 104, 112, 14, 218, ...>>,
<<48, 130, 2, 43, 48, 130, 1, 177, 160, 3, 2, 1, 2, 2, 10, 123, 113,
182, 130, 86, 184, 18, ...>>,
<<48, 130, 5, 176, 48, 130, 3, 152, 160, 3, 2, 1, 2, 2, 16, 21, 200,
189, 101, 71, 92, ...>>,
<<48, 130, 2, 64, 48, 130, 1, 229, 160, 3, 2, 1, 2, 2, 12, 1, 84, 72,
239, 33, ...>>,
<<48, 130, 5, 71, 48, 130, 3, 47, 160, 3, 2, 1, 2, 2, 9, 17, 0, 52, 182,
...>>,
<<48, 130, 3, 56, 48, 130, 2, 32, 160, 3, 2, 1, 2, 2, 6, 32, 6, 5, ...>>,
<<48, 130, 4, 48, 48, 130, 3, 24, 160, 3, 2, 1, 2, 2, 16, 80, 148, ...>>,
<<48, 130, 5, 222, 48, 130, 3, 198, 160, 3, 2, 1, 2, 2, 16, 1, ...>>,
<<48, 130, 2, 143, 48, 130, 2, 21, 160, 3, 2, 1, 2, 2, 16, ...>>,
<<48, 130, 5, 70, 48, 130, 3, 46, 160, 3, 2, 1, 2, 2, ...>>,
<<48, 130, 5, 90, 48, 130, 3, 66, 160, 3, 2, 1, 2, ...>>,
<<48, 130, 5, 179, 48, 130, 3, 155, 160, 3, 2, 1, ...>>,
<<48, 130, 2, 157, 48, 130, 2, 36, 160, 3, 2, ...>>,
<<48, 130, 2, 96, 48, 130, 2, 7, 160, 3, ...>>,
<<48, 130, 5, 218, 48, 130, 3, 194, 160, ...>>,
<<48, 130, 2, 85, 48, 130, 1, 220, ...>>,
<<48, 130, 5, 165, 48, 130, 3, ...>>,
<<48, 130, 5, 116, 48, 130, ...>>,
<<48, 130, 5, 56, 48, ...>>,
<<48, 130, 5, 179, ...>>,
<<48, 130, 2, ...>>,
<<48, 130, ...>>,
<<48, ...>>,
<<...>>,
...
],
verify_fun: {&:ssl_verify_hostname.verify_fun/3,
[check_hostname: ~c"mail.infomaniak.com"]},
partial_chain: &:tls_certificate_check_shared_state.find_trusted_authority/1,
customize_hostname_check: [
match_fun: #Function<6.80064207/2 in :public_key.pkix_verify_hostname_match_fun/1>
],
server_name_indication: ~c"mail.infomaniak.com"
],
username: "[redacted]"
]}}
Weirdly, when I switch the sender to SSL/TLS
security, I get another result:
{:error, :retries_exceeded,
{:network_failure, "mail.infomaniak.com", {:error, :timeout}}}
Lastly, when I try to send a campaign with STARTTLS security, I get the error I had already before (also on 0.14.3): Failed sending email to [redacted]@gmail.com for campaign nmc_pyrzyLMx: {:retries_exceeded, {:network_failure, ~c"83.166.143.45", {:error, {:tls_alert, {:unexpected_message, ~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}
The result you get from :gensmtp.open/1
suggests that sending emails should also work.
Does this still throw an error when using STARTTLS?
import Swoosh.Email
sender = Keila.Mailings.get_sender("YOUR SENDER ID")
conf = Keila.Mailings.SenderAdapters.SMTP.to_swoosh_config(sender)
email = new() |> from("test@example.com") |> to("test@example.com") |> subject("test") |> text_body("test")
Keila.Mailer.deliver(email, conf)
Unfortunately same result as last version (I triple-checked that I'm on 0.14.3):
{:error,
{:retries_exceeded,
{:network_failure, ~c"83.166.143.45",
{:error,
{:tls_alert,
{:unexpected_message,
~c"TLS client: In state hello at tls_record.erl:561 generated CLIENT ALERT: Fatal - Unexpected Message\n {unsupported_record_type,50}"}}}}}}
So gensmtp.open continues to work but Keila.Mailer.deliver isn’t working? :scream:
Can you share the output of conf
again, then?
I was just able to reproduce this, I’ll try to figure this out some more.
After a little deep-dive into the inner workings of Swoosh and gen_smtp, 0.14.4 might just do the trick now. Turns out that Swoosh was merging the system mailer config with the sender config which isn't normally a problem because sender config takes priority. But in this case it might have mixed in some conflicting SSL configuration - which is why :gen_smtp.open/1
worked and Keila.Mailer.deliver/2
was erroring.
Nice work! Indeed now I can send emails with STARTTLS
🎉
I still have timeout issues with SSL/TLS
, not sure why. Even with :gen_smtp.open
I don't seem to be able to get a connection to the server via this method.
Partially solved?
Did you make sure to use port 465 when using SSL/TLS? That’s working for me; if I try port 587 with SSL, I get a TLS error.
I did notice though that the connection on port 465 is quite slow (~2 seconds), so maybe if your network is even just a little bit slow, the connection might genuinely time out. You can measure the time (in µs) like this:
:timer.tc fn -> :gen_smtp_client.open(conf) end
Hey there!
It's been a while since I had the opportunity to send out a campaign with my instance of keila and today it doesn't seems to work. I updated to the latest version in docker.
I triple-checked my SMTP sender settings and all is fine. The same settings are used in other clients without hiccup.
When I try to send a campaign, the logs show only this:
Note that the IP address can be pinged from the same machine so it seems very strange. Any ideas?