SSHの使えないレンタルサーバにて、Pythonからメールを送信しようとしたらClient host rejectedエラーが出たため、対応をメモしておきます。
環境
レンタルサーバ
開発環境
- Windows7 x64
- Visual Studio Code 0.5.0
- Python 2.x
- Bottle 0.12.8
状況
開発環境で以下のようなPythonスクリプトを書いて実行してみたところ、メールを送信することができました。
msg = MIMEText(email_body, 'plain', 'utf-8') msg['Subject'] = Header(u'メールテスト', 'utf-8') msg['From'] = SENDER_ADDRESS msg['To'] = ','.join(RECIEVER_ADDRESSES) charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') smtp_client = smtplib.SMTP(SENDER_DOMAIN, 587) smtp_client.sendmail(SENDER_ADDRESS, RECIEVER_ADDRESSES, msg.as_string()) smtp_client.quit()
その後、レンタルサーバへアップロードして試してみたところ、
{u'sender@example.com': (554, '5.7.1 : Client host rejected: Access denied')}
のようなエラーが出て、メールを送信できませんでした。
対応
SMTPの587ポート(サブミッションポート)で送信するため、レンタルサーバ上ではSMTP-AUTHなどができていないのかなと考えました。そこで、以下の2通りの方法での送信を試してみました。
smtplibでログインアカウントとパスワードを渡す方法
Pythonのドキュメントを参考にしてsmtplib.login()
を使用してみたところ、メールの送信ができました。
20.12. smtplib — SMTP プロトコルクライアント — Python 2.7ja1 documentation
smtp_auth_client = smtplib.SMTP(SENDER_DOMAIN, 587)
smtp_auth_client.login(SENDER_LOGIN_ID, SENDER_PASSWORD)
smtp_auth_client.sendmail(SENDER_ADDRESS, RECIEVER_ADDRESSES, msg.as_string())
smtp_auth_client.quit()
レンタルサーバ上のsendmailを叩く方法
上記の方法だとSMTPサーバーを使うIDとパスワードをPythonスクリプト内に埋める必要があるため、少し不安でした。
レンタルサーバのドキュメントを読んでみたところ、sendmail
が使えそうでした。
そのため、以下を参考に、Pythonのsubprocess
モジュールを使って、Pythonからsendmailを叩くことにしました。
email - Sending mail via sendmail from python - Stack Overflow
msg = MIMEText(email_body, 'plain', 'utf-8') msg['Subject'] = Header(u'メールテスト', 'utf-8') msg['From'] = SENDER_ADDRESS msg['To'] = ','.join(RECIEVER_ADDRESSES) charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE) p.communicate(msg.as_string())
こちらもメールを送信することができました。
ソースコード
GitHubに上げました(mail.py
, mail.html
)。再現しやすいよう、Bottleでフォームを作っています。
thinkAmi-sandbox/Bottle-sample
参考
メールまわり