Hatena::ブログ(Diary)

hnwの日記 このページをアンテナに追加 RSSフィード

[プロフィール]
 

2016年5月22日(日) 勝手にMarkdownプレビューを開くVS Codeのエクステンションを書いた このエントリーを含むブックマーク このエントリーのブックマークコメント

Visual Studio Code(以下VS Code)、みなさん使ってますか?VS CodeはMicrosoftが開発しているオープンソースエディタです。Electronベースという意味ではAtomと似た存在ですが、Atomより軽いという評判を聞いたりします。


私も最近VS Codeを使い始めました。いまのところMarkdown編集専用という状況ではありますが、便利に使っています。それだけでなく、「Auto-open Markdown Preview」というエクステンションを書いて自分好みの挙動になるようにしてみました。本稿ではその顛末について紹介します。


ちなみに作業はすべてMacOSX上で行いましたが、WindowsでもLinuxでも同様だと思います。


作ったもの

今回、「Auto-Open Markdown Preview」というエクステンションを作りました。Markdownファイルを開いた場合に、自動的にプレビュー画面も開くというものです。


Auto-Open Markdown Preview導入前

f:id:hnw:20160522123147g:image


Auto-Open Markdown Preview導入後

f:id:hnw:20160522123148g:image


大した差では無いように見えるかもしれませんが、個人的な感覚としては凄い便利になりました。Markdown編集するときには常にプレビューしたいに決まっているじゃないですか。


もちろん意見には個人差があります。差があるからこそカスタマイズ性が大事だと思うんですよね。


Auto-Open Markdown Previewのインストール

このエクステンションインストールは簡単で、VS Code上で「F1」を押して「>」を消して「ext install auto-open markdown」とタイプすればインストール候補として出てきます。


f:id:hnw:20160522123146g:image


以下、これを実現するまでの流れを紹介します。


VS Codeのエクステンションとは

すでに紹介した通りVS Codeにはエクステンションの仕組みが用意されており、ユーザーの手でエディタ機能を拡張することができます。エクステンションJavaScriptまたはTypeScriptで書くことができますが、TypeScriptで書いている人が大多数のようです。


また、書いたエクステンションVisual Studio Marketplaceに誰でも無料でパブリッシュすることができます。エクステンションパブリッシュすると上で紹介したようにVS Code本体のエクステンション検索機能でインストール候補として表示されますので、多くのユーザーに簡単に使ってもらえるような仕組みになっています。


エクステンションの作成

VS Codeエクステンションを作るための道具はnpmに登録されています。あのMicrosoftがnpmに自社ツールを登録するなんて…と不思議な気持ちになるのは私だけでしょうか。それはさておき、さっそく準備していきましょう。


$ npm install -g yo generator-code
$ yo code

     _-----_
    |       |    .--------------------------.
    |--(o)--|    |   Welcome to the Visual  |
   `---------´   |   Studio Code Extension  |
    ( _´U`_ )    |        generator!        |
    /___A___\    '--------------------------'
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What type of extension do you want to create? (Use arrow keys)
> New Extension (TypeScript)
  New Extension (JavaScript)
  New Color Theme
  New Language Support
  New Code Snippets

指示に従って適当に答えていくとエクステンション名のディレクトリが作られ、その下にひな形が生成されます。また、node_modules以下に必要モジュールがnpm installされます。


自動生成直後の状態では、「Hello World」と表示するだけのextensionが作られています。


$ code --disable-extensions .

上記のようにエクステンションディレクトリをVS Codeで開き、「F5」を押せばエクステンションデバッガ上で動作します。この環境では、ブレークポイントを置いたり変数値を確認したりしながらエクステンション開発ができます。


詳しくは下記URLを参照してください。



エクステンションパブリッシュ

上記の環境で開発が一段落したら、まずパッケージングしてみましょう。


$ npm install -g vsce
$ vsce package

このようにnpmでvsceパッケージをインストールしてコマンドを打てばプロジェクトディレクトリに*.vsixファイルが出来ます。これがVSCodeのエクステンションパッケージになります。これをVS Codeでオープンすればパッケージがインストールされます。


$ code vscode-auto-open-markdown-preview-0.0.1.vsix

Marketplaceへのパブリッシュもコマンド一発です。ただし、Visual Studio Team ServicesMicrosoftの無料リポジトリ&イシュートラッキングサービス、以下VSTS)のアカウントと、VSTS上で発行されるアクセストークンが必要です。


$ vsce create-publisher hnw
$ vsce login hnw
$ vsce publish

詳しくは下記URLを参照してください。



まとめ

VS Codeの挙動に不満があったら自分でエクステンションを作れば解決できるかもしれないこと、またVS CodeのエクステンションをMarketplaceに公開するまでのハードルは非常に低いということを紹介しました。まだまだエクステンションまわりは資料が少ないという印象ですが、Microsoftの公開している資料やVS Code自体のソースコードTypeScript部分が多い)があれば何とかなると思います。


皆さんも便利なエクステンションを書いて公開してみてはいかがでしょうか。

トラックバック - http://d.hatena.ne.jp/hnw/20160522

2016年4月30日(土) 新MacBook (12-inch, Early 2016)を買ったので性能比較してみた このエントリーを含むブックマーク このエントリーのブックマークコメント

先日発表された12-inch MacBookの2代目を衝動買いしました。MacBook Air (13-inch, Mid 2012)からの買い替えです。MacBook Airは不満の少ないマシンでしたが、持ち歩いていたら肩こりがひどくなったので、性能が落ちずに物理的に軽くなるならと考えて買い換えてみました。


スペック比較

両方ともBTOなしの上位モデルです。


MacBook Air
(13-inch, Mid 2012)
MacBook
(12-inch, Early 2016)
CPU 2.0GHz Intel Core i7
(最大3.2GHz)
1.2GHz Intel Core m5
(最大2.7GHz)
Memory 4GB 8GB
SSD 256GB 512GB
Weight 1.35kg 0.92kg

ネット上の情報からするとCPU性能も大差ないと判断して買ったのですが、動作周波数だけで見ると圧倒的に負けているのがわかります。


コンパイル時間でベンチマークテスト

さて、本当に両者の性能に差はないのでしょうか?ベンチマークテスト上は互角でも、体感値とは違う可能性も考えられますので、自分の身近な作業の速度で比較してみたいところです。


というわけで、PHP 7.0.6のビルド時間を測ってみることにしました*1。makeのオプションを-j1と-j4と試してみて、1並列と4並列の場合で比較しました。


MacBook Air
(13-inch, Mid 2012)
MacBook
(12-inch, Early 2016)
相対性能
1並列 12分8秒 11分15秒 +7.3%
4並列 6分44秒 6分30秒 +3.5%


ギリギリですが、新MacBookの方が速いという結果になりました。この程度の差だと条件が少し変わるだけで逆転されそうですが、互角程度であるという点では間違いなさそうです。


上の結果からCPU単体の速い遅いの判断はできません。大物ソフトウェアコンパイル・リンクではディスクI/O性能の差もかなり効いてきます。SSDの性能は新MacBookの方が断然上なので、その差が結果に出ている可能性もありそうです。


1並列より4並列のときの方が両者の差が縮まっている理由としては、新MacBookCPUが過負荷に弱いということが考えられます。IntelTurbo Boostは温度やその他に余裕があるときにオーバークロックする技術なので、ファンレスで動いている新MacBookの方が早く頭打ちが来ても不思議はありません。


実際、他のベンチマーク結果を見ても1コア性能は互角、マルチコア性能は若干落ちる程度のようです。


とはいえ、CPUの動作周波数だけ見ると勝ち目がなさそうに見えたのが、身近な作業で互角かそれ以上の性能だったことに少し安心しました。


参考URL


まとめ

  • MacBook Air (13-inch, Mid 2012) と MacBook (12-inch, Early 2016)の性能は大差なさそう
  • 430gの軽量化に払う金額としては高すぎると思う
    • でも肩こりがツラかったので仕方ない(自分への言い訳)

*1:「phpenv install 7.0.6」の実行時間を比較したので、xdebugその他のビルド時間も含まれています

トラックバック - http://d.hatena.ne.jp/hnw/20160430

2016年4月19日(火) php-timecopをPHP 7対応させてみた このエントリーを含むブックマーク このエントリーのブックマークコメント

自作のPHP拡張であるphp-timecopPHP 7に対応させてみました。この機会に改めてphp-timecopの紹介をしてみます。


php-timecopとは

php-timecopというのは筆者が4年ほど前に作ったPHP拡張で、現在時刻に紐付いた値を返すPHP関数について、基準となる現在時刻を過去や未来の任意の時刻に設定することができるというものです。


以下に簡単な例を紹介します。


<?php
var_dump(date("Y-m-d")); // 今日の日付
timecop_freeze(0);
var_dump(gmdate("Y-m-d H:i:s")); // string(19) "1970-01-01 00:00:00"
var_dump(strtotime("+100000 sec")); // int(100000)

上記プログラム中2行目のtimecop_freeze()関数php-timecopにより導入される新たな関数で、現在時刻を指定された時刻に固定するというものです。timecop_freeze()の引数として0を指定するとグリニッジ標準時1970年1月1日、いわゆるUNIXエポックを指定したことになります。実際、プログラム中3行目4行目の戻り値を見ると、本来なら現在時刻を基準にするはずの関数UNIXエポック基準で値を返していることがわかります。


詳しい使い方

php-timecop拡張を導入すると、以下の組み込み関数について現在時刻をズラせるような実装に差し替えます。ただし、そのままであれば返す値は元の関数と完全に同じです(変わっているようならバグです)。


  • time()
  • mktime()
  • gmmktime()
  • date()
  • gmdate()
  • idate()
  • getdate()
  • localtime()
  • strtotime()
  • strftime()
  • gmstrftime()
  • microtime()
  • gettimeofday()
  • unixtojd()
  • DateTime::_construct()
  • DateTime::createFromFormat() (PHP >= 5.3.4)
  • date_create()
  • date_create_from_format() (PHP >= 5.3.4)

また、次の3つの関数を使って現在時刻を仮想的にズラせるようになります。


  • bool timecop_freeze(int $timestamp)
  • bool timecop_travel(int $timestamp)
  • bool timecop_return()

上の2つの関数を呼ぶと現在時刻を$timestampで指定された時刻にズラします。timecop_freeze()を呼び出すと時刻はズレたままずっと同じ値を返すようになります。一方、timecop_travel()は呼ばれたタイミングで時刻をズラしたあと時計が通常の速度で動きます。timecop_return()を呼び出すと本来の時刻に戻ります。


timecop_travel()を使う場合、現在の実装では秒の単位しかズラせず、マイクロ秒の単位は元のままである点に注意してください。つまり、timecop_travel(0)を呼び出すと仮想時刻は1970-01-01 00:00:00.000000から1970-01-01 00:00:00.999999のどこかになります。タイミングが悪いと、次の処理を行うまでに1970-01-01 00:00:01になっているかもしれません(いずれ直したいとは考えています)。


php.iniで指定できる設定値は2つあります。


  • timecop.func_override
  • timecop.sync_request_time

前者は組み込み関数の置き換えを行うかどうかの指定で、0を指定すると組み込み関数の差し替えを行いません。デフォルトは1です。1を指定した場合、差し替える前の関数をtimecop_orig_mktime()のように「timecop_orig_」というプレフィックスがついた形で呼び出すことができます。


後者はtimecop_freeze()やtimecop_travel()が呼ばれたタイミングで$_SERVER['REQUEST_TIME']を書き換えるかどうかの指定です。0を指定すると書き換えません。デフォルトは1です。


php-timecopの使いどころ

この拡張は現在時刻が絡んだ自動テストに使うと便利です。PHP標準の日付系関数・クラスを使っている場合、現在時刻によって挙動が変わってしまうので自動テスト対象にするのが難しいのですが、php-timecopを使えば既存コードの変更なしにテストできるようになります。日またぎや年またぎといったテストしづらい状況のテストに利用できるかもしれません。


また、サービスの管理者が動作確認をするような場合にも有用です。たとえば、特定の時間になったら特定の表示を行うような処理について、php-timecopを使えば事前に確認することができます。実際に、筆者の勤務する会社ではこの拡張を使って管理者向けの「仮想カレンダー」機能を実現していました*1


PHPで組み込み関数の挙動を変えるには

ところで、php-timecopはどうやって組み込み関数を差し替えているのでしょうか?RubyPythonなどの言語では組み込み関数をユーザー定義関数で上書きすることができます。一方、PHPではPHPプログラム上から組み込み関数を書き換えることはできません。


実は、組み込み関数を動的に書き換えられないというのはpure PHPレベルでの制約であり、PHP拡張にはそのような制限はありません。PHP関数は内部的には関数名をキーにした連想配列で管理されています。この連想配列PHP拡張から操作できるので、これを書き換えれば関数の差し替えを実現できるというわけです。


php-timecopでは特定の関数だけを自前実装したCの関数で差し替えていますが、RunkitAOP-PHPを使えば任意の関数メソッドの挙動変更をPHP関数で記述できます。時刻系関数以外にもテストの悩みがある場合はこれらの拡張を使った方が便利かもしれません。現時点では両者ともPHP 7に未対応ですが、のんびり待っていれば公式対応が来るんじゃないかな?と個人的には思っています。


PHP 5対応のPHP拡張をPHP 7対応に書き換えるコスト

PHP 7に移行したいけれども使っている拡張がPHP 5にしか対応していない、という悩みを持っている方がいらっしゃるかもしれません。PHP拡張のPHP 7への移行はそんなに大変なのでしょうか?


個人的な感覚として、PHP拡張の書き換えのコストは元のコード量に依存します。PHP 5とPHP 7とでは内部的なAPIが大幅に変更されているため、大物の拡張だと移行は大仕事です。PHP 7の方が内部APIが整理されており、バグを作り込みにくくなったのがせめてもの救いでしょう。


一方で、内部構造の変更は予想より少ないと感じました。zval周り・ハッシュ周りは大幅変更されていますが、それ以外の変更量はそれほど大きくありません。慣れてくるとPHP 7への書き換えは単純作業のような気がします。


ちなみに、php-timecopのPHP 7対応では#ifdefなどによる分岐をあきらめ、ソースコードとして別管理としました。差分に興味がある方はリポジトリ上のtimecop_php5.cとtimecop_php7.cとを見比べてみてください。


まとめ

PHP 7対応を機に、php-timecopについて紹介しました。このところ自分では全く触っていなかったのですが、想像以上に使われているようで驚いています。ご意見・ご要望などあればお気軽にどうぞ。


参考URL

*1:新しい案件では賢い時刻クラスが使われていましたが、古い案件に後から導入するのに活躍しました

トラックバック - http://d.hatena.ne.jp/hnw/20160419

2016年3月27日(日) DNSSECを利用してゾーン情報を抜き出してみた(NSEC編) このエントリーを含むブックマーク このエントリーのブックマークコメント

さいきんDNSSECについて調べているのですが、普及について懐疑的な人が多いという印象を持ちました。批判点として運用の難しさを挙げる人も多く、仕様策定時に運用負荷の観点が入っていたらまた違ったのかなと感じたりもします。


また、運用面の視点以外に、技術仕様面でも批判的な人が一定数いるように思います(DJBが筆頭ですかね…)。批判の一つがゾーン情報の列挙(Zone enumeration)に関するものです。特に、初期のDNSSECの仕様では「NSEC walking」により完全なゾーン情報を第三者が取り出すことができました。これを改良するためNSEC3レコードが導入されたという経緯がありますが、今でもNSECで運用されているゾーンが一定数残っていたりもします。


本稿ではNSEC walkingによりゾーン情報を読み出す方法を紹介します。


NSECレコードとは

NSECレコードというのはDNSSECで導入された新しいレコードタイプで、問い合わせに対して不存在を回答するためのものです。


そもそもDNSSECは、公開鍵暗号を使ってDNS問い合わせの回答に署名するような仕組みです。この仕組みがあれば、存在するレコードについては署名により正当性の確認ができます。しかし、レコードが存在しない場合に従来のDNSでは何も返さない仕様だったので、署名する対象がありません。不存在に対して署名するために、存在しないことを意味するNSECレコードが新設されたというわけです。


このNSECレコードは「aaa.example.comからbbb.example.comの範囲には何もないよ」というような返事をする仕様になっています。すべての問い合わせに対して個別に「それは存在しないよ」と返事を返しているとキリがないので、キャッシュ効率を考えてこのような仕様にしたのだと思われます。しかし、このような仕様になっていることで、先ほどの例なら「aaa.example.com」と「bbb.example.com」という2つのレコードがありそうだということが外部から丸わかりになってしまいます。


もちろん、ゾーン内にどのようなレコードがあるか知られたからといって即座に危険というものではありません。とはいえ、ホスト名にミドルウェア名やアプリケーション名をつけることは珍しくないはずですし(例:redis, irc)、Webサーババーチャルホスト設定をしている場合など、正しいホスト名を知らないとアクセスできないサービスもあるわけです。こうした例からも明らかなようにホスト名を知られることは攻撃リスクの増加につながるため、不用意にゾーン情報を公開しないのが一般的なノウハウです。ところが、レコードの不存在に対してNSECレコードを返してしまうとゾーン情報を全世界に公開するのと同じ状態になってしまうのです。


この問題はNSECレコード導入直後から指摘されていたようで、2008年にはこの問題を解決する目的のNSEC3レコードRFCに採択されています。また、現在では多くのDNSサーバがNSEC3レコードを利用して運用されています。実はNSEC3レコードにも問題点はあるのですが、その話題は別の記事でまとめたいと思います。


digコマンドでNSECレコードを確認してみる

現在ではNSEC3レコードで不存在を回答するDNSサーバの方が多数派ですが、まだまだNSECレコードも現役です。digコマンドで.moeドメインの問い合わせをしてみましょう。


$ dig a zunopan.moe +dnssec +nocmd

; <<>> DiG 9.10.3-P3 <<>> a zunopan.moe +dnssec +nocmd
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 21684
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;zunopan.moe.			IN	A

;; AUTHORITY SECTION:
moe.			6665	IN	SOA	ns1.dns.nic.moe. hostmaster.neustar.biz. 72673 900 900 604800 86400
moe.			6665	IN	RRSIG	SOA 8 1 7200 20160426103703 20160327093703 20989 moe. KkV+vuFD/V36pDolnSIwSXZ24bh+LZHjRBfo44g/I9XL5HbZnfoQZ6nn On0GQcVHbjPKmwKuncdBJ3YEvNP1fmmIe85tznIVm8TvVugc+fgQRe1F v+ShBeY6n84r3ZNc+IOG4vMJ6jJgWEjXPCBwfQjUOISC6cFTOCWUAioZ Ais=
ZUNKO.moe.		83996	IN	NSEC	ZUO.moe. NS RRSIG NSEC
ZUNKO.moe.		83996	IN	RRSIG	NSEC 8 2 86400 20160406151432 20160307144911 20989 moe. ab2jy3xntU87B8eSGONcspcC8yx2joTnfo7fBg445F4C8QlyIIJ8Hiqr K39JwpWcgHrekqgqdc6CGHuRbPtNM1Xq+Qclo28D3Fo5WMuajzBjzZBR DNzTMclkMSWotYP80ksA6vXp7NMbEYCRZo9mcfDKSlOojvjv12E0s4E0 7/8=
moe.			83983	IN	NSEC	0-0.moe. NS SOA RRSIG NSEC DNSKEY
moe.			83983	IN	RRSIG	NSEC 8 1 86400 20160405140613 20160306131312 20989 moe. DEmFsg1au3cB3Xr7xKJt8j+1HkqTGaIKdVXVv6AdrEyAmJooBrQ57oZb eQO+rRfyBuxLsXOaU7aLHfdepTLlphmVuw3tP3rXd4U8JzJaDWFThtZC 9AiA6/UtScSbh6QLfJpQaXFqEHXecsAGFtjmxo9IkADRG3M7tFdMeYP+ uyc=

;; Query time: 129 msec
;; SERVER: 192.168.48.1#53(192.168.48.1)
;; WHEN: Sun Mar 27 19:50:31 JST 2016
;; MSG SIZE  rcvd: 664

上記のうち、下から2行目のNSECレコードが今回話題にしているレコードです。これによれば、「zunopan.moe」は存在しないけど、「ZUNKO.moe」というレコードがあり、対応するレコードタイプは「NS RRSIG NSEC」の3つだということ、その次のレコードは「ZUO.moe」であることがわかります。これを辿っていけばゾーン内の全レコードを取り出せてしまうというわけです。


ちなみに、一番最後のRRSIGレコードが対応する署名になります。参考まで。


NSEC walkingを行うツール

これまで説明してきたような性質を利用してゾーン内の全レコードを取り出すことをNSEC walkingなどと言います。これを行うツールは下記のように何種類か作られています。ちなみに3つめは筆者が今回Go言語の練習がてら書いてみたものです。



筆者の作った「go-dnssec-walker」の実行例を示します。当然ですが、他のツールでも同じような出力が得られます。


$ walker -s zunko moe
zunko.moe.
zuo.moe.
zxz.moe.
zyii.moe.
zyon.moe.
zzz.moe.

このノリで全域を調べると、たとえば.moeドメインには現時点で5075ドメイン登録されているらしい、なんてことがわかったりします。


NSEC walkingできるTLD

今回NSECについて調べてみて、現在もNSECで運用されているgTLD・ccTLDが下記の通りたくさんあることがわかりました。下記のTLD内のドメインは赤の他人が簡単に一覧を取得できるというわけです。他人に知られて困るようなドメインを持っている人は気をつけた方がいいかもしれませんね。


gTLD
  • .accountant
  • .audio
  • .auto
  • .best
  • .bible
  • .bid
  • .biz
  • .blackfriday
  • .buzz
  • .car
  • .cars
  • .ceo
  • .christmas
  • .click
  • .club
  • .cricket
  • .date
  • .diet
  • .download
  • .earth
  • .faith
  • .flowers
  • .game
  • .gift
  • .guitars
  • .help
  • .hiphop
  • .hosting
  • .how
  • .jetzt
  • .juegos
  • .link
  • .loan
  • .lol
  • .moe
  • .mom
  • .nyc
  • .osaka
  • .party
  • .photo
  • .pics
  • .property
  • .qpon
  • .racing
  • .review
  • .science
  • .sexy
  • .soy
  • .taipei
  • .tattoo
  • .trade
  • .uno
  • .webcam
  • .whoswho
  • .win
  • .みんな(.xn--q9jyb4c)
  • .世界(.xn--rhqv96g)
ccTLD
  • .ad
  • .bg
  • .br
  • .ind.br
  • .co
  • .com.gn
  • .id
  • .co.id
  • .or.id
  • .web.id
  • .kg
  • .ky
  • .lk
  • .mg
  • .com.mm
  • .org.mm
  • .na
  • .pr
  • .biz.pr
  • .com.pr
  • .net.pr
  • .org.pr
  • .se
  • .sl
  • .com.sl
  • .tn
  • .com.tn
  • .us

まとめ

  • DNSSECの不存在をNSECレコードで返すのはゾーン情報の公開と同じ
  • どうせDNSSECやるならNSEC3で返した方が多少はマシ

飽きていなければ次回はNSEC3編を書きます。

トラックバック - http://d.hatena.ne.jp/hnw/20160327

2016年3月21日(月) DNSSEC対応の独自ドメインを年額$0.88で運用できるよという話 このエントリーを含むブックマーク このエントリーのブックマークコメント

(2016/3/27追記)0.88ドルというのは期間限定のキャンペーン価格のようです。普段はもっと高いのかもしれません。


DNSSECって名前は聞くけど詳細は知らないな、というくらいの理解度の人って多いんじゃないでしょうか。実は筆者もそんな一人だったのですが、この連休中に独自ドメインを取得してDNSSEC対応させてみました。DNSSEC対応できるレジストラドメインの組み合わせとしてはNamecheapで.pwドメインを取るのが探した範囲では最安値で、最初の1年間だけ維持するなら0.88ドル、翌年以降更新する場合でも年額7.88ドルに収められることがわかりました。


本稿では一連の顛末を紹介します。


そもそもレジストラドメインのDNSSEC対応って何?

DNSSECにおいて、レジストラはどういう役割を担うのでしょうか?レジストラの選択がDNSSECの利用にどういう影響を与えるのでしょうか?これを理解するには、DNSSECの仕組みを知る必要があります。


DNSSECを一言で説明すると、従来のDNSレコード公開鍵暗号による署名を付けることで、問い合わせ結果の正当性を保証するような仕組みです。


この仕組みを成立させるためには署名を行うDNSサーバの公開鍵が本物であることを誰か別の人が保証しなくてはなりません。そこで、DNSSECでは上位の権威サーバが下位ゾーンの公開鍵の正当性を保証するという形になっています。具体的には、DSレコードと呼ばれるリソースレコードに下位ゾーンの公開鍵のハッシュ値登録することで、下位ゾーンの公開鍵の正当性を担保します。


言い換えると、DNSSEC対応するためにはレジストラ経由で上位の権威サーバ(.jpドメインならJPRSの管理するDNSサーバ)にDSレコード登録する必要があるのですが、このDSレコード登録取り次ぎを行っているかどうかはドメインによってもレジストラによってもバラバラという状況です。つまり、独自ドメインと自前のDNSサーバを持っていたとしても、ドメインレジストラの両方がDNSSECに対応していないとDNSSECは使えないということになります。


国内レジストラのDNSSEC対応状況

まずは日本国内に目を向けてみます。JPドメインについて言うと、ドメイン側は2011年にDNSSEC対応が済んでいます。


一方で、レジストラ側の対応状況は芳しくないようです。JPドメイン指定事業者一覧のページに各レジストラのDNSSEC対応状況のリストがあるのですが、600を超える指定事業者のうちで、2016年3月現在DSレコードの取り次ぎに対応しているのは下記の11サービスのみでした(自己申告制のリストなので、記載していない会社もあるようですが)。DNSSECの普及という観点では寂しい状況ですね…。



また、上記11サービスには主要顧客が法人であるものも含まれており、個人だと価格面で敷居が高かったり、そもそも利用できなかったりします。


ちなみに、一見するとお名前.comもDNSSEC対応しているように見えるのですが、単純なDSレコード取り次ぎには対応していないようで、あまりオススメしません。


そんなわけで、DNSSECの実験を安価に行おうと考えた場合は海外ドメイン・海外レジストラを探した方が良さそうな状況だと言えるでしょう。


DNSSEC対応かつ安価な海外レジストラ

海外では多くの大手レジストラDSレコード取り次ぎに対応しています。CloudFlareの記事「How do I add a DS Record to my registrar?」にDNSSEC対応レジストラとその設定方法が書いてあり、レジストラ選びの参考になりました。


今回、上記の記事に挙げられているレジストラのうち、それなりに安くDNSSEC対応しているレジストラ3つについて比較検討してみました。


GoDaddy

まず世界最大手レジストラとして有名なGoDaddyを検討しました。GoDaddyでDNSSEC対応しているドメインは少なめで、.com/.net/.org/.bizなどです。


GoDaddyの価格は初年度のみ良心的で2年目以降は普通という印象です。通常ルートでは少し安い程度なのですが、プロモーションコードを使うと激安になったりします(ググると.comドメインを初年度0.99ドルで購入できるコードが見つかります)。ただ、登録者の個人情報を隠すオプションが別料金だったり、プロモーションコードを使うとPayPal支払いできなくなったりと細かい点に不満を感じたので結局購入を見送りました。


Gandi

Gandiは少し前まで格安レジストラとして有名だったフランスレジストラで、今でもボチボチ安い部類になると思います。また、GoDaddyより多くのドメインについてDNSSEC対応しています


GandiでのDNSSEC対応ドメインのうち最安値は.rocksドメインの初年度5.97ユーロ(約750円)でした。これでも十分安いと思うのですが、実験用には若干高いと考えて見送りました。


Namecheap

最終的にはNamecheapでドメインを買うことにしました。Namecheapは世界第二位のレジストラeNomのリセラーで、eNomリセラーの中では最大手の一つだと思われます。


このNamecheapは名前の通り値段が安いのが特徴で、多くのドメインについて初年度のみ0.88ドルという価格設定を行っています。また、登録者情報を別会社名で隠してくれるサービスも初年度は無料です。


今回、初年度0.88ドルのドメインの中からDNSSEC対応していて2年目以降もボチボチ安いドメインとして.pwドメインを選びました。


Namecheapが他の2つより劣っている点は、DSレコード登録のWebインターフェースが用意されておらず、カスタマーサポート問い合わせ経由で登録依頼する必要があることです。即時性やセキュリティ観点では若干不安だと言えるでしょう(後述するとおりレスポンスは速そうですが)。


CloudFlareDNSサービスを使えばDNSSEC対応が簡単かつ無料

今回、Namecheapで取得したドメインCloudFlareDNSで管理してDNSSEC対応しました。


CloudFlareといえば無料CDNサービスが有名ですが、高機能な無料DNSサービスも提供しています。筆者は趣味で独自ドメインを管理しており、以前はRoute53を使っていたのですが、昨年の2月からCloudFlareを利用しています(参照:「CloudFlareのCNAME FlatteningをGitHub Pagesで使ってみた」)。約1年間の運用で全く不満はありませんし、「CNAME Flattening」のような気の利いた機能が使えるのも良い点だと感じています。


また、CloudFlareは2015年11月からDNSSECに対応しており、簡単にDNSSEC対応ドメインの管理ができるようになっています。今回はこれを試してみたわけです。


DNSSEC設定の作業フロー

ドメイン取得後の実際の作業は下記4ステップになります。


CloudFlareDNSサービスに取得したドメイン登録する

管理画面の「Add Site」からドメイン登録します。


NamecheapでドメインのネームサーバCloudFlareのものに変更する

ドメインのネームサーバCloudFlareが提供するサーバ2つに切り替えます。


CloudFlare側でDNSSECを有効にする

ネームサーバ登録後、しばらくするとCloudFlareでのドメインの表示が「Status: Active」になります。Activeになってから、「DNS」「DNSSEC」「Enable DNSSEC」をクリックすれば下位ゾーン側のDNSSEC設定が準備できます。


NamecheapのカスタマーサポートにDSレコード登録を依頼

下位ゾーン側の準備ができたら、レジストラを通じて上位の権威サーバDSレコード登録してもらう必要があります。CloudFlareの「DNS」「DNSSEC」「DS Record」から下記のような情報が見えますので、これをNamecheapに伝えるとDSレコード登録してもらえます(下記画像には一見怖そうな内容が並んでいますが、全て公開情報です)。


f:id:hnw:20160321123037p:image


この手順についてはCloudFlareの文書「How to add a DS record to Namecheap – CloudFlare Support」も参考にしてください。


既に紹介した通り、NamecheapでのDSレコード登録カスタマーサポートによる人力対応です。対応の速度やソーシャルハック対策ができているかなど色々不安にはなりますが、筆者が依頼したときは日本時間で日曜日の昼頃だったにもかかわらず30分後に設定完了の連絡が来ました。いつもこんなに速いという保証はありませんが、ご参考まで。


(追記:一部のドメインについては管理画面からDSレコード登録ができるようになったようですが、.pwドメインについては2016年3月時点で未対応でした)


動作確認

DNSSECの設定確認にはDNSVizというサービスが便利です。このサービスは、DNSSECの「信頼の連鎖」をグラフィカルに表示してくれるものです。DNSSECの設定に失敗しているような場合、特定のレコードが「Insecure」と表示されます。


例えば、筆者の取得したドメインの結果は下記URLで確認することができます。グラフ上の全てのノードが「Secure」の表示になっており、正しく設定できていることがわかります。


感想など

自分でDNSSECについて調べたり設定したりしてみて、これ手動運用したら絶対事故るような仕組みだなあ、というのを今さら実感したりしました。つい先日もAPNICさんがやらかしたらしいですが、さもありなんという印象です。


また、自分で試すまではドメインをDNSSEC対応にすると古いOSアプリケーションで名前が引けないなどのトラブルがあると想像していたのですが、そんなことはありませんでした。


実は仕組みから考えてもトラブルが起こる方が珍しいくらいで、不幸な条件が複数重なって初めて変な状況になるように推測しています。手元の環境で http://ecdsap256sha256.pw/ が見えない、などのトラブルがあった方は教えてもらえると嬉しいです。


有名な事例としてはDNSSEC対応ドメインに対してqmailからのメールが届かないというトラブルがあるようなので、再現実験をしてみたいと考えています(参考:「qmail/netqmailにおける512バイトを超えるDNS応答の不適切な取り扱いについて」)。


まとめ

トラックバック - http://d.hatena.ne.jp/hnw/20160321
 
ページビュー
1816146