Rails3でメールを送信したところ、送信できなかった。
ActionMailerの設定は、
config/initializers/02_action_mailer.rb
ActionMailer::Base.delivery_method = :smtp ActionMailer::Base.smtp_settings = { :address => "mail.example.com", :port => "587", :domain => "example.com", :user_name => "username", :password => "password", :authentication => :cram_md5 }
のようにしている。
同じ設定で、Rails2では送信できている。
原因
ActionMailer::Base.raise_delivery_errors = true
を追加して実行したところ、
OpenSSL::SSL::SSLError (hostname was not match with the server certificate)
となり、SSL証明書の検証で例外が発生しているらしいことが分かった。
また、メールサーバのログでも、
connect from xxxxx setting up TLS connection from xxxxx TLS connection established from xxxxx lost connection after STARTTLS from xxxxx disconnect from xxxxx
という状態だった。
このメールサーバはテスト用のpostfixで、
smtpd_tls_security_level = may
にしており、
smtpd_tls_cert_file、smtpd_tls_key_file には、自己署名証明書を設定していた。
Rails3では、STARTTLSがデフォルトで有効になっているためTLSで接続しようとするが、このメールサーバの証明書がテスト用の自己証明書だったので検証に失敗していたのが原因らしい。
解決方法
証明書を正当なものにすればよいと思われるが、テスト環境なのでとりあえず今は自己署名証明書を使いたい。
そのためには、ActionMailer::Base.smtp_settingsの設定で、STARTTLSを無効にするか証明書の検証を無効にする。
ActionMailer::Base.smtp_settings = { :address => "mail.example.com", :port => "587", :domain => "example.com", :user_name => "username", :password => "password", :authentication => :cram_md5, :enable_starttls_auto => true, # STARTTLSを無効にする場合はfalseにする :openssl_verify_mode => 'none' # STARTTLSを有効にしつつ、不正な証明書もOKにしたい場合は、証明書の検証を無効にする }
証明書の検証を無効にするのは本当はよくないけど、テスト環境等で自己署名証明書でもOKにしたい場合は、とりあえず上記のようにすれば、TLSでメールが送信できます。
OpenWebOps
email - Postfix & Rails 3.0 ActionMailer: lost connection after STARTTLS - Stack Overflow