|目次|手順 0|1|2|3|A|B|C|D|E|F|G|H| I |J|K|L|M|N|O|P|Q|
作成日:2005年10月16日、更新日:2005年11月05日、作成:鷹の巣Windows自宅サーバー用フォームメールの設定方法(総集編)を示します。
OSがWindowsの自宅サーバーでWebページからフォームメールを行おうとするとこれまでに種々の問題点が多く発生しました。そこで、どのようにすれば、障害を回避できるのかをまとめました。また、少しでも障害を回避できる様にKENT WEBさんのPostMail(フォームメール)v3.3(2005/11/02)を改造して、PostMail(フォームメール)改造版のフリーソフトを再配布(使用に当たっては、KENT WEBさんのCGIスクリプト利用規定を遵守)するものです。この改造版は、Perlのperl.exeとPerlIS.dllの両方が使用できる様にして、オリジナル版のBlatjに加えて、sendmaneとPerlのNet::SMTPモジュールにも対応させました。
注)Perlのバージョンは、5以降でないと、動作しません。
目次
KENT WEBさんのPostMail(フォームメール)は、非常に素晴らしく、また親切設計されたスクリプトで、設置が容易であることが特徴です。それでも、OSがWindowsの自宅Webサーバーに設置しようとするには、大変難しいものがありました。そこで、OSがWindowsであっても少しでも容易に設置出来るように改造しました。(UNIX上でも動作することを確認していますが、送信先メールアドレスの隠蔽対策以外の利点は、ありません。)以下に機能強化改造内容を示します。
UNIXのSMTPサーバーのsendmailとWindowsのSMTP中継ソフト(SMTP インターフェィス)のBlatj以外に下記のメールソフトに対応させました。
WindowsのBlatjとsendmaneとNet::SMTPモジュールは、Perlがperl.exeとPerlIS.dllのどちらでも動作可能。
メールソフトが出すエラー出力をWebページに表示。(参考サイト:Blatj でメール送信)(後述)
送信元へ写しを送信する場合は、送信者のメールアドレスをabuse@example.comにして、隠蔽。(後述)
動作の検査用にデバックモードとセーフモードを追加。(デバックモードをOFFにすると、オリジナル版の簡易チェックができないようにした。)
OSがWindowsの自宅Webサーバーに設置して、これまでに解っている問題点を整理して対策し、改造を実施しました。以下に問題点を列記します。
$mailprog(メールソフト)が存在しない場合、下記のopen行でエラーが表示されない。close行に下記の太字のスクリプトを入れるとエラーが表示された。(簡易チェックの「http://~~/postmail.cgi?mode=check」を使用すれば発見できますが念のため)
open(MAIL,"| $mailprog -t") || &error("メール送信失敗");
print MAIL "To: $mailto\n";
~
close(MAIL) || &error("メール送信失敗");
●改造版での対策:簡易チェック以外にデバッグモード時に$mailprogが存在するかどうかを検査
if ($debug && $mailprog ne "") {unless (-e $mailprog) {&error("$mailprogが見つかりません。");}}
メールソフトがエラー出力していてもWebページにエラー表示が出ない。(参考サイト:Blatj でメール送信)
●改造版での対策:セーフモード時にメール本文(ヘッダも含む場合もある)をオリジナル版のBlatjのスクリプトの様に一旦、一時ファイル($tmpfile)に書き出し、バッククォーテーションを使用して、プロセスを起動し、メールソフトのエラー出力を受け取り、表示する。
if ($safe || $ENV{'PERLXS'} eq "PerlIS") {my $out = `$mailprog -t < $tmpfile`;}
if ($?) {&error("$out<br><br>コマンド状態=$?",$tmpfile);} 注)$?は、最後に実行されたコマンドのステータス
Perlがperl.exeではなく、PerlIS.dllの場合にopen(MAIL,"| $mailprog -t") の様なパイプ処理ができない。また、メールソフトのsendmaneが使用できない。
●改造版での対策:環境変数$ENV{'PERLXS'}にて、PerlIS.dllかどうかを判断し、セーフモード時と同様に一時ファイル($tmpfile)からのリダイレクト入力処理を行う。
if ($safe || $ENV{'PERLXS'} eq "PerlIS") {my $out = `$mailprog -t < $tmpfile`;}
その他の参考サイト:[NT-TOOLS 00631] Re: perlでBlatJを稼動
利便性を損なわずに迷惑メール(スパムメール)対策を行うには、フォームメールを使用するのが、最も効果的であると考えます。私のWebページの連絡先は、全てフォームメールへのリンクに変更しました。以下の様に変更して、Another HTML-lint gatewayにて、合格点をもらっています。
HTMLヘッダ内のメールアドレスの表記を
<link rev="made" href="mailto:webmaster@example.com" />
より
<link rev="made" href="/cgi/postmail/postmail.html" />
に変更。
HTML本文内のメールアドレスの表記を
<address>作成年月日、更新年月日 作成:<a href="mailto:webmaster@example.com">鷹の巣</a></address>
より
<address>作成年月日、更新年月日 作成:<a href="/cgi/postmail/postmail.html">鷹の巣</a></address>
に変更。
PostMail(フォームメール)の「控えを送る(送信元へ写しを送信)」にチェックを入れても、送信先のメールアドレスを隠蔽していますので、メールアドレス自動収集ロボットや人手でメールアドレスを収集される心配がありません。
●改造版での対策:送信元へ写しを送信する場合は、送信者のメールアドレスをabuse@example.comにして、隠蔽しました。
今までに色んなWebページを読んで、良いと思われる内容を加味して、改造しました。CGIの処理速度は低下する方向ですが、改造内容を以下に示します。
use strictを宣言し、厳格にスクリプトを書きました。(Perl5以降しか動作しません)
CGIから出力するHTMLファイルをW3C勧告HTML 4.01 strict.dtdに対応させ、Another HTML-lint gatewayのサイトにて、現在のところ、Shift_JISのHTML 4.01 strictで、合格点が取れる様に改造しました。
CGIから出力するhttpヘッダに状態コードと文字コードを追記。
print "Status: 200 OK\n";
print "Content-Type: text/html;charset=Shift_JIS\n";
print "\n";
print <<"HTML";
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Language" content="ja">
~
HTML
参考サイト:CGIプログラムの改良案/ヘッダの書き方
PerlがPerlIS.dllではない場合、CGIから出力するURL転送のhttpヘッダに状態コードを追記。
if ($ENV{'PERLXS'} eq "PerlIS") {
print "HTTP/1.0 302 Temporary Redirection\r\n";
} else {
print "Status: 301 Moved Permanently\n";
}
print "Content-type: text/html\n";
print "Location: $back\n";
print "\n";
参考サイト:サイト全体の引越し(URL転送)についての覚書
KENT WEBさんのCGIスクリプト利用規定に同意されましたら、
ダウンロード ⇒ PostMail(フォームメール)改造版のフリーソフト
をダウンロードして、解凍しオリジナル版のpostmailと同様に設置して下さい。下記のaの例の様にWebサーバーのドキュメントルートとCGIの実行パスがローカルパス(実際のハードディスクのパス)と同じ場合は、public_html / postmail のフォルダに解凍したフォルダ内の全ファイル(postmail.cgiとjcode.plと全てのHTMLファイル)を設置することになります。
設置例は、オリジナル版と全く同じです。オリジナル版をすでに設置している場合は、オリジナル版のpostmailというディレクトリをpostmail_orgにリネームして、新たに改造版のpostmailというディレクトリを設置して下さい。
WebサーバーのドキュメントルートとCGIの実行パスがローカルパス(実際のハードディスクのパス)と同じ場合の例)
WebサーバーのドキュメントルートとCGIの実行パスがローカルパス(実際のハードディスクのパス)と異なる場合の例)
PostMail(フォームメール)改造版に対するご質問や不具合について
PostMail(フォームメール)改造版に対するご質問や不具合がございましたら、「鷹の巣」の自宅サーバー掲示板にご投稿願います。このPostMail改造版は、KENT WEBさんとは全く無関係ですから、KENT WEBさんへは、絶対にご質問しないで下さい。
改造版のpostmail.cgiファイル内の「▼基本設定部分」を設定して下さい。(「▼基本設定部分」は、オリジナル版と同じ構成にしています。)赤字部分は、環境に合わせて必ず設定する必要があります。
#!C:/Perl/bin/perl.exe #!/usr/local/bin/perl use strict; use vars qw($DEBUG $SAFE); # 広域変数の定義 (中略) #---------------------------------------------------------------------------- # PostMail(フォームメール)改造版 2005.10.16 作成:鷹の巣 # POST-MAIL v3.3 (2005/11/02) ※改造:鷹の巣 2005.11.05 #------------------------------------------------- # ▼基本設定 #------------------------------------------------- # 文字コード変換ライブラリ require './jcode.pl'; # MIMEエンコードライブラリを使う場合(推奨) # → メールヘッダの全角文字をBASE64変換する機能 # → mimew.plを指定 my $mimew = './mimew.pl'; # メールソフトまでのパス # → sendmailの例 :/usr/lib/sendmail (UNIXのsendmail) # → BlatJの例 :c:\blatj\blatj.exe (Windowsのblatj.exe) # → sendmaneの例 :c:\sendmane\sendmane.exe(Windowsのsendmane.exe)※鷹の巣が追加 # → Net::SMTPモジュールの例 :空白にすること。 ※鷹の巣が追加 my $mailprog = ''; # 初期値は、Net::SMTPモジュールを使用する設定になっています。 # 送信先メールアドレス my $mailto = 'xxx@xxx.xxx'; # 送信前確認 # 0 : no # 1 : yes my $preview = 1; # メールタイトル my $subject = 'フォームメール'; # 本体プログラムURL my $script = './postmail.cgi'; # 確認画面テンプレート my $tmp_conf = './tmp_conf.html'; # 一般エラー画面テンプレート my $tmp_err1 = './tmp_err1.html'; # 入力エラー画面テンプレート my $tmp_err2 = './tmp_err2.html'; # 送信後画面テンプレート my $tmp_thx = './tmp_thx.html'; # 送信後の形態 # 0 : 完了メッセージを出す. # 1 : 戻り先 ($back) へ自動ジャンプさせる. my $reload = 0; # 送信後の戻り先 # → http://から記述する my $back = 'http://www.xxx.xxx/'; # 送信は method=POST 限定 (0=no 1=yes) # → セキュリティ対策 my $postonly = 1; # アラーム色 my $alm_col = "#DD0000"; # ホスト取得方法 # 0 : gethostbyaddr関数を使わない # 1 : gethostbyaddr関数を使う my $gethostbyaddr = 0; # 送信元へ控え (CC) を送る # 0=no 1=yes # *セキュリティ上この機能は推奨しません. # *name="email" のフィールドへの入力が必須となります. # 鷹の巣が改造しています。0にする場合は、postmail.htmlの # 「控えを送る(送信元へ写しを送信)」行を削除して下さい。 my $cc_mail = 1; #------------------------------------------------- # ▼追加設定 ※鷹の巣が追加 #------------------------------------------------- # コマンドラインからの設定値チェックモード # 最初のコマンドラインからの設定値チェック時のみ「1」とし、通常は、「0」にすること!!! my $cmd_data_check = 0; # デバッグモード # 最初の動作試験時のみ「1」とし、運用直前にセキュリティ上「0」にすること!!! # デバッグモードでは、Webサーバーから、簡易チェック # http://~~/postmail.cgi?mode=check # が行えます。また、エラー表示には行番号が表示されます。 $DEBUG = 1; # セーフモード # セーフモードは、Net::SMTPモジュールを使用する時以外で有効となります。 # Perl.exeであっても、PerlIS.dllと同じ動作になります。(送信時に一時ファイルを作成します。) # 最初の動作試験時のみ「1」とし先ずは、確実にメールが送信できることを確認して下さい。 # 但し、UNIXのsendmailを使用する場合には、必ず「0」にして下さい。 # # セーフモードの利点 # 1.メール本文が長い(大きい)場合にコマンドプロンプト画面のバッファサイズの影響を排除できる。 # (コマンドプロンプト画面のタイトルバーで右クリックして、プロパティのレイアウトタブにて、 # 画面のバッファサイズを幅80の高さ300以上にしておかなくても良い。) # 2.SMTPサーバーへの応答が多少速くなり、タイムアウトしにくくなる。 # セーフモードの欠点(普通の用途では、あまり欠点は表面化しないと思います) # 1.一時ファイルの作成と消去を行うので、メール送信頻度が多い場合、ディスクの断片化が生じる。 # 2.速度の遅いディスクの場合に処理速度が多少低下する。 # # Perl.exeの場合、送信成功確認後に「0」にすると、多少動作速度が速くなる場合があります。 # → UNIXのsendmail :$SAFE = 0(必ず「0」にすること) # → WindowsのBlatJ :$SAFE = 1(Perl.exeの場合、「0」にしても良い) # → Windowsのsendmane :$SAFE = 1(Perl.exeの場合、「0」にしても良い) # → Net::SMTPモジュール:$SAFE = 無効。 $SAFE = 1; # メール本文内のタイトル my $title = 'フォームメール'; # フォームメール入力ページ名 my $postmail_html = './postmail.html'; # 送信に使用するSMTPサーバーの設定($mailprog = ''で、Net::SMTPモジュールを使用する場合のみ有効。) # SMTPサーバー名(自宅SMTPサーバーの場合はLAN内のブライベートアドレスや127.0.0.1でも可) # my $mailserver = 'smtp.example.com'; # 接続プロバイダのSMTPサーバーのホスト名 # my $mailserver = '192.0.34.166'; # 接続プロバイダのSMTPサーバーのグローバルIPアドレス # my $mailserver = '192.168.0.2'; # SMTPサーバーのLAN内のブライベートIPアドレス # my $mailserver = '127.0.0.1'; # 自己診断用IPアドレスで自宅SMTPサーバーがWebサーバーと同居 my $mailserver = '127.0.0.1'; #------------------------------------------------- # ▲設定完了 #-------------------------------------------------
フォームメールのWebページから、試験する前に以下の内容を確認して下さい。
改造版のpostmail.cgiファイル内の「▼追加設定部分」の$cmd_data_check = 0を1に設定して、コマンドプロンプト画面から「Perl.exe postmail.cgi」と入力して設定データが正しいことを確認して下さい。
このコマンドプロンプト画面からの検査は、ローカルパスの検査を行います。前出の5.1.aの様にWebサーバーのドキュメントルートとCGIの実行パスがローカルパス(実際のハードディスクのパス)と同じ場合は、すべてOK表示がでなければなりません。
下記の画面では、水色がコマンド入力、緑色が得られた結果の表示、赤色が得られた結果の注目すべき表示としております。
D:\WWW\cgi\postmail>perl Postmail.cgi
コマンドラインチェックモード
□メールソフトパス: ○OK
□jcode.plバージョンチェック: ○OKバージョンOK (v2.13)
□テンプレートチェック
テンプレート ( ./tmp_conf.html ) :○パスOK!
テンプレート ( ./tmp_err1.html ) :○パスOK!
テンプレート ( ./tmp_err2.html ) :○パスOK!
テンプレート ( ./tmp_thx.html ) :○パスOK!
WebサーバーのドキュメントルートとCGIの実行パスが
ローカルパス(実際のハードディスクのパス)と異なる場合は、
パスの検査結果は無視して下さい。
検査結果が良ければ、次に$cmd_data_check = 0で$DEBUG = 1として、
簡易チェック[ http://~~/postmail.cgi?mode=check ]を
実施して下さい。
D:\WWW\cgi\postmail>_
上記の検査で、BlatJとsendmaneの場合、パス名に半角スペースが含まれていれば、エラー表示されます。
これは、WebサーバーのCGIから、BlatJとsendmaneを実行する場合、半角スペース以降が引数と解釈されてしまうからです。
悪い例)C:\Program□Files\sendm098\sendmane.exe -t
C:\Programが実行ファイルで、Files\sendm098\sendmane.exe -tが引数と見なされてしまう。
参考URL:[02/01/22 17:49] Win98で半角空白を含むパスにあるexe, batのCGIがエラーになる
前出の5.1.bの様にWebサーバーのドキュメントルートとCGIの実行パスがローカルパス(実際のハードディスクのパス)と異なる場合は、パスの検査結果は無視して、次のブラウザからの検査を行って下さい。
コマンドプロンプト画面からの検査結果が良ければ、次に$cmd_data_check = 0で、$DEBUG = 1として、Webサーバーを起動しておいて、ブラウザから、簡易チェック[ http://~~/postmail.cgi?mode=check ]を実施して下さい。
注)$DEBUG = 0の場合は、簡易チェックが機能しない様に改造しています。
使用するSMTPサーバーを起動しておいて、コマンドプロンプト画面からメールが送れるかどうかを検査します。BlatJの場合やsendmaneの場合は、以下のリンク先を参考にして、SMTPサーバー中継ソフトを入手してインストールして、中継ソフトの初期設定を済ませておく必要があります。まずは、管理者権限のコマンドプロンプト画面からメールが送信できることを確認して下さい。次にWebサーバーのCGIの実行権限と同じコマンドプロンプト画面からメールが送信できることを確認して下さい。
BlatJの場合は、コマンドプロンプトからメールを送るを参照。
sendmaneの場合は、Windows自宅サーバー用フォームメールの設定例(sendmane.exe編)を参照。
Net::SMTPモジュールの場合は、NETsmtpMail1.pl.txt - メール送信Perlスクリプトその1(Net::SMTPモジュール版)を使用。
改造版のpostmail.cgiファイル内の「▼追加設定部分」の設定を$cmd_data_check = 0,$DEBUG = 1,$SAFE = 1とし、$mailserver = '127.0.0.1'の設定を済ませて、フォームメールのWebページから、メールの送信試験を行います。エラー表示されずにメールが送信できることを確認します。また、SMTPサーバーのログに記録されていることも確認して下さい。
メールの送信試験が成功したら、前項の設定を$DEBUG = 0にして、エラー行の表示が出ないようにします。$SAFE = 0として、フォームメールのWebページから、メールの送信が著しく速くなるようであれば、$SAFE = 0とします。
以上です。ご成功を祈ります。