Actionmailer Smtp "Certificate Verify Failed"

ActionMailer SMTP certificate verify failed

From the described behavior I am quite sure that peer verification has not been done in the console and that you need to explicitly set the certificate store for verifying peer certificates in your Rails configuration.

Why it "works" in the console and how to actually verify peers there:

The observation that it works from the console but does not from Rails code is caused by the fact that smtp.enable_tls in your console code does not force peer verification whereas your Rails configuration apparently does. Indeed, when you write the command to the console, you get the SSLContext printed out:

smtp.enable_tls
# => #<OpenSSL::SSL::SSLContext:0x000000064043d0 @cert=nil, @key=nil,
@client_ca=nil, @ca_file=nil, @ca_path=nil, @timeout=nil,
@verify_mode=nil, @verify_depth=nil, @renegotiation_cb=nil,
@verify_callback=nil, @cert_store=nil, @extra_chain_cert=nil,
@client_cert_cb=nil, @session_id_context=nil, @tmp_dh_callback=nil,
@session_get_cb=nil, @session_new_cb=nil, @session_remove_cb=nil,
@tmp_ecdh_callback=nil, @servername_cb=nil, @npn_protocols=nil,
@alpn_protocols=nil, @alpn_select_cb=nil, @npn_select_cb=nil>

Note that @verify_mode is nil so there is no peer verification enabled by default on the SSLContext.

To force peer verification in console, so that you can play with the SSL settings manually, you need to use a custom SSLContext and pass it to enable_tls:

ssl_context = Net::SMTP.default_ssl_context
ssl_context.set_params
smtp.enable_tls(ssl_context)
# => #<OpenSSL::SSL::SSLContext:0x000000063c27c8 @cert=nil, @key=nil,
@client_ca=nil, @ca_file=nil, @ca_path=nil, @timeout=nil,
@verify_mode=1, @verify_depth=nil, @renegotiation_cb=nil,
@verify_callback=nil, @cert_store=#<OpenSSL::X509::Store:0x00000002894408 @verify_callback=nil, @error=nil, @error_string=nil, @chain=nil, @time=nil>, @extra_chain_cert=nil,
@client_cert_cb=nil, @session_id_context=nil, @tmp_dh_callback=nil,
@session_get_cb=nil, @session_new_cb=nil, @session_remove_cb=nil,
@tmp_ecdh_callback=nil, @servername_cb=nil, @npn_protocols=nil,
@alpn_protocols=nil, @alpn_select_cb=nil, @npn_select_cb=nil>

Watch closely the differences: the SSLContext now has verify_mode set to 1 and has a certificate store for the verifications defined. This is (among other things) what the set_params method in SSLContext does.

How to configure the certificate store in Rails

Now, Rails does not call the set_params methods when constructing the SSLContext for SMTP connection. Instead, it sets the individual attributes on it according to the options (see here and here in the source code). You have properly configured Rails that you want to verify peer certificates but you have not configured a certificate store to verify peers against.

This can be done using the ca_file or ca_path options, so the following Rails configuration should work for you:

config.action_mailer.smtp_setting = {
...
ssl: true
enable_starttls_auto: false,
openssl_verify_mode: OpenSSL::SSL::VERIFY_PEER,
ca_file: "/etc/ssl/certs/ca-certificates.crt",
...
}

I have no idea why this is not properly documented in the Rails Guides...

Why isn't a self signed SMTP Certificate ignored by Rails ActionMailer 6.1 / Ruby 3.0?

This boils down to the following: When I use the settings

enable_starttls_auto: false,
openssl_verify_mode: OpenSSL::SSL::VERIFY_NONE

it does perform TLS transmission and fails with state=error: certificate verify failed (self signed certificate) (OpenSSL::SSL::SSLError), which is double wrong in my eyes, as it should never even start a TLS handshake and if so, should skip certificate validation.

Rails uses the Mail-Gem to handle these options, which indeed had an incompatible change.

As a workaround in my case, removing the enable_starttls_auto setting completely (thus keeping TLS transmission), only disabling the certificate validation with openssl_verify_mode: OpenSSL::SSL::VERIFY_NONE was helping (but will not help if you have other reasons to avoid TLS than having a bogus certificate).

Rails Action Mailer TLS Certificate Issues

Resolved issue by using sendmail and configuring sendmail to use the proper smtp settings required to use rackspace email hosting.

ssl erros sending mail using devise in rails 6

The problem

If you encounter this problem when running Ruby on Rails:

OpenSSL::SSL::SSLError (hostname "localhost" does not match the server certificate)
it is likely due to ActionMailer using the smtp as the delivery_method and your local mail server supporting TLS/SSL, but not having a correct/valid certificate.

The solution

You can add a valid certificate, but if the server is just used for sending out mails, this may not be suited. In that case, you can change the delivery_method to sendmail, which makes ActionMailer use the sendmail binary directly.

source

ActionMailer: Using multiple self-signed certificates

1) Is it possible to set more than one ,in my case three, different self-signed certificates? If the answer is yes, how?

The ca_file can contain multiple CA certificates in PEM format. Just put them one after each other into the file, i.e. cat cert1.pem cert2.pem > ca.pem. Make sure that each of the input files has a line end at the end though.

2) Is it possible to use a .der file as a self-signed certificate instead of a .crt file? or Should I always convert a .der file into a .crt file when I use it as a self-signed certificate?

DER and PEM are both essentially the same data only with a different encoding (binary vs. base64 with some ASCII envelope) and it is easy to convert one into the other. ca_file expects a list of PEM, not DER.



Related Topics



Leave a reply



Submit