Search code examples
ruby-on-railsemail

Rails, sending emails: No authentication, which possible settings


My Rails app sends emails using dynamical settings. Each user has his own settings for his own email server. The user's email server is then used as a relay to send mails to other people that come from the user's e-mail server (in the sense that the sender of the mails is the user's email account).

I can not find any documentation that goes into the depths of how to accomplish this dynamic configuration. The most common settings are always mentioned (host, port, domain, enable_starttls_auto). However, there are different authentications: "plain", "login", "cram-md5" and "none" that require different settings. In particular, "none" is proving difficult. Some clients want to use "no auth" in combination with whitelisting the IP address of my Rails app. I cannot get this to work.

So far, I have managed to find out that if I have no authentication, I must not send the :authentication key/value pair at all (setting it to nil does not work), i.e. I must delete it from the message.delivery_method.settings hash. By pure chance I found a comment in some SO post that said "I had to set :openssl_verify_mode to 'none'". I did that, and now I can receive emails with no auth on my email account on mailosaur.net, but it doesn't work for the settings of a user who claims to have no auth enabled on his email server.

Where can I find comprehensive information about what settings there are, in which situation which ones must be present or not and of course what they mean?


Solution

  • All right, I'll answer my own question, hoping that it may be useful for somebody else.

    My sources are

    A complete set of smtp settings for an ActionMailer::Message object contains (at least) 12 settings with very different roles. On initialization of this object, the settings also get initialized. For some values in the Rails project initializers are used. Others contain a value of nil. (The setting that concern us here are :address, :port, :domain, :user_name, :password, :authentication, :enable_starttls, :enable_starttls_auto, :openssl_verify_mode, :ssl/:tls, :open_timeout, :read_timeout.)

    To understand how settings may or may not be needed, it is important to understand SMTP.

    Minimal SMTP

    As a first step, the SMTP session is opened by using a FQDN of the mail server. SMTP uses Port 25 (unless the mail server has been configured to run from a different port, see setting :port).

    A minimal sequence of messages (requests) sent to a mail server in order to send an e-mail is the following. After each message the mail server responds with a status code and sometimes with some additional information. I will omit the mail server responses here and only mention them when they are relevant.

    1. EHLO mydomain.de
    
    2. MAIL FROM:<[email protected]>
    
    3. RCPT TO:<[email protected]>
    
    4. DATA
    
    5. ...... # Here transmission of the contents starts.
    

    What is missing is authorization and encryption. These were added to the protocol later (when the need for them became obvious).

    Authentication

    Usually, this takes the form of a login. (There are others, but I won't cover them.) The login process will come directly after the EHLO (this is not a typo, btw).

    This means requiring a username and a password. However, there are several possible ways of transmitting them.

    • LOGIN: The client transmits username and password in two separate requests.
    • PLAIN: The client transmits username and password in one request.
    • CRAM-MD5: This is a computational challenge involving the password, and so more secure.

    In the first two cases username and password are Base64-encoded.

    This is the first place where you can see that different settings for the authorization mode will cause the client to send different requests to the mail server. These are not just placeholders in the sequence, unlike sender and recipient email and the host address.

    The setting :authentication is used to specify which authentication method is used. There is, however, the possibility that the mail server does not require authentication. This can be used if the mail server is only contacted from certain trusted IP addresses which are then whitelisted in the mail server configuration. And in this case it is important not to include the settings :authentication, :username and :password as their presence will cause the client to make the requests. How the mail server will respond to an erroneous sending of these requests is dependent on the mail server. I have met some that simply ignore the requests, and others return an error and terminate the session.

    Encryption

    There are two methods of encryption. The first is to start the SMTP session in plain text and encrypt the contents only. This is called STARTTLS. So again, the setting :enable_starttls will cause additional requests to be sent to the mail server. If this is set and the mail server does not support it the session will fail.

    In the ActionMailer smtp settings, there is also a setting :enable_starttls_auto, which, according to the documentation at https://guides.rubyonrails.org/action\_mailer\_basics.html, will detect if the mail server supports starttls and use it in this case. I don't know why the setting :enable_starttls is also available, maybe for backwards compatibility.

    Sometimes a mail server will run using SSL and TLS (this is called SMTPS), thus encrypting the whole communication between client and itself. This is the safest method, and it uses yet another couple of settings. The setting :ssl/:tls enables it. SSL involves certificates, and the setting :openssl_verify_mode specifies whether or not to check the mail server's certificate. (The Rails documentation says that disabling this is useful during development. The value for "do check" is :peer, and for "don't check" is :none.)

    As yet, I have no experience with accessing a mail server that uses SMTPS. So I can't say whether the settings :enable_starttls or :enable_starttls_auto may be present and are ignored, or must be removed from the settings hash. The same holds for the authentication settings. But at least it has (hopefully) become clear that this is a point where problems of this kind may be expected, and why.