*IRC/SMTPゲートウェイ [#w3c4b9e7] RIGHT:2008-10-20 RIGHT:川俣吉広 IRCとメールとの間でメッセージをやりとりする機能の試験的な実装。 **アーキテクチャ [#i8b051b4] アーキテクチャの概略を下図に示します。 // +----+ SMTP +-------------+ SMTP +--------+ // |Mail|<--------|< - - - - - -|<---------------[migw.pl]<-------->| IRC | // |User| | mail server | ^ | Server | // | |-------->|- - - - - - >|-->[.forward] |socket +--------+ // +----+ +-------------+ | | // +------>[minjector.pl] |&ref(migw-internal.gif,wrap);| 上図の &ref(migw.pl); および &ref(minjector.pl); の部分が今回作成した部分です。 migw.pl は、IRCクライアントとして目的のチャンネルにJOINしており、 IRC内での発言を受信します。 受信された発言はメールに変換され、SMTPサーバに渡されます。 一方、メールからIRCへの転送は、メールサーバでの .forward あるいは .procmailrc などの設定により メールのヘッダおよび本文が minjector.pl というプログラムに引き渡されます。 minjector.plは、標準入力からメールのヘッダと本文を読み込み 一定の形式に変換した後、Unixドメインソケットを経由して migw.pl に 引き渡され、最後に IRCネットワークのJOINしているチャンネルで 発言されます。 **設定及び起動手順 [#ie5adb66] IRC/SMTPゲートウェイの設置と運用は、通常ユーザの権限で可能です。~ 以下の例では、設置と運用を行うユーザのホームディレクトリ直下にmigwというディレクトリを 作成し、その中にスクリプトや設定ファイルを置く場合を想定して説明を行っています。 ***準備 [#a32786c6] -このPerlスクリプトは、 --Net::IRC --Jcode --Net::SMTP --IO::Socket というモジュールを使用しますので、 これらのモジュールがない場合は、CPANあるいはOS毎に 用意されているパッケージシステムなどからインストールします。 ***設定ファイルの編集 [#yb77e279] -このページに添付されている&ref(sample.conf);を元に、設定の編集を行います。 # 各種パラメータ設定 # $IRC_NICK = 'migw'; $IRC_SERVER = 'irc.example.net'; $IRC_PORT = 6667; $IRC_NAME = 'IRC/SMTP gateway'; $IRC_CH = '#foo'; $IRC_MAXLINES = 20; $IRC_ITIMEOUT = 120; $IRC_CTIMEOUT = 150; $IRC_HANDLEFILE = $ENV{HOME} . "/migw/sample-handlenames.pl"; $SMTP_SERVER = 'localhost'; $SMTP_FROM = 'migw@example.com'; $SMTP_TO = 'talk-irc@mx.example.org'; $SOCKPATH = $ENV{HOME} . "/migw/sample.sock"; $DEBUG = 1; 設定書式は、Perlの文法に従います。~ 設定項目の一部を以下に説明します; :$IRC_MAXLINES|一通のメール本文からIRCへ送信される最大行数。メッセージ本文でこの行数を超えた部分はIRCチャンネルへは送信されない。 :$IRC_ITIMEOUT|IRCからメールへ送信する場合のタイムアウト。IRCで発言のない期間がこの秒数を超えると、その時点までで送信されていなかったIRCの発言が、まとめて一通のメールとしてSMTPサーバに送信される。 :$IRC_CTIMEOUT|IRCからメールへ送信する場合のタイムアウト。IRCで$IRC_ITIMEOUTによるタイムアウトが発生していない状況で、発言がこの$IRC_CTIMEOUTで設定した秒数を超えると、その時点までで送信されていなかったIRCの発言が、まとめて一通のメールとしてSMTPサーバに送信される。 :$IRC_HANDLEFILE|メールをIRCに中継した場合、IRCチャンネル上ではメールの送信者が誰かを明示する必要があります。そのため中継されたメッセージの冒頭には、発言者のメールアドレスを縮めたものが付きます。例えば、メールの送信者アドレスが、kaw@on.rim.or.jpの場合、IRCチャンネル上では、 <migw> kaw@on: こんにちは。 のようになります。このkaw@onをハンドル名と呼ぶことにします。~ ハンドル名は、上に述べたようにメールアドレスから生成されますが、 それ以外のものを定義することもできます。その定義ファイルの位置を指定するのが$IRC_HANDLEFILEです。~ $IRC_HANDLEFILEによるハンドル名の変換機能を使用しない場合は、この行をコメントアウトします。 :$SOCKPATH|minjector.plとmigw.plが通信するためのUnixドメインソケットのパス その他は、自明な項目だと思いますので省略します。 ***メール関係の設定 [#tca1f5b9] -minjector.plがメールを受け取るメールアカウント(設定ファイルでの$SMTP_FROM)を作成します。 -実際にminjector.plがメールを受け取るように、メールサーバの設定を行います。 --~/.forwardに記述する場合 | perl $HOME/migw/minjector.pl $HOME/migw/sample.conf || exit 75 --~/.procmailrcに記述する場合 :0 * ^To: talk-irc@example\.org |perl $HOME/migw/minjector.pl $HOME/migw/sample.conf Perlスクリプトや設定ファイルの置場は、実際のものに読み換えて下さい。 ***ハンドル名変換ファイルの設定 [#x33bf18e] 設定ファイル中で$IRC_HANDLEFILEを定義した場合は、そのファイルを用意します。~ 設定ファイルは、Perlの文法に従います。内容は&ref(sample-handlenames.pl);のようになります。 %stat_handlenames = ( 'mail@example.com' => 'HandleName', 'mawk@foobar.ne.jp' => 'mika' ); 1; このように、%stat_handlenames に、メールアドレスとハンドル名の対を 連想配列の要素として定義します。 ***プログラムの起動 [#db525786] 設置を行ったユーザアカウントでログインし、コマンドラインから以下のように実行します。 perl $HOME/migw/migw.pl $HOME/migw/sample.conf 設定ファイルで$DEBUGが1の場合、動作にしたがってメッセージが出力されますので、 実際にIRCで発言したり、$SMTP_TOで設定したアドレスにメールを送信したりして動作を確認します。 ***運用 [#yee47733] :ハンドル名の変更|ハンドル名は起動前にあらかじめ定義したものを、運用中に変更することができます。メールアドレスからハンドル名の変換を行う変換表は、2種類あります。~ ~*静的変換表 ... $IRC_HANDLEFILE中で定義した変換表 ~ ~*動的変換表 ... メールユーザがコマンドメールを送信することにより設定できる変換表。~ ~ 静的変換表の内容を変更するには$IRC_HANDLEFILEの内容を変更した後、migw.plプロセスにUSR1シグナルを送信し、変更を反映させます。~ ~ 動的変換表を更新するには、ハンドル名を変換したいメールアドレスから以下の形式の本文を含むメールを送信します。 ゲートウェイのIRCニックネーム<-iam ハンドル名 sample.confの設定値を例にとれば、具体的には以下のようになります。 migw<-iam kaw@home これで、ハンドル名がkaw@homeに設定されます。ハンドル名を付けず、 migw<-iam と送信した場合は、設定されていたハンドル名がリセットされます。~ ~ なお、静的変換表と動的変換表で同じ内容が設定された場合は、動的変換表の内容が優先されます。 :中継動作の中断と再開| ゲートウェイの中継動作を停止させたい場合は、以下の形式の本文を含むメールを送信します。 ゲートウェイのIRCニックネーム<-relay off これによりメール->IRC, IRC->メールのいずれの方向の中継動作は停止します。~ これによりメール->IRC, IRC->メールのいずれの方向の中継動作も停止します。~ ~ 停止している中継動作を再開させたい場合は、以下のようにします。 ゲートウェイのIRCニックネーム<-relay on **Tips [#s9ca28e2] ***複数のメールアドレスとIRCの間で交信を行いたい。 [#pa098cb1] 複数のメールアドレスと交信したい場合は、MLを作成し、このMLのアドレスを$SMTP_TOに設定します。そして、設定ファイルの$SMTP_FROMのアドレスをこのMLに追加します。~ 動作のイメージとしては、以下のようになります。~ |&ref(migw.gif,wrap);| |CENTER:MLからIRCへの中継| ~ |&ref(migw-reply.gif,wrap);| |CENTER:IRCからMLへの中継| MLといっても、一般的なメーリングリストドライバを導入せず、/etc/mail/aliases等を用いた簡易なものを使用することも可能です。 ***splitしているIRCサーバの間を接続するために使いたい。 [#ccd2f480] これは、前項のTip、''複数のメールアドレスとIRCの間で交信を行いたい''の応用になります。例えば、IRCサーバ fooと barを接続する場合は、以下のようになります。 --foo用の設定 ---foo用の設定ファイル、foo.confを作成 ---foo用のメールアカウントを作成し、foo.confを指定したminjector.plがメールを読むように.forwardなどを設定。 --bar用の設定 ---barに対しても、fooと同様な設定作業を行う。 --foo, bar共に加入しているMLを作成する。 --foo用の設定でmigw.plを起動する。 --bar用の設定でもmigw.plを起動する。~ ~ ... 動作設定を増やすことで、さらに多くのIRCチャンネルを多元接続することも可能です。 **ToDo [#v1a9f1ec] -IRCの接続が切れた時に再接続を行う機能 --IRC接続断をトラップする方法が現在不明なため、現在は未実装です。