FC2ブログ

PCで: Linuxで受け取ったメールをコピーを残しつつ転送

 私のウチのメインのPCはLinuxで運用しているわけですが、独自のドメイン持ったりとかしているわけでも何でもありません。なので、余所のマシンとのお付き合いという意味では、ごく普通の個人のクライアントPCです。
 勿論、今回の話題のメールも、プロバイダ(ISP)のサーバとかに取りに行っています。

 ところで、自分のアドレスに届いたメールの一部を、コピーを残しつつ自分のケータイに転送したいな、という状況になりました。しかしながら、プロバイダのサーバではそこまで細かく設定できません。
 というわけで、PC側で対処することにしました。

 やりたいことはこんな感じです。
  • 特定のメールアドレスから届いたメールをケータイに転送する
  • その際、PCにもコピーを残す
  • 複数のメールアカウントを扱えること
  • ローカルなメールが外に出てしまったりしないようにする
  • プロバイダの送信用サーバが要求する認証に対応する

 さて、現状、というか今回の作業の前の環境です。
 プロバイダ等のサーバにメールを取りに行くには、fetchmailを使っています。その際、ローカル配信用のMDAにはprocmailを使っています。また、ローカルのみでpostfixも設定してあります。これで、外からもらってくるメール、システム内の例えばcronデーモンからのメールなどいずれも、自分のローカルなアカウントで処理できています。
 基本はこの構成で、設定をいじるのみでなんとかなりました。

 次に、メールの流れのイメージはこんな感じです。
外部メール受信サーバ(プロバイダ等)
↓ POP3, IMAP4等
fetchmail
↓ メール受信時に呼び出し
procmail → ローカルのメールボックス

postfix
↓ SMTP
外部メール送信サーバ(プロバイダ)
 主な作業は三つ。
 ~/.forwardとかでは柔軟性が今一つなので、~/.procmailrcに色々設定することにしたこと。プロバイダのSMTPサーバが認証を要するのでSMTP-AUTHに対応(SASL)。そして、外に出るメールをふるいにかける。
 というわけで、順に解説。

[1]. ~/.procmailrcの設定
 なんかこう歴史的に一種独特のシンタックスになっていますが、こんな感じで書きます。簡単に言うと、「レシピ」を書き連ねます。
:0 c
* ^From:.*送信元メールアドレス
| $SENDMAIL -f 自分のメールアドレス 転送先メールアドレス
:0 A
$DEFAULT

 以下、内容の解説。
  • :0 c
    ":0"はおまじない。「レシピ」の始まり。続く"c"はレシピのフラグ。今回は一通のメールを二つに複製するので、「カーボンコピーを作成する」という意味の"c"を指定。それに続く":"は、実際にはそのあとに続くロックファイルとともに省略可。(下記P.S.3参照)
  • * ^From:.*…
    '*'で始まる行は条件。メールの中身がこの条件に引っ掛かったメールのみに、続く「アクション」に書いてある処理が施される。ここでは一行だけだが複数行書くこともできる。条件は、egrepを使うつもりで書く。ということは、メールアドレスに含まれる'.'は'\.'とか書く方がいいと思う。
    今回の例では特定のアドレスから届いたメールを対象とするので、ヘッダのFromフィールドを見ている。正規表現では厳密にマッチさせるの難しいけどまあ送るのは自分のケータイだし、余分なのがヒットしてもいいか。
  • | $SENDMAIL …
    アクション。一つのレシピには一行のみ。これでこのレシピは終了。行の先頭に"!"を書き、メールアドレスを続ければそちらに転送してくれる。しかし今回はそれ以上のことをしたいので、変った書き方に。理由は後述。
  • :0 A
    二つ目のレシピの始まり。ただ、"A"というフラグが指定してあるので、これは前のレシピの条件に引っ掛かったものが続くアクションの対象となる。
  • $DEFAULT
    二つ目のレシピのアクション。$DEFAULTはデフォルトのメールボックスファイルに追記、という意味。

 今思ったんですけど、この二つのレシピは順番を入れ替えた方がいいかも?
 というわけで逆にして試してみましたが、ちゃんと動作しますので、まず保存してからというようにするのがよろしいかと。つまりこんな感じ。
:0 c
* ^From:.*送信元メールアドレス
$DEFAULT
:0 A
| $SENDMAIL -f 自分のメールアドレス 転送先メールアドレス

[2]. postfixの設定(1) - SMTP-AUTH
 まずは、/etc/postfix/main.cfにこんなものを書きます。
smtp_sender_dependent_authentication = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

 続いて、/etc/postfix/sasl_passwdにこんなものを書きます。
自分のメールアドレス    プロバイダアカウント:プロバイダパスワード
 このファイルはrootにしか読めないようにしておくこと。そして、以下のコマンドを実行します。これで、通常は".db"の拡張子の付いたファイルが出来上がります。
postmap /etc/postfix/sasl_passwd
 これは相対パスでファイルを指定してもOk。postmapはファイルを変更する度に実行しなければいけませんが、これを変更してpostmapを実行したとき、postfix自体を再起動する必要はないようです。
 このsasl_passwdには複数行書くことができます。それぞれ複数のメールアドレスと、それに対応するアカウントとパスワードを指定できます。

[3]. postfixの設定(2) - メールの篩い分け
 今回の設定をすることで、通常使用しているメールリーダを使わずにメールが外部に送れるようになるので、ちょっとおかしなことをして外にメールを飛ばしてしまったり、その他の危険を回避するために、なるべくpostfix経由で外に出せるメールを制限することにします。
 元々、ローカルのみで使うために、/etc/postfix/main.cfにこんな設定をしていました。
mydomain = localdomain
default_transport = local
 これで他に何か設定してない限り、外には出せないようになっています。
 そして、今回の設定のために、こういうのを加えます。
transport_maps = regexp:/etc/postfix/transport
sender_dependent_default_transport_maps = hash:/etc/postfix/sender_default_transport
 二行目のパラメータはpostfixの2.7以降にしかないようです。
 /etc/postfix/transportにはこんなことを書きました。ちょっと特殊な設定です。まあ、今回のように送信できるメールを制限するというのが特殊な設定なので。
!/転送先メールアドレス/     local:
/.*/ :
 これはどういう意味かというと、メール送信(転送)先が正規表現で記述した転送先メールアドレスにマッチしなかったら(行頭の"!")、ローカル配信とする、ということになります。つまり、今回の例で言えば、自分のケータイにしか送れない、ということです。ちなみにここ、ローカル配信でなくエラーとしてしまうという手もありますが、まあそこは適当に。
 そして二行目は、一行目に引っ掛からなかったメールはこの"/etc/postfix/transport"というファイルがなかったかのような動作をせよ、という意味になります。これがないと、上記のsender_dependent_default_transport_mapsが機能しません。最初、transportの一行目に引っ掛からなかったらsender_dependent_default_transport_mapsで指定したファイルを見てくれるかなと思っていたのですが、そうではないようです(postconf(5)参照)。

 この"/etc/postfix/transport"も、上記のsasl_passwdと同じように、編集したらpostmapを実行しなくてはいけません。
 postmapコマンドですが、どうにも、"postmap regexp:transport"という風に実行しなければいけないような気がしますが、実際には"regexp:"は必要なく、普通にhashと同じように作って、main.cfでregexp指定すればいいようです。勿論、postconf -mを実行したときに"regexp"があれば、ですが。

 このtransportというファイルの設定は結局、特定のアドレス「以外」はこうしたい、という設定をしたいがために、正規表現で記述するように、main.cfでの設定を"hash:"ではなく"regexp:"にしたのでした。

 さて続いて、/etc/postfix/sender_default_transportの内容。このファイルには、コピーされ転送されるメールの送信者によってどこの送信サーバを使用するかを指定できます。そしてこれも上記のファイルのように、postmapコマンドの実行が必要。
 こんな感じです。
自分のメールアドレス1    smtp:[外部のメール送信サーバ1]:submission
自分のメールアドレス2 smtp:[外部のメール送信サーバ2]:submission
 ポートがsubmissionになっているのは、まあ最近よくある指定で、これと上記のSMTP-AUTHの設定と対ですね。またサーバアドレスが"[]"で囲んであるのは、MXを引かずに直接そのサーバに送るようにするという意味です。

 ここでこれまでの設定を追ってみると、
  1. メール受信でfetchmailがprocmailを呼び出し、.procmailrcが参照され、転送対象と判断されると、
  2. .procmailrcで指定した転送先がtransportによりOkとなったら、
  3. 転送する際の送信者メールアドレス($SENDMAILの-fオプションで指定した自分のメールアドレス)からsender_default_transportによりメール送信用のSMTPサーバを見つけ、
  4. 同じく送信者のメールアドレスからsasl_passwdによりそのSMTPサーバにアクセスするための認証情報を見つけて送信、
ということになります。

 ここで、.procmailrcでメール送信の「アクション」に"! 転送先メールアドレス"としなかった理由の解説です。
 この"!"を使った方式だと、まあpostfixの設定にもよりますが、通常ならこのLinuxマシンでの自分のアカウント名に"@マシン名.localdomain"がくっついた(上記の設定による)メールアドレスが送信者となります。が、そうするとそれを受け付ける外部のSMTPサーバが多分弾いてしまうんですよね。
 そのためには、main.cfに設定を追加しなければいけません。一例として、こんな風に。
smtp_generic_maps = hash:/etc/postfix/generic
 そして/etc/postfix/genericには、
Linuxアカウント@マシン名.localdomain    自分のメールアドレス
みたいに書いておかないと。
 でもそうすると、そのアカウントから異なる複数の送信者メールアドレスを使用しての送信(使い分け)が出来ません。
 設定ファイルを用意する手間はさして変らない(genericとsender_default_transport)のだから、自由度が高い方がやっぱいいですよね。

 とまあこんな感じの設定をすることで、冒頭に並べたことが実現できました。

P.S.
 fetchmailや、普段使っているメールリーダによる送信とかではSSL(TLS)を使用していますが、今回はそこまでやりませんでした。どうやら、使っているpostfixがそれをサポートするように作ってないようなので。

P.S.2
 今回の作業の途中で気付いたのですが、余所のSMTPサーバにも結構適当に送りつけられるもんですね。ということは、postfixの設定を頑張ってもあまり意味ないかも。

[追記: 2017-04-23]
P.S.3
 文中に「それに続く":"は、」とあるのに実はない(笑)のには理由があります。
 当初はそれで動かしていたのですが、実は問題があることがわかりました。この追記を書いている時点では、fetchmailからgetmailに移行して、大体安定して使えるようになったかなーという感じです。fetchmailは開発が止まってもうだいぶ経ちますし、その間(通称)SSLも変ってますし、設定の不自由さも気になるしで。
 でその際に気付いたのですが、procmailが並行していくつか動くと何やら"Couldn't determine implicit lockfile"という警告メッセージが出ます。調べてみたらどうやらこういうことらしい。
A typical newbie problem is placing a redundant but harmless lock on a forwarding recipe. Here's an example:

:0:
* ^TO_johnny@lunatix.com
! jjasmith@ppp.home.in.isp.net

 出典はProcmail FAQ
 ……"A typical newbie problem"だって……(笑)。
 で理由というのは、まあこっそり直しちゃってもよかったのですが、こういう間違いもありがちってことで、直しはしましたが痕跡を参考として残しておくことにしたのでした。

コメント

非公開コメント

プロフィール

水響俊二

Author:水響俊二
水響 俊二 [MIZUKI Shunji]

暫定的に、18禁作品の感想などは裏サイトで書いています。
   

最新記事
最新コメント
カテゴリ
検索フォーム
リンク
RSSリンクの表示
月別アーカイブ
アクセス解析中