2007年9月14日金曜日

lighttpd/RubyOnRails の SSL化

RubyOnRailsでは、Webサーバーとして動作が高速なlighttpd(ライティ)がよく使われる。

lighttpdはSSLもサポートしているのだが、SSL化のためのキチンとした資料が見つからずSSL化ではまってしまったがなんとかできた。(^^)


そこで、SSL化の手順をまとめてみた。

・SSL化するサイト
http//shop.sample.co.jp → https//shop.sample.co.jp


・SSL認証
費用がやすいグローバルサイン社をつかうことに

・RubyOnRailsのアプリケーションディレクトリ
~/jstore

参考URL Generate a CSR for an SSL Certificate for Lighttpd


-------------------------------
グローバルサイン社の以下のページを参照しなならCSRを生成する
-------------------------------

グローバルサイン社 CSRの生成



1) ssl関係のファイルの格納ディレクトリ~/jstore/ssl の作成



$ cd jstore
$ mkdir ssl



2) 秘密鍵ファイル shop.sample.co.jp.key を生成する

$ openssl genrsa -out shop.sample.co.jp.key 1024
Generating RSA private key, 1024 bit long modulus
........................++++++
..............++++++
e is 65537 (0x10001)

3) 生成された秘密鍵ファイルのpermissionを変更

$ chmod 600 shop.sample.co.jp.key


4) CSR shop.sample.co.jp.csr を生成する

$ openssl req -new -key shop.sample.co.jp.key -out shop.sample.co.jp.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Kanagawa
Locality Name (eg, city) []:Yokohama
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sample Inc
Organizational Unit Name (eg, section) []:-
Common Name (eg, YOUR name) []:shop.sample.co.jp
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


-----------------
Country Name 国を示す2文字のISO略語です。 JP
State or Province Name 組織が置かれている都道府県です。 Kanagawa
Locality Name 組織が置かれている市区町村です。 Fujisawa
Organization Name 組織の名称です。 Sample Inc
Organization Unit Name 組織での部署名です。
※指定がない場合は - (ハイフン)を入力してください。 -
Common Name ウェブサーバのFQDNです。shop.sample.co.jp
Email Addres 入力不要です。
※指定がない場合は項目自体を作成しないでください。 -
A challenge password 入力不要です。 -
An optional company name 入力不要です。 -
------------------


以下の内容のCSRファイル shop.sample.co.jp.csr が生成される

$ cat shop.sample.co.jp.csr
-----BEGIN CERTIFICATE REQUEST-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE REQUEST-----


5) グローバルサイン社にサーバー証明書を申請する

https://system.globalsign.com/direct/directdvhigh.do

上記を開き購入するする証明書を指定し「注文する」ボタンを押す

次に企業情報の入力画面で自社の企業情報を入力

最後に上記のCSRを所定フィールドにCOPY&PASTEして申請する。
CSRは、破線の行も含めてコピーすること。


申請して数分くらいでグローバルサイン社からサーバー証明書のある
URLがメールで送られてくる。

-----BEGIN CERTIFICATE-----
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzz
-----END CERTIFICATE-----


6) 上記の内容を shop.sample.co.jp.crt ファイルとして保存する。

7) shop.sample.co.jp.key と shop.sample.co.jp.crt とを合体
して、shop.sample.co.jp.pem ファイルを作成する。


$ cat shop.sample.co.jp.key shop.sample.co.jp.crt > shop.sample.co.jp.pem
$ chmod 600 shop.sample.co.jp.pem



8) lighttpd のデフォルトインストールでは、ssl に非対応なのでインストールし直す。

lighttpd を オプション--with-opensslをつけて再コンパイル


$ cd ~/src/lighttpd-1.4.15
$ ./configure --prefix=/usr/local --with-pcre=/usr/local --with-openssl
$ make
$ sudo make install


9) lighttpd.conf にsslのためのパラメータを指定

以下の4行を ~/jstore/config/lighttpd.conf に追加する

#### SSL engine
ssl.engine = "enable"
ssl.pemfile = CWD + "/ssl/shop.sample.co.jp.pem"
ssl.ca-file = CWD + "/ssl/dvcacert.cer"


ファイル dvcacert.cer は、グローバルサインからダウンロードした中間CA証明書
中間CA証明書のダウンロード先はグローバルサイン社からのメールに表示されている。

この中間証明書がないと「認証局不明」の警告がでてしまう。

10) lighttpd を起動し、完了!!

覚書:jstoreの開発経緯

ようやくシェアウエア・ライセンスキーの即時発行システム jstore が完成した。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
これまでのシステム
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

レンタルサーバー付属のショッピングカート(Perl)をベースに2001年に作成
ショッピングカートからの注文データ(CSV形式)を、オフラインでデーリーに回収し、ユーザー管理データベース(FileMaker)へ取り込み、登録コードを計算しユーザーへ登録メールを発送。取り込み/メール発送部分はアップルスクリプトで自動化。支払い方法はクレジットカードと銀行振込をサポート。クレジットカードの認証/代金回収はZEUS社を利用(手数料約5%+)。ZEUS社が英語ページ・海外クレジットカードに対応していないので、海外からの注文には、Kagi.comを利用(手数料10%+)

問題点

1)オフラインの登録コード処理のため、登録コードの発送が1日遅れになってしまう。
2)連休、年末年始、夏季休暇のときは発送が休日明けになってしまい、その間の売り上げがダウン。
3)国内売り上げと海外売り上げが異なった処理方法になり煩雑。

いまどき登録コードを即時発行できないシステムは、ユーザーからの苦情が多く、もう限界に達していた。。。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
新システムを模索
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

kagi.com や esellerate を使えば登録キーの即時発効は可能だが
・ユーザーへのメールが日本語に対応していない
・手数料が高すぎる 10%超
・即時発効の登録コード生成ルーチンを先方へ渡してしまうのは不安
・macsbなどのメーリングリスト書き込みをみると、kagi.com離れが進んでいる(?)

国内にはベクターがあるが
・英語に対応していない
・手数料がさらに高い 15%!!
・なんとなくダサイ (^^;

そんななかで今年からPayPalが完全日本語化された。
PayPalを使えば
・海外と国内の売り上げを統一して扱える
・手数料も 3.4% + $0.30 と安い
・cgiインターフェースもあるので登録キーの即時発効もできそう。

2007年6月末、登録キー即時発効システム PotionStore の存在をmacsbで知る。
http://www.potionfactory.com/potionstore


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
PotionStore 概略
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

・KagiやEsellerateなどのサービスを使わない、Mac OS X デベロッパーための登録キー即時発行システム
・Open source で、Ruby On Rails アプリケーション
・PayPal か Google Checkout にマーチャントアカウントがあれば簡単に自分の登録キー発行システムを構築できる

主な特長
・PayPal Website Payments Proをサポート
・PayPal Express Checkout support(PayPalアカウントなしでの支払い)をサポート
・Google Checkout をサポート
・Admin(管理者)インターフェースもサポート
・クーポンの生成と受け入れをサポート
・ライセンスキー問い合わせをサポート

ライセンス

Creative Commons Attribution-Share Alike 3.0 License.
http://creativecommons.org/licenses/by-sa/3.0/deed.ja

あなたは以下の条件に従う場合に限り、自由に
  作品を複製、頒布、展示、実演することができます。
  二次的著作物を作成することができます。
あなたの従うべき条件は以下の通りです。
  表示. 原著作者のクレジットを表示しなければなりません。
  継承 二次的著作物は配布するときは同じ条件で配布しなければなりません。

システム構成

・言語: Ruby
・フレームワーク: Ruby On Rails
・Security: 要SSL
・データベース: PostgreSQL


Ruby On RailsとSSLが利用できるサーバーであれば、レンタルサーバーでも動作可能。
PotionStoreのページで、導入した人の書き込みをみると4日間ほどで稼働したとのこと。

ーーーーーーーーーーーーーーーーーーーーーー

で、PotionStoreをダウンロードして実際に試してみた。

Unixコマンドにうとく、PostgreSQLも初めて、Rubyも初めて、Ruby On Rails も初めてという状態。

まずは、システムのインストールから。。。

OSXにRuby on Rails環境をインストールする方法
http://d.hatena.ne.jp/dtocos/20060304

PostgreSQL のインストール
PostgreX PostgreSQL Easy Installer for Mac OS X
http://www.magic3.org/postgrex/


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
PotionStore は 日本で使えるのか?
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

実際にPotionStoreをインストールして以下のことがわかった。

1)PotionStoreで利用してる支払いシステム PayPal WebPayment Pro、Google Checkout が日本ではサポートされていない。
2)Webページやメールのバイリンガル(英語、日本語)化が必要

というわけで、そのまま(configファイル、ライセンス生成ファイルの修正だけ)では、とても使えないということが判った。

2)はなんとかなるとしても、とくに1)はプログラムの構造そのものの変更が必要になり致命的。(^^;

日本のPayPalでサポートしている API は、WebPayment Proでなく、それより古いタイプのWebPayment Standard。


PayPal がサポートしてる支払いシステム一覧
https://www.paypal.com/us/cgi-bin/webscr?cmd=_merchant-outside

・WebPayment Standard
・WebPayment Pro
・Email Payment


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
WebPayment Pro
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://www.paypal.com/us/cgi-bin/webscr?cmd=_wp-pro-overview-outside

・米国でのみサポート
・マーチャントページで顧客の氏名、住所、クレジットカードの情報を取得し、それらの情報をPayPalのWebサービスに送信、決済を依頼する。Webサービスから正常リターンなら、登録コードを顧客に開示しメールを送る。
・WebPayment Standardに比べてプログラムが単純化できる。
・顧客にはPayPalのページは一切表示されないので、顧客にとってもシンプルで判りやすいインターフェースになる。
・クレジットカード情報をマーチャント側で行うので、SSLが絶対に必要、かつそのクレジットカード情報の取り扱いには細心の注意が必要。


ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
WebPayment Standard
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
https://www.paypal.com/us/cgi-bin/webscr?cmd=_wp-standard-overview-outside

・米国以外(日本)でも利用可能
・PayPalのWebページのなかで決裁する必要があり、マーチャントページからPayPal ページへリンクし、PayPal内で決済が終わったら、マーチャントページへまた戻る形になる。
・決済がマーチャントページだけで終わらないので、顧客にとっても複雑なインターフェースになってしまう。
・マーチャントページのなかでクレジットカード情報を扱わないのでマーチャントとしては気が楽。SSLも絶対必要ではない。
・PDT(Payment Data Transfer)と IPN(Instant Payment Notify)の2種類のAPI がサポートされている。
・PDTと IPN の2つのインターフェースを実装する必要があり、プログラムとしては複雑になる。

PDT(Payment Data Transfer)

PDT の主要機能は、買い手が支払い完了時に自Paypalのサイトから自サイトに自動的にリダイレクトされた時に、支払い取引の詳細を表示することです。つまり、Paypalと自サイトの処理は同期型です。(ここがポイント!)なので、PDTによってコールバックされる情報を元にバックエンドと統合を行うことが可能になります。

[参考] PHPでWebPayment Standardを利用したときの解説
http://blog.katsuma.tv/2007/06/paypal_pdt_ipn_intro.html


PayPalサイトで決済が正常終了すればこちらのサイトにリターンされ、Thank you ページを表示し登録キーを開示、登録キーお知らせメールを発送する。

しかし、顧客がPayPal内で支払いを完了したと同時にWebブラウザを終了してしまうと、Thank you ページの表示が行われなくなってしまう。結果として、支払いが発生しても登録キーが顧客に渡らなくなってしまう。

それを防ぐために、次のIPNとの併用が必要。

IPN(Instant Payment Notify)

IPNは、PDTと(ほぼ)同じデータがPaypalから自サイトにPOSTされますが、そのタイミングは支払いが終了したとき、また支払い状態が「Pending」の場合において決済されたとき、失敗したとき、拒否されたときにも別の通知を受け取ることになります。つまり、コールバックされるタイミングはWebのフローとは非同期に行われます。(これがPDTと違う大きなポイント!)PDTとは独立してWebフローとは非同期に自サイトへPOSTされてきます。

IPN では、顧客がPayPal内で支払いが完了すれば自動的にマーチャント側へ通知されるので、顧客がWebブラウザを閉じてしまっても問題ない。

jstore(今回作成したPotionStoreの日本語版)では、PDTとIPNの両方をサポートし、さきに発生したほうのイベントで登録キー生成、送信、DB更新を行うようにした。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
jstore (PotionStoreの日本語版)について
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

アートマン21のjstoreのアドレス
https://support.artman21.co.jp:8080/

オリジナル(英語版)からの変更・追加

・WebPayment Standard (PDT & IPN)をサポート
・銀行振込み(国内のみ)をサポート
・日本語と英語の2言語をサポート
・製品価格を円とドルの2種類をサポート
・アップグレードの際の登録キーチェックをサポート


今後の予定

・9月中旬から実際の運用を開始
・数ヶ月実績をみて、問題なければ年末あたりにOpenSourceとして公開するかも

2007年9月12日水曜日

PayPalの日本語処理のバグ

PayPalのWebPayment Proを利用したオンラインショップのプログラムを Ruby On Railsで開発した。

PayPalは今年の初めに日本語化されたが、まだ日本語まわりでいろいろなバグがある。そのなかで一番重大と思う「全角ハイフン」のバグについて報告します。このバグについてはすでにPayPalに報告済みでPayPalでは現在(2007年9月12日現在)対応作業中です。

日本語入力でエラーがでるようなときは、このバグを疑ってみてください。

バグの要約:

PayPalで、全角ハイフン「−」(unicode: 0x2212, shiftJIS: 0x7c81)を入力すると、日本語でないとしてエラーメッセージが表示され受付けてもらえない。

再現方法:

PayPalにログインして、個人設定>アカウント情報>住所 を選択。
「追加」ボタンで、以下のような全角ハイフン「−」を含む住所の登録をこころみる。

住所1行目:南藤沢16−11

すると以下のようなエラーメッセージが表示される

このフィールドに使用できない文字が入力されています。現在利用できる文字タイプは次のとおりです。ヨーロッパ言語、中国語、韓国語、日本語、タイ語。もう一度実行してください。

問題点:

マーチャントのページのショッピングカートから
http://www.paypal.com/cgi-bin/webscr
へ住所も含めてPOSTしたときに、その住所に全角ハイフン「−」が含まれていると
PayPalの画面が表示されたときにエラーメッセージが表示される。
顧客には、そのエラーがなんのことかわからないので、ほとんどの顧客はそこで
取引をキャンセルしてしまい、マーチャントにとっては重大な機会損失が生じる。

全角ハイフン「−」は、何丁目何番などを省略して表示するときによくつかわれる文字なので、エラーになるのは絶対にまずい!!!