2012-12-16

[windows] ESD インストール ファイル を再登録する

C:\ESD\Windows が存在するのにシステムから認識されなくなってしまった場合、以下のレジストリ断片を結合すると再度認識されるようになりました。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\WebSetup]
"ImageIndex"=dword:00000001
"ImageLocation"="C:\\ESD\\Windows\\sources\\install.esd"
"MediaLocation"="C:\\ESD\\Windows"

このまま foobar.reg などと保存して結合できます。

Windows ESD インストールファイル C:\ESD\Windows はインストールディスクの内容をコピーしたり、Windows8-Setup.exe を実行後プロダクトキーを入力して再ダウンロードすることで再取得できます。

Windows8-Setup.exe は自動的に既存の C:\ESD\Windows とレジストリの WebSetup キーをクリアするようなので既に利用可能な Windows ESD インストールファイルを壊したくない人は実行に注意してください。

関連情報
プロダクト キーのみを使用して Windows 8 にアップグレードする方法 - Microsoft Windows
hidekiy blog: Windows 8 のリフレッシュ機能を試してみました

2012-12-08

[Node.js] man-in-the-middle 攻撃にご用心

Node.js は基本的にはサーバーサイドで使うものなので、まともなホスティング業者のサービスを利用する限りは通信環境についてそこまでセキュリティリスクは高くないと思います。しかしナントカ API に https でアクセスしているから安全に違いないと信じ込むのは考え物で、

HTTPS Node.js Manual & Documentation - https.request(options, callback)
rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Default false.
を見ると分かりますが、Node.js v0.8.18 時点で未だに rejectUnauthorized のデフォルト値が false なのでデフォルトのまま使うと中間者攻撃の余地があります。

証明書の検証をしない SSL なんて存在しない方がましだと思うので、きちんと検証できているかどうかを必ず確認しましょう。例えば https://www.l.google.com/ など接続はできて証明書の検証に失敗するアドレスにリクエストして、エラーになることを確認すると簡単だと思います。さらに心配性な方は Node.js が正当なルート証明書を使っているかどうかも調べておきましょう。

[windows] BitLocker を有効にしてみました

Windows 8 Pro にしたら一緒に付いてきた、保護されないアクセスからデータを守ってくれるらしい BitLocker を有効にしてみました。

保護されないアクセスとは例えば以下のようなアクセス許可が正常に適用されない状況です。
  • LiveCD で起動して USB メモリにデータをコピーして持って帰る
  • HDD を取り外して持ち出し、別の OS からアクセス許可を無視してオフラインアクセスする
  • オフラインで OS にルートキットを秘密裏に書き込んでおきパスワードを盗む

暗号化の処理について、作業を中断することなくバックグラウンドで処理が進行し、暗号化が途中まで完了しているという状態が許容されているようです (暗号化進行中にシャットダウンしても大丈夫)。暗号化も Low-Priority I/O でおしとやかに処理されるのでとても良くできている印象を受けました。

BitLocker による保護とは意図したとおりの OS のみがディスクにアクセスするよう制限することにあるので、TPM 付きのマシンなら同じマシンで起動していることを自動的に確認できるので起動時のパスワード入力は無しにできます (PIN も設定可能)。TPM 無しの場合でも USB メモリもしくはパスワードでも BitLocker を有効にできます (要ポリシー変更)

また起動時に起動用のパスワードを打ち込めば必ずフルアクセス出来るようになるのではなく、正常に保護されない恐れのあるアクセス (正規の Windows 以外からアクセスされる場合) の時は回復キー (数字48桁) を要求されます。この理由はフルコントロール可能な回復キーは管理者が管理し、標準ユーザー権限のユーザーは正規の認証を経ることになっているからだと思います。

この仕組みはデータが複数個に増えるわけではなく、データを暗号化する鍵を別々の方法で暗号化して保管することで実現されています。内部で実際にデータを暗号化しているマスターキーは目に見える形では表示されません。

WinRE を使いたい時も回復キーを要求され少しめんどくさいですが、あらかじめ Windows 内で「保護の中断」を管理者権限で実行しておくと回復キー不要でアクセスできます。BIOS のアップデートも回復キーを要求されるはずなので、行う際は同様に保護の中断を行っておくとスムーズに行えると思います。

「保護の中断」と「BitLocker を無効にする」の違いは、保護の中断の場合はディスクの暗号化はそのままで、鍵が誰でも使用可能な状態で書き込まれるということで、次の Windows 起動時に自動的にパスワード不要の鍵は削除され保護が再開します。BitLocker を無効にするを行った場合は全てのセクタの暗号化が解除され BitLocker を有効にする前の何も保護されていない状態に戻ります。解除には使用中の領域全体への読み取りと書き込みアクセスを伴うので少し時間がかかります。

スリープ状態の場合は BitLocker では保護されませんが休止状態ならば保護されます。スリープ状態のパソコンからメモリダンプを取ることができれば鍵を盗むことができるかもしれません。休止状態の場合は保護されるので、自動的に休止状態に移行するように設定することもより安全性を高めるために役に立つかもしれません。

関連情報
BitLocker ドライブ暗号化でファイルを保護する
BitLocker に関してよく寄せられる質問 (FAQ)

[windows] Windows 回復環境 (WinRE) を修理する

Windows 本体が起動しない場合は WinRE もしくはインストールメディアから利用可能なスタートアップ修復によって自動修復することができます。しかしインストール済みの WinRE 自体が起動しなくなった場合は自分で修理する必要があるようです。

winre.win の入ったパーティーションの開始位置をずらした場合や、BCD (ブート構成データ) から WinRE 自体のエントリをうっかり消去してしまった場合は、bootrec /rebuildbcd を使っても自動修復できません。そこで bcdedit を使ってちまちま再設定するのではなく reagentc を使うと以下の手順で簡単に再設定出来ることが分かりました。
  1. winre.win というイメージをインストールディスクから抽出するか設置先から救出してきて、C:\Windows\System32\Recovery に戻します
  2. reagentc /enable というコマンドで BCD エントリとディスクイメージの設置 (winre.win のコピーではなく移動w) が完了します
  3. 内部状態 ReAgent.xml には設定していると記録されていて、実際には BCD エントリが存在していない矛盾した状態になっているとエラーが出ます。その場合は ReAgent.xml を初期化すると無事動きます。
    初期状態の ReAgent.xml は C:\Windows\WinSxS 内のどこかにあるようなので検索してみてください。手元の Windows 8 では C:\Windows\WinSxS\x86_microsoft-windows-winre-recoveryagent_... みたいな所にありました。
Windows 回復環境の現在の設定状況については reagentc /info で調べることができ、WinRE の無効化は reagentc /disable で行えます。

壊れる原因について
Windows において MBR 経由の従来型のブート方式ではパーティーションごとの UUID 的な何かではなく、ディスク内でのパーティーションの開始位置によってどの OS を起動するべきかを BCD 内で指定しています。

よって gparted などで C:\Windows の入った領域の開始位置をずらす操作 (右側への拡張と縮小ではなく、左側への移動) を行うとブート不能になり、スタートアップ修復が必要になります。

スタートアップ修復を行おうにも何もブートしない場合はインストールメディアから起動すればスタートアップ修復が行えます。

スタートアップ修復に頼らずに BCD を修復するには
Windows に関しては WinRE 内に収録されている bootrec /rebuildbcd でおそらく復活します。

手動で直したい場合には BCD を bcdedit で更新すると直ります。具体的には以下の手順で行えます。
  1. WinRE のコンソールを開きます。
  2. bcdedit /enum osloader で identifier を確認します。device の所が Unknown になっているエントリが壊れています。
  3. diskpart を使って list volume などでドライブレターを確認し、dir /a c:\ などで内容を確認します。
  4. bcdedit {identifier} /set device partition=C: などと OS の入っているドライブを指定して正しいパーティーション開始位置をセットします

関連情報
スタートアップ修復 - Microsoft Windows
GParted FAQ - 14: After resizing my Windows 7 or Vista partition, my computer won't boot. How can I fix this?
win7 システムの修復
Installing WinRE to hard disk - MSFN Forum

2012-12-07

[Express] req.next は場合により壊れている

Express で何か作る際に、探検好きな人はレスポンスオブジェクト res には リクエストオブジェクト req が入っていて、req には次に呼び出すべき関数に goto する関数 next が入っていることをご存知かと思います。

この req.next について、値はミドルウェア中では正しくてもリクエストルーター中ではちょっと間違っている (リクエストルーター自体を skip する next になっている) ように見えるので、保守的な方は常に引数として渡される方の next を使うようにしましょう。

var express = require('express'),
    app = express();

app.use(function (req, res, next) {
    console.log('middleware:', req.next === next, res.req.next === next);
    next();
});

app.get('/', function (req, res, next) {
    console.log('router:', req.next === next, res.req.next === next);
    // req.next(); doesn't work correctly.
    next();
}, function (req, res, next) {
    res.send('ok');
});

app.listen(3000);

/*
middleware: true true
router: false false
*/

[Express] エラーの伝搬と処理について

Express でリクエストを処理しているとき、発生したエラーを適切に処理する仕組みについてドキュメントではあまり詳しく取り扱われていませんが、少し理解しておくともっと楽しくコードが書けると思います。

express において設定するコールバック関数は受け取る引数の数で勝手に分類され、3個以下の場合は正常系、4個の場合は異常系となります。正常系のとき引数リストは req, res, next で、異常系のときは err, req, res, next です。

正確には connect の範疇となるミドルウェアも、express に内蔵されているリクエストルーターと同じような振る舞いをするように作られています。

正常系でエラーが発生した場合はコールバック関数と同期的に発生したエラーは throw でも良いですが非同期的に発生したエラーは next(err) として伝搬させる必要があります。区別が面倒な方はすべて next(err) と書くことにしてもよいと思います。

異常系のコールバック関数は必ずエラーに対処しないといけないわけではなく、next(err) を呼び出してエラーを伝搬することもできます。

全てのミドルウエアを処理してもエラーを処理しきれなかったとき connect によりデフォルトのエラー画面が表示されます。あらかじめミドルウェアの最後の方に errorHandler を入れておくと素敵なエラーページを出せます。connect のモジュールを使っているのにタイトルが Express となる理由は express の lib/express.js を見ると分かります。

以下のコードで色々試してみてください。

/*
Q. 以下のアドレスのレスポンスはどうなるでしょうか
http://localhost:3000/
http://localhost:3000/?error=1
http://localhost:3000/?error=1&catch=1
http://localhost:3000/?pass=1
*/

process.env.DEBUG = '*';

var express = require('express'),
    app = express();

// middleware
app.use(express.logger());
app.use(function middlewareA(req, res, next) {
    req.trace = [0];
    next();
});
app.use(app.router);
app.use(function middlewareB(err, req, res, next) {
    req.trace.push(5);
    res.send({msg:'final: error', trace: req.trace, error: String(err)});
});
app.use(function middlewareC(req, res, next) {
    req.trace.push(6);
    res.send({msg:'final: not error', trace: req.trace});
});

// request router
app.get('/', function (req, res, next) {
    req.trace.push(1);
    next();
});
app.get('/', function (req, res, next) {
    req.trace.push(2);

    if (req.param('error')) {
        next(new Error('something happened'));
    } else {
        next();
    }
}, function (req, res, next) {
    req.trace.push(3);

    if (req.param('pass')) {
        next();
    } else {
        res.send({msg:'ok', trace: req.trace});
    }
}, function (err, req, res, next) {
    req.trace.push(4);

    if (req.param('catch')) {
        res.send({msg:'caught error', trace: req.trace, error: String(err)});
    } else {
        next(err);
    }
});

app.listen(3000);

リンク
node.js - Error handling principles for NodeJS + Express apps? - Stack Overflow
express/test/app.routes.error.js

[Express] static と directory を組み合わせて使う

正確には Express というより connect についての話です。staticdirectory を使ってあるディレクトリの中を全て公開するような設定の仕方について考えます。

このように書くと http://localhost:3000/some/directory への要求は static によって http://localhost:3000/some/directory/ へのリダイレクトになり、index.html があればその内容が static により返され、無ければ次のミドルウェアに fallback して directory によるファイル一覧が返ります。

Apache 風の動作はこちらが該当します。

var express = require('express'),
    app = express();

app.use(express.static('/path_to_dir'));
app.use(express.directory('/path_to_dir'));
app.listen(3000);

一方でこのように先ほどとは逆順でミドルウェアを追加すると、http://localhost:3000/some/directory と http://localhost:3000/some/directory/ の返答は必ず directory によるファイル一覧になり、index.html があっても返りません。

ソースツリーをそのまま公開したい場合など index.html ではなくファイル一覧が出てほしい場合はこっちのコードが役に立つかもしれません。

var express = require('express'),
    app = express();

app.use(express.directory('/path_to_dir'));
app.use(express.static('/path_to_dir'));
app.listen(3000);

static について、ディレクトリが trailing slash 付きでリクエストされたとき自動的に index.html を探す動作は send というライブラリが行っています。

水面下での動作が気になる人は express, connect, send で活用されている debug によるデバッグ出力を環境変数 DEBUG を * に設定することで有効にできます。

$ env DEBUG='*' node app.js

2012-12-02

[facebook] 空の写真アルバムを作成する方法

または、簡易アップローダーを復活させる方法について。

Facebook で例えば携帯アップロード内の写真を別のアルバムを新しく作って移動させたいとき、移動先のアルバムが既に存在している必要があって、さらに空のアルバムを作る方法が存在しないように見えるので詰みます。

ユーザーを信頼していない Facebook の UI にイライラしていた方も今日からは以下の方法で空のアルバムを大量生産しましょう。

方法
  1. Flash Player を一時的に無効にする。
    chrome://plugins (Chrome), アドオンマネージャー (Firefox), アドオンの管理 (Internet Explorer) から一時的に無効にできます
  2. [+写真を追加] ボタンを押すといつもと違う「簡易アップローダー」の画面が出るのでアルバムを作成する
  3. 写真を5枚までアップロードできるページが開くが何もしなくてよい (この画面の時点で既に空のアルバムが出来ています)

関連情報
アルバム間で写真を移動するにはどうすればよいですか。 | Facebookヘルプセンター

ノート PC のバッテリーを安全に 0% まで使い切る方法

バッテリーの真の状態とコントローラーが想定している状態にずれが生じると残量パーセント表示が少なめに出るようになる (0% 表示になっても本当はもう少し使える) ことが起こりえます。

この状況を何とかするためにはバッテリをいったん使い切ってもう一度フル充電すると良いのですが、ディスクをマウントしたまま電源断を起こすのは心苦しく、省電力設定をいじるのも面倒くさいので、安全に電池を使い切る方法について考えてみました。

方法
いったん再起動して、BIOSセットアップやブートメニューを出してその画面で放置する。

解説
この画面ではまだストレージは読み書きモードでマウントされておらず、省電力機能も有効ではないので安全確実に残量 0% 表示のあと勝手に電源が落ちるところまで進みます。電源が落ちた後は過放電を防ぐために速やかに充電してください。

2012-11-30

[Node.js] async を使って複数のファイルを同時に fs.stat する

非同期処理をもっと楽しくする async の async.parallel を使うと複数の処理を並列に行い、全部処理が終わった時点もしくはいずれかの処理でエラーが発生した時点で、代表して一度だけコールバック関数が呼ばれるようにできます。

処理完了もしくはエラー終了の時点で、cb を cb(err, result) の形式で呼び出します。エラーがない場合は err を null とすれば OK です。

var async = require('async'),
    fs = require('fs');

async.parallel([
    function (cb) {
        fs.stat('b.txt', function (err, stat) {
            if (err) { return cb(err); }
            cb(null, +stat.mtime)
        });
    },
    function (cb) {
        fs.stat('b.txt', function (err, stat) {
            if (err) { return cb(err); }
            cb(null, +stat.mtime)
        });
    }
], function (err, results) {
    if (err) { throw err; }
    console.log(results);  // [ 1354174306000, 1354112137000 ]
});

fs.stat するコードが同じことを繰り返している点が格好良くないので一つにまとめます。

var async = require('async'),
    fs = require('fs');

async.parallel(['a.txt', 'b.txt'].map(function (file) {
    return function (cb) {
        fs.stat(file, function (err, stat) {
            if (err) { return cb(err); }
            cb(null, +stat.mtime)
        });
    };
}), function (err, results) {
    if (err) { throw err; }
    console.log(results);  // [1354174306000, 1354112137000 ]
});

async.parallel の第一引数をオブジェクトにすると結果 results もオブジェクトにもできることを用いて、さらに underscore の便利な関数 _.object (二要素の配列の配列もしくは同じ長さの配列2つからオブジェクトを作る関数) を活用して以下のようにできます。

var async = require('async'),
    fs = require('fs'),
    _ = require('underscore');

async.parallel(_.object(['a.txt', 'b.txt'].map(function (file) {
    return [file, function (cb) {
        fs.stat(file, function (err, stat) {
            if (err) { return cb(err); }
            cb(null, +stat.mtime)
        });
    }];
})), function (err, results) {
    if (err) { throw err; }
    console.log(results);  // { 'a.txt': 1354174306000, 'b.txt': 1354112137000 }
});

2012-11-29

[windows] 復元ポイントに保存されたレジストリを閲覧する (Windows XP用)

レジストリを壊してしまった場合は「システムの復元」という機能で直近の復元ポイントの状態まで戻すのが安全かつ確実でお勧めできる方法ですが、少し昔のレジストリがどうなっていたかだけを知りたい場合には、C:\System Volume Information\_restore{GUID}\RPxxx\Snapshot の中に入っているレジストリハイブのスナップショットを使えばよいです。

RPxxx (xxx は連番, RP=RestorePoint) はそれぞれ一つの復元ポイントを表していて、更新時刻を見ることでどのくらい過去の状態か分かります。

これらのレジストリハイブはバイナリで保存されていてそのままでは中が見れません。しかしながらレジストリエディタで「ハイブの読み込み」という機能を使うと過去の任意のレジストリハイブをマウントして閲覧でき、ついでにエクスポートなどもできます。

ハイブの読み込みについて、具体的には、HKEY_LOCAL_MACHINE を選択した後、ファイル>ハイブの読み込み、でレジストリファイルを読み込み、適当な名前 system_rp123 などを付けて読み込み、不要になったらアンロードすれば良いです。

関連情報
システムの復元とは - Windows 7
System Volume Information フォルダへアクセスする方法
レジストリにハイブを読み込む

2012-11-27

[blog] ソースコード表示を SHJS に乗り換えました

ブログのコードを見やすいように予約語や文字列リテラル、数値リテラルなど文法に沿って色付きにしてくれるスクリプトとして長らく google-code-prettify を使っていましたが、Internet Explorer 10 で改行が消滅して表示がおかしくなっている (2011年6月版で改行が LF のみの場合に変になることを確認) のを発見したので、代わりに SHJS を使ってみることにしました。

SHJS には google-code-prettify と違って言語の自動解析機能が付いていない所が気に入りました。対応言語も一通り揃っていて、付属のカラーテーマも色々あって楽しいです。行番号を付加する機能は付いていません。

使い方本体と言語定義ファイルを読み込み、コードを pre の中に書いて class を言語定義ファイルに合わせて sh_LANGUAGE とするだけです。例えば JavaScript なら sh_javascript とすればよいです。

このブログでは現在カラーテーマは whitengrey になっています。
SHJS を SHJS で表示した例:

/*
SHJS - Syntax Highlighting in JavaScript
Copyright (C) 2007, 2008 gnombat@users.sourceforge.net
License: http://shjs.sourceforge.net/doc/gplv3.html
*/

if (! this.sh_languages) {
  this.sh_languages = {};
}
var sh_requests = {};

function sh_isEmailAddress(url) {
  if (/^mailto:/.test(url)) {
    return false;
  }
  return url.indexOf('@') !== -1;
}

function sh_setHref(tags, numTags, inputString) {
  var url = inputString.substring(tags[numTags - 2].pos, tags[numTags - 1].pos);
  if (url.length >= 2 && url.charAt(0) === '<' && url.charAt(url.length - 1) === '>') {
    url = url.substr(1, url.length - 2);
  }
  if (sh_isEmailAddress(url)) {
    url = 'mailto:' + url;
  }
  tags[numTags - 2].node.href = url;
}

SHJS - Syntax Highlighting in JavaScript

2014/08/10 追記
さらに Highlight.js に乗り換えました。

2012-11-26

[Express] Cannot GET /foobar はどこで出されているか

Express で全てのコールバックがレスポンスを返さなかった場合に表示される Cannot GET /foobar という感じの 404 エラーページは誰が出しているのかというと、express.js の依存ライブラリ Connectlib/proto.js で関数 app.handle が出力しています。

ルーターを含む全ての Middleware が next() を行って最後まで突っ走ってしまうと Cannot ... のコードに到達します。

ちなみに Middleware 内で next() をせず res.send() などでレスポンスを返すこともしなかった場合は、クライアント側からの見え方は延々と何もレスポンスが返らない状態になり、一方でサーバーもエラーを出すことのない両者にらみ合いの膠着状態になります。

2012-11-23

Windows 8 のリフレッシュ機能を試してみました

Windows 7 から Windows 8 にアップグレードしたらもともと入っていた IME 2010 がインストーラーの不具合?で削除できなくなってしまったので、興味のあった PC のリフレッシュ機能を試してみました。

リフレッシュ機能とはドキュメントや写真、音楽などのファイルを受け継ぎつつ OS を初期化する新機能で、コンピュータの復元でも回復できないとき (セーフモードでも起動しないような、起動に必要なファイルが破損している状況など) でもこれを使えばかなり強力に復活できるように見えます。

この機能にアクセスする方法は PC 設定>全般>PC をリフレッシュする、もしくは起動失敗時にブートマネージャーが自動的に出してくれる回復用画面より選択できます。

リフレッシュに伴ってレジストリと Program Files, AppData, ProgramData は C:\Windows.old 内に移動されました。Windows ストアからインストールしたアプリは自動的に再インストールされ復活しました。Windows のほとんどの設定は、システムとユーザーアカウント固有の設定ともに受け継がれるようです。

インストールされていた従来型のアプリケーションとその設定は消滅しますが、インストールされていたアプリケーションの一覧という遺書をリフレッシュ時にデスクトップに HTML 形式で保存してくれるのが役に立ちました。

詳しい説明
リフレッシュ機能は OS のインストール時に自動的に作成される C:\ESD\Windows に保存されたインストールイメージを用いて Windows 8 をデータ受け継ぎ方式で再度インストールを実行する仕組みのようです。したがってリカバリディスク作ってないや派の人や、インストールメディアを作らずアップグレードした人、自力でアップグレードしたからリカバリディスクが Windows XP しかない人でも安心して(?) OS を破壊できることになります。

レジストリや AppData が自動的に受け継がれない理由はおそらく、システムと密結合した設定が保存されるので、リフレッシュ後にも障害が残ることを危惧してこのようにクリアされるようになっているのだと思います。

リフレッシュ時に Chrome のプロファイルはリセットされますが、C:\Windows.old\Users\USERNAME\AppData\Local\Google\Chrome から必要なだけ持ってくれば復活します。

古い環境からのファイルの救出が完了したあと C:\Windows.old を削除しようとするとアクセス権限が面倒くさいことに気づくと思います。管理者なら任意のオブジェクトの所有権を奪還する特権を行使してアクセス権を再設定すれば削除できますが、簡単に削除するには Windows 付属の ディスク クリーンアップ を使うとよいです。
Windows.old フォルダーを削除する方法 - Microsoft Windows ヘルプ

C:\ESD\Windows も「Windows ESD インストールファイル」という項目で同様に削除できますが残しておくと便利だと思います。

C:\ESD\Windows を削除してしまっていたり、ブートマネージャーも含めて壊れてしまっているときはインストールメディアで起動すれば修復機能が使えます。

参考
PC を復元、リフレッシュ、または初期状態に戻す方法 - Microsoft Windows ヘルプ

2012-11-20

[heroku] 最新の Node.js を使ってアプリを動かす設定

Heroku に Node.js で動くアプリケーションを置くことまでは出来たけれど Node.js のバージョンが v0.4.7 になることにがっかりしている人はこの記事をご覧ください。

どのバージョンの Node.js を使うかを指定するには公式ドキュメント Specifying a version of Node.js or npm に書かれている通り、package.json の engines プロパティに最新版を使用する旨を記述すればよいです。

デプロイする度にとにかく最新になることを望む edgy な方や遊びのプロジェクトは単に x と指定しておけば最新の stable release になります。

もし製品版をデプロイするときは自動的に壊れてしまうことを防ぐため、依存モジュールも含めてバージョンを全て固定することを強くお勧めします。

とにかく最新版になる package.json の例:

{
    "name":"適当な名前",
    "version":"0.0.1",
    "dependencies":{
        "express":"",
        "underscore":"",
        "mongoose":"",
        "request":""
    },
    "engines":{
        "node":"x",
        "npm":"x"
    }
}

[dotcloud] 新しい Perl を使うように設定してみました

基本的には設定ファイル dotcloud.yml を 公式ドキュメント dotCloud - Perl Service にある通り perl_version: v5.16.x などと設定するだけで OK のはずだと思っていました。

しかし最近追加されたインクリメンタルなビルド機能 (前回のビルド結果を受け継いで変更のない依存モジュールをそのまま使いビルド時間を短縮する) が Perl のバージョンの更新を察知してくれないせいで、バイナリのリンクがだまって壊れました。

この問題を解決するためにはクリーンなビルド (前回の結果を受け継がないビルド) を行うようにデプロイを

$ dotcloud push --clean

と --clean オプション付きで実行する必要があります (2012/11/19 時点)。

2012-11-17

パスワードの管理について

メインのメールアドレスに設定しているパスワードを他のサイトのパスワードに設定しないことが何より肝心だと思います。

うちでは使用頻度の低いサイトのアカウントにはランダムな文字列のパスワードを設定して、それをパスワード管理ソフト KeePass を使ってマスタパスワードで暗号化して保存しています。そして保存した最新のパスワードが他のパソコンでも使えないと不便なのでそのファイルを Dropbox を使って同期しています。

非公式ですが公認されている Android 版のクライアント KeePassDroid も緊急用として活用しています。

[Node.js] request を使って Facebook の Graph API にアクセスする

Facebook Graph API など REST で OAuth 2.0 な API にアクセスする際は素朴な HTTP クライアントがあれば十分と思うので Node.js では最近は request を使っています。

このクライアントを使うにあたり中間者攻撃などを防ぐためオプション strictSSL を true として SSL の証明書の検証を行うことを有効にすることが大切だと思います。しかし残念なことに Node.js v0.8.14 では graph.facebook.com の wildcard 証明書について壊れていますw (#4255) Node.js v0.8.16 で直っているように見えます。

request について、パラメータの与え方が GET の場合は qs、POST の場合は form になることに注意します。また、オプション json を true にしておくとレスポンスを JSON としてデコードしてくれます (正確にはリクエストボディ body の Content-Type を application/json に設定する機能も含みます)。

さらに詳しくは 公式ドキュメント をご参照ください。

Graph API には具体的に以下のコードでアクセスできます。

var request = require('request').defaults({
    strictSSL: true
});

function getIdentity() {
    request.get('https://graph.facebook.com/me', {
        qs: {
            access_token: ACCESS_TOKEN
        },
        json: true
    }, function (err, resp, data) {
        if (err) { throw err; }
        if (resp.statusCode !== 200) { throw new Error(JSON.stringify(data)); }
        console.log(data);
    });
}

function writeWall() {
    request.post('https://graph.facebook.com/me/feed', {
        form: {
            message: MESSAGE,
            access_token: ACCESS_TOKEN
        },
        json: true
    }, function (err, resp, data) {
        if (err) { throw err; }
        if (resp.statusCode !== 200) { throw new Error(JSON.stringify(data)); }
        console.log(data);
    });
}

蛇足ですが request には OAuth 1.0 用のリクエスト署名機能も内蔵されているので oauth パラメータを渡すことで Twitter - REST API にも追加モジュールなしでアクセス可能です。

2012-10-15

[apache] .htaccess であるモジュールが組み込まれているか調べる

以下のように .htaccess に IfModule と Header を使えばビーコン診断的にどのモジュールが httpd に組み込まれているか分かります。結果はブラウザの開発者ツールなどを用いてレスポンスヘッダを見ます。自分が httpd.conf を設定できる状況ではない共有サーバーなどで役に立つかもしれません。

# in .htaccess

<IfModule mod_rewrite.c>
    Header set X-Has-Rewrite 1
</IfModule>

<IfModule mod_deflate.c>
    Header set X-Has-Deflate 1
</IfModule>

<IfModule mod_filter.c>
    Header set X-Has-Filter 1
</IfModule>

2012-09-27

[linux] ping は通るのに No route to host と言われる

ping による疎通は確認できるのに、いざ ssh などで繋ごうとすると No route to host というエラーで即座に接続失敗し途方に暮れる場合、おそらく原因は接続先のホストの iptables によりパケットがブロックされ、到達不能を意味する ICMP パケットが返ってきたことによります。

以下のコマンドで INPUT ポリシーをチェックします。上から順にマッチさせていき、マッチし次第ジャンプして終わるので、デフォルト条件の設定されていそうな一番下の行が肝心です。

# /sbin/iptables -L

--verbose を追加してブロックしているポリシーのカウンタを見ながらブロック状況を観察できます。

# /sbin/iptables -L --verbose

おそらく問題となっているのは INPUT ポリシー最下行で全てのパケットにマッチするこういう行です

... -j REJECT --reject-with icmp-host-prohibited

追加の説明
ファイアウォールの良くある動作として、不都合なパケットの受信を単に無視する動作ならタイムアウトとなります。しかしクライアントから見て TCP や UDP でパケットを送信した後、ICMP で Destination Unreachable Message が届いたときは親切にも No route to host と案内してくれるようです。

ちなみに icmp-host-prohibited は ICMP Unreachable Message の コード10 であり、経路上の障害などを調査するためのコマンド traceroute の結果に !X や !10 と表示されるようです。

参考
Man page of IPTABLES
traceroute - Wikipedia
Internet Control Message Protocol (ICMP) - Wikipedia

2012-08-02

Windows 8 でスタートメニューはどうなったのか

スタートメニューは一体どこへ消えたのかというと、全画面化して「スタート画面」アプリになったと考えると理解しやすいと思います。

旧スタートメニューの「すべてのプログラム」相当の画面はスタート画面から右クリックして下に出るメニュー右端、もしくは右下または右上隅からチャームを出して検索からアプリを選択すると出てきます。

結局のところ全てのアプリは全画面表示となり、デスクトップも一つの全画面表示アプリであり、Windows 7 以前のアプリケーションを継続して動作させるための互換性維持のために存在するアプリであって、必要なければ使わなくてもよい、という意味だと思います。

Windows 8 Release Preview を試してみました

ふと思い立って Windows 8 Release Preview をデュアルブートでインストールしてみた感想を書いておきます。手順は最初にパーティーションを縮小して新しい領域をフォーマットし、ISOイメージをUSBメモリに書き込んでブートしてインストールしました。インストール時に高度なオプションみたいな感じで任意のパーティーションにインストールできます。

結局のところ全体的にいい感じで互換性も十分に確保されているように思ったのでクリーンインストールしようと思います。

セキュアデスクトップ遷移が瞬時に終わる
権限昇格確認時に登場するセキュアデスクトップの使用頻度が通常低いためか常にスワップアウトされてるんじゃないか?っていうもっさり感が大きく改善されているようです。

スタートアップアプリを誰でも気軽に殺せる
行儀の悪いアプリはタスクマネージャーからどんどん無効化して欲しいという意図を感じます。Autoruns を使わなくとも、IEのアドオンの管理から無効化する感じでスタートアップアプリ(スタートメニューのスタートアップだけでなく、レジストリから起動するものも含む)を簡単に無効化できます。

エクスプローラーのお気に入りがフォルダ的に動作する
Windows 7 のエクスプローラー (MS純正ファイラー) のお気に入りという所を活用していていまいち不便なのが選択した瞬間に実のフォルダを開きなおす動作でチラついていらいらしたり、やっぱりお気に入りのもう一つ下を開きたかったときに上にスクロールする必要があるのがイマイチだったので。

画面遷移のアニメーションに酔わない
Windows 7 よりアニメーションが平面的で、奥行き方向に動かない様になって酔いにくく快適です。

Windows Defender の強化
最初から入ってる Windows Defender が Microsoft Security Essentials 相当に機能強化されているようです。
MSE が気に入っているのでこの変更によりそのまま使えるのが良いです。しかしメーカー製PCでは大人の事情により期限付きウイルス対策ソフトが入っていて、期限後アンインストールを要求するとは思えず、代わりに身代金を要求する可能性が大ですw

シャットダウンが設定の中に隠されてる
PC初心者(?)がせっせとシャットダウンして貴重な人類の活動時間をOSのブートで浪費することなく、何となくスリープで使っておけというメッセージに賛同します。

唯一気になる点:左矢印がギザギザ
インストールされていたメトロスタイルアプリを試したところアプリ内で戻るときの丸付きの左矢印が適切にアンチエイリアス処理されておらずギザギザなのがいまいちです。

追記:違うマシンでは滑らかに表示されたのでこれはハードウエア依存の問題のようです?

2012-06-15

Heroku や Google App Engine のさびれたアプリの初回アクセスを速くする方法

Heroku や Google App Engine などのWebアプリケーションを無料からホストしてくれるとてもありがたいサービスで、自分しか使わないデモアプリなどを置いている場合、久しぶりにアクセスすると、そのアクセスしたタイミングでやおらアプリケーションのインスタンスが立ち上がるのでしばらく(数秒程度)待たされます。

この動作があまり格好良くないので、何とかする方法を考えたところ、Webサイトの死活監視を無料で50サイトまで行ってくれるとてもありがたいサービス Uptime Robot を使って監視しておくと、定期的にアクセスしてくれるのでとても快適に動くようになります。ついでにダウンタイムも分かります。

もちろん世の中の全てのホストされているアプリをこのようにしてしまうとメモリ資源が無駄に必要になると予想されるので、良い子は監視対象とするのは必要な分だけにしましょう。

蛇足として Google App Engine では静的なファイルは Google CDN から配信されるのでアプリケーションがレスポンスを出すような URL を設定する必要があります。

2012-06-07

[Express] app.configure と app.use の使い方について

Express では app.configure を使うことで、NODE_ENV の本番環境 (production) 、開発環境 (development) の指定に応じて処理を分岐して設定を行うことができます。今回は具体例として、ミドルウエアを淡々と app.use(fn) で追加していく場合を考えます。

この時 app.use() が呼ばれる順番の通りに app の内部状態が設定されるので、production, development の両方に共通したミドルウエアを末尾の方に追加するには、適切なタイミングまで待ってから fn が呼ばれる app.configure(fn) を使う必要があります。app.configure も呼ばれた順番を尊重してコールバック関数を呼ぶことに要注意です。

また他にも、複数の場合に対応する app.configure(env1, env2, ..., fn) もOKです。NODE_ENV が存在しなかった場合のデフォルト値は development です (express/lib/http.js)。

var express = require('express'),
    app = express();

app.use(function (req, res, next) {
    console.log('1. before config');
    next();
});

app.configure('development', function () {
    app.use(function (req, res, next) {
        console.log('2. development');
        next();
    });
});

app.configure('production', function () {
    app.use(function (req, res, next) {
        console.log('2. production');
        next();
    });
});

app.configure('development', 'production', function () {
    app.use(function (req, res, next) {
        console.log('3. development/production');
        next();
    });
});

app.configure(function () {
    app.use(function (req, res, next) {
        console.log('4. after config');
        next();
    });
});

app.get('/', function (req, res, next) {
    console.log('5. get root');

    res.type('txt');
    res.send('ok');
});

app.listen(3000);

/* 実行例: http://localhost:3000/ をGETした場合

$ node server.js
1. before config
2. development
3. development/production
4. after config
5. get root

$ env NODE_ENV=production node server.js
1. before config
2. production
3. development/production
4. after config
5. get root

*/

2012/12/11 追記
app.configure は v3.0.0 で非推薦メソッドとなっているようです。今後は if (app.get('env') === 'development') などとして分岐すれば良いとのことです。

2012-06-03

[Express] リクエストハンドラの引数 next の使い方について

Node.js の Web Application Framework の一つである Express において、リクエストハンドラ第三引数の next の使い方について調べてみました。結局のところこれは一体何なのかというと、next の中身は次にリクエストを処理するべき関数を呼び出してくれる関数オブジェクトです。物好きな人用の説明なら、req, res の状態を持って次のリクエストハンドラに goto する continuation のイメージです。

実際にどのように使うかと言うと、何らかの理由でレスポンスを返さない場合に next() という感じで関数呼び出しを行います。引数として、自分のところで対処できないエラー (例外) が発生した場合はエラーオブジェクトを渡し、エラーはないけれど自分のところで対処するべきリクエストでない場合は引数なしで呼び出します。

エラーが発生した場合に適切に伝搬させるの例

var express = require('express'),
    app = express();

app.get('/error_sync', function (req, res, next) {
    next(new Error('sync error'));
    // この場合は throw new Error('sync error') でもOK
});

app.get('/error_async', function (req, res, next) {
    setTimeout(function () {
        next(new Error('async error'));
    }, 100);
});

app.listen(3000);

自分のところでは対処しないの例: リクエストのパラメータが3の倍数の場合 aho と返す。

var express = require('express'),
    app = express();

// 例えば http://localhost:3000/say/31 を開くと?

app.get('/say/:num', function (req, res, next) {
    var num = req.param('num');

    if (num % 3 === 0) {
        res.type('txt');
        res.send('aho: ' + num);
    } else {
        next();
    }
});

app.get('/say/:num', function (req, res, next) {
    var num = req.param('num');

    res.type('txt');
    res.send('not aho: ' + num);
});

app.listen(3000);

このコードを動作させるためには node.js に加えて express が必要なので、本体に同梱の npm コマンドを使って、同じディレクトリで npm install express として express をインストールする必要があります。

2012-06-02

[gimp] PNG 画像のファイルサイズを小さくするには

画面のキャプチャなどを JPEG で保存すると色が急激に変化するところの周りにもじゃっとしたノイズが乗るので通常 PNG で保存すると思いますが、何も考えず保存するとおそらくRGB各色8ビット(True Color) でアルファチャンネルなしの1ピクセルあたり24ビットのファイルが出来上がります。ネットも速くなったので通常これでクライアント側は困ることはないと思いますが、配信側の都合上転送量を削減したいなど極限まで絞りたいという場合は、もっと効率的なビット割り当てで同じような見た目になるインデックスカラーを検討してみる価値があります。

インデックスカラーとはピクセルごとにRGB値を記録するのではなく、あらかじめ色の目次(インデックス)を作ってから、各ピクセルでは目次の何番の色を置いたらよいかを記録する方式です。例えば256色インデックスカラーなら、log2 256 = 8 から、各ピクセルでは8ビットの割り当てで済みます。

GIMP を使ってファイルサイズをケチった画像を作るには、パレットを画像> モードから例えば256色に減色してから、PNGでエクスポートします。スクリーンショットなどはディザリングはオフにした方がごま塩のようなピクセルが入らなくて綺麗だと思います。写真などの場合はディザリングを有効にした方がいい感じになると思います。

True Color 24 bits/pixel (30,920 bytes)

Indexed Color 8 bits/pixel (10,708 bytes)


ピクセルあたりの単価が 24bit から 8bit になったので、ファイルサイズはだいたい三分の一になっているのが分かると思います。代償として減色時にパレットを使い切ってしまったときはぴったり済んだ場合を除いて情報が失われています。

上の場合は減色されて情報が失われていることが良く見ると分かります。幅広のグラデーションが階段状になっているのが見えるでしょうか?

さらに過激派な方は16色インデックスカラーに挑戦してみましょう!失われるものも多いですがファイルサイズはさらに半分になります。

Indexed Color 4 bits/pixel (5,029 bytes)

2012-05-28

[Node.js] uncaughtException イベントでスタックトレースを出す

公式ドキュメントのコードをそのまま使うと、デフォルト動作時にはプロセス終了とともに表示されていたスタックトレースを握りつぶすことになるので、混乱を避けるためスタックトレースを出しておくのがお勧めです。

公式にはエラーオブジェクトの仕様が載っていませんが、スタックトレースを取り出すには、node docs :: What is the error object? の通り、error.stack を読み取れば良いようです。中身は human-readable な文字列なのでそのまま出力できます。

console.error とは Node.js では STDERR に出力する console.log です。

process.on('uncaughtException', function (error) {
    console.error('uncaughtException: ' + error.stack);
});

setTimeout(function () {
    throw new Error('something happened');
}, 1000);

/*
出力例:

uncaughtException: Error: something happened
    at Object._onTimeout (C:\Users\hideki\Desktop\uetest.js:7:8)
    at Timer.ontimeout (timers.js:94:19)
*/

Event: 'uncaughtException' - node.js Manual & Documentation

2012-05-25

Google 検索の SSL 有効化に伴うキャンペーン

Google ウェブマスター向け公式ブログ で紹介されている通り行動すると…
  1. 流入キーワードが見れなくなり気になる人が仕方なく Google Webmaster Tools に登録する
  2. サイト管理者宛に Google のオンライン広告プログラム AdWords のクーポン5000円分が届く
  3. クーポンは課金を有効にしないと使えないと分かり、しぶしぶ課金情報を入力する
  4. Google は課金会員を獲得!

2012-05-24

[windows] EMET v3.0 を導入してみました

Microsoft より興味深いアプリケーション EMET (Enhanced Mitigation Experience Toolkit) の新しいバージョン v3.0 がリリースされたとアナウンスがあったので試してみました。このアプリケーションは攻撃者の任意のコードの実行を許してしまうシェルコードを実行しないようにすることで攻撃を緩和するソフトウエアで、適切に使用することで未知の脆弱性に対する攻撃からも保護される可能性があります。

常用範囲ではパフォーマンスの劣化は特に感じないので、副作用が出ても自力で対処できる方 (強制終了により保護される仕組みなので未保存の作業内容が失われても怒らずに、保護オプションを調整できる方) はぜひ試すと良いと思います。標的型攻撃にさらされる可能性が高い特異な方もぜひ導入をお勧めします。

インストールは こちらのマイクロソフト社のダウンロードページ から、Microsoft によるコード署名を確認しつつ導入しましょう。インストール最終段階で表示されるコマンドプロンプト画面は少し待つと消えるので待ちます。

残念ながらインストールしただけではダメで、インストール後にスタートメニューの Enhanced Mitigation Experience Toolkit > EMET 3.0 より初期設定を行います。不具合による訴訟を避けるため(?)初期設定は EMET によって保護されるアプリケーションは空になっているので、右下の Configure Application より保護するアプリケーションを追加します。開発者おすすめプロファイルが用意されているので、各自の責任で File > Import より、C:\Program Files (x86)\EMET\Deployment\Protection Profiles のAll.xml などを読み込むと簡単に設定できます。



Download: EMET - Microsoft Download Center - Download Details
EMET の最新バージョン EMET 3.0 を公開しました - 日本のセキュリティチーム - Site Home - TechNet Blogs
EMET (not Brown) « Brundle's Laboratory - おっしゃる通り、ワトソン博士に引き続き、今回は Back to the Future のあの博士の名前に似ています

2012-05-22

[apache] Error 410 (Gone) を返す設定

HTTP にてリソースの消滅を明示するために 404 Not Found よりも強力な 410 Gone を返すためには、.htaccess や httpd.conf にて以下のように設定すれば良いです。

# 単純な場合
Redirect gone /some/path

# より複雑な指定は正規表現を使用
RedirectMatch gone regexp

# 変なエラーコードが必要な場合(?)
Redirect 420 /some/path

mod_rewrite でも同様の設定は可能ですが、より標準的な mod_alias で良いと思います。
Redirect ディレクティブ - mod_alias - Apache HTTP サーバ

2012-04-04

ねんきんネットに Gmail などフリーメールのアドレスを設定する

日本年金機構ねんきんネットは現時点ではどういうことかメールアドレスとしてフリーメールが使えません。フリーメールの方がプロバイダのメールや携帯メールのアドレスよりも永続性が高いので、機構側から見ても設定させて不利はない(メールアドレスから身元を割るのが面倒になる?)と思います。また指示通りプロバイダメールなどを入れるとこちらがメールアドレスをアップデートするメンテナンスコストを払うことになるのが面倒です。

そこで良く調べたところドメインのブラックリスト判定が Case-sensitive matching (大文字小文字を区別するマッチング) になっているようなので、うっかりして @gmail.com ではなくて @Gmail.com などと入力すると通過します(2012/4/4時点)。ドメインは大文字小文字は同一視されて解決されるのでメールは問題なく届くはずです(ウェブサービスにはあるまじき変更時の確認メールなしの仕様で、次のお知らせ配信までメールが来ないようなので未確認!)。

日本年金機構はこの誰も得をしない(利用者はメールアドレスをアップデートし忘れないか心配し、年金機構はメールの不達に悩むこととなる)制約をすみやかに外すべきです。

2012/4/6 追記
問題なかったようで、本日無事ねんきんネットからGmail宛にメールが届きました。

2012/7/19 追記
コメント欄での enthumble さんのご指摘の通りこの挙動は修正されてしまったようです。引き続き別の方法が判明しましたら追記します。

2012/9/6 追記
ついに公式に登録できるようになりました!
いったん登録した後変更することでフリーメールアドレスに変更できるようです。手元でも @gmail.com のメールアドレスを入力して承認されることを確認しました。匿名さん コメントありがとうございます。

年金Q&A - フリーメールアドレスでは申込みができないのですか。また、入力したアドレス宛に日本年金機構から連絡がくることはあるのですか。 | 日本年金機構

2012-03-19

パナソニック製業務用電子レンジ NE-1801 で手動調理

プリセットのプログラムを使わず、マニュアルで加熱時間を設定したいときは、最初に「出力切替」ボタンを押して、画面を P10 (出力パワー10段階中10) にした後、テンキーで加熱時間の分と秒を設定します。たとえば1分20秒なら120と入力します。NE-1800, NE-1800P でも同様だと思います。

高周波出力1,800ワットで強力なので温めすぎにご注意!加熱時間は常温なら100グラム当たり20秒弱、冷凍なら30秒で見積もります。

2012-03-16

[windows] 設定されている環境変数を一覧表示する

Windows で設定されている環境変数をすべて表示するには、Linux で環境変数を一覧表示する際に env コマンドをオプションなしで実行するのと同じ感じで、コマンドプロンプト cmd.exe で、コマンド set をオプションなしで実行します。さらに詳しい情報は set /? を参照してください。

[windows] ポータブル版 Google Chrome を自作する

USBメモリに入れて持ち運びながら使えるポータブル版 Google Chrome 的な何かは、PortableApps.com や、SRWare Iron のポータブル版 などがありますが、他人のいじったバイナリはなんとなく不気味なので何とかしたいところです。そこで自分で簡単に作る方法が分かったのでメモしておきます。

Chrome 本体を取得する方法はとりあえず深く考えずに 公式サイト からインストールし、それを拝借することとします。インストール先は %LOCALAPPDATA%\Google\Chrome です。%...% で表される環境変数はエクスプローラでも展開されるのでこのアドレスで簡単にアクセスできます。このフォルダをUSBメモリーにコピーして、たとえば F:\Chrome とします。

chrome.exe はレジストリから起動するべき最新のバージョンを表す文字列を取得するようですが、全く Chrome が存在しない環境ではバージョンを取得できないので、こんなエラーが Chrome\Application\debug.log に出て、エラーダイアログも何も表示されず正常に起動しません。

[0316/121113:ERROR:client_util.cc(319)] Could not get Chrome DLL version.
[0316/121113:ERROR:client_util.cc(356)] Could not find exported function RelaunchChromeBrowserWithNewCommandLineIfNeeded

このエラーは --chrome-version="17.0.963.79" というスイッチで明示的にバージョンを指定することで回避できました。

加えて、--user-data-dir を chrome.dll からの相対パスで指定することで、F:\Chrome\User Data に履歴やクッキーなどのプロファイルが書き込まれていい感じに動作しました。蛇足ですが Chrome 内でバックグラウンドアプリケーションが動いていると chrome.exe が常駐するようになって、通知領域のアイコンから終了しないと正常にアンマウントできないので注意が必要です。

' F:\chrome.vbs
' chrome.exe に適切なオプションをつけて起動するスクリプトです。
' バージョン番号(17.0.963.79の部分)は適切に書き換える必要があります。
' 文字列 "..." の中のダブルクオートはダブルクオート2つで表します。

Set shell = CreateObject("WScript.Shell")
shell.Run ".\Chrome\Application\chrome.exe --chrome-version=""17.0.963.79"" --user-data-dir=""../../User Data"""

リンク
chrome_switches.cc
List of Chromium Command Line Switches - 上記ソースコードなどから自動生成された準公式リスト
Run Chromium with switches (flags) - The Chromium Projects

2012-03-15

Facebook アカウントをメールアドレスで検索されないようにする

Facebook でメールアドレスで検索される機能をほぼ停止できる待望の新機能が実装されていました。Facebook はこれまでずっと設定項目自体を作らず、検索されることから逃れられない驚嘆の仕様だったのでこれは進歩だと思います。

設定項目は、右上歯車 > アカウント設定 > 共有設定 >
メールアドレスまたは電話番号であなたを検索できる人 です。

これは自分をメールアドレスや電話番号で検索可能な人を選べという意味で、デフォルト値は「すべてのユーザー」です。完全に検索不可能にする選択肢は無いようですが、「友達」にしておけば既に友達になっている人を除き検索できなくなるので十分と思います。


ご参考までに、Facebook でメールアドレスからアカウントを検索する機能を使うにはアドレス帳インポート機能を使わずとも、上にある検索窓にメールアドレスを入れれば良いです。

補足
@bulkneets さんのご指摘 の通り、この設定を行っても最も制限した状態が友達までなので、既に友達になっているもしくは新たに何らかの方法で友達になれば、アカウント復旧用オプションのつもりで追加したメールアドレスが確かにその人のものであると確認できてしまいます。

リンク
Facebook: Privacy Settings
How do I control who can find me on Facebook with my contact info? - Facebook Help Center
Privacy: Finding Friends and the Suggestions Feature - Facebook Help Center
メールアドレスや電話番号から友人を検索する機能について知っているいくつかのこと - 金利0無利息キャッシング – キャッシングできます - subtech

2012-02-19

[windows] システムのフォントが壊れた場合の対処方法

MS ゴシック, MS Pゴシック などシステムのフォントが利用不能になった場合、本来とは違うフォントにフォールバックされることで IE の設定ダイアログが文字が大きくなって画面からはみ出す感じになったり、Yahoo Japan のページが明朝体になったりするなど、MS ゴシック系のフォント名がハードコードされている画面がことごとくヘンになるようです。この状況では例えば wordpad でもフォント一覧から MS ゴシックが消滅するので、このことを手掛かりにできます。

そのような症状が出ている場合は以下の手順を順にお試しください。

1. スキャンディスクでファイルシステムを修復する
そもそもファイルシステムが正常でないと常人には不可解な症状が出るので、最初に修復しておくことをお勧めします。
エラーがないかドライブをチェックする

2. セーフモードで起動する
セーフモードで起動したときに自動的にフォントキャッシュがクリアされます。
コンピューターをセーフ モードで起動する

3.1. システムファイルチェッカーでフォントを修復する
本来は自動修復されるはずなのですが、手動で再スキャンをしてみる価値があります。
KB929833 システム ファイル チェッカー ツールを使用して、Windows Vista または Windows 7 の不足しているシステム ファイルまたは破損しているシステム ファイルのトラブルシューティングを行う方法

3.2. 手動で修復する
自動修復できなかった場合でもインストールディスクから自力でフォントのファイルを持ってくる方法があります。他の PC からコピーしてくるという方法もあります。
How to extract missing system files from the DVD of Windows 7/Vista.

4. フォントを再登録する
ファイルが正常であっても登録されている情報が正常ではない場合があるので、以下の手順で再インストールを試してください。

フォントのフォルダは仮想化されていてファイル実体が見えないので、コマンドプロンプトを使って以下のコマンドでファイル実体をコピーします。
dir c:\windows\fonts (ファイル名一覧が出ます)
copy c:\windows\fonts\msgothic.ttc c:\ (C:\直下にフォントをコピーします)
このコピーしたフォントを右クリックしてインストールします。

5. Aero関係のリセット
デスクトップを右クリックして出る [個人設定] から、Aeroテーマとベーシックテーマを何度か交互に変更すると、壊れていた場所がリセットされる場合があるようです。

おわりに
以上の手順でどうしてもうまくいかない場合でも、修復インストールやシステムのリカバリという確実に直せる手段もあります。

Windows 8 をご利用の場合は PC のリフレッシュを行うことで簡単に復旧すると思います。

リンク
TouchSmartTX2 with Windows7の備忘録: トラブル:Vistaでブラウザのフォントが突然、勝手に変わった
hidekiy blog: Windows 8 のリフレッシュ機能を試してみました

[windows] どうしても消せないファイルを何とかする

とりあえずログオフや再起動を試してみましょう。それでもダメな場合は以下の手続きをお試しください。

1. 自動起動するアプリケーションがファイルを開いている
怪しいプログラムを Autoruns で自動起動しないように無効にしてみる。タスクマネージャーや ProcessExplorer を管理者権限で開いて怪しいプロセスを終了する。

マルウエアによってはプロセスを相互にリスタートさせる工夫を凝らした双子型プロセスになっている場合もあります。

原因が良くわからない場合でも、起動時に F8 を押すと出るメニューからセーフモードを選んで起動すれば、最小限の構成で起動し、後からやってきた余計なプログラムは自動起動しないので、おそらく消せなかったファイルを削除できます。

ProcessExplorer の表示カラムの選択画面で、Verified Signer を表示するように選択することで、動作しているプロセスのコード署名を検証して表示してくれるようになるので、簡単に怪しいプロセスを特定できます。MS 製の由緒正しいプログラムにはすべて Microsoft Corporation で署名が付いています。

2. 操作するための権限権がない
2.1. 管理者なのに権限を設定できない
管理者は所有者を自由に上書きできるので、所有者を再設定すれば好きな権限を設定できるようになります。

Windows XP でファイルまたはフォルダーの所有権を取得する方法 - Windows 7 でもUIにほとんど変更がないのでこの KB が適用可能

2.2. プロパティに [セキュリティ] タブがない
フォルダー オプション - 表示 より簡易ファイルの共有を無効にすると表示されます。

2.3. セキュリティディスクリプタが破損している
権限の再取得もアクセスが拒否される場合はセキュリティディスクリプタの破損が考えられます。その場合はドライブのプロパティにあるスキャンディスクにて修復可能です。

3. ファイルシステムが破損している
同様にスキャンディスクにて修復可能です。

4. 読み取り専用属性が付いている
ファイル・フォルダのプロパティから解除可能です。

その他にも長すぎるファイルパスを持つファイルを削除できない問題など、公式情報が以下のページにありますのでぜひご覧ください。
KB308421 NTFS ファイル システム上のファイルまたはフォルダを削除できない

セーフモードで起動してもダメなときは KNOPPIX など別の OS で起動してディスクにアクセスすれば必ず削除できるはずです。またHDDをいったん外して別のマシンからアクセスする方法もあります。

[firefox] プラグインのインストールを促す黄色いバーを隠す

about:config から plugins.hide_infobar_for_missing_plugin を true に変更する。

主に Flash Plugin を入れていない人のための「このページをすべて表示するにはプラグインを追加する必要があります。」と毎度毎度のたまう黄色いバーを表示しないようにするための設定です。Firefox 10.0.2 で有効なことを確認しました。

2012-01-28

[security] ブラウザ別フィッシングサイト報告手順

もしあなたの所に Twitter の DM経由などでユーザー名・パスワード ペアを盗む怪しいフィッシングサイトへ誘い込むリンクが届き、そのサイトがまだブロックされていないことを見つけた場合、以下の手順でレポートすると速やかに (数時間以内程度) ブロックされるようになるようです。

攻撃サイトが転送URLを利用している場合は、Twitter の場合 t.co でブロックされることを期待して、初段と終段を登録すると良いように思います。

Google Chrome
Google Chromeの設定 (右上のレンチ) > ツール > 問題の報告
> 問題が発生した箇所(フィッシング)
スクリーンショット付きを推薦

Internet Explorer 9
ツール (右上の歯車ボタン) > セーフティ > 安全でないWebサイトを報告する

Firefox
こちらのフォームに入力: フィッシング サイトの報告
ただし、Googleのデータを使っているのでChromeでレポートすれば不要

Opera 11.61
メニュー (左上Opera) > ページ > 開発者ツール > セキュリティ情報
> フィッシング・マルウエア防止機能

2012-01-15

「体系的に学ぶ 安全なウェブアプリケーションの作り方」を読みました

徳丸さんに 直々にプレゼント していただいた 安全なウェブアプリケーションの作り方 を読んだ感想について書かせていただきます。

まず基本的な構成として、手を動かして学ぶことを意識した、とても実践的な内容になっているように思いました。仮想環境のセットアップ、デバッグ用プロキシ Fiddler のセットアップから始まっていて、具体的な通信内容を見て確認していく構成が素晴らしいと思います。

自分が特に興味深く読ませていただいたのは、セッション ID、CSRF トークン、自動ログインなど、Web アプリケーションを作るときは避けて通れない機能について、きっとこんな感じじゃないかな?という怪しげな実装になりがちな部分について、脆弱性が生まれるパターンを様々に例示して説明されているおかげで、正しい実装について深く学べる内容になっていると思いました。

セキュリティの話はどの話も全体のごく一部のような感覚があり、全体像がぼんやりともつかめない辛さがありましたが、この本は徹底的に網羅されているので、少しずつ読み進め理解を深めることで、理解しているつもりの方々とは一線を画す知識が得られると思います。内容がかなり盛りだくさんなので、最初から通して読もうとはせず、同じテーマの部分を繰り返し通して読むことで理解が深まりました。

Amazon.co.jp: 体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 大型本 - 2011/3/3 徳丸浩 (著)

[twitter] Snowflake で生成された ID をデコードする

Snowflake とは Twitter の新しい Status ID 生成アルゴリズムの名前です。これは ID 生成サービスをスケーラブルなものにするために、生成サーバーの ID (workerId, datacenterId) と時刻 (timestamp) と、それらが重なった場合に増加させるカウンタ (sequence) に基づいて生成される 64bit 符号なし整数です。

したがって、この Snowflake ID をくっつける前の状態に戻すと元の要素に分解することができるので、それを作ってみました。JavaScript では Snowflake ID は大きすぎて数値として扱えないので、BigNumber という多倍長整数演算ライブラリを使っています。


snowflake decoder
textarea を書き換えると ID らしきものを抽出して詳細が表示されます。

リンク
Twitter Engineering: Announcing Snowflake
Twitter IDs, JSON and Snowflake
src/main/scala/com/twitter/service/snowflake/IdWorker.scala at master from twitter/snowflake - GitHub
はてな匿名ダイアリー - snowflakeの実際
mofigan's tumblr. - Twitterのstatus_idの生成アルゴリズムはsnowflakeなので、ビット演算をすれば投稿...
PFIセミナー - ツイートID生成とツイッターリアルタイム検索システムの話

2012-01-09

_nomap で Google 位置情報からアクセスポイントを削除する

ポータブル Wi-Fi ルーターに Android 端末を繋いで使っていると、頻繁に自宅に連れ戻される症状に大変困っていました。これは周辺に他のアクセスポイントがない場合に、Wi-Fi 位置情報によりポータブルルーターの位置を引いてしまい、普段ずっと使っている自宅を現在位置と認識するためのようです。

2011/11 に Google により発表された Wi-Fi位置情報システムからのオプトアウト方法 に従って、SSID の変更を 2011/11/16 に行い、オプトアウトの完了を 2012/1/8 に確認しました。位置情報データのアップデートは月に1回程度行われるようです。

SSID の末尾に _nomap を付ける変更後、電波出力を 100% にして、より多くの Android 端末に捕捉されるようにしてみました。オプトアウト完了後は Google Map を使っても頻繁に現在地が自宅に戻る不愉快な動作もなく快適に利用できています。そもそも、移動するノードはすべて出荷時デフォルトが _nomap で良いと思います。

Google 側の更新を待てないお急ぎの方は、アクセスポイントを SSID ステルス設定にして使うと、Wi-Fi 位置情報クライアントがそれを認識し、近隣のアクセスポイントとして送信されなくなり、_nomap によるオプトアウト完了後相当の測位結果になるのでお試しください。

なぜ SSID ステルスモードへの変更でオプトアウト出来ないのか?
Google の位置情報サービスの説明 にあるように、位置情報サービスは公共に発信され、誰でも得ることができる情報 (広告されている ESSID, BSSID, 電界強度) のみに基づきサービスを運用しているので、送信される近隣アクセスポイント一覧には SSID が広告されているアクセスポイントのみの情報が含まれ、自分が繋いでいる SSID ステルスなアクセスポイントについての情報は送信されません。

したがって、サーバー側から見た場合、あるアクセスポイントが SSID ステルスモードに変化したのか、電源を落とされたのかは区別できず、電源の落ちているアクセスポイントの自動削除などは行われないため、SSID ステルスに変更する前の情報が記録されたままとなります。
この状況を改善するためには、以下のいずれかのようなものを用意すれば良いと考えられます。

  • BSSID (MACアドレス) の入力によるオプトアウト
  • SSID ステルスに変更したことを送信するツール
  • 一定期間非アクティブなアクセスポイントの自動削除

メモ
ブラウザ用 Google 位置情報 API ではアクセスポイント 1 個の場合は測位不能になる一方で、Android からは1個でも測位可能なようです。

リンク
Google Map ヘルプ - 位置情報サービス
高木浩光@自宅の日記 - Wi-FiのMACアドレスはもはや住所と考えるしかない