JavaScript:excanvasを使ってWebページに画像を表示する

【概要】
JavaScriptでWeb上にグラフィックを描く技術に「Canvas」があります。
Canvasは現在IE9,FireFox,Google Chrome,Safariなどで実装されていますが,IEは8以前では実装されていません。
IEの8以前でCanvasの機能を使うために,Googleから「excanvas」というライブラリが公開されています。
今回のエントリでは,excanvasを使って画像データを表示させたときに嵌ったところを紹介します。

●excanvasの参照
嵌ったところではありませんが,excanvasはjavascriptで書かれた外部ファイルなので,HTMLのheader内で参照する必要があります。
このとき,ネットで見つかるサンプルの多くは以下のようなコードになっています。

<!--[if IE]>
<script type="text/javascript" src="js/excanvas.min.js"></script>
<![endif]-->

しかしながら,canvasはIE9で実装されているので,IE9ではexcanvasは不要です。
なので次のように書くべきかと思います。

<!--[if lt IE 9]>
<script type="text/javascript" src="js/excanvas.min.js"></script>
<![endif]-->

●画像の読み込み
画像データはImageクラスで読み込んで,読み込みが完了してから描画を行います。
この処理でよく見かけるサンプルコードは以下のようなものです。

var image = new Image();
image.src = 'path/filename.jpeg';
image.onload = function () {
  // 画像描画処理.
};

このコードは,画像ファイルを読み込んで,読み込みが完了したらonloadの中の画像描画処理が実行される,という動作を意図したものです。Canvasの画像描画は事前に画像データの読み込みが完了していなければならないので,このような処理になります。
このコードはブラウザによってはうまく動作しますが,Imageクラスの使用方法としては誤りのようです。少なくともIE8ではonloadは呼ばれませんでした。
誤っている点ですが,Imageクラスではsrcにパスを指定するより前にonloadを設定しなければならないようです。正しいコードは以下になります。

var image = new Image();
image.onload = function () {
  // 画像描画処理.
};
image.src = 'path/filename.jpeg';

●同一イメージファイルを何度も読み込む場合
IE8以前でImageクラスを使った場合,一度画像データを読み込んでキャッシュされた状態で同じ画像ファイルを読み込もうとすると,onloadの処理が呼ばれず画像描画処理が実行されない問題があるようです。
この問題の対処方法としてよく見かけるのは,ファイルパスの最後に「?+ランダムな値」を付加して同一のファイルを毎度異なるファイル名で読み込む方法です。
他の方法では,試してはいませんが,jQueryのempty()関数はキャッシュも削除するようなので,これで対処できる可能性があります。

●canvasエレメントをcreateElementで作った場合の問題
canvasエレメントをdocument.createElementで生成した場合,excanvasの環境ではcanvasエレメントとして初期化されず,canvasエレメントにあるはずのgetContext関数が存在しない状態になってしまいます。このような場合はexcanvasの初期化関数を使って明示的に初期化する必要があります。canvasタグをHTMLファイルに直接書いた場合は,初期化コードが自動的に実行されるので問題は起きません。

var canvas = document.createElement('canvas');
if (typeof G_vmlCanvasManager !== 'undefined') {
  canvas = G_vmlCanvasManager.initElement(canvas);
}

なお,G_vmlCanvasManager.initElementは引数のcanvasエレメントが初期化済みかチェックするので,すでに初期化されたエレメントを渡しても問題ありません。また,G_vmlCanvasManagerはexcanvas固有のクラスなので,Canvasが実装されていてexcanvasを使用しない環境でこのコードを実行しても,G_vmlCanvasManagerの存在確認をすれば問題ありません。

Imageクラスの問題とcanvasエレメントの問題に対処したコードは以下のようになります(一部jQueryを使っています)。

var parent = document.getElementById('parentElementId');
$(parent).empty();

var image = new Image();
image.onload = function () {
  var canvas = document.createElement('canvas');
  $(parent).append($(canvas).attr('id','canvasElementId'));

  if (typeof G_vmlCanvasManager !== 'undefined') {
    canvas = G_vmlCanvasManager.initElement(canvas);
  }
  if (canvas.getContext) {
    var context = canvas.getContext('2d');
    context.drawImage(image, 0, 0, image.width, image.height);
  }
};
image.src = 'path/filename.jpeg';

■参考URL
Googleのexcanvas配布元:http://excanvas.sourceforge.net/
HTML5.jpのCanvasドキュメント:http://www.html5.jp/canvas/index.html
mozillaのCanvasドキュメント:https://developer.mozilla.org/ja/Canvas_tutorial/Using_images

■関連書籍をAmazonで検索:[Canvas]
HTML5 Canvas

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ プログラム・プログラマへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


ソニーストアウェーブミュージックシステム - サウンドリンク

| | トラックバック (0)

C言語:TRUEとFALSEの値

【課題】
以前どこかで次のようなCのコードを見たことがあります。

if (flag == TRUE) {
  処理1
}
else if (flag == FALSE) {
  処理2
}
else {
  処理3
}

ここで「処理3」は実行されることがあるのか?というのが今回のエントリのテーマです。

まず最初に,C言語におけるbooleanについての確認です。
Cのbooleanは2つの異なる定義があります。

●booleanの定義その1:条件分岐の判定
if文,for文,while文など,値がtrueかfalseか判定して条件分岐を行う場合のtrue/falseの値については,Cの解説書に書かれていてよく知られています。false=0,true=0以外です。1,2,3…及び-1,-2,-3…はすべてtrueです。

●booleanの定義その2:比較演算子の演算結果
比較演算子の演算結果はTRUE/FALSEのどちらかになりますが,Cでは元々boolean型がなく,このTRUE/FALSEには数値が割り当てられます。
この数値の具体的な値を確認するには,たとえば以下のようなコードで確認できます。

int flag = (int)(a == b);

aとbに値を設定して,この変数flagにどのような値が入るかprintfで表示させるなどして確認してみましょう。

aとbが等しい場合,これは値が「1」になるはずです。「TRUE」の値は「1」です。
aとbが等しくない場合,これは値が「0」になるはずです。「FALSE」の値は「0」です。


定義その2より,最初のコードは以下のコードと同等です。

if (flag == 1) {
  処理1
}
else if (flag == 0) {
  処理2
}
else {
  処理3
}
ここでflagの値が0,1以外の値であった場合は処理3が実行されることがわかります。 結論としては処理3が実行されることはありうる,ということになります。

定義その1で条件判定する場合は,結局のところ以下の書き方になるかと思います。

if (flag) {
  処理1
}
else {
  処理2
}

どうしてもTRUE/FALSEを使いたい,という場合は以下のように書くことになるかと思います。

if (flag != FALSE) {
  処理1
}
else {
  処理2
}


■関連書籍をAmazonで検索:[C言語]
C実践プログラミング 第3版

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ プログラム・プログラマへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
ioPLAZA【アイ・オー・データ直販サイト】

| | トラックバック (0)

Mac OS X Server:ローカルユーザのドメイン詐称をチェックする

【概要】
メールサーバがメールを受け取ったときに,送信元を身元確認する「ドメイン認証」が普及しつつありますが,逆に自ドメインからメールを送信するときにドメイン詐称をチェックする仕組みを組み込むことについて考えてみます。

この仕組みは,スパムメール阻止とは多分あまり関係ありません。
関係あるとしたら,メールサーバが乗っ取られたり,身内にスパム発信元がいたりしたときに,スパムメールを中継するのを阻止する防波堤になるかもしれない,ということくらいです。
この仕組みは,自ドメインからメールを送信する正規アカウントユーザに対して,他所のドメインのアドレスでメールを出す行為を禁じるのが目的になります。
これには以下のような効果があると思います。

  • ドメイン認証の普及により,これからは他所のドメインでメールを出せなくなっていくが,このルールを違反メールを阻止することで周知徹底させる。
  • ドメイン認証を送信側が行う形になるので,メールの送り先でドメイン認証によりメールをスパム扱いされることがなくなる。
このエントリでは,送信元アドレスの中のドメイン部分のみチェックして,自ドメイン(または特定のドメイン)でなければ送信元のメールクライアントにエラーを返すようPostfixの設定を行ってみることにします。

【設定の概要】
メールサーバがクライアントから送信メールを受け取るとき,SMTPプロトコルのMAIL FROMにて,送信元のメールアドレスを受け取ります。このメールアドレスのドメイン部分が自ドメインでなかったら,クライアントに対してエラーを返してメール受信を拒否するように転送ルールを設定します。

MAIL FROMに対するチェックの設定は,Postfixでは設定パラメータ「smtpd_sender_restrictions」で行うことになっています。
ここではOP25Bに対応していることを前提に説明します。OP25B対応していた場合,設定は「/etc/postfix/master.cf」で行いますが,master.cfではパラメータ値の定義でスペースを含めた定義を行うことができないので,設定を「/etc/postfix/main.cf」で定義してmaster.cfで参照するようにします。

【設定手順】
まず最初に自ドメインを許可する設定ファイルを作成します。
ディレクトリ「/etc/postfix/」にて,例として「permit_mydomain」というファイル名で以下の内容のテキストファイルを作成します。

設定ファイル記述例:permit_mydomain
example.co.jp  OK

このファイルをDBファイルに変換します。ターミナル上で以下のようにコマンド実行します。
sudo postmap hash:permit_mydomain

このコマンドを実行した結果,「permit_mydomain.db」というファイルがカレントディレクトリに作られます。
このファイルが設定ファイルで記述したとおりに判定するかどうかを以下のコマンドで確認します。
sudo postmap -q example.co.jp hash:permit_mydomain

実行結果が「OK」と返ってくれば,「example.co.jp」の値が「OK」のデータがDBファイルに格納されています。

次に,この「permit_mydomain.db」を参照する定義を「main.cf」にユーザ定義パラメータとして記述します。

例:main.cfでのユーザ定義パラメータの定義
check_sender_mydomain = check_sender_access hash:/etc/postfix/permit_mydomain

※この定義の記述で,拡張子「.db」はなくても良いようです。

次に,「/etc/postfix/master.cf」ファイルを編集してユーザ定義パラメータをsubmissionポートのMAIL FROMで適用されるように設定します。。
まず,master.cfでのsubmissionの設定が以下のようになっているとします。
※master.cfで定義されていないパラメータはmain.cfでの定義が適用されます。

例:master.cfでのsubmissionの定義
submission inet n  -  n  -  n  smtpd
  -o smtpd_etrn_restriction=reject
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_helo_restrictions=permit
  -o smtpd_sender_restrictions=reject_non_fqdn_sender,permit
  -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,permit_sasl_authenticated,reject

これにmain.cfで定義したユーザ定義パラメータ「check_sender_mydomain」を追加しますが,定義済みのパラメータを参照する場合はパラメータ名を「${パラメータ名}」とすることで参照できます。パラメータを追記した結果は以下のようになります。
submission inet n  -  n  -  n  smtpd
  -o smtpd_etrn_restriction=reject
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o smtpd_helo_restrictions=permit
  -o smtpd_sender_restrictions=reject_non_fqdn_sender,{$check_sender_mydomain},reject
  -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,permit_sasl_authenticated,reject
注)「-o」の前のスペースは,上の行からの継続を意味しますので,削除してはいけません。

●追加した設定の説明
ユーザ定義パラメータの定義により,差出人のアドレスが自ドメインであれば「OK」と判定されて送信されます。
そうでなければ次の「reject」が適用されるので,自ドメインでない差出人アドレスはエラーになります。

以上の設定が終わったら,ターミナル上で「sudo postfix check」を実行してエラーがないか確認し,「sudo postfix reload」を実行して修正内容を実行環境に反映します。

以上で設定は完了です。自分宛メールなどで設定が有効になっているか確認してみましょう。


■関連情報
Postfix 2.3日本語ドキュメント:[基本設定][main.cf設定パラメータ][master.cf]
Appleサポート:Mac OS X Server 10.4送信メールを設定する
Apple Server 製品ドキュメント:メールサービスの管理[PDF]

■関連書籍をAmazonで検索:[Postfix][Mac OS X Server]
Postfix実用ガイド

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


新生活応援セールウェーブミュージックシステム - サウンドリンク

| | トラックバック (0)

Mac OS X Server:メールサーバにドメイン認証(SPF)を設定する

【概要】
メールサーバMTA)またはメールクライアントがメールをMTAへ送信する際に,メール転送プロトコル(SMTP)に従いメール送信者のアドレスを送信先のサーバに知らせますが,この送信者アドレスが正当なものであるかを確認する仕組みがSMTPには組み込まれていません。すなわちメール送信者のアドレスは詐称が可能です。

この問題への対処として,メールを受け取ったサーバが,送信元サーバが正当な送信サーバかどうかを確認する「送信ドメイン認証(SPFなど)」が普及しつつあるようです。SPFは,送信側がメールを送信するサーバのアドレスを,そのドメインのDNSサーバで公表することで,メールを送信したのが正当なサーバかどうかを受信側が確認することを可能にするものです。
SPFはドメインとメールサーバを関連付けるものなので,ドメインの詐称を検知することはできますが,アカウントの詐称は検知することができません。

このエントリでは,メール送信側がDNSに設定するSPFの書式と設定方法について解説します。
このエントリは,メール受信側がSPFレコードをどのように利用するかについては対象外です。

【Hellow World:SPFをDNSに設定してみる】
最初に「何も判定しない」SPFレコードをDNSに記述して,これを公開してみることにします。SPFの公開がうまくいったのが確認できたら,必要な判定を随時追加修正すればいいでしょう。

例 1:何も判定しないSPF定義
v=spf1 ?all
例1の定義のうち,最初の「v=spf1」は,以下に続くテキストがSPFの定義であることを表します。「?all」は,すべてのIPアドレスの判定を保留にすることを表します。

SPF定義はBIND(DNSサーバ)のゾーンファイルに設定します。ゾーンファイルが保存されているディレクトリパスは,BINDの環境設定ファイル「/etc/named.conf」にて「option」セクションの「directory」に定義されています。Mac OS X Serverの場合,デフォルトのままならゾーンファイルは「/var/named/」にあります。
ドメイン名が「example.co.jp」の場合,ゾーンファイルのファイル名は「example.co.jp.zone」になります。このファイルをviなどのテキストエディタで開き,上記SPF定義を以下のように追加します。

example.co.jp. IN TXT "v=sft1 ?all"
ドメイン名「example.co.jp.」の最後にピリオドを付けるのを忘れないでください。

この行を追加して保存した後で,DNSを再起動します。
再起動をコマンドライン上で行うには,「named restart」を実行します。
Mac OS X Serverの場合は,「サーバ管理」ツールを起動して「コンピュータとサービス」から「DNS」を選んで「サービスを停止」ボタンを押し,停止したら「サービスを起動」ボタンを押すことにより再起動することができます。

以上の操作によりSPFの設定を行った後で,これが上位ドメインに反映されているかを確認します。

●Windows XPから確認する場合:
DOSプロンプトにて以下のようにコマンド実行します。

nslookup -query=txt example.co.jp

●LinuxやMac OS XなどUNIX系OSから確認する場合:
ターミナルシェルより以下のようにコマンド実行します。
dig example.co.jp txt

●Mac OS Xから「ネットワークユーティリティ」で確認する:
Mac OS Xでは「ネットワークユーティリティ」というアプリケーションからも確認できます。このツールは「dig」コマンドにGUIを被せたものです。
「ネットワークユーティリティ」はフォルダ「アプリケーション」→「ユーティリティ」に入っています。
使用方法は,ツールを起動して「Lookup」タブを選び,アドレス入力欄にドメインまたはDNSサーバのIPアドレスを入力,「ルックアップする情報」メニューで「テキスト情報」を指定して「Lookup」ボタンを押すと,下のテキストエリアに結果が出力されます。

※SPF設定後の注意:Mac OS X Server(10.4.x)でSPFを設定し「サーバ管理」ツールを使ってDNSの設定を更新すると,サーバ管理がSPF定義をエラーと解釈して勝手に削除してしまいます。SPF定義を記述した後はサーバ管理ツールはDNSの起動・停止のみ行い,DNS定義の変更はサーバ管理ツールでは行わないようにしてください。

【SPFによるメール送信元サーバの指定】
前項で設定したSPFの定義は,送信元サーバの指定をまったく行わないものでした。本項より送信元サーバを指定する方法を順次説明します。

●正当なメールサーバのIPアドレスを列挙する
例 2:正当なメールサーバのIPアドレスの列挙
v=spf1 +ip4:1.2.3.4 +ip4:1.2.3.5 +ip4:1.2.3.6 -all
「v=spf1」に続く「+ip4:IPアドレス」のリストは,DNSサーバが管理するドメインのメールを送信するメールサーバ(MTA)のIPアドレスのリストです。
「ip4:IPアドレス」はIPv4形式のIPアドレスによるサーバの指定です。アドレスの前の「+」は指定したサーバがメールの送信元として正当なサーバであることを表します。
末尾の「-all」について,「all」はそれより前に列挙したIPアドレスのどれにも該当しない全てのアドレスの判定を指定します。allの前に「-」を付与した場合,IPアドレスに該当しないアドレスは,メールの受け取りを拒否すべきであることを表します。
注意:IPv4のアドレスの指定でよくある誤りは「ipv4:」と記述するケースです。正しくは「ip4:」になります。

●IPアドレスとサブネットマスクで指定する
例 3:IPアドレスとサブネットマスクによる指定
v=spf1 +ip4:1.2.3.0/24 -all
IPアドレスの指定方法として,サブネットマスク(プレフィックス長)を付加して「ip4:IPアドレス/プレフィックス長」としてIPアドレスの範囲指定を行うこともできます。

●IPv6アドレスで指定する
例 4:IPv6アドレスによる指定
v=spf1 +ip6:1234:5678:9abc:def0:1234:5678:9abc:def0 -all
v=spf1 +ip6:1234:5678:9abc:def0:1234:5678:9abc:def0/96 -all
IPアドレスとしてIPv6のアドレスを「+ip6:IPアドレス」で指定することもできます。また,これにサブネットマスク(プレフィックス長)を付加して「ip6:IPアドレス/プレフィックス長」でIPアドレスの範囲指定を行うこともできます。

●メールを送信しないサーバを指定する
例 5:メールを送信しないサーバの指定
v=spf1 +ip4:1.2.3.4 -ip4:2.3.4.5 ~all
IPアドレスの前に「-」を付けた場合は,指定したIPアドレスからこのドメインのメールは送信されないことを表します。
ただし,最後が「-all」ならば,指定したIPアドレスはこの「-all」で判定されるので,指定は無意味です。IPアドレスで「-」を指定する場合に意味があるのは,allが「-」以外である場合です。
allには「-」のほか,「~」(チルダ),「?」を付与することができます。「~」は「弱い失敗」,「?」は「ニュートラル」を表します(詳細は次項)。
allに「+」を指定することも可能です。この場合,「-」を付与したIPアドレスを除くすべてのアドレスが正当なアドレス,という指定になります。
例5では,IPアドレス「1.2.3.4」は正当なアドレス,「2.3.4.5」は不正なアドレス,それ以外は「弱い失敗」を指定しています。

●このドメインのメールアドレスは存在しないことを表明する
例 6:送信用メールサーバは存在しない
v=spf1 -all
サーバ指定で「-all」とだけ書いた場合,このドメインからのメールはすべて受信拒否しなければならないことを表します。この指定は,このドメインのメールアドレスは存在しないことを表しています。

【サーバ指定について】
この項では,サーバを「正当」または「不当」と判断するための決まりごとについて説明します。

●アドレス及び「all」に付与する記号(限定子)について
例 7:「弱い失敗(Soft Fail)」「ニュートラル」
v=spf1 +ip4:1.2.3.4 ~all
v=spf1 +ip4:1.2.3.4 ?all
IPアドレス及び「all」の前に付与する「+」「-」について,「+」は指定したサーバが正当なサーバ,「-」は不当なサーバであることを表しますが,これ以外の指定に「~」(チルダ)と「?」があります。「~」は「弱い失敗(Soft Fail)」を表します。これに該当するサーバは,正当なサーバとは見なさないが,メールを受け取ってもかまわないことを表します。実際の実装ではSoft Failに対してメールの受信側は受信したメールのヘッダにスパム情報を挿入して受け取るようです。「?」は「ニュートラル」を表し,「+」と同じ扱いになります。「?」は本来「-」や「~」であるべきものを一時的に「+」と同じ扱いにする場合に指定します。

●評価順について
例 8:指定した範囲のアドレスのうち特定のアドレスだけ正当なアドレスに指定する
v=spf1 +ip4:1.2.3.4 -ip4:1.2.3.0/24 ~all
SPFレコードのアドレス指定を評価するときは,アドレス指定の列挙の最初から順番に比較していって,一致したところで評価が確定し,これ以降の評価は行いません。
例5の場合,IPアドレス「1.2.3.4」は正常受け取り,「1.2.3.4」を除く「1.2.3.0/24」は受け取り拒否,それ以外は「弱い失敗」で受け取るよう指定しています。ここで「1.2.3.4」は「1.2.3.0/24」に含まれますが,先に指定している「1.2.3.4」が優先されます。
例6の指定方法は,「1.2.3.0/24が自分達に割り振られているすべてのIPアドレスで,そのうち1.2.3.4をメールサーバに使用している」ということを表す場合に使えます。
「all」の指定が出現したところですべてのアドレスの評価が確定するので,allの後ろにアドレス指定を記述しても評価されません。そのためallはSPFレコードの末尾に記述します。
末尾にallなどがなく,評価が確定せずに終わった場合,評価は「ニュートラル(末尾が「?all」の場合と同義)」になるようです。

●サーバ指定で「+」など(限定子)を省略した場合の解釈
例 9:サーバ指定で「+」を省略
v=spf1 ip4:1.2.3.4 -ip4:2.3.4.5 ~all
アドレス指定及び「all」にて,先頭の「+」「-」「~」などの指定を省略した場合は「+」が指定されたものと解釈されます。例9は例2と同じ指定になります。

【アドレスを直接指定しないサーバ指定】
前項まではSPFレコードの中でIPアドレスを直接指定していましたが,本項では当該SPFレコード以外の場所で記述されたアドレスを指定する方法について説明します。

●DNSの「A」または「AAAA」レコードの内容を指定する
例 9:DNSのAまたはAAAAレコードに記述されたアドレスで判定する
v=spf1 +a -all
v=spf1 +a:example.co.jp -all
v=spf1 +a/24 -all
v=spf1 +a:example.co.jp/24 -all
・「a」
メール送信元のドメイン名からIPアドレスを正引きし,得られたIPアドレス(IPv4,IPv6共)のなかに送信元アドレスが含まれているかどうかを判定します。
・「a:example.co.jp」
引数のドメイン名でIPアドレスを正引きし,得られたIPアドレスのなかに送信元アドレスが含まれているかどうかを判定します。
・サブネットマスク指定
アドレス指定に「/プレフィックス長」を付加することで,サブネットマスクによるIPアドレスの範囲指定ができます。
※これらの指定は,A及びAAAAレコードからIPアドレスに展開するためのDNS参照が発生します。

●DNSの「mx」レコードの内容を指定する
例10:DNSのMXレコードに記述されたメールサーバアドレスで判定する
v=spf1 +mx -all
v=spf1 +mx:example.co.jp -all
v=spf1 +mx/24 -all
v=spf1 +mx:example.co.jp/24 -all
・「mx」
メール送信元ドメイン名のMXレコードをDNSで問い合わせ,取得したホスト名のIPアドレスを再度問い合わせて送信元IPアドレスと一致するものがあるかを判定します。DoS攻撃防止のため,MX問い合わせで複数のサーバ名が得られた場合は最大10件までで判定を行います。
この機構を指定する場合はDNSでMX及びAレコードが定義されている必要があります。
・「mx:example.co.jp」
指定したドメイン(example.co.jp)のMXレコードをDNSで問い合わせ,取得したホスト名のIPアドレスを再度問い合わせて送信元IPアドレスと一致するものがあるかを判定します。MX問い合わせで複数のサーバ名が得られた場合は最大10件までで判定を行います。
・サブネットマスク指定
アドレス指定に「/プレフィックス長」を付加することで,サブネットマスクによるIPアドレスの範囲指定ができます。
※これらの指定は,MXレコードからIPアドレスに展開するためのDNS参照が最大10件発生する可能性があります。

●DNSの逆引きの結果で判定する
例11:DNSでIPアドレスを逆引きできるかどうかで判定する
v=spf1 +ptr -all
v=spf1 +ptr:example.co.jp -all
・「ptr」
メール送信元のIPアドレスを逆引きして得られたホスト名に対して,正引きしてIPアドレスを取得し,得られたIPアドレスに送信元アドレスが含まれているかを判定します。DoS攻撃防止のため,逆引きで複数のサーバ名が得られた場合は最大10件までで判定を行います。
・「ptr:example.co.jp」
メール送信元のIPアドレスを逆引きして得られたホスト名に,引数のドメイン名と一致するものがあるかどうかを判定します。
※これらの指定は,ドメインからIPアドレスに展開するためのDNS参照が最大10件発生する可能性があります。

●指定したドメインの存在のみ判定する
例12:Aレコードの存在のみで判定する
v=spf1 +exists:example.co.jp -all
指定したドメインのAレコードが存在するかどうかで判定します。そのAレコードのIPアドレスの内容は参照しません。例11ではDNSでexample.co.jpのAレコードが見つかれば送信ドメインは正当なものと見なします。
この指定はマクロと組み合わせることで,メールブラックリストの問い合わせを作ることができるようです。

●別ドメインのSPF定義を参照する
例13:別ドメインのSPFを参照する
v=spf1 redirect=example.com
v=spf1 include:example.com -all
「redirect=ドメイン名」と指定すると,指定したドメインのSPFレコードに判定処理を引き継ぎます。redirectは,同一DNSサーバで複数のドメインを管理している場合に共通のSPFレコードで判定を行う使い方を想定しています。redirectはSPFの記述の最後に「all」の代わりに記述するのが一般的です。

※「redirect」と「ドメイン名」の間は「:(コロン)」ではなく「=(イコール)」でつなぎます。

「include:ドメイン名」を指定すると,指定したドメインのSPFレコードを取得し,取得したSPFレコードで送信サーバのアドレスが正当かどうかのみをチェックします。ここで正当(Pass)以外の結果のときは判定が確定しないことに注意してください。上記の例ではinclude先での判定が正当以外の結果だった場合は末尾の「-all」が最終的な判定になります。

■関連情報
SPFの解説記事
間違いから学ぶSPFレコードの正しい書き方
SPFレコード・テストサイト
NTT docomo 送信ドメイン認証について
EZwebへメール送信する際の注意事項
@IT解説記事
RFC4408(SPF)日本語訳

■関連書籍をAmazonで検索:[BIND/DNS][Mac OS X Server]
改訂新版 BIND9によるDNSサーバ構築 (エッセンシャルソフトウェアガイドブック)

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


ソニーストアシマンテックストアioPLAZA【アイ・オー・データ直販サイト】

| | トラックバック (0)

SEO:ブログ記事を検索結果から消さないために

当ブログを始めたのは2008年1月からですが,ブログのアクセス解析を見ると,最初は少なかったアクセス数が3月頃に増え始めて3月後半から4月前半にピークを迎えました(最も多い日で訪問者60,アクセス数90)。しかしその後がっくり落ちて,1日のアクセス数が5件にも届かなくなってしまっていました。ブログの更新頻度が低く記事の数も少なかったというのもありますが,それにしても落差がありすぎるのはなんでだろうと思っていろいろ調べてみたところ,次のようなことがわかりました。

  • 当ブログの訪問者のほとんどはGoogle検索からやってくる。
  • ブログの場合,Googleの検索結果にはGoogleブログ検索へのPingでも載るが,Pingで載った場合は一定のアクセスがある記事を除き数週間程度で検索結果から消えてしまうようだ。
  • Googleの検索からは数週間で消えるが,「Googleブログ検索」からは検索可能。しかしそもそもGoogleブログ検索からやってくる人はほとんどいない。
  • 記事のリンクがココログの「ココフラッシュ」や「瞬!コレ」などに載ることがあり,これらのページがGoogleにインデックスされてそこからアクセスしてくる人がまれにいる。しかし「ココフラッシュ」は同一カテゴリの記事の投稿があれば古いものから消えていくし,「瞬!コレ」への登録は全く制御できないので当てにはできない。
上記のうち,アップしてから一定期間が経過したブログ記事がGoogleの検索結果から消えてしまっているのを発見したときは衝撃を受けました。誰も興味を持たない話題をアップしているとか,検索結果の順位が低くてアクセス数が少ないならまだ納得がいきますが,検索結果から消えてしまっては…そりゃ誰も来ませんね。ということで,この記事ではブログ記事が検索サイトのインデックスから消えないようにするためにこちらでやってみたこと,まだやってないけど調べたことなどを紹介いたします。

ブログのURLを検索サイトに登録する
検索サイトにURLを登録することで,検索サイトにウェブクローラが巡回してほしいサイトを知らせることができます。各検索サイトへは以下から登録できます。但し登録を行ったサイトが検索結果に表示されることは保障はされていません。
 Google Web登録登録確認 ディレクトリ登録
 Yahoo! Web登録登録確認解説カテゴリ登録
 bing Web登録 解説 
goo及びBIGLOBEはGoogleのインデックスを使っているそうです。(出典1)(出典2

ウエブマスターツールに登録する
GoogleウエブマスターツールではGoogleに収集された自分のサイトについて,ウェブクロールの際に発生したエラー一覧,Google検索で自分のサイトが表示されたときの検索語一覧,インデックス情報のモニタ,robots.txtの文法チェック,サイトマップ(後述)の登録更新,削除したWebページのGoogleインデックスからのURL削除,グーグル八分になったときのサイトの再審査リクエストなどを行うことができます。
とりあえず(もっていなければ)Googleアカウントを取得して,ウエブマスターツールに自分のブログを登録してみることをお勧めします。
なお,ウェブマスターツールのすべての機能を使うには,ブログのHTMLファイルに認証コードを埋め込むか,トップディレクトリに認証ファイルを置く必要があります。
※ココログの場合,HTMLファイルを直接編集できるユーザ種別は「プロ」だけです。
Yahoo!でウェブマスターツールに相当するのが「サイトエクスプローラ」になるかと思います。サイトマップの登録もここから行います。こちらにもYahoo! JAPAN IDを取得して登録してみることをお勧めします。
Googleウェブマスターツールログインヘルプ
Yahoo!サイトエクスプローラログインヘルプ

サイトマップを作る
ウェブクローラが参照するためのTXTまたはXML形式のサイトマップを用意することで,ブログの個別の記事をウェブクローラが見つけやすくなります。ブログでサイトマップを利用するには,ブログ管理者がトップディレクトリへファイルをアップロードできる機能が提供されている必要があります。
サイトマップのファイル名は任意です。1つのサイトで複数のサイトマップを持つことができます。サイトマップは他のサイトや上位ディレクトリのURLを記述できません。

TXT形式のサイトマップは,テキストファイルにサイトを構成するページのURLを「http://」を含めて1URL1行で記述します。
XML形式のサイトマップは,各ページのURLのほかにオプションで,最終更新日(lastmod),更新頻度(changefreq),ページの優先度(priority)を記述できます。
XML形式のサイトマップの書き方についての詳細は,[Google][Yahoo!][本家sitemaps.org]を参照してください。

例:当ブログのサイトマップ(テキスト形式)
http://endeavour.cocolog-nifty.com/developer_room/index.html
http://endeavour.cocolog-nifty.com/about.html
http://endeavour.cocolog-nifty.com/developer_room/cat8156880/index.html
http://endeavour.cocolog-nifty.com/developer_room/cat8157219/index.html

(略)
注:当ブログのサイトマップは実際にはXML形式です。

例:当ブログのサイトマップ(XML形式)
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">

<url>
<loc>http://endeavour.cocolog-nifty.com/developer_room/index.html</loc>
<changefreq>weekly</changefreq>
<priority>0.3</priority>
</url>
(略)
</urlset>
作成したサイトマップをブログのトップディレクトリに保存して,検索サイトにサイトマップの登録更新を伝えます。その方法は,
  • Googleの「ウェブマスターツール」やYahoo!の「サイトエクスプローラ」でサイトマップを登録または更新する。(「サイトエクスプローラ」では「フィード」にサイトマップを登録する。)
  • 「robots.txt」に「Sitemap: http://サイトマップのURL」行を追加する。robots.txtは通常ウェブクローラに対して巡回してほしくないディレクトリパスを指定するために使いますが,サイトマップのURLを指定することもできるようになったようです。
例:上記XML形式のサイトマップを指定した当ブログのrobots.txt
User-Agent: *
Sitemap: http://endeavour.cocolog-nifty.com/endeavour_sitemap.xml

注:ココログに「Googleサイトマップ」という機能があるのを最近見つけました。
当方では自力でサイトマップを作ってしまったのでこの機能をOFFにしていますが,この機能をONにすればサイトマップの作成はGoogleに対しては必要ないかもしれません。但しYahoo!に対しては別途サイトマップの送信等の処理が必要かと思われます。ココログの「Googleサイトマップ」の設定は「ブログ」→「設定」→「更新通知」で行います。

メタ情報を設定する
ココログでは各HTMLファイルにkeywordsとdescriptionのメタタグを追加するようになりました。
ここで追加するメタタグのうち,descriptionはブログのサブタイトルがデフォルトで設定されますが,「ブログ」→「設定」→「更新通知」の「meta情報の生成」で変更することができます。
このメタタグの効果はまだよくわかりませんが,すべての記事に同じメタタグが挿入されてしまい,記事ごとの説明文を設定できないのが少々困りものです。(かといって,できたらできたで面倒くさい!となってしまいますが…笑)Googleウェブマスターツールでも「重複description」の警告が大量に出てしまいます。

ブログランキングサイトへの登録
にほんブログ村 IT技術ブログへとか人気ブログランキングへとかのことです。前者の「にほんブログ村」の場合,「トラコミュ」というブログ記事のトラックバックでコミュニティを構成する機能があり,アクセス数に左右されない外部リンクが確保できます。

これまでの成果
サイトマップの登録を8月に行ったところ,検索結果から消える現象にかなりの改善が見られました。また,これに伴いアクセス数も回復しつつあります。
ただし新たな問題も見つかっています。それは,サイト内でリンクを張っていた場合にその中の代表ページをGoogleが判断してそれ以外のページをインデックスから削っていると思われる問題です。これはこのブログの記事では「Java:CSVパーサを作る」の「その1~3」のうち,検索結果に表示されるのが「その2」だけ,といった形で現れてきています。

…あとはこのブログの記事の質と量の問題でしょうか。

■関連書籍をAmazonで検索:[SEO][Google][Yahoo!]
SEOを強化する技術 エンジニアが内側から支えるサイト設計・構築術

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ Webサイト構築へ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
アフィリエイトならリンクシェア

| | トラックバック (0)

Mac OS X Server:PostfixでOP25B対応

【OP25Bとは】
Outbound Port 25 Blockingの略です。ISP(インターネットサービスプロバイダ)各社が,自ドメインの利用者がユーザ回線を使ってインターネットへスパムメールを送信するのを阻止するために導入しているもので,プロバイダのユーザ回線からインターネットへ出て行く外向きのTCP25番ポートへの接続を塞いでしまう,というものです。

【OP25Bの影響】
OP25BはSMTPに使う25番ポートを塞ぐので,POPIMAPには全く影響ありません。
OP25Bはユーザ回線に対して実施されるもので,固定IPの回線には影響ありません。
OP25Bは内から外へ出て行く25番ポートへの接続を阻止するので,外から内へ入ってくる接続には影響しません(外から内へ入ってくる25番ポートへの接続を阻止するのは「IP25B」)。
使用しているISPがOP25Bを導入したとき,ユーザへの影響には以下の3つのケースがあります。

  1. メールクライアントからプロバイダが提供する送信用SMTPサーバを使ってメール送信する場合,ISPのメールサーバはインターネットに出て行く手前にいるため接続はOP25Bに阻止されずにこれまでどおり25番ポートを使えることが多く(プロバイダによる),この場合は特に影響ありません。
  2. メールクライアントからインターネットの向こう側にいる送信用SMTPサーバを使ってメール送信しようとした場合(独自メールサーバのアカウントからメールを送る場合など),メールクライアントとSMTPサーバの接続がOP25Bで阻止されます。
  3. ユーザプログラム(ボット含む)や独自メールサーバがユーザ回線を使ってメールを転送する場合,OP25Bで阻止されます。独自メールサーバからメールを転送するには固定IPが必須になります。
上記のうち,OP25Bは3.でのメール送信阻止を狙ったものです。それに対して2.は関係ないのに巻き添えを食らっており,対策が必要です。

【メールクライアントのための対策:サブミッションポート】
メールクライアントのための独自メールサーバの対策として,メールクライアントが25番ポートで接続してくることができないので,メールクライアントに対して25番以外のポートから接続できるように設定する必要があります。
そのための代替ポートとして「RFC2476」にて「サブミッションポート(TCP587番ポート)」が定められています。
サブミッションポートはメールクライアントからSMTPサーバに接続するときに使い,SMTPサーバどうしのメール転送は従来どおり25番ポートを使います。また,サブミッションポートへの接続にはSASL認証(SMTP Auth)を課すことで,「単にポート番号が変わっただけ,587番ポートからスパム送り放題」とならないようにします。

※サブミッションポート以外の対応策として,SMTPサーバをSSL化し,SSL用のポートを使用する,という手もあります。

【Mac OS X Serverで稼動するPostfixでサブミッションポートを利用する手順】
1)SASL認証を有効にする
Mac OS X ServerにプリインストールされているPostfixでは,SASL認証のためのモジュールが最初から組み込まれています。SASL認証を有効にするには,まず「サーバ管理」ツールにて「コンピュータとサービス」で「メール」を選び,「設定」→「詳細」→「セキュリティ」でセキュリティパネルを表示します。ここで「認証」→「SMTP」列のいずれかのチェックボックスをONにして「保存」ボタンを押すとSASL認証がONになります。

※SASL認証のユーザ名とパスワードは,Mac OS X Serverではワークグループマネージャに登録したユーザ名とパスワードになります。すなわちメール受信用のユーザ名とパスワードと同一になります。

2)サブミッションポート(TCP587番ポート)を有効にする
「/etc/postfix/master.cf」ファイルを編集します。事前にバックアップを取った上で「sudo vi」などでファイルを開き、

#submission inet n - n - - smtpd
# -o smtpd_etrn_restrictions=reject
この2行について,最初の「#」(コメントアウト)を削除します。(注:「-o」の前のスペースを削除してはいけません。)
ここでmaster.cfを保存して終了し,コマンドラインで「sudo postfix check」と入力してエラーチェックを行います。問題なければ「サーバ管理」でメールサービスをリスタートするか,コマンドライン上で「sudo postfix reload」コマンドを実行すると,サブミッションポートが有効になります。このときサブミッションポートに適用されるパラメータ値は,main.cfで定義された25番ポートのパラメータ値と同じです。

3)サブミッションポートのパラメータ設定
サブミッションポートで適用されるパラメータ値は「/etc/postfix/main.cf」で定義した25番ポート用の値がデフォルトとして適用されます。
サブミッションポートで適用されるパラメータ値を25番ポートとは別の値にしたい場合は,master.cfのsubmissionセクションの末尾に「-o」+「パラメータ=値」で設定したいパラメータ値を追記することで,サブミッションポートのパラメータ値が上書きされます。このとき「-o」+「パラメータ=値」の記述で気をつけなければならないのは,
  • 「-o」の前後にスペースが必要。行頭のスペースは前の行からの継続を意味する。
  • スペースで区切って解釈されるため,「パラメータ=値」は途中でスペースを入れない。
の2点です。
設定例1:
submission inet n - n - - smtpd
 -o smtpd_etrn_restrictions=reject
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
 -o smtpd_helo_restrictions=permit
 -o smtpd_sender_restrictions=reject_non_fqdn_sender,permit
 -o smtpd_recipient_restrictions=reject_non_fqdn_recipient,permit_sasl_authenticated,reject
※追記:最後の行に「smtpd_recipient_restrictions」の行を追加しました。このタイミングで「permit_sasl_authenticated」の判定を行うためです。

「パラメータ=値」の途中でスペースを入れることができませんが,「check_sender_access tyep:table」などのように間にスペースを入れなければならないパラメータ値もあります。このような値を指定する場合は,main.cfでユーザ定義のパラメータ値を定義して,master.cfでこれを指定することができます。具体的には,main.cfにて「name = パラメータ値」とパラメータ値に名前を付け,master.cfでこの名前を「${name}」と呼び出すと,これがパラメータ値に展開されます。

設定例2:
main.cfの設定:ユーザ定義パラメータ「check_sender_mydomain」の定義
check_sender_mydomain = check_sender_access hash:/etc/postfix/permit_mydomain

master.cfの設定:ユーザ定義パラメータ「check_sender_mydomain」の利用
submission inet n - n - - smtpd
 …
 -o smtpd_sender_restrictions=reject_non_fqdn_sender,${check_sender_mydomain},reject
main.cf及びmaster.cfを編集保存したら,ターミナル上で「sudo postfix check」を実行してエラーがないか確認し,「sudo postfix reload」を実行して修正内容を実行環境に反映します。

以上でPostfixの設定は完了です。設定完了後LAN内からメールを送信してみてうまくいったら,外部と接続するルータなどでもサブミッションポートへの接続を許可する設定にして,今度は外部からメール送信できるか確認します。

※ところで「permit_mydomain」て何?という方はこちら


■関連情報
ISPによるOP25B 実施状況((財)日本データ通信協会・迷惑メール相談センター)
各ISPによるOP25Bの解説ページインデックスOP25B連絡会
Postfix 2.1日本語ドキュメント:[基本設定][設定パラメータ][master.cfファイルフォーマット]
Appleサポート:Mac OS X Server 10.4送信メールを設定する
Apple Server 製品ドキュメント:メールサービスの管理[PDF]

■関連書籍をAmazonで検索:[Postfix][Mac OS X Server]
無停電電源装置:APC Smart-UPS750 計画停電対策に

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


宿・ホテル予約ならじゃらんnet新生活応援セール

| | トラックバック (1)

Mac OS X Server:Postfixとメールクライアントの接続問題

【問題】
Mac OS X Server 10.4.x(Tiger Server)のメールサーバ(Postfix)を設定するとき,「/etc/postfix/main.cf」ファイルのパラメータのうち,以下のパラメータによるアクセス制限を厳しくすると,このメールサーバに接続するメールクライアントからメール送信ができなくなることがあります。

パラメータ内容
smtpd_client_restrictionsクライアントからの接続要求のチェック
smtpd_helo_restrictionsSMTP HELOコマンドのチェック
smtpd_sender_restrictionsMAIL FROMコマンドのチェック
smtpd_recipient_restrictionsRCPT TOコマンドのチェック
各パラメータの詳細はこちら

【原因】
SMTPは,メールサーバ(MTA)間のメール転送もメールクライアントからのメール送信も同じ25番ポートで受け付けます。そのため両者が同じルールでチェックされてしまい,メールサーバに対してだけ厳しくチェックされるべきアクセス制限が,メールクライアントにも適用されてしまいます。

【対策】
SASL認証(SMTP Auth)をONにすると,上記の各パラメータチェックで「permit_sasl_authenticated」の指定が意味を持つようになります。各パラメータに「permit_sasl_authenticated」を加えることで,SASL認証にパスしたメールクライアントソフトはそのパラメータのチェックをスキップしてメール送信ができるようになります。下記の設定例では,クライアントのメールソフトからの接続を「reject_invalid_hostname」が阻止してしまうのを「permit_sasl_authenticated」が防いでいます。特定のパラメータ値を「permit_sasl_authenticated」で防ぐには,そのパラメータ値より前に「permit_sasl_authenticated」を入れる必要があります。
設定例:
smtpd_helo_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_invalid_hostname,permit

Mac OS X ServerにプリインストールされているPostfixには,SASL認証に必要なモジュールがデフォルトで組み込まれています。このSASL認証をONにするには,「サーバ管理」ツールにて「コンピュータとサービス」で「メール」を選び,「設定」→「詳細」→「セキュリティ」でセキュリティパネルを表示します。
ここで「認証」→「SMTP」列のいずれかのチェックボックスをONにして「保存」ボタンを押すと,SASL認証がONになります。
ここでの設定は「/etc/postfix/main.cf」ファイルのパラメータ「smtpd_sasl_auth_enable」「smtpd_pw_server_security_options」などに反映されます。

注1:SASL認証のユーザ名とパスワードは,Mac OS X Serverではワークグループマネージャに登録したユーザ名とパスワードになります。すなわちメール受信用のユーザ名とパスワードと同一になります。
注2:認証時のKerberosとCRAM-MD5はログインを暗号化して行い,LoginとPLAINは平文で行います。クライアント側はアップルの「Mail」はCRAM-MD5で認証を行い,マイクロソフトの「Outlook」「Outlook Express」はLoginで認証を行います。

【追記】
Postfixのドキュメントから設定可能なパラメータを調べるために,Mac OS X Serverで稼動しているPostfixのバージョン番号を知る必要がありますが,「サーバ管理」ツールではこれは表示されません。
Postfixのバージョン番号を知るには,コマンドライン上で
postconf mail_version
と入力することでバージョン番号を知ることができます。
ちなみにMac OS X Server 10.4.11のPostfixのバージョンは2.1.5でした。

■関連情報
Postfix 2.1日本語ドキュメント: [基本設定][設定パラメータ]
Appleサポート:Mac OS X Server 10.4送信メールを設定する
Apple Server 製品ドキュメント:メールサービスの管理[PDF]

■関連書籍をAmazonで検索:[Postfix][Mac OS X Server]
Postfix詳解―MTAの理解とメールサーバの構築・運用

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
Mac ソフトのことなら act2.comMac ソフトのことなら act2.com宿・ホテル予約ならじゃらんnet

| | トラックバック (0)

Mac OS X Server:Webサーバ設定の問題

【問題】
Mac OS X Server 10.4.x(Tiger Server)にて,OS付属のWebサーバApache)を稼動させて,これにWebブラウザでアクセスすると,一部のコンテンツが表示されないことがあります。また,ApacheのKeepAlive機能(「サーバ管理」ツールでの表記は「持続的な接続を許可する」)をONにすると,Webクライアントからアクセスしたときに,すべてのコンテンツの表示が完了するのに時間がかかることがあります。

【原因】
Mac OS X ServerのWebサーバには「パフォーマンスキャッシュ」という機能が組み込まれており,デフォルトでONになっています。
このパフォーマンスキャッシュは,通常Webサーバが使用するポート番号80でリクエストを受け付けます。Webサーバ(Apache)は,パフォーマンスキャッシュがONのときはポート番号16080でリクエストを受け付けます。
外部からのリクエストはまずポート番号80が受け取り,パフォーマンスキャッシュでコンテンツがキャッシュされていなければポート番号16080へリダイレクトされます。そのためポート番号16080が外部からアクセスできないとキャッシュにないコンテンツを表示させることができません。

また,パフォーマンスキャッシュがONのときにKeepAlive機能もONだった場合,KeepAliveで設定されたタイムアウト時間がリダイレクト時のウエイトタイムになってしまうようです。そのためたとえばタイムアウト時間が15秒だった場合,Webページ上の画像が1枚表示されるごとに15秒待たされる,ということになってしまいます。

【対策】
パフォーマンスキャッシュをOFFにすれば,とりあえず問題は解消します。パフォーマンスキャッシュをONにしたまま問題が出ないようにするには以下のようにします。

  1. ルータなどの設定により,ポート番号16080を外部からアクセスできるようにする。
    →ポート番号16080にアクセスできるかどうかは,HPのURLがたとえば「http://www.example.co.jp/」だった場合,この URLを「http://www.example.co.jp:16080/」と変更してWebブラウザからHPにアクセスできるかどうかで確認することができます。
  2. KeepAlive機能(「持続的な接続を許可する」)をOFFにする。
    パフォーマンスキャッシュとKeepAliveの両方をONにすると,上記のような問題が生じるので,「自分達のサイトにとってどちらの機能がより恩恵があるか」を検討し,どちらをONにするかを決定することになるかと思います。
■関連情報
Appleサポート:Webパフォーマンスキャッシュについて学習する
Appleサポート:Webサービスがデフォルトでポート80と16080を使用する
Appleサポート:Appleソフトウエアで使用するTCP/UDPポート
Appleサポート:Mac OS X Server 10.4Web サイトを管理する
Apple Server 製品ドキュメント:Webテクノロジーの管理[PDF]

■関連書籍をAmazonで検索:[Apache][Mac OS X Server]
Apacheセキュリティ

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ にほんブログ村 IT技術ブログ Webサイト構築へ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
シマンテックストアMac ソフトのことなら act2.com

| | トラックバック (0)

Mac OS X Server:DNS設定の問題

【問題】
Mac OS X Server 10.4.x(Tiger Server)にて,設定ツール「サーバ管理」でDNSサーバBIND)の設定を行ったときに以下のような問題がありました。
注:この問題がLeopard Serverで改修されているかどうかは未確認です。

●設定が勝手に書き換わる問題
「サーバ管理」は,DNS設定を変更したあとで「保存」ボタンで変更内容を反映するときに,設定ファイルの内容やファイル名をチェックして,エラーと判断した箇所を書き換えているようです。
この機能は,間違った設定のままDNSを運用してしまわないための機能だと思われますが,一部正しいはずの設定をエラーと判定するケースがあるようです。
ここでは現在こちらで把握している不備の内容についてリストアップしたいと思います。

1)逆引き設定をクラスC未満にできない
クラスC未満の逆引き設定を行い,「サーバ管理」の「保存」ボタンを押すと,逆引き設定がクラスCに拡張して保存されてしまいます。

2)SPF設定が消える
SPFの設定は,ドメイン名に対してTXTレコードを割り当てて,そこに記述しますが,ドメイン名へのTXTレコードの割り当ては,「サーバ管理」は設定の誤りと解釈するようで,SPFの設定を行ったあとで「サーバ管理」の「保存」ボタンを押すと,SPFの設定をファイルから削除して保存されてしまいます。

●view設定がエラーになる問題
「view」はBIND9から追加された機能で,Tiger ServerのBINDも9.xなので当然使えるのですが,設定ファイルをviewを使って書き換えてBINDを起動し直すと,「サーバ管理」のステータス表示でDNSがエラー状態になってしまいます。

【対処方法】
設定が勝手に書き換わる問題については,「サーバ管理」による設定の更新を行わないようにするしかないと思います。「サーバ管理」による設定は,最初のドメイン設定ファイルの生成までにして,その後の設定はテキストエディタで直接設定ファイルを編集して「サーバ管理」からは設定は行わないようにします。「サーバ管理」は設定ファイルの書き換えを行ったあとのDNSの起動・停止でのみ利用します。
view機能の障害については,viewを使わないか,エラー表示に目を瞑るしかないようです。

■関連情報
Appleサポート:Mac OS X Server 10.4DNS サービスの概要
Apple Server 製品ドキュメント:ネットワークサービスの管理[PDF]
JPRS:DNS関連技術情報
OPENTECHPRESS:SPF解説

■関連書籍をAmazonで検索:[BIND/DNS][Mac OS X Server]
DNS & BINDクックブック―ネームサーバ管理者のためのレシピ集

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ ネットワーク・SEへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。


サンワダイレクト USBフラッシュメモリが激安!Mac ソフトのことなら act2.comシマンテックストア

| | トラックバック (0)

Java:CSVパーサを作る(その3) - RFC4180対応 後編

前回の記事で未実装だった「レコードの確定」と「レコードのフィールドへの分割」を行うメソッドについて実装を行い,CSVパーサを完成させます。

【実装の考察】
●レコードの確定
レコード確定では,入力テキストデータに対して,ダブルクォーテーション(二重引用符)のペアをヒントに各レコードの末尾を確定して,レコードの切り分けを行います。処理手順は以下のようになります。

  1. BufferedReaderのreadLineメソッドを使ってテキストを1行分(現在の位置から改行が現れるまで,またはファイルの終了まで)取り出して,行の先頭からダブルクォーテーションを探す。見つからなければその1行を1レコードとして確定する。(readLineメソッドは「CR」「LF」「CRLF」を改行と認識するので,「CRLF以外の改行も考慮する」仕様の要求を満たしています。)
  2. ダブルクォーテーションが見つかった場合,ペアになる後ろのダブルクォーテーションを探す。後ろのダブルクォーテーションが見つかったらその位置から後続のダブルクォーテーションのペアを探す。この手順を行の終わりまで繰り返す。ダブルクォーテーションペアの外側で行が終了していれば,その行を1レコードとして確定する。
  3. ペアの後ろのダブルクォーテーションが見つからずにダブルクォーテーションペアの内側で改行に達したら,その改行を文字列フィールドに含まれる改行と見なしてBufferedReaderのreadLineメソッドより次の行を取り出して前の行と連結し,ペアの後ろのダブルクォーテーションを探すところから処理から継続する。これをダブルクォーテーションペアの外側で改行が見つかるまで繰り返す。後ろのダブルクォーテーションが見つからずにファイルの末尾に達したときは,ファイルの末尾にダブルクォーテーションを付加して行の末尾とする。この連結した行を1レコードとして確定する。
以上の処理を行うコードは次のようになります。(2009年6月22日改訂)
//------------------------------------------------------------------
/**
 * BufferedReaderから1レコード分のテキストを取り出す。
 * @param reader 行データを取り出すBufferedReader。
 * @return 1レコード分のテキスト。
 * @throws IOException 入出力エラー
 */
private String buildRecord (
  BufferedReader reader)
  throws IOException
{
  String  result = reader.readLine();
  int    pos;
  if (result != null && 0 < result.length() &&
    0 <= (pos = result.indexOf("\"")))
  {
    boolean  inString = true;
    String   rawline = result;
    String   newline = null;
    StringBuffer buff = new StringBuffer(1024);
    while (true) {
      while (0 <= (pos = rawline.indexOf("\"", ++pos))) {
        inString = !inString;
      }
      if (inString && (newline = reader.readLine()) != null) {
        buff.append(rawline);
        buff.append("\n");
        pos = -1;
        rawline = newline;
        continue;
      }
      else {
        if (inString || 0 < buff.length()) {
          buff.append(rawline);
          if (inString) {
            buff.append("\"");
          }
          result = buff.toString();
        }
        break;
      }
    }
  }
  return result;
}
注意)上記コードでは,フィールド内の改行をLF("\n")に決め打ちしていますが,実際にはCSVパーサの出力結果を受け取るプログラム(データベースなど)が要求する改行コードを挿入する必要があります。
使用すべき改行コードの選択は,プログラムが稼動するプラットフォームの改行コードを取得する
「String returnStr = System.getProperty("line.separator");」
が知られていますが,実行環境によってはCSVパーサの出力結果を受け取るプログラムがCSVパーサとは異なるOSで稼動する場合もありうるので,上記コードで取得できる改行コードを常に適用できるとは限りません。
そのため,実コードでは使用する改行コードをプロパティファイルで設定できるようにするなど動作環境に合わせて変更できる仕組みを作る必要があります。

●レコードのフィールドへの分割
フィールド分割では,レコードに切り分けたテキストに対して,最初にレコード全体をカンマで分割し,分割した個々の文字列にダブルクォーテーションをヒントに必要な連結やエスケープ処理を行って,個々のフィールドを確定します。処理手順は以下のようになります。
  1. レコード全体をStringクラスのsplitメソッドを使ってカンマで分割し,分割した個々の文字列データを順に先頭からダブルクォーテーションを探す。見つからなければその文字列は1フィールドとして確定する。
  2. ダブルクォーテーションが見つかったら,次のダブルクォーテーションを探す。次のダブルクォーテーションの直後にダブルクォーテーションがあれば,エスケープされたダブルクォーテーションとして処理し,そうでなければフィールドの終わりと見なす。
  3. フィールドで後ろのダブルクォーテーションが見つからない場合,フィールドに含まれるカンマでsplitメソッドが分割したものと見なして,フィールドの後ろに(splitメソッドが削除した)カンマと次のフィールドを連結する。
  4. フィールドの開始と終了のダブルクォーテーションは削除する。
以上の処理を行うコードは次のようになります。(2009年6月22日改訂)
//------------------------------------------------------------------
/**
 * 1レコード分のテキストを分割してフィールドの配列にする。
 * @param src 1レコード分のテキストデータ。
 * @param dest フィールドの配列の出力先。
 */
private void splitRecord (
  String    src,
  LinkedList dest)
{
  String[]  columns = src.split(",");
  int     maxlen = columns.length;
  int     startPos, endPos, columnlen;
  StringBuffer buff = new StringBuffer(1024);
  String   column;
  boolean  isInString, isEscaped;

  for (int index = 0; index < maxlen; index++) {
    column = columns[index];
    if ((endPos = column.indexOf("\"")) < 0) {
      dest.addLast(column);
    }
    else {
      isInString = (endPos == 0);
      isEscaped = false;
      columnlen = column.length();
      buff.setLength(0);
      startPos = (isInString)? 1: 0;
      while (startPos < columnlen) {
        if (0 <= (endPos = column.indexOf("\"", startPos))) {
          buff.append((startPos < endPos)?
                column.substring(startPos, endPos): isEscaped? "\"": "");
          isEscaped = !isEscaped;
          isInString = !isInString;
          startPos = ++endPos;
        }
        else {
          buff.append(column.substring(startPos));
          if (isInString && index < maxlen - 1) {
            column = columns[++index];
            columnlen = column.length();
            buff.append(",");
            startPos = 0;
          }
          else {
            break;
          }
        }
      }
      dest.addLast(buff.toString());
    }
  }
}


以上で「RFC4180対応のCSVパーサ」はひととおりできあがったかと思います。

※上記コードでは,整形のため全角スペースを使用している部分があります。
【著作権表記】上記コードを含む本ブログのプログラムコードは,私的利用可,商用利用可,改変しての利用可です。利用の際に作者に許諾を得る必要はありません。

■関連書籍をAmazonで検索:[Java]
ソースコードリーディングから学ぶ Javaの設計と実装



にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ プログラム・プログラマへ 人気ブログランキングへ ←この記事が役に立ったという方はクリックお願いします。
▼CSVパーサを作る[][][その3]
ソニーストアウェーブミュージックシステム - サウンドリンク

| | トラックバック (0)

«Java:CSVパーサを作る(その2) - RFC4180対応 前編