_ 一般向けの記事も出てるぐらいなんで別にいまさら書く必要もない気がせんでもないが、自分が後で思い出したくなったときのためにメモ。
_ ipv4 がめでたく売り切れました。厳密にはまだ /8 が5個残ってるけど、これは RIR に自動的に分配される分なので、おばちゃんおかわり、と言ってもごめんねーごはんもうないんだわ、となる。
_ 最後のおかわりは、大方の予想どおり APNIC に2ブロック。この APNIC の在庫も年内には枯渇するはず。ほとんど中国が使っちゃうのかなー。
RIR exhaustion of the unallocated address pool would occur in 2022.2003年の時点で、RIR の枯渇が2022年の予想。文中では言及されてないけど、 グラフで見ると IANA のプールは2021年という予想。18年後という予測が大外れして、たったの8年で枯渇しちゃったのね。この時点では /8 がまだ90個も残ってたらしいので、ほんとあっとゆーま。_ 10年前は小さな ISP があんなに乱立していたのに、いつのまにやら淘汰されて大きなところばっかりになり、そして v4 アドレスの取得が不可能になって新規参入ができなくなり、既得権として v4 を持っている業者の影響力がますます強くなる。ずいぶん変わったもんだね、と淘汰された小さな ISP で以前仕事していたわしは思うのでありました。
4. 新しいSSL証明書はサーバの移行時や同時に複数のサーバを実行している時に購入する必要がある
SSL証明書の購入手順は次のようになっている。こうした手順が採用されているのは、メールやダウンロードでSSL証明書を提供した場合に中間者によってSSL証明書を取得されてしまうのを防ぐため。もしSSL証明書を他のサーバで使いたいのであれば、一旦証明書を他のデータ形式にエクスポートして移動させる必要がある。
- 証明書署名要求(CSR)を作成
- CSRを使ってSSL証明書を購入開始
- CSRプロセスを完了させSSL証明書のインストールを完了させる
_ なにこれ?
_ SSL の証明書って、誰に見られてもいいもののはずなんですが。中間者に取得されて何が困るのか。そうでなけりゃ証明書が正しいものなのかどうか第三者から検証できないでしょ。うちは正当な証明書を交付されてる!という主張をするのに、肝心なその証明書を隠してたら誰が信用なんかするもんか。秘密鍵さえ盗まれなければ、公開鍵である証明書なんぞ好きに持ってけ。
_ 他のデータ形式にエクスポートする、というのもよくわからん。翻訳ではなく元記事の方を見ると IIS の話みたいだけど、よそに移すためにエクスポートが必要というより、それ以前に IIS で SSL 証明書を使うには事前にインポート作業が必要(=インポート元のファイルを用意しなきゃいかん)だというだけのことだよね。
_ で、複数のサーバを動かす場合には証明書を買い増ししなきゃいけないことがあるのは厳然たる事実であって誤解でもなんでもない。これは証明書の発行業者によっては1サーバにしか使っちゃダメよ、とライセンス制限してるだけのことであって(してないところもある)、技術的な話とはまったく無関係なこと。
_ 「ほげほげについてのn個のナントカ」というタイトルの記事って、ほんと役に立たないものばっかりだよね。この記事に限らず。
_ そして、日本時間で今日の 23:30、最後の /8 x 5ブロックを各 RIR に手渡しするセレモニーがおこなわれて、正式に IANA の v4 在庫が枯渇したのでありました。ustream の同時通訳つき中継を見てたけど(というか今まさに見てるけど)、セレモニーの内容よりも、おい中継スタッフもっとがんばれよ、という感想の方が先に:-)。セレモニーが終わって記者会見になってからはだいぶよくなったけど。
_ で、その中継は ustream のも通訳なしの本家のも ipv4 だけだったというのが何だか象徴的だなーと思った。v6 への移行をスムーズにおこなうためには、ほんとは枯渇しちゃう前にある程度 v6 が普及してるとよかったんだけど、けっきょくダメだったね。まだ RIR の在庫はあるけど、間に合わんよね。足りない v4 を苦しまぎれにやりくりする期間を経てやっと v6 になる、と。LSN とかまじわけわかんね。
_ APNIC の在庫も年内には尽きるようだけど(そして JPNIC は在庫を一切持たない)、どこで目にしたか、5月にはなくなるよ、という話もあるらしい。そんなに早いんかよ。トヨタじゃないんだからもっと在庫持てよ。まあ、各 RIR は向こう3ヶ月以内(たったかな?)で必要になる分しか IANA に申請できないとかそんなルールがたしかあったはずなんで、5月でないにしても夏を越すのは難しいか。もしかして年末ぐらいから「v4 アドレスが欲しいのにないって言われたー」とかいう嘆きがふつーに見られちゃったりするんだろうか。
_ DNSSEC がはじまった後でアレだけど、djb 大先生の DNSCurve についてもちゃんと調べてみ
_ …るつもりだったけど、途中でやめた。ダメだこりゃ。使えん。
_ 上述のとおり仕様を詳しく読んだわけではないので認識が間違ってるところがあるかもしれないけれど、わしの理解ではだいたい以下のとおり。
ということで、SSL のように通信路自体を暗号化することで攻撃から守り、DNSSEC なら公開鍵のハッシュを DS として登録するところを、DNSCurve では公開鍵そのものを NS として登録することで信頼の連鎖を形成する、というのが主要なアイデアみたい。
- レコード単位で署名するけど暗号化はしない DNSSEC と異なり、DNSCurve はパケット単位で暗号化する
- パケットを暗号化するので、NSEC という不在証明(悪魔の証明)は必要ない
- 毎回暗号化するので、署名の期限などいうものは考えなくてよい
- 暗号化アルゴリズムは djb 謹製の Curve25519 という楕円曲線暗号がデフォだが、いちおう他のアルゴリズムも使えるようにはなっている(現時点では未定義)
- サーバの公開鍵を base36 でエンコードした謎文字列(base64 でも base32 でもない)を NS レコードとして使う
_ でもダメ。どこがマズいか。これ、ひとつのサーバでひとつの鍵しか持てない仕様だよね。SSL でもひとつの IP アドレスで複数の証明書を持てない (*1)のと同じように、DNSCurve でも IP アドレスひとつにつき鍵はひとつしか持てない。DNS ホスティング業者だとお互い無関係な大量のゾーンを持つことになるけど、自分のドメインと赤の他人のドメインがまったく同じ鍵で暗号化されることになる。かなり気持ち悪いけど、そのことについては気持ち悪い以外の問題はないのでまあいいとする。
_ 鍵ひとつという縛りのために発生するもっとひどい問題は、鍵を取り替えることができない、ということ。
_ 新しい鍵を作って入れ替える、という操作自体はかんたんにできる。しかし、それをやるととーぜん公開鍵が変わり、ということは NS レコードも変えなきゃいけない。新しい NS を親ゾーンに登録するまでにはいくらか時間がかかり、その後キャッシュがすべてそれに置き換わるまでにはさらに時間がかかる。その過渡期に名前を聞かれると、サーバで実際に使われている鍵と親ゾーンに登録されている情報との食い違いのため、改竄されたとみなされて名前解決に失敗する。DNSSEC は複数の鍵を同時に持てる仕様なので、鍵変更の過渡期でも正しく名前解決できる組み合わせを常にひとつ以上残すことで安全に検証できるようになってるし、DNS から離れて SSL なんかでは証明書はキャッシュされないので鍵交換の過渡期というものがそもそも存在しない。DNSCurve は、それをまったく考慮していない。DNSSEC で鍵変更する手順はひじょーに難解複雑で、それが DNSSEC はダメだと批判される理由のひとつだし否定するつもりもまったくないけど、仕様レベルでそれができない DNSCurve は難解複雑以前の問題外。
_ もっとも、DNSCurve でロールオーバーがまったくできないわけではない。以下手順。
NS が1台しか存在しない場合、最初のステップで NS を消すわけにはいかないので名前変更することになる。これ、よーするに DNSCurve をいったんやめて、しばらくしてまたはじめるということなので、鍵変更の過渡期は DNSCurve の守りはなくなる。NS が2台以上存在する場合は、交換したい NS を消してクエリをもう1台の方に集めて、その間にロールオーバーする、ということができるので常に DNSCurve で守ることはできるけど、ロールオーバー中は通常より1台少ない縮退運転になるので、この間にサーバが死ぬと危険なことになる。
- 鍵を変更しようとする NS レコードを親ゾーンから消す、または magic string を含まない名前に変更する
- 変更後 TTL が過ぎてキャッシュから消えて DNSCurve なクエリが飛んでこなくなるのを待つ
- 新たな鍵を生成して、その公開鍵を NS として親に登録する
_ 上のロールオーバー手順における NS 更新をさらに掘り下げて考えてみる。NS が1台だけの場合でも、上位ゾーンへの NS 変更は2回必要。上述のとおり、DNSCurve では鍵はゾーンに対してではなくサーバに対して作成するものなので、鍵のロールオーバーはサーバの数だけ繰り返すことになる。つまり、サーバが2台なら NS 更新は4回、3台なら6回。鍵はゾーンではなくサーバに対して作成するものだからサーバが増えなければ収容するゾーンが増えても NS 更新の回数が増えない、というのであればありがたいんだけどそうはならず、NS レコードはゾーンに書かなければならないので、結局増えた分だけ NS 更新が必要になる。DNSSEC でも鍵を変更するときには上位サーバの DS レコードを更新する必要があるけれど、二重署名方式ならサーバが何台あっても1ゾーンにつき1回。しかも、DNSSEC はたくさんのゾーンを収容するサーバでもそれぞれのゾーンの鍵交換は独立して好きなタイミングで実行できるけど、DNSCurve はサーバの鍵変更のタイミングに合わせてすべての収容ゾーンが足並み揃えて一斉に変更しなければならない。顧客調整が必要になる DNS ホスティング業者では事実上不可能といってよい。DNSSEC が複雑で運用困難だって? DNSCurve の方がよっぽどめんどくさいじゃないか。
_ Curve25519 がどれだけ強固な暗号なのかは知らないけど、計算機の処理能力の向上によって現実的な時間で解読できるようになる将来はきっとやってくるだろうし、あるいは処理能力とはまったく無関係に簡単に解読できてしまう脆弱性が発見されるかもしれない。もっと単純に、人的ミスやサーバに侵入されたりして秘密鍵が漏曳することもあるかもしれない。なので、鍵を取り替えられるような仕組みにすることは必須で、仕様上でもアルゴリズム変更の余地はたしかにあるんだけれど、運用上はそれができない、あるいは非常に困難な仕様になっている。これでは使いものにならない。
_ 以下こまかいこと。
_ DNSSEC の隠れたメリットとして、ゾーンに署名するホストと署名されたゾーンを置くホストを物理的に分離できるというのがあったりする。つまり、DNS サーバ上に秘密鍵を置かなくてもいいので、そういう構成になっていれば万が一外部から侵入を許してしまった場合でさえ毒入れできない。DNSCurve はサーバ上に鍵を置くのが必須なので、侵入されてしまったら DNSCurve 的には正当だけど実は改竄された応答というのを返してしまうことがありうる。これが DNSCurve のデメリットというつもりはないけど(SSL だってサーバに秘密鍵が必要だし)、気にしておいてもいいことだとは思う。
_ あと、DNSCurve は権威サーバとキャッシュサーバの間のセキュリティしか担保できないことにも注意。DNSSEC はスタブレゾルバでも署名の検証を(実際にやるかどうかはともかくとして少なくともやろうと思えば)できる仕組みになってるけど、DNSCurve はパケットを暗号化するという仕様のため、権威サーバと直接パケットをやりとりしないレゾルバやフォワーダでは使えない。/etc/resolv.conf に IP アドレスではなくて公開鍵エンコードなホスト名を書いて、そのホスト名を /etc/hosts で解決させればレゾルバとキャッシュの間も暗号化できる理屈だけど、DNS の設定が DHCP で降ってくるような環境じゃ無理だし、これをやったとしてもあくまでレゾルバとキャッシュの間で毒入れされないだけで、キャッシュと権威サーバの間で毒入れされなかったかどうかはレゾルバからは知る方法がない。
_ もうひとつ重要なこと。dnscurve.org や yp.to などの NS には uz5 な magic string が含まれていて、すでに DNSCurve を導入しているように見えるけれど、そう見えているだけで実は毒入れされてまったく別のところに誘導されている可能性がゼロではない。つまり、dnscurve.org の NS が正しいことを確認する前にまず org が正しいことを確認する必要があるが、それを検証する手段がない。これは DNSSEC も同じで、信頼の連鎖が形成されていないゾーンを署名しても意味がない。SSL のオレオレ証明といっしょ。DNSSEC ではそのためにルートからの信頼の連鎖を辿れない場合でもトラストアンカーやら DLV やらを使って検証できるようにしていたわけで、DNSCurve でも同様のものが必要。が、現時点では唯一の DNSCurve キャッシュ(?)である djbdns へのパッチにはそのへんの仕組みは存在していないように見える。つまり、このパッチを使っても、何かを守れたつもりになっているだけで、実は毒入れに対し防御できない。これは実装の不備であって、仕様の問題ではない。
(*1): ワイルドカード証明書や SNI を使っても異なるコモンネームをひとつの証明書でまかなえるようになるだけで、複数の証明書が使えるようになるわけではない。
_ せっかくなんで、ついでに djb 大先生の Breaking DNSSECについても。
_ 主な論点はふたつ。ひとつ、レスポンスのサイズがクエリよりも何倍も大きいので、DDoS の踏み台に使える。ふたつ、ゾーンウォーキングされないための NSEC3 を使ってもゾーンウォーキングできてしまう。まったくもってそのとおりで、反論するつもりはない。書かれていることは正しい。それを認めた上で、それぞれについて考えを述べると以下のようになる。
_ 前者について。これは古くから DNS amplification attackとして知られている攻撃手法のバリエーションで、別に DNSSEC だからこの問題が起きるというわけではない。DNSSEC によって問題が発現しやすくなったことは否定しないけど、DNSSEC がなくたって可能な攻撃。つまり、DNS 自身の問題であって DNSSEC の問題ではない。大きな応答を返すレコードが存在するのであれば DNSCurve を使っていても発生しうる(はず)。つーことで、ISP のみなさんはイングレスフィルタの導入をよろしくお願いしますです。
_ 後者について。これは NSEC3 のハッシュアルゴリズムが弱いというだけで、NSEC3 のしくみがダメだといってるわけじゃない。もっと強いアルゴリズムが定義されていないというのはそれはそれでよろしくない気もするけど、どうせ聞かれたら正直に答えるものなんだから、高性能のマシンをぶんまわしてもぜったいに解析されないような強いアルゴリズムでがちがちに固めてまで守る必要のあるものではないと思う。つーか、自分がやるのならそんなことしないで、権威サーバに存在しそうな名前を辞書から生成してかたっぱしから問い合わせて存在するかどうか調べる、というプログラムを書く。この方法ならアルゴリズムに左右されないし。つまり NSEC3 にそこまでの強度を求めるという考えがそもそもナンセンス。
_ DNSCurve の問題点、もうひとつ致命的なものに気がついた。公開鍵を NS として登録するというしくみ。これ自体がすでにおかしかった。
_ DNS において、NS レコードは親ゾーンと子ゾーンの両方に同じものを登録する必要があるけれど、権威があるのは子ゾーンのものだけであり、親ゾーンの NS は子ゾーンを置いてあるサーバを探すための権威のないヒント情報でしかない。そのため、キャッシュサーバは親から得られた NS レコードはキャッシュしない。その NS を元に子に聞きにいき、その結果得られた NS をキャッシュする。もしも親と子で NS が食い違っていれば子の方が正しい情報であるとする。DNSSEC では自分が権威を持たない情報には署名しないことになっているので、親ゾーンに登録された NS レコードには署名されない。子ゾーンの方で署名する(DS レコードは権威情報なので、親ゾーンの方で署名する)。
_ ところが DNSCurve においては、親ゾーンに登録する NS は公開鍵そのものであり、信頼の連鎖を形成するための最重要な要素になる。これが正当なものでないと子の正当性を検証できない。つまり、子ではなく、親ゾーンの NS も権威情報として扱う必要がある。これは DNS の権限委譲の概念を改変するものであって、現行 DNS と互換性がない。既存の NS レコードの意味を変えるのだから、DNSCurve 非対応の DNS サーバもそれに応じた修正が必要になる。DNSCurve が従来の DNS と互換性があるというのはウソということになる。
_ 互換性の方を重視して、親ゾーンに登録される NS は従来どおり権威のない情報であるという立場を取るのであれば、子の情報に親がお墨つきを与えないということであり、信頼の連鎖が形成されない。ルート証明書 - 中間証明書 - サーバ証明書という連鎖によって構成される SSL や、DS - DNSKEY の連鎖で構成される DNSSEC などとはこの点が決定的に異なる。仮にルートサーバはじめ世界中のすべての DNS サーバが DNSCurve に対応したとしても、そのすべてのサーバが第三者から検証できないオレオレ鍵で勝手に暗号化しているにすぎないということで、その結果得られた情報が正しいものであると保証することはできない。DNSCurve で DNS は守れない。
_ ということで、きのうはトラストアンカー(的なもの)を設定できないキャッシュについて「実装の不備であって仕様の問題ではない」と 書いたけど、これは間違いでした。仕様の不備です。
_ どうすればいいか。DNSSEC が親ゾーンに登録する情報を権威のない NS と権威のある DS に分離したように、DNSCurve でも親ゾーンに登録する権威情報を NS とは別のレコードに分離するよりほかないんじゃない?
_ オワコン言いたかっただけ:-)。 いいかげん qmail は捨てようやと書いたのはもう5年も前か。ずいぶん時間がたったし、もうみんな qmail なんかとっくに捨てたよね。
_ …といいたいところだけど、まだ使ってるところいっぱいあるんだよなぁ。qmail を捨てられない理由もあるんだろうけど、qmail を捨てないことによるデメリットとか考えてくださいよいいかげん。
_ つーことで、たいへん不本意ながら life with qmail の翻訳に訳注を追加。ほんとだったら「いいかげん捨てましょう」と一言だけ書いたページに差し替えたいところ。捨てられないのはしかたないとして、それならば 最低限必要なパッチを適用しているか確認して、まだだったらコンパイルしなおしてください。おれ qmail じゃなくて netqmail だもんねー、とかいう人もパッチ必須。なぜだか知らんが netqmail でも無視されてるパッチなので。qmail-1.03 が出て2ヶ月後にはすでに発覚してパッチが出てるバグなのに、なんでそれから10年以上たってもみんなまだ放置してるんかね。
_ 具体的には、 jprsや yahooでもトラブルの例として取り上げられてたり、あるいはつい最近 twitter でも少し話題になったらしい件(わしのアカウントではないが)。以下それについてのちょっと詳しい解説。
_ メールは DNS の MX レコードのホストに送ることになっているけど、同時に、ここには CNAME は使えないことにもなっている。このため、qmail では CNAME かどうかの判定をしているが、ここが腐っている。CNAME かどうかを調べるのに、CNAME を問い合わせずに ANY を問い合わせるという曲芸をやっている。CHANGES によると不具合のある古い BIND4 (BIND8 ですらない!)のゲロ (*1)に対応するためにやむなくやったものらしいけど、逆にそれが問題の原因。qmail には512バイト以上の DNS 応答を扱えないという有名なバグがあり(djb は認めていないけどバグ以外の何ものでもない)、そして、ANY ではしばしばこのサイズを越える応答が返ってくる。結果として、こういう大きな応答を返すサイトには qmail でメールが送れない。
_ 最近では SPF がかなり普及して大きな TXT レコードを持つドメインも増えたし、何より決定的なのが DNSSEC。これに対応しているドメインに ANY で問い合わせると、(DNSSEC 非対応なキャッシュサーバからの問い合わせであっても)ほぼ確実に 512バイトを越えるサイズの応答が返る。つまり、DNSSEC に対応したドメインには素の qmail ではメールが送れない。512バイト超の応答を返す DNS と、それを扱えない qmail のどちらが悪いかというと、疑う余地もなく qmail。DNSSEC や SPF が普及したのは比較的最近だけど、DNS 応答が512バイト以上にはならない、なんてのは qmail が出た13年前ですらウソだったんだから。
_ うちは DNSSEC 対応してないから関係ないや、と思っていても、よそが対応をはじめた以上は逃れられないので、パッチを当ててない qmail 管理者の人はかならず パッチを当てて作りなおしてください。前述のとおり、netqmail もパッチは当たってません。ってゆーか、パッチを検討するより qmail 以外のものへの乗り換えを本気で検討しましょう。
_ つーことで、DNSCurve にひきつづき djb ネタでした。べつに叩きたくて叩いてるわけじゃないんだよ。いいものはちゃんと評価してやりたいのに、評価できないところばっかり目につくのがいけないんだよ。
_ 余談。古めの sendmail は配送先を調べるのに MX → A ではなく、まず ANY で聞いて、その応答に MX がなければあらためて MX → A で聞き直す、ということをやっていたらしい(伝聞につき未確認)。ただし、512バイトでコケるようなしょぼい問題はないので、これが原因で qmail のようにコケたりはしない。
(*1): CHANGES にほんとにゲロ(barf)と書いてある。というか連呼してる。
_ 前にも書いたとおり斜め読みしかしてないので、 いろいろ指摘いただけるのはたいへんありがたい。
BASE36ってどこに書かれてるんだろ、BASE32 でしょ。うん、 ここにちらっと出てきてるを勘違いした。ウソですね。ただ、同じページの中に aeio の文字は使わないともあって、これは RFC4648 で定義されてる a-z2-7 の base32 や 0-9a-v の base32hex とは明らかに異なるので、32進数であったとしても base32 と称するのは難あり。DNSCurve では鍵の更新できないんじゃないかってのは、DNSSEC やめる手順ないじゃんみたいに考慮する必要なしとしてるんじゃないかなDNSSEC は親から DS を削除してから各地のキャッシュから消えるのを待って署名をやめる、という手順で安全に止められます。で、たぶん鍵更新の考慮は不要という判断したのだろう、というのは同意。ただし、それは暗号が十分に強いから長期間使い続けても安全だということではなく、何かヘマをやらかして鍵の緊急交換をせざるをえなくなったようなサイトはインターネットから一時的に消えるぐらいのペナルティを受けて当然、という考えなんじゃないかと。暗号強度とはまったく無関係に鍵を紛失、漏曳してしまうことはありうることで、どんなに暗号が強くても鍵を作り直さざるを得ない場合があるのを承知してないはずがない。なのに更新できない作りになってるのは、鍵の緊急更新なんて起きないから必要ないという現実無視の設計なのではなく、そんなアホな問題を起こすような奴の面倒は見ない、と考えたのではないか。いや、ほんとのところは知らんけど。_ つーか、UDP のパケット暗号化ならば DTLS というプロトコルもあるんだけど、djb にはきっと受け入れがたいんだろうな。わしも DTLS について詳しいことは知らんので、こういう用途に使えるのかどうかわからんでてきとーなこと言ってるけど。