procmailを触ってみた

procmailなるものを触る機会があって、結構記事が古かったり、数が少なかったりで苦労大変だったので簡単にまとめて見ようかなと思います。

# procmailとは
基本的には振り分けメール転送ツール。
メールサーバ(postfixとdovecot)が構築されているのが前提でそこに入ってきたメールを別のメールアドレスに転送するツール。
レシピというものに条件を記述しておくとそれに見合ったメールだけを転送したり破棄したりすることが出来る。
複雑な振り分け設定もレシピの法則に従えばわりかし簡単に設定することが出来る便利なやつ。




# procmailのインストール
導入もわりかし簡単でした
※大前提にpostfixとdovecotのインストール構築が終了していること。

* 検証サーバのOS：Centos7

## インストール

```bash
yum -y install procmail
```

パスを確認

```bash
which procmail
```

このように返ってこれば問題なし

```bash
/usr/bin/procmail
```

## 設定
postfixの設定ファイルを編集します。

445行前後に追記

```vim:/etc/postfix/main.cf
#mailbox_command = /some/where/procmail
#mailbox_command = /some/where/procmail -a "$EXTENSION"
+ mailbox_command = /usr/bin/procmail
```

Postfix再起動

```bash:
systemctl restart postfix
```

これでprocmailが動く環境が整いました。

# レシピ作成
振り分けの条件を書いたものをレシピと呼びます。

## 設定ファイルの設置
振り分けと言っても、全体のユーザに適応したい設定と各ユーザに適応させたいユーザに分かれてくる場合があると思います

* 全体のユーザに適応させたい場合は

ホームディレクトリ直下に

```procmailrc``` を作成

新しくprocmailrcのファイルをさ作成し個々に記述します

* 個々のユーザに適応させたい場合は

対象ユーザのホームディレクトリに
```.forward```
```.procmailrc```
ファイルを設置

```vim:.forward
"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75 #username"
```
※「|」はパイプライン

本来転送機能等のみは.forwardファイルに記述したら出来る機能がデフォルトであるようなのですが
それをprocmail側に実行を投げてしまおうって設定。

procmailrcに関しては次に詳しく記述します。

## 具体的なレシピの書き方
実際のレシピはprocmaircに記述していきます。

### レシピで出来ること 
* レシピには複数のレシピを記述することが可能。
* 自分はメール転送を目的で利用したが、削除したり別のディレクトリに保存することも可能

### レシピの基本
* 1つのレシピは「:0」から始まり、次の「:0」かファイルの終端(EOF)で終わる。
* 「#」でコメントアウトすることが可能

### レシピの構成
レシピは基本的に3つの構成からなります。
* フラグ・・・Procmail にメールを渡す方法を指定する。
* 条件文・・・条件文処理を行うメールを特定する。
* アクション・・・メッセージが条件に該当した場合に行う処理を示す。

次に各構成についてまとめたいと思います。


## フラグ

メッセージを処理するとき、procmailに渡すメッセージの渡し方・渡す箇所を指定します。

* 条件文に対するフラグ

|フラグ|説明|
|:----|:---|
|H|メッセージのヘッダ部分のみを条件文で判定する。フラグを記述していないデフォルトの状態はこのフラグが適応される。|
|B|メッセージの本体部分のみを条件文で判定する。|
|HB|メッセージのヘッダ部分、本体の両方で判定する。|
|D|判定の際大文字と小文字を区別する。デフォルトの状態では区別されない|
|A|同じブロックレベルに記述された A や a の用いられてないレシピが該当した場合にだけ判定する。同じ条件文の後で更に条件分岐したい場合に用いる。|
|a|Aと同様だが、手前のレシピが正しく実行された場判定する。|
|E|Aの逆で手前のレシピが実行されなかった場合判定する。|
|e|aの逆で手前のレシピが失敗した場合判定する。|
|i|あらゆる書きこみエラーを無視して判定する。条件は満たしていたのにエラーが発生した場合等に対処出来る。|

* アクションに対するフラグ

|フラグ|説明|
|:----|:---|
|h|アクションにメッセージのヘッダ部分のみを渡す。|
|b|アクションにメッセージの本体部分のみを渡す。|
|hb|アクションにメッセージのヘッダ部分、本体部分の両方を渡す|
|f|パイプを通して処理したメッセージを以降のレシピに渡すことができる。|
|c|続くレシピにメッセージのコピーを渡す。他のアドレスへのメッセージ送信や、ブロック文内で一つのメッセージにたいして複数の処理を行いたい場合に用いる。またこれをつけておくと転送後もメールのコピーは残る。（つけていないと転送先にしかメールは残らない）|
|w|フィルタやプログラムの返り値をチェックする。失敗した場合にはテキストが処理されない。|
|W|wと同様だが、処理の失敗に関するメッセージを出力しない。|
|:[]|メッセージに対して複数の処理が行われないようにする|


## 条件文
|条件|説明|
|:----|:---|
|!|条件の否定を表す|
|$|条件文に現れる変数をシェルの用に扱うことが出来る|
|?|指定したプログラムの終了コード (0:true1:false) を利用できる。|
|<|長さが後に記述されたバイト数 (10進) 以下であれば実行。|
|>|長さが後に記述されたバイト数 (10進) 以上であれば実行。|
|変数名??|指定された値と変数を比較する。|
|\|\/ と記述すると該当箇所を変数 MATCH に格納する。|

## アクション
|アクション|説明|
|:----|:---|
|!|記述したメールアドレスに転送。スペース区切りで複数のアドレスを指定可。|
|&#124;|メッセージを他のプログラムに渡す。シェルから呼び出せるプログラムを実行する際に使用。|
|ファイル名|メッセージをファイルに格納、ロックを忘れずに|
|ディレクトリ名|メッセージにユニークなファイル名をつけてディレクトリに格納する。|
|ディレクトリ名/.|メッセージをディレクトリに MH 形式 (連番) で格納する。|
|dev/null|メッセージの破棄。復元不可|


まだ未知数なところが多々

## レシピ例

* 送信元が一致すれば転送するレシピ

```vim:.forward
SHELL=/bin/bash
PATH=$HOME/bin:/usr/bin:/usr/local/bin
MAILDIR=$HOME/Maildir/
DEFAULT=$MAILDIR
LOGFILE=$MAILDIR/procmail.log　


:0 c
* ^From.@aaa.ne.jp
{
     :0 c
     !test@hoge.co.jp
}

```

以後引き続き触る予定。
一旦ここまで。