SMTP Mails don't send and connection fails, but openssl works

Hi! I’m sorry if this issue has already a clear solution; I’ve really looked around and haven’t found a clear solution to my problem.

So, I self-hosted a discord instance and after some fiddling got the correct configuration for SMTP, but mails to new users don’t send (not even to the initial admin user; I ended up creating one with the rake command inside the container).

At first I thought it wouldn’t be able to connect to the SMTP due to some DNS shenaningans, since when messing around with ./discourse-doctor and eventually entering the container shell it returns:

Testing sending to xxxx@gmail.com using smtp-relay.brevo.com:587, username:xxxxxxx@smtp-brevo.com with plain auth.
======================================== ERROR ========================================
Connection to port 587 failed.
====================================== SOLUTION =======================================
The most likely problem is that your server has outgoing SMTP traffic blocked.
If you are using a service like Mailgun or Sendgrid, try using port 2525.
=======================================================================================

However, the openssl command recommended on the SMTP troubleshooting guide not only connected, but I was able, with EHLO , AUTH LOGIN and all those commands (which I didn’t know existed until now, heh ^^') to send a test email to myself from inside the container itself. So I don’t think the problem is the container being incapable of connecting with the SMTP server.

EDIT FOR CLARITY
I was able to do this from within the container: I logged into the container using the ./launcher enter container command. From that prompt I did the former commands.

Here are my SMTP settings, if it helps. I edited out the login info, of course.

  DISCOURSE_SMTP_ADDRESS: 'smtp-relay.brevo.com'
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: 'xxxxxxxx@smtp-brevo.com'
  DISCOURSE_SMTP_PASSWORD: 'xxxxxxxxxxxx'
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (required by some providers)
  DISCOURSE_NOTIFICATION_EMAIL: 'noreply@mydomain.xyz'    # (address to send notifications from)
  #DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none

The notification email was the one I tested via the openssl command, and the last line I read it somewhere in another post and added it, but commented it out and never tried it because it was an old post.

Anyway, I’m really lost here, I hope someone can give me a hand, and I’m really sorry if this was a solved issue I didn’t find!

Could you try what the error suggests, to see if it works by chance?

2 Likes

Hi! I already tried that, it didn’t work :frowning:

I was able to send a test mail with openssl, but through port 587, though. But through the discourse interface(both through the test email button in the GUI and the rake tests:email[mail]command) I wasn’t able to do so, both through port 287 and 2525.

On another note, I found the sidekiq error for the unsent mail:

Jobs::HandledExceptionWrapper: Wrapped Net::OpenTimeout: execution expired

Found the shared/standalone/log/rails/production.log relevant lines:

Started POST "/admin/email/test" for 192.168.0.206 at 2024-10-18 23:49:02 +0000
Processing by Admin::EmailController#test as */*
  Parameters: {"email_address"=>"jggalindez@gmail.com"}
Completed 422 Unprocessable Entity in 5201ms (Views: 0.4ms | ActiveRecord: 0.0ms | Allocations: 12487)

Are you able to connect to port 587 from inside the container?

Sounds like you can connect on port 587 from the host but you might not be able to do so from inside the container which would mean a networking problem on your server.

2 Likes

Hi! Sorry, I was a little unclear. I was able to connect to port 587 from inside the container, at least to my understanding, as I did the following:

  • I logged into the container using ./launcher enter containername.
  • From within the container, I ran the openssl command.
  • From within the pseudo telnet prompt(I’m not really sure what it actually is), I authenticated with the SMTP server(Doing all the converting username and password to base64 thingy) and sent an e-mail.

I didn’t actually try to send an email from with the server, though. Just from within the container(as I understand it) but I figured if it was able to do so from within the container it would be from within the server

So, I got it working. It seems it was a problem with the DNS, somehow(because it was able to resolve the url when using the getent and openssl commands). So I ran getent to get the host IP of the SMTP relay and ran the container changing the server address to the raw IP. That got me to a different error, the one in this thread. The solution pointed out there, to add the line DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none to the yaml file, got it working in the end.

Don’t really know if the DNS thing will cause problems in the future, hope not lol, but thank you both for your help!

1 Like

So you are having a networking problem in the container, but it stems from DNS not IP connectivity.

Are you able to connect using openssl s_client to the hostname from inside the container?

You should be able to run:

openssl s_client -connect smtp-relay.brevo.com:587 -starttls smtp

and get:

…
Verify return code: 0 (ok)
…

That’s expected since you’re connecting to an IP address and that IP address won’t be on the cert.

It will.

1 Like

Yeah, I figured, so I ended up adding the docker_args yaml tag to the config file and specifying some dns servers directly.

For anyone wondering(I had to look up where the docker_args tag went), here’s a part of the app.yml file:

*******Omitted lines above*********
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

docker_args: "--dns 1.1.1.1 --dns 8.8.4.4 --dns 8.8.8.8"

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
*******Omitted rest of file below*********