サーバでメールを送るまで

正直、こんなにはまると思ってなかった。。。

目標:symfonyからmailを送る - あんこの成長記録で書いたsymfonyからメールを送るを、前回はMacbookProで試したが、今回はCentOSでたてたサーバで試す。

まずは、以下のページを参考にしてMTAをpostfixに切り替える。
/var/log/maeda.log: CentOSでMTAをSendmailからPostfixに切り替える

% yum install postfix
% alternatives --config mta
% /etc/init.d/postfix start

この状態で、前回作成したタスクを今回の環境用にenvとconnectionを修正して実行。
試しに自分のgmailアカウント宛にメールを送信してみる。

でも、失敗。


そこで、ログを確認。

% less /var/log/maillog
postfix/smtp[**]: connect to gmail-smtp-in.l.google.com[74.125.53.27]: Connection timed out (port 25)

いろいろ調べてみたところconnection timed outする原因として、Outbound port 25 Blocking(OP25B)なんていうのもあるようで。
[Postfix][自宅サーバ]Outbound port 25 Blocking対策してメール送信する方法 · DQNEO起業日記

でも今回の原因はこれではないよう。
OP25BだとstatusがNo route to hostなので)


サーバの中へメールを送ってみる。成功。
ということで、サーバの内→外でsmtpが通っていないっぽい。


もうしばらくはまってから、同じようにはまってる人を発見。
http://www.zimbra.com/forums/administrators/20333-solved-can-t-send-external-domain-connection-timed-out.html
最終的にファイアウォールの設定が問題だったっぽい。


というわけで、確認。

% less /etc/sysconfig/iptables
...
  • A OUTPUT -d ! *.*.*.*/*.*.*.* -p tcp -m multiport --sports *,*,*,*,* -j DROP
...

外向きのtcpで拒否してるのはコレだけだったので、違うっぽい。


ここらへんでいったん断念して時間を置いた。
サーバ関連の知識がないので、いろいろ調べつつ、勉強しつつ。
小悪魔女子大生のサーバエンジニア日記
がすごく勉強になった。

まだ全部消費しきれてないので、少しずつ読んでいくつもり。



調べた結果、使っているサーバでは25番からの外向きパケットは遮断されているみたい。

telnet smtp.gmail.com 25
Trying 74.125.53.109...
(no reply)

telnetが通らない時点で気づくべきだった><


25番ポートの攻防:Security&Trust ウォッチ(32) - @IT
スパム対策として、25番ポートからのパケットは遮断することが多いのかな。
代わりに、465, 587番ポートが使われるみたい。

% telnet smtp.gmail.com 465
Trying 74.125.53.109...
Connected to smtp.gmail.com (74.125.53.109).
Escape character is '^]'.
...
% telnet smtp.gmail.com 587
Trying 74.125.53.109...
Connected to smtp.gmail.com (74.125.53.109).
Escape character is '^]'.
220 mx.google.com ESMTP hogehoge
...

465, 587番ポートのパケットは通る。


次に、メールサーバへのsslを試す。
OpenSSLのコマンドラインプログラムの使い方 - builder by ZDNet Japan
smtp over sslはport 465っぽい。

% openssl s_client -connect smtp.gmail.com:465
CONNECTED(00000003)
...

というわけで、smtp over ssl使えばいけそう。
調べてみると、

symfony 1.x legacy website

GmailのアカウントがあればGmailのサーバを使ってメールを送れそう。
上のページにある通り、apps/frontend/config/factories.ymlを編集。

transport:
  class: Swift_SmtpTransport
  param:
    host:       smtp.gmail.com
    port:       465
    encryption: ssl
    username:   あなたの Gmail ユーザー名
    password:   あなたの Gmail パスワード

これでいけると思ってたのがどうかしてた。。
ローカルでpostfixあげてない状態でタスクを実行。

Warning: fsockopen(): unable to connect to localhost:25 (Connection refused) in /usr/share/pear/symfony/vendor/swiftmailer/classes/Swift/Transport/StreamBuffer.php on line 233

                                                                                     
  Connection could not be established with host localhost [Connection refused #111] 

全く理解が足りてなかった。port 465にしたのにlocalhost:25にアクセスしようとしてる...とか。
どうやらローカルで動いてるpostfixにつないで、クライアントとして使ってるみたい。

というわけで、postfixtlsと認証のクライアントとしての設定をして、postfixを起動。
この部分は主に以下のページを参考にしました。
Postfix で、Gmail にメールをリレーする - 私の二次記憶
Postfix - memo.xight.org

/etc/postfix/main.cfに追加した設定

...
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
smtp_tls_CApath = /etc/pki/tls/certs/ca-bundle.crt

このあと、/etc/postfix/sasl_passwdを作成して、

[smtp.gmail.com]:587 username@gmail.com:password

権限を変更。

% chown root:root /etc/postfix/sasl_passwd
% chmod 600 /etc/postfix/sasl_passwd

/etc/postfix/sasl_passwd.dbを作成して、postfixを再起動する。

% postmap /etc/postfix/sasl_passwd
% /etc/init.d/postfix restart

これでようやくメールが送れました。

factories.ymlにパスワードが書いてあるのはひどいと思ったのと、わざわざsasl用のdbを作ってるはずなので、factories.ymlにはアカウント・パスワードは書かなくてもいいはず。
というわけで変更。(といっても、該当部分を削っただけ)

transport:
  class: Swift_SmtpTransport
  param:
    host:       smtp.gmail.com
    port:       587
    encryption: ssl

これでもちゃんと送れているみたい。
sasl_passwd.dbからFromのアカウントのパスワードを見て、認証してるのかな。


わからないことだらけだけど、だいぶ勉強になった気がします。



他に参考にしたページ
��Postfix�̃R���g���[�������S�҂̂��߂�Linux�T�[�o�[�\�z�u��(CentOS �����T�[�o�[�Ή�)�����֗��T�[�o�[.com��
http://linux.kurumania.net/archives/2006/07/postfixmail.php