c/fe

http://d.hatena.ne.jp/uzulla から移行しました。

そこらにあるEC2+EBSでの世代バックアップスクリプトが

「EC2 EBS 世代バックアップ 」とかでググっ出てくるコードがどれも今一つピンと来ない、つーか使いづらい*1ので、色々な所のコードを(どれも似てるので、みんなコピペで改造してるっぽい)参考にしつつ、自分も書いた。

オチ

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
import datetime
import httplib
from boto import config
from boto import ec2
from boto.ec2.connection import EC2Connection

GENERATION_NUM = 5
VOL_ID = 'vol-XXXXXXXX'
AWS_ACCESS_KEY_ID = 'XXX'
AWS_SECRET_ACCESS_KEY = 'XXX'
DESCRIPTION_PREFIX = 'daily backup'
REGION_NAME = 'ap-northeast-1'

conn = httplib.HTTPConnection( "169.254.169.254", 80 )
conn.request( "GET", "/latest/meta-data/instance-id" )
res = conn.getresponse()
if res.status != 200:
    print "cant get instance-id"
    sys.exit()

INSTANCE_ID = res.read().decode( "UTF-8" )
conn.close()

DESCRIPTION = DESCRIPTION_PREFIX + ' ' + INSTANCE_ID + ' ' + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print DESCRIPTION

regions = ec2.regions(aws_access_key_id=AWS_ACCESS_KEY_ID,aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
for r in regions:
    if r.name == REGION_NAME:
        _region=r

conn = EC2Connection(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,region=_region)

conn.create_snapshot(volume_id=VOL_ID, description=DESCRIPTION)

snapshot = {}
for x in conn.get_all_snapshots(owner='self'):
    if(x.volume_id == VOL_ID and re.compile(DESCRIPTION_PREFIX).match(x.description) ):
        tmp = {x.id:x.start_time}
        print x.id + " " + x.volume_id + " " + x.description
        snapshot.update(tmp)

snapshot = sorted(snapshot.items(), key=lambda (k, v): (v, k), reverse=True)
for i in range(GENERATION_NUM, len(snapshot)):
    print "DELETE " + snapshot[i][0]
    conn.delete_snapshot(snapshot[i][0])


当然だけれど、botoが入ってないとダメ。
入れ方はググれ。
あとはCronにいれて回せばOKや。

所で…

datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
とか
re.compile("test").match(u"test")
って書き方が「マジで!?」なんだけど、実際の所Pythonerに聞いてみたい…


しかしPHPPerlに慣れた人間には、$とか{とかないコードは、視線の引っかかる所がなくてよみづらいですな…慣れるのかな…。

*1:世代管理はいいけど、同一のVol_idだとガッツリ古いのから消しやがるので、あるポイントのスナップショットをとっておけないとか、とってくるデータにフィルタ入ってないから無駄な処理じゃね?とか、説明文にインスタンスIDくらいいれようよ…とか色々

EC2でvsftpdのpasv_addressをbootupのしかけでどうにかする

AWSのEC2くそおそいね!(挨拶)
LargeがさくらのVPS 4Gの4倍くらい遅い!値段何倍だよ!(挨拶)
Groongaをビルドしたら30分かかった!(挨拶)


ーー
AWSを仕事で使う機会が最近また出てきました。
まあそれがどうしたって感じですけど、まあ今までとちょっと違う感じのお客さんなのです。


まあ、うまくぼかして言うと、FTPとかつかえないとダメなんですよね。びたいちぼかせてないけど。
「えーマジFTP?」「FTPが許されるのは・・・」
世の中にはFTPがないと呼吸困難になって死ぬ人がいるらしいので、仕方がありません*1

オチ

yum install vsftpd
してvsftpを入れて、
AWSのセキュリティゾーンに

Custom TPC rule
Port range:60000-60010
Source:0.0.0.0/0

Custom TPC rule
Port range:21
Source:0.0.0.0/0

みたいな設定をした上で、vsftpd.confに
pasv_min_port=60000
pasv_max_port=60010
pasv_address=123.123.123.123(EC2インスタンスの、パブリック側IPアドレス
こんなのを追記してvsftp再起動すれば完璧ですね。*2

EC2がオチるとオチがつかない

で、上はネットのかしこにある情報なんですけど、これEC2再起動したらダメなんですよね。
ElasticIP(固定IP)つけておけばオッケーですけど、無いとダメです。
AWSってどんどん増やせるのが前提じゃないですか、そうなるとElasticIpをつけたり外したりとかまじ☆めんどい!


ただ、そうなると再起動する度にいちいちSSHでログインして、
pasv_address=123.123.123.123
を書き換えるとかしなきゃいけない。
なにそれAMI保存しておけばいくらでも増やせるのがクラウドじゃないの?マジ☆メンドイ!

スクリプトを設定しましょう

ってことで、スクリプトつくればいいんだよね。

#!/usr/bin/perl

$PUBLIC_IP = `curl http://169.254.169.254/latest/meta-data/public-ipv4`;
$TMPL = '/etc/vsftpd/vsftpd.conf.tmpl';
$CONF = '/etc/vsftpd/vsftpd.conf';

open $fh, "<", $TMPL;
open $oh, ">", $CONF;

while(<$fh>){
	$_ =~ s/_REPLACE_TO_PUBLIC_IP_/$PUBLIC_IP/g;
	print $oh $_;
}
`/etc/init.d/vsftpd restart`

こんなコードを保存して、/etc/rc.localあたりから呼ぶようにしておくといいですね。


その前に、
/etc/vsftpd/vsftpd.conf.tmpl
ってファイルをつくっておいて、

pasv_address=_REPLACE_TO_PUBLIC_IP_

って書いておいてね、置換されるよ!

オチの解説

curl http://169.254.169.254/latest/meta-data/public-ipv4
こんなのをEC2インスタンスから実行すると、パブリックのIPがとれる。
他にも色々とれるので
curl http://169.254.169.254/latest/meta-data/
とかやってみるといいね。

curl http://169.254.169.254/latest/user-data/
とかもググってみるといいよ。


っていうかね、いまさらこれ知ったよ俺。しらなかったよ俺。どんだけAWS活用してないの俺。

もっといい解決策あれば是非お教え下さい。

*1:勿論SSHもKeyとか使えない

*2:ポートレンジは変えてもいい

先日のPHPConf2011で本をいただいたので

先日のPHPカンファレンス2011において、懇親会のじゃんけんゲームで勝利し、いただいたので、感謝の代わりに感想など。


Being Geek ―ギークであり続けるためのキャリア戦略

Being Geek ―ギークであり続けるためのキャリア戦略

自分は色々な立場に同時にいるので、感覚が普遍なものかはわからないが、
まず、フリーランスの立場で読めば、「ああ、会社員はこうなんだろうな、大変だなー」みたいな感想
会社役員としての立場で読めば、「ああ、そうねこういう風にもなるよね」みたいな感想
雇われ人としての立場で読めば、「あーあーあるある、判ってない人の仕様変更ひどいよねー」みたいな感想
日本人としての立場で読めば、「まあシリコンバレーはそうなんだろうな」みたいな感想


正直こういう本はアメリカンな感覚が多いので、日本人が読んでも全く役立たないんじゃないかって思っていましたが、同感だなという所も多かったので、IT業界のわりと古いキャリアパスや身の振り方について知りたい若い人は読むのもいいんじゃないでしょうか。

すでに業界に何年もいる人はいまさら読むような必要はないのではないかね、共感はできるだろうけど、新しい発見になりそうなネタはやはりアメリカンなもので、日本で適用できる気はあまりしなかった。


まあ兎に角俺にはコンピューターしかないからメシもコンピューターでしか食えないよ!という人に向けた本なのだが、Geek…というよりSEとか、ITエンジニアとかそういう感じ。
邦題なら「ITエンジニアの歩き方」とかそんな感じか。

個人的はGeekかくあるべしみたいな作者のとらえ方もイマドキではないと思っていて、どんな仕事やってても、家でやることやってればGeekだとおもうし、これこそがGeek!という価値観はちょっと古い気がしないでもない。(ただ、これは日本的な感覚なのかもしれない)


もらっておいてこの感想も無い気がするが、カッコイイタイトルと装帳の割には、書いてあることは作者の泥臭い仕事論(しかもちょっと古い気がする)みたいな感じなので、シリコンバレーにあこがれている若いGeek以外は、技術書をかったほうがよい。

延命centos5系

副題:いい加減CentOS6をそこらへんの業者がつかえるようになってほしい

yum remove php*
yum install php53*
(必要ならremove php*ではずれちゃった他の物を戻す)
yum install php-pear
pear upgrade --force Archive_Tar Console_Getopt PEAR XML_RPC
yum install pcre-devel
pecl install apc

どうでもいいけど、groongaのリポジトリをいれていると、mysqlMySQLがケンカして、php53にまで影響がでるのがちょっと困る。
(いや、groongaいれたら一回外せばいいだけなんだけど)


追記:
上のをやった後でVirtualminを入れるとコケる。
install.shのrhdepをいじるか、事が終わってからやった方が良い。

エクセルで普通に開けるUnicodeなCSV

文字コード:UTF-16LE(BOM必須)
改行コード:CRLF
区切り文字:tab

出オチですが。

  • -

昨今は多言語に対応したフォームを作ってくれ、というオーダーもちらほらありますが、お客さんは管理画面からDLできるCSVをエクセルで開くわけで、何も考えて作らないとバリバリ文字化けします。
そういう時はエディタで開くとか、エクセルなんかではなくて、Open Officeとかで開くのが順当なんですがね、そんなちゃんとしたことが出来る方は滅多にいませんし。


Excelは当然ユニコード対応してるんですけど、なぜかUTF-8はちゃんと認識してくれない。
UTF-16とかいまさら誰がつかってんの(内部コード用にはよくつかわれてますけど、ファイルフォーマットとしては、UTF-8が世界的にもデファクトちゃうの?)という気がしますし、そもそもBOMがないとやっぱりコケるのが謎すぎる。
さらに、そのUTF-16にしても、カンマではなくタブがデフォルト区切り文字になるとか…

  • -

ここが本題ですが、知られてませんが、ゆるふわPHPでもUTF-16LEの取り扱いははちゃんと対応してます。
(実は案外多いですよ : http://www.php.net/manual/ja/mbstring.encodings.php

echo mb_convert_encoding($input, "UTF-16LE", "UTF-8");

ただ、上記だとBOMがつかないんですよね。
なので、エクセルで認識させるには、

echo chr(255).chr(254);//この行(BOM)は、かならずレスポンスの先頭に出力される必要がある。
echo mb_convert_encoding($input, "UTF-16LE", "UTF-8");

とする必要が有ります。
BOMは単なる特殊文字なので、ファイルの先頭2バイトに出力されていればよいですね。

  • -

ただまあ、もうOpenOfficeとかつかうべきですよね(請求書や見積もり書作成以外では)

phpのfile_get_contentsでHEAD Request

まあ、普通にできるんですけど、あんまりHeadでリクエストする人もいないのか、あんまり記事がなかったので、メモ。

<?php

echo getAvaterImageUrl('fb', 'junichi.ishida');
echo '<br>';
echo getAvaterImageUrl('tw', 'uzulla');

function getAvaterImageUrl($mode, $id){
    $opts = array(
      'http'=>array(
        'method'=>"HEAD",
      )
    );

    $context = stream_context_create($opts);

    if($mode=='fb'){
        $file = file_get_contents('https://graph.facebook.com/'.$id.'/picture', false, $context);
    }else if($mode=='tw'){
        $file = file_get_contents('http://api.twitter.com/1/users/profile_image/'.$id, false, $context);
    }else{
        return null;
    }

    $location = array_merge(preg_grep('/^location:/i', $http_response_header));
    $url = preg_replace('/location:[ ]*/i', '', $location[0]);

    return $url;
}

見てわかる通り、TwitterFacebookで、ユーザーのID、Screen_nameを元にアバターアイコンの実体URLを取得する方法ですね。


所で、FacebookAPI経由でアイコンにアクセスさせて文句いわれないみたいですけど(特に文句をかいてないので)、Twitterの方はユーザーには出すなとかかいてあってこんな面倒なコードをかかないといけない。
最近のTwitterは微妙だからもっとがんばってほしいわー、ホントFBをみならってほしいわー。


http://dev.twitter.com/doc/get/users/profile_image/:screen_name
http://developers.facebook.com/docs/reference/api/

phpfog がヤバい件

最近PaaS流行ってますね、dotcloudとか。
正直dotcloudはかなりイケてるんですが、ややこしいのがいけません!!*1


普段PHPとかいうゆるふわコードをかいてると、ウェブとDBが別のインスタンスとか、よくわかんない!PSGIとかよくわかんない!(嘘です)


ということで、ゆるふわphperでも使えるPaaSがphpfogなのです。

phpfogについて

https://www.phpfog.com/
詳しくはググれなんですが、まじで情報無い。
ざっくりしたことを言うと、phpが動くPaaSであり、つまりGoogle App Engineみたいなものです。
さらにざっくり言えば、まあレンタルスペースの一種です。

レンサバなら別に今もつかってるし…という愛されphperさん、貴方の考えは概ね間違ってないんですが…*2
ほら、クラウドとか色々回りが言ってるじゃないですか、今までにありませんでしたか?
周囲のPythonerやRubyestが「俺はGAEですわ」「あたしRailsラブだからheroku!」と言っているのを。
「え、なにそれ?」と聞いて「phperには関係ないし(にやにや」といわれたことはありませんか?


そこで「ボクはphpfogだよ!」って言いたいですよね、言いたいってことにしておこうね。


phpfogをやってみよう!

phpfog登録

https://www.phpfog.com/
にアクセスしてください。

こういうなんかスタイリッシュなページの途中に

こんなレジストフォームがありますよ!


ここにメールアドレスと、パスワードを入れてください。
なにも怖い事はありませんが、ここでメールアドレスを間違えると結構アレなので、ちゃんといれましょう。


さあRegist!
すると当然確認画面に…

…なりませんでした、あれ?

  |l、{   j} /,,ィ//|     / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  i|:!ヾ、_ノ/ u {:}//ヘ     | あ…ありのまま 今 起こった事を話すぜ!
  |リ u' }  ,ノ _,!V,ハ |     < 『おれはphpfogにアカウント登録しようとしていたら
  fト、_{ル{,ィ'eラ , タ人.    |  確認すらなく、いつのまにかログインまで完了していた』
 ヾ|宀| {´,)⌒`/ |<ヽトiゝ   | 規約読まないとか捨てアド使うとか
  ヽ iLレ  u' | | ヾlトハ〉.   | そんなチャチなもんじゃあ 断じてねえ
   ハ !ニ⊇ '/:}  V:::::ヽ. │ もっと恐ろしいものの片鱗を味わったぜ…
  /:::丶'T'' /u' __ /:::::::/`ヽ \____________________

ビビりますね。難しい事なんて一切考えたくないphperのことをよくわかってます。
出オチもいい所。どう見ても登録完了です、有り難うございました。

Appを作る!

難しい事考えないで、ボタンを押していきます。

この中から好きなものを選びます、Wordpressとかありますね。想像通りの結果になりますけど、まあ取り合えずここはCustom Appにしておきましょうか。
これが「なにもない」状態を作るものです。


次はプランを選びます。

プランはなにも考えずにFreeを選びましょうね。
ここにツッコミ所が一個あるんですけど、まあなにも考えないで、FreeをChooseしてください。



サクサクいきましょうね。
nameは管理画面で表示されるアプリの名前で、パスワードは適当に。
ドメインは「???.phpfogapp.com」ならタダでつかえますので、適当なものをいれて、or use a phpfogapp.com domain name をクリックすればいいですね。(今回は、hogehoge.phpfogapp.comと仮定します)

当然なんですけど、このドメインは被ってると使えません。いくらtestが作りたくても作れない場合は、なにか別なものを入れましょう。


そしてCreate Appを押せば、Tadaaa!アプリ作成完了ですね!

コードをUP!の前に…

さて、アプリを作ったらサイトチェック…の前にファイルをアップロードしたいですね、当然です。
実はここが難関です。難関過ぎてここで脱落しちゃうphperもいると思う…!


phpfogにファイルをアップロードするには、ffftpfilezillaとかじゃなくて、gitをつかいます。
gitってなんやねんと思うでしょうが、phpfogにファイルがアップできるだけでなく、「俺gitつかってるよ?」って言えて一歩先行くphperになれる、つまりモテるので、とりあえずgitをつかうしかありません。PaaSと一緒にgitも体験しておけば、履歴書に書けます。


所で、残念ですが私はマカーなのでWindowsの人の説明を書く事が出来ません!
嘘です、書く事はできるんですけど、めんどい。もしこの記事にブクマがつくような事でもあれば書きます。
以下Macでの話。えーーー…とても面倒くさいですが、頑張ろうね。


まずgitはコマンドラインで操作する必要が有ります。凄く面倒くさいですね。
terminalを一度もつかったことが無い人は、断念するしかないかも…GUIのgitクライアントもあるっぽいけど…残念ですがお帰り頂いた方が良いかもしれません…でも頑張ろう!


さて言い訳は以上、長いのでさっさといきますよ!

・gitをインストール
入ってるなら飛ばしましょう、MacPortsでもいいですけど、
http://code.google.com/p/git-osx-installer/
ここからgit-osx-installerをとってきて入れるのが速いですね。

http://fujitaiju.com/blog/%E3%83%84%E3%83%BC%E3%83%AB/macgit-osx-installer%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6mac%E3%81%ABgit%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/
このあたり等を参考にしましょう。

インストールがおわったら、gitの初期設定もしましょうね、Terminalから
$ git config --global user.name 'my name'
$ git config --global user.email you@example.com
などと適切に設定してください。


sshの共有キーをつくる
すでにキーを持っている人はこのフェーズを飛ばせます。
~/.ssh/id_rsa
がある場合には飛ばせますね。

http://www.atmarkit.co.jp/flinux/rensai/linuxtips/432makesshkey.html
ここらへんや
http://docs.phpfog.com/index.php/features/article/generating_a_ssh_key
ここを参考にしてください。

要約すると、 terminalを起動して、

$ mkdir ~/.ssh(Enter)(すでにディレクトリがある場合もあります)
$ ssh-keygen -t rsa(Enter)
Enter file in which to save the key (/Users/PHPFog/.ssh/id_rsa):(Enter)
Enter passphrase (empty for no passphrase):(適当にパスワードを入力
Enter same passphrase again:(上と同じパスワードを入力

という流れになります。


sshの公開鍵をphpfogに登録する
$ cat ~/.ssh/identity.pub
と実行して出てきた文字列
ssh-rsa XXXX(略)
をコピーして
https://www.phpfog.com/account#/ssh_keys

こちらの画面のPublic Key欄にペーストします。
nameには適当に自分のあだ名でもいれておきましょう。


長かった、さあgitを使う用意ができました!


おもむろに適当な場所にディレクトリを作り、そこにcdしてgit pullします。
phpfogの
https://www.phpfog.com/apps/{アプリのID}#/source_code

に移動しまして、Clone your git repository:の所にある

git clone git@git01.phpfog.com:ほげほげ.phpfogapp.com

こんな行ををコピペして実行ですね。
(もしこれがでていなければ、ページを何度かリロードしてみて下さい)


具体的に言えば、Terminalから

cd
mkdir phpfogtest
cd phpfogtest
git clone git@git01.phpfog.com:hogehoge.phpfogapp.com

こんな感じですね。


するとごちゃごちゃと出力がされて、そのディレクトリの中に
hogehoge.phpfogapp.com
みたいなディレクトリができると思います。
さあやっとコード書く用意ができましたよ!
※まだTerminalはひらいたままでいてくださいね。

改めてコードを書いてUP!

先ほど出来たhogehoge.phpfogapp.comディレクトリの中に、index.phpを作ります。
open ~/phpfogtest/hogehoge.phpfogapp.com
とかやればそこがFinderで開くので

とかかいて保存しましょう。


ではアップロードです、アップロードはgitをつかいますが、とりあえずなにも考えず、こういうふうにタイプしてください

git add .
git commit . -m "my first commit"
git push

するとごにゃごにゃごにゃとなにか出力されて、完了します。
エラーっぽい出力がなければ、アップロード完了です!


http://hogehoge.phpfogapp.com
にアクセスしてみましょう!

phperならもう100回は見ているphpinfo画面が表示されるはずです、お疲れ様でした!


当然作製していくとファイルを更新したり追加したりします。
上の三行はファイルを追加したのでadd&commit&pushしていますが、更新だけならcommit&push、ファイルが増えたりしたら add&commit&pushです。まあ、必ず三行やっても大丈夫ですけど。
他にも色々操作はあるのですが、gitでググりましょう。そもそも私も普段gitつかわないのでかなりうろおぼえです。
後、gitの操作はそのディレクトリの中でやりましょう。

DBについて

そうそう、DBアクセスしないphpとかありえないですよね。
DBをつかうのは超簡単です。最初っからMysqlがついてきますからね!別にインスタンス作らないと行けないサービスとは手軽さがちがいます。


https://www.phpfog.com/apps/{アプリのID}#/logs_and_database

この画面を開きまして、Change Database Passwordから適当にDBパスワードを変更しましょう。


そして、おもむろにAccess the Database through phpMyAdminリンクを踏みますと、phperの友、phpMyAdminからDBが操作できるわけですね!

もうここは説明不要ですよね?
すでにhogehoge-phpfogapp-comみたいなDBができていると思うので、そこにTableをざくざくと作っていけばOkですね。


PHPからアクセスする為のMysqlのホスト名とかは
https://www.phpfog.com/apps/{アプリのID}#/logs_and_database
この画面に書いてありますので、コピペしましょう。

以上!どうですか!

かんたんでしょ?
phpfogヤバイ(手軽的な意味で)

phpfogの気にくわない所

残念ですけど、phpfogにも気にくわない所はけっこーあります。
いくつかあげておきますね


・サーバーのエラーログが見れない
一番これがありえないんですけど、まあその内実装されるっぽいのでまちましょう。
http://help.phpfog.com/discussions/problems/825-seeing-php-errors-how
http://help.phpfog.com/discussions/problems/551-logging
Display_errorsとかありえない…

そもそも500が帰ってきたとき(コンパイルエラーとか)、画面に何も出ないので、辛い。


phpが刺さって落ちてる事がある
これは多分phpfcgiとして動かしているからなんだとおもいますが、phpが落ちる事が有ります。
管理画面だと
https://www.phpfog.com/apps/{アプリのID}
ここの画面で、
Status: Checking
となっている時がそうです。(こうなってても動いてる事もあります。ページが開けない&ここがCheckingの時がおそらく刺さってる)

ほっとくと直るよ、みたいな事かいてあるんですが、案外直りません。
phpを再起動してやる必要があり、それにはどうやらgit pushしてやるのが一番速いみたいです。


・Freeといいつつ、6ヶ月でおわってしまう
プラン選択の所で書きましたが、phpfogは6ヶ月以上つかうなら、有料にしてね、という事みたいです。
まあ私はお金をはらうのはやぶさかではないのですが(今のクオリティではどうかと思うが)、とにかくフリー!という人は微妙ですね。

しかしまあ、色々あるけどこの手軽さはすごい

herokuもそうですけど、phpfogはさらに手軽。手軽こそ正義のphpを体現したPaaSといえます。
クラウドとかよくわかんない、という人も是非一度つかってみて、手軽さを体感しましょう。


さらに、お金をはらえば、クラウドの神髄たるスケーリング(サーバー性能アップや、DBの容量アップ)を体験できますし、
そもそも体験できちゃまずいですがバックアップやハード故障のことをかんがえなくてすむ(といっても…ですが)クラウドの手軽さもよくわかるんじゃないかなと。


正直、本当に正直な所をいえば、dotcloudの方がいいんですけど、この手軽さは他のPaaSも見習うべきですよね!ってことで以上です!


オマケ:Facebook連携したなにか!

dotcloudやGAEでFacebook連携したレポートを知ってる人が書いているので、便乗します…と言いたいんですけど、時間がない。


一応こんな感じでちゃんと動きますよ!
http://hpm.phpfogapp.com/
(データは保存してません)


Facebook PHP SDKfacebook.php fb_ca_chain_bundle.crtの二つと、以下を適当に保存して、適当にfacebook アプリ登録からキー生成して突っ込めばうごきましたね。
このあたりのフローは http://d.hatena.ne.jp/ramyana/20101012/1286897340 こちらなどが参考になるかと。

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

require_once('./facebook.php');
$facebook = new Facebook(array(
  'appId'  => '「APP IDを入れる」',
  'secret' => '「アプリの秘訣訳はどうか…」',
  'cookie' => true,
));

$session = $facebook->getSession();
$me = null;
// Session based API call.
if ($session) {
  try {
    $uid = $facebook->getUser();
    $me = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
  }
}

//create login or logout url
$permissions = array('req_perms'=>'user_about_me,read_friendlists');
// login or logout url will be needed depending on current user state.
if ($me) {
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $loginUrl = $facebook->getLoginUrl($permissions);
}

?>
<html>
<head>
<title>fb test</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
</head>

<body>
    <div>
    <?php if($me){ ?>
    <a href="<?php echo $logoutUrl; ?>">
      <img src="http://static.ak.fbcdn.net/rsrc.php/z2Y31/hash/cxrz4k7j.gif">
    </a>
    <?php }else{ ?>
      <a href="<?php echo $loginUrl; ?>">
        <img src="http://static.ak.fbcdn.net/rsrc.php/zB6N8/hash/4li2k73z.gif">
      </a>
    <?php } ?>
    </div>

    <?php if ($me){ ?>
    <h3>あなた</h3>
    <img src="https://graph.facebook.com/<?php echo $uid; ?>/picture">
    <?php echo $me['name']; ?>

    <h3>あなたの情報</h3>
    <div style="overflow:scroll; height:400px; width:1000px;">
	    <pre><?php print_r($me); ?></pre>
    </div>
	
	<h3>あなたの友達 10人</h3>
	<pre>
	<?php
	// read my friends 	
	if ($session) {
		try {
			$friends = $facebook->api('/me/friends');
		} catch (FacebookApiException $e) {
			error_log($e);
		}
	}	

	$limit = 10;
	foreach($friends['data'] as $friend){ 
		$f =  $facebook->api('/'.$friend['id']);
		$limit--;
		?>
			<img src="https://graph.facebook.com/<?php echo $f['id']; ?>/picture"> <?php echo $f['name']; ?><br />
		<?php 
		if( $limit <= 0 ){ break; } 
	}
	?>
	</pre>

    <?php }else{ ?>
	    <strong>未ログイン</strong>
    <?php } ?>
</body>
</html>

*1:あれでややこしいと言ってしまうのに罪悪感もありますが、つかみなので…

*2:実際、間違ってないんだよなw