Perl and Email #3
@azumakuniyuki Cubicroot Co. Ltd.
Kyoto.pm #05 in 京都::はてなさん 2013/07/13(土)
Emailクラウド風メール送信用HTTP API "Haineko"
七
月
十
七
日
加
筆
修
正
自己紹介
あずま@京都
@azumakuniyuki
鯖管
プログラマ
たまに
Perl
+(猫)
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
2
作ったもの
- bounceHammer
- バウンスメール解析するやつ
- YAML/JSONで出る
- http://bouncehammer.jp/
- Acme::Nyaa
- 初CPANモジュール/猫系
- 神と和解せよ => ネコと和解せよ
- 祇園祭です => 祇園祭ですニャー
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
3
Perl and Email #3
Emailクラウド風メール送信用HTTP API "Haineko"
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
4
Haineko``はいねこ''
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
5
HTTP
API
INTO
ESMTP
K=undef
O=undef
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
6
- リレーサーバ(キューは持たない)
- HTTPでメールを送る => Mojolicious
- 他のSMTPサーバかEmailクラウドへリレー
- 応答は全てJSON
- Hainekoに渡すときの認証は未実装
- $REMOTE_ADDRでリレー制限(relayhosts)
- 許可された宛先のみに送信(recipients)
Hainekoの概要
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
7
Architecture
Hainekoの処理の流れ、全体図と部分図。
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
8
Haineko Flow
Haineko
HTTP Request
HTTP Request
ESMTP Relay
Email Cloud
SendGrid(実装済)
Postmark(まだ)
MailChimp(まだ)
AmazonSES(まだ)
HTTP Listen on 2794
HTTPS Listen on 2894
mailertable/sendermt
HTTP Response
ESMTP Response
HTTP Response
POST
HTTP CLIENT
Browser / wget / curl
to JSON
Any SMTP Server
smtp.example.jp:25
tls.example.com:465
smtp.gmail.com:587
Another
Haineko Server
SMTP
HTTP / HTTPS
SMTP-AUTH
STARTTLS
PIPELINING
Check REMOTE_ADDR
Check RCPT_TO
Rejected
Cannot connect
JSON
JSON
JSON
JSON
JSON
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
9
ESMTP Relay
Haineko
ESMTP or HTTP Response
etc/mailertable
etc/sendermt
etc/mailertable:default
宛先アドレスのドメインに一致
発信アドレスのドメインに一致
一致するドメインなし
defaultの定義がない
127.0.0.1:25にリレー
一致する発信アドレスのドメインなし
一致する宛先アドレスのドメインなし
to JSON
127.0.0.1でSMTPdが動いていない
127.0.0.1:25 SMTP
SMTP
HTTP / HTTPS
HTTP/HTTPS
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
10
Table Files
各種の制限項目、経路テーブルなど。
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
11
- 宛先ドメインでのルーティングテーブル(YAML)
default:
mailer: 'ESMTP'
host: '192.0.2.22'
port: 25
example.com:
mailer: 'ESMTP'
host: 'smtp.gmail.com'
port: 587
auth: 'Google'
starttls: 1
etc/mailertable
← 宛先が *@example.comの時は
← ESMTPで
← Gmailの587番ポートに接続
← etc/authinfoの"Google"認証情報を使う
← SMTPセッションでSTARTTLSを使う
← mailertable, sendermtのどちらにも一致しない場合
← このSMTPサーバの25番に接続して送信(リレー)
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
12
- 発信ドメインでのルーティングテーブル(YAML)
- mailertableと同じ書式
example.jp:
mailer: 'ESMTP'
host: '192.0.2.253'
port: 25
example.org:
mailer: 'SendGrid'
auth: 'SendGrid'
etc/sendermt
← 発信者が *@example.jpの時は
← Haineko::Relay::SendGridを使う(Web API)
← etc/authinfoの"SendGrid"認証情報を使う
← このSMTPサーバの25番に接続して送信(リレー)
← 発信者が *@example.orgの時は
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
13
- SMTP-AUTH, EmailクラウドのAPI用認証情報(YAML)
- ファイルのパーミッションに注意
Google:
username: '******@gmail.com'
password: 'nekochan22'
SendGrid:
username: 'kijitora'
password: 'nyanko22'
etc/authinfo
← mailertable, sendermtの``auth''で指定したラベル
← SendGrid APIのパスワード(API_KEY)
← Gmailのユーザ名とパスワード
← SendGrid APIのユーザ名(API_USER)
← mailertable, sendermtの``auth''で指定したラベル
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
14
- メールのリレーを許可するクライアントのIPアドレス
- IPアドレスかネットワーク帯域を記述(YAML)
- open-relayは危ないので将来削除するかも
open-relay: 0
relayhosts:
- 127.0.0.1
- 192.0.2.22/32
- 168.254.0.0/16
etc/relayhosts
← ``1''にするとIPアドレスのチェックをしない(危険)
← 許可するIPアドレスかネットワークを配列で列挙
← Net::CIDR::Liteが理解出来る形式で
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
15
- メールを送っても良い宛先のアドレスかドメイン
- このファイルに一致しない宛先には送らない
- open-relayは危ないので将来削除するかも
open-relay: 0
domainpart:
- 'example.co.jp'
recipients:
- 'neko@cat.example.jp'
- 'kijitora@example.com'
etc/recipients
← ``1''にするとどんな宛先にも送れる(危険)
← 送っても良い宛先をドメインで指定(配列で列挙)
← 送っても良い宛先を個別に指定(配列で列挙)
← *@example.co.jp宛はなんでもOK!
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
16
Sending & Reply
メール送信とJSONでの応答
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
17
- sbin/hainekod サンプルスクリプト
$ sbin/hainekod -d start (morboが起動する)
$ sbin/hainekod start (hypnotoadが起動する)
$ morbo --listen 'http://*.2794' script/haineko
$ hypnotoad script/haineko
- psgiファイルを書けばPlackでも動く、たぶん。
Start Haineko
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
18
$ curl 'http://127.0.0.1:2794/submit'
-X POST
-H 'Content-Type: application/json'
-d '{ ehlo: "ホスト名",
mail: "neko@example.jp",
rcpt: [
"kijitora@example.org",
"mikeneko@example.com" ],
body: "ネコと和解せよ",
header: { subject: "ニャー!!", … } }'
メール送信(curl)
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
19
{
"smtp.queueid":"r6DCXsV00649aTl2",
"smtp.response": {
"dsn": "2.0.0",
"error": 0,
"message":[ "Accept for delivery" ],
"command": "QUIT",
"code": "221" },
"smtp.useragent": "ユーザエージェント(USER_AGENT)",
"smtp.recipient": [ "kijitora@example.jp"],
"smtp.addresser": "NNN@example.org",
"smtp.remotehost": "127.0.0.1", "smtp.remoteport":49989
}
正常応答(JSON)
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
20
{
"smtp.queueid":"r6DCXsV00649aTl2",
"smtp.response": {
"dsn": "5.7.1",
"error":1,
"message":[ "Recipient address not permitted" ],
"command": "RCPT",
"code": "533" },
"smtp.useragent": "ユーザエージェント(USER_AGENT)",
"smtp.recipient": [ "kijitora@example.gov"],
"smtp.addresser": "NNN@example.org",
"smtp.remotehost": "127.0.0.1", "smtp.remoteport":49989
}
エラー応答(JSON)
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
21
Repository
github.com/azumakuniyuki/Haineko
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
22
- Perl and SMTP
| Mojoliciousでメール送信APIを作った話
| HTTP-API for sending email
- http://yapcasia.org/2013/talk/show/
f023c72c-dfd4-11e2-8f00-96816aeab6a4
- 夏のうちにもう少し開発をする予定
- 採用されたらHainekoの話をします!
YAPC::Asia Tokyo 2013
Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土)
Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd.
23
終
24

Perl and Email #3 ``Haineko''/Kyoto.pm #5

  • 1.
    Perl and Email#3 @azumakuniyuki Cubicroot Co. Ltd. Kyoto.pm #05 in 京都::はてなさん 2013/07/13(土) Emailクラウド風メール送信用HTTP API "Haineko" 七 月 十 七 日 加 筆 修 正
  • 2.
    自己紹介 あずま@京都 @azumakuniyuki 鯖管 プログラマ たまに Perl +(猫) Kyoto.pm #5 in京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 2
  • 3.
    作ったもの - bounceHammer - バウンスメール解析するやつ -YAML/JSONで出る - http://bouncehammer.jp/ - Acme::Nyaa - 初CPANモジュール/猫系 - 神と和解せよ => ネコと和解せよ - 祇園祭です => 祇園祭ですニャー Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 3
  • 4.
    Perl and Email#3 Emailクラウド風メール送信用HTTP API "Haineko" Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 4
  • 5.
    Haineko``はいねこ'' Kyoto.pm #5 in京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 5
  • 6.
    HTTP API INTO ESMTP K=undef O=undef Kyoto.pm #5 in京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 6
  • 7.
    - リレーサーバ(キューは持たない) - HTTPでメールを送る=> Mojolicious - 他のSMTPサーバかEmailクラウドへリレー - 応答は全てJSON - Hainekoに渡すときの認証は未実装 - $REMOTE_ADDRでリレー制限(relayhosts) - 許可された宛先のみに送信(recipients) Hainekoの概要 Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 7
  • 8.
    Architecture Hainekoの処理の流れ、全体図と部分図。 Kyoto.pm #5 in京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 8
  • 9.
    Haineko Flow Haineko HTTP Request HTTPRequest ESMTP Relay Email Cloud SendGrid(実装済) Postmark(まだ) MailChimp(まだ) AmazonSES(まだ) HTTP Listen on 2794 HTTPS Listen on 2894 mailertable/sendermt HTTP Response ESMTP Response HTTP Response POST HTTP CLIENT Browser / wget / curl to JSON Any SMTP Server smtp.example.jp:25 tls.example.com:465 smtp.gmail.com:587 Another Haineko Server SMTP HTTP / HTTPS SMTP-AUTH STARTTLS PIPELINING Check REMOTE_ADDR Check RCPT_TO Rejected Cannot connect JSON JSON JSON JSON JSON Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 9
  • 10.
    ESMTP Relay Haineko ESMTP orHTTP Response etc/mailertable etc/sendermt etc/mailertable:default 宛先アドレスのドメインに一致 発信アドレスのドメインに一致 一致するドメインなし defaultの定義がない 127.0.0.1:25にリレー 一致する発信アドレスのドメインなし 一致する宛先アドレスのドメインなし to JSON 127.0.0.1でSMTPdが動いていない 127.0.0.1:25 SMTP SMTP HTTP / HTTPS HTTP/HTTPS Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 10
  • 11.
    Table Files 各種の制限項目、経路テーブルなど。 Kyoto.pm #5in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 11
  • 12.
    - 宛先ドメインでのルーティングテーブル(YAML) default: mailer: 'ESMTP' host:'192.0.2.22' port: 25 example.com: mailer: 'ESMTP' host: 'smtp.gmail.com' port: 587 auth: 'Google' starttls: 1 etc/mailertable ← 宛先が *@example.comの時は ← ESMTPで ← Gmailの587番ポートに接続 ← etc/authinfoの"Google"認証情報を使う ← SMTPセッションでSTARTTLSを使う ← mailertable, sendermtのどちらにも一致しない場合 ← このSMTPサーバの25番に接続して送信(リレー) Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 12
  • 13.
    - 発信ドメインでのルーティングテーブル(YAML) - mailertableと同じ書式 example.jp: mailer:'ESMTP' host: '192.0.2.253' port: 25 example.org: mailer: 'SendGrid' auth: 'SendGrid' etc/sendermt ← 発信者が *@example.jpの時は ← Haineko::Relay::SendGridを使う(Web API) ← etc/authinfoの"SendGrid"認証情報を使う ← このSMTPサーバの25番に接続して送信(リレー) ← 発信者が *@example.orgの時は Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 13
  • 14.
    - SMTP-AUTH, EmailクラウドのAPI用認証情報(YAML) -ファイルのパーミッションに注意 Google: username: '******@gmail.com' password: 'nekochan22' SendGrid: username: 'kijitora' password: 'nyanko22' etc/authinfo ← mailertable, sendermtの``auth''で指定したラベル ← SendGrid APIのパスワード(API_KEY) ← Gmailのユーザ名とパスワード ← SendGrid APIのユーザ名(API_USER) ← mailertable, sendermtの``auth''で指定したラベル Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 14
  • 15.
    - メールのリレーを許可するクライアントのIPアドレス - IPアドレスかネットワーク帯域を記述(YAML) -open-relayは危ないので将来削除するかも open-relay: 0 relayhosts: - 127.0.0.1 - 192.0.2.22/32 - 168.254.0.0/16 etc/relayhosts ← ``1''にするとIPアドレスのチェックをしない(危険) ← 許可するIPアドレスかネットワークを配列で列挙 ← Net::CIDR::Liteが理解出来る形式で Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 15
  • 16.
    - メールを送っても良い宛先のアドレスかドメイン - このファイルに一致しない宛先には送らない -open-relayは危ないので将来削除するかも open-relay: 0 domainpart: - 'example.co.jp' recipients: - 'neko@cat.example.jp' - 'kijitora@example.com' etc/recipients ← ``1''にするとどんな宛先にも送れる(危険) ← 送っても良い宛先をドメインで指定(配列で列挙) ← 送っても良い宛先を個別に指定(配列で列挙) ← *@example.co.jp宛はなんでもOK! Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 16
  • 17.
    Sending & Reply メール送信とJSONでの応答 Kyoto.pm#5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 17
  • 18.
    - sbin/hainekod サンプルスクリプト $sbin/hainekod -d start (morboが起動する) $ sbin/hainekod start (hypnotoadが起動する) $ morbo --listen 'http://*.2794' script/haineko $ hypnotoad script/haineko - psgiファイルを書けばPlackでも動く、たぶん。 Start Haineko Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 18
  • 19.
    $ curl 'http://127.0.0.1:2794/submit' -XPOST -H 'Content-Type: application/json' -d '{ ehlo: "ホスト名", mail: "neko@example.jp", rcpt: [ "kijitora@example.org", "mikeneko@example.com" ], body: "ネコと和解せよ", header: { subject: "ニャー!!", … } }' メール送信(curl) Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 19
  • 20.
    { "smtp.queueid":"r6DCXsV00649aTl2", "smtp.response": { "dsn": "2.0.0", "error":0, "message":[ "Accept for delivery" ], "command": "QUIT", "code": "221" }, "smtp.useragent": "ユーザエージェント(USER_AGENT)", "smtp.recipient": [ "kijitora@example.jp"], "smtp.addresser": "NNN@example.org", "smtp.remotehost": "127.0.0.1", "smtp.remoteport":49989 } 正常応答(JSON) Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 20
  • 21.
    { "smtp.queueid":"r6DCXsV00649aTl2", "smtp.response": { "dsn": "5.7.1", "error":1, "message":["Recipient address not permitted" ], "command": "RCPT", "code": "533" }, "smtp.useragent": "ユーザエージェント(USER_AGENT)", "smtp.recipient": [ "kijitora@example.gov"], "smtp.addresser": "NNN@example.org", "smtp.remotehost": "127.0.0.1", "smtp.remoteport":49989 } エラー応答(JSON) Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 21
  • 22.
    Repository github.com/azumakuniyuki/Haineko Kyoto.pm #5 in京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 22
  • 23.
    - Perl andSMTP | Mojoliciousでメール送信APIを作った話 | HTTP-API for sending email - http://yapcasia.org/2013/talk/show/ f023c72c-dfd4-11e2-8f00-96816aeab6a4 - 夏のうちにもう少し開発をする予定 - 採用されたらHainekoの話をします! YAPC::Asia Tokyo 2013 Kyoto.pm #5 in 京都::はてなさん 2013/07/13(土) Perl and Email #3 ``Haineko'' @azumakuniyuki / Cubicroot Co. Ltd. 23
  • 24.