本サイトの IPv4 アクセスをブロックするテスト
Intro
4/1 なので、本サイトを IPv6 のみのアクセスに限定することにした。
背景を解説する。
IPv6 の現状
最初の RFC 1883、2460 からおよそ 30 年。RFC 8200 からも 9 年ほど経過した。
2011 年に IANA から IPv4 アドレスの在庫が枯渇し、World IPv6 Day で大規模なデプロイテストがされてから 15 年経つ。
IPv6 の基盤技術自体は整備されつつあるが、コストをかけて移行するほど差し迫った動機がないといった理由から、完全移行とはならずに現在に至る。
Google へのアクセスのうち、半分近くは IPv6 経由の通信になっている。
https://www.google.com/intl/en/ipv6/statistics.html#tab=ipv6-adoption
IPv4 の割り当てが枯渇しても、余剰アドレスは中古市場で取引されている。アドレスが少なくとも、NAT を始めとした延命技術がなまじ成果を出してしまったため、未だに IPv4 の運用は珍しくない。
NAT の存在が新しいプロトコルの制約になる場面は多い。例えば WebRTC の疎通はだいたい NAT との戦いだ。また、QUIC の普及期に NAT Table が溢れた際に、「IETF はこんなことも予見できずにプロトコルを策定しているのか」という反応を見たこともある。これからのインターネットの基盤となるプロトコルを考える上で、IPv4 を前提にするはずがないにもかかわらずだ。
一方、Apple のストアに出すアプリは v6-only 対応が必須となり、大手クラウドでの v4 は課金対象かつその料金は上がっていくだろう。米中を始めとする多くの国が、政府/行政システムの v6 移行を強く進めている。
本来は民間にも「IPv4 税」が重くのしかかることで、ビジネスメリットでしか重い腰を上げられない層を動かせるだろうが、まだその手前にある状況といえる。
また、単に慣れと認知負荷の低さから、IPv4 ベースで考えてしまうエンジニアもいるだろう。ループバックを示すときすら ::1 より 127.0.0.1 を使っているドキュメントも多く目にする。個人でドメインを持っている人も、A レコードだけ設定して終わっている人も、それなりにいるだろうと思う。
インターネットの大きな転換は常に「いつかやることになるとしても、先陣を切るのは自分たちではない」という層をどう切り崩すかの戦いでもある。
本ブログの状況
本ブログは、Web に関わるあらゆる技術を試し、その結果を記録するということを、何年にもわたり続けてきた。
読者もほとんどが「日本」の「Web エンジニア」だろう。ログを見ても「Mac の Chrome」の UA が 7 割を超えている。
これだけ対象読者が半径 1m に絞られたブログで、今年に入ってからのアクセスログを解析したところ、Source IP の v4/v6 比はちょうど 8:2 だった。
IPv4: 55.74 (80.0%)
IPv6: 13.91 (20.0%)
あまりにも少ない。
今のスマホ+キャリア回線ならだいたいは v6 で見られるだろう。v4 しか通らない会社のネットワークや、マンションタイプのネットワークの自席から、PC で見ている人が多いのかもしれない。
IPv6 Only のトライアル
様々な理由はあるだろうが、日本のエンジニアが主な対象となるこのサイトを、v6 のみにしたら何が起こるのかは、ずっと気になっていた。
掴んだ WiFi がだめでも、スマホのキャリア回線は大抵 v6 が通るため、代替方法が一切ないことはないだろう。そもそも、見られなくなったところで人の生命に関わるわけでもなく、アクセスが減ったところで筆者も困るわけではない。そうしたコンテンツが、移行に消極的である必要もない。
「アクセスできなくなったことの不便」を正当化する人もいるだろうが、v6 移行自体がそうした人によってこそ阻まれている側面は無視できない。その意味でも Dual Stack で運用してきたが、アクセスを断つことで「普段意識していなかった v4 環境」を意識するきっかけを提供する方が、本ブログの意図に合う。
マンションの場合、契約の見直しや設定の確認だけで有効になる場合もあるかもしれない (場合によっては「夜ネットが遅い」問題も解決するかもしれない)。
社内の場合、「うちの会社は未だに v4 なのか」と気づくと、イントラに対する見え方も変わるだろう。管理者に問い合わせて、高度に洗練された七色の言い訳を聞いてみる機会になればいい。
クローラなどを自分で作っているユーザは、もし挙動が壊れたら、実装を見直すきっかけになる。
そうした啓蒙と実験の意図を兼ねて、本サイトを IPv6 のみの提供に絞ってみることにした。
実装方法
Sakura VPS に立てた h2o で配信している。DC 内通信も VLAN も VPN アクセスも CDN もない、たかがブログであるため、移行のハードルは全く高くない (ちなみに、Sakura VPS における IPv4 は現在デフォルトであり、それが有料になったなどの理由で実施するものではない)。
最も端的な方法は、A レコードを返さず、AAAA レコードのみを返す方法だ。これなら、Happy Eyeballs も不要で、迷うことなく IPv6 を選び、対応していなければエラーになる。
ところがこの方法だと、多くの繋がらないユーザが「サイトが落ちている」と勘違いするだろう。その報告を大量に受け続けるのはさすがに面倒くさい。
ネットワークレイヤでエラーになると「v6 のみ提供している」というこちらの意図を、クライアントに伝えることができない。ポリシーを説明するために、この記事へリダイレクトすることもできない。
そこで、IP レイヤでの Dual Stack は維持しつつ、アプリケーションレイヤでエラーとすることにした。なまじ A レコードが返ってしまうことによる不具合も想像できるが、サイトが落ちてると思われるよりは良い。
具体的には v4 アクセスのみエラーステータス、および HTML の場合はエラーページを返す方針だ。
本サイトは、IPv6 での接続のみを受け付けるように制限しています。
あなたのアクセスは IPv4 であるため、別のネットワークからアクセスしてください。
あなたのアドレス: #{addr}
この制限は、あなたの身の回りに IPv4 のみの環境がどのくらい残っているかを啓蒙する目的で行っています。
詳細な背景については以下を参照してください。
https://blog.jxck.io/entries/2026-04-01/ipv6-only.html
ただし、この記事も IPv6 で接続しないと見られません。
スマホのキャリア回線でテザリングするか、Cloudflare WARP を入れるのが手軽です。
Jxck
ステータスコード
さて、HTTP のステータスコードはどうするべきだろうか。
本来、IP レイヤの問題を HTTP レイヤに持ってきてしまったので、話は多少ややこしくなる。
使えそうな 400 番台のコードは以下のようになる。
400 Bad Request
かなり汎用的にリクエストのエラーを示すことができるが、主に「HTTP リクエスト」自体に問題がある場合に返す想定だ。しかし、今回はリクエストのシンタックスやフォーマットには問題がないにもかかわらず返すことにはなる。
例えば「リクエストを直せば通る可能性がある」と考えるクライアントもあるかもしれないが、今回はその下位レイヤであるコネクションから修正しないと、いくら HTTP レイヤを見直しても意味がない。これは、今回のエラーが HTTP のネゴシエーションで発生するものではなく、その上にある「権限」や「ポリシー」に近い理由でエラーにしていると考えられ、その点で妥当なアドバタイズとは言えないだろう。
406 Not Acceptable
気持ちにはかなり近いが、これも意図とズレている。
そもそもこれは Content Negotiation の結果、受け入れることができないと判断した場合に使うものであり、今回の意図は Content Negotiation よりも手前で起こるものだ。
412 Precondition Failed
「前提条件」と訳すとこれも使えそうに見えるが、こちらは Conditional Request における前提条件の話をしているので、やはり異なる。
426 Upgrade Required
「プロトコルのアップグレードを要求する」という点で、なんとなくそれっぽくも見える。
しかし、ここで言っている「プロトコルのアップグレード」は、例えば HTTP/1.1 を WebSocket に切り替えるなどの要求を指す。
アップグレード先を示す Upgrade ヘッダが MUST であり、現状 IANA に登録されたプロトコルは以下だけだ。
- HTTP
- TLS
- WebSocket
- websocket
- h2c
- connect-udp
- connect-ip
もちろん、登録されていない ipv6 を書くことも可能かもしれないが、やはりここでも IP レイヤのアップグレードを示唆したところで、HTTP レイヤのクライアントが何かできるわけでもないため、良い使い方とは言えないだろう。
451 Unavailable For Legal Reasons
うっかりこんなものを返すと、余計にややこしいことになる。
403 Forbidden
そもそも HTTP 上で、下位レイヤに言及すること自体がレイヤバイオレーションなので、素直に「そのクライアントには見せない」という Content Author (筆者)の意図を 403 Forbidden で表すのが妥当だろう。
静的アセット(CSS, JS, Image, RSS etc) は 403 のみを、HTML には合わせてエラーページを返す実装とした。
Outro
これを思いついたのは、筆者の引っ越したマンションが、事前開通済みマンションタイプの全戸一括加入型ネットワークであったためだ。共有部にルーターがあり、部屋の壁から Cat5 の LAN が生えており、繋ぐと IPv4 が落ちてくる。ONU もなく、ISP の選択もできず、トンネルも設定できない。
コロナ禍に建った新築で、ゼロから敷設したネットワークであるにもかかわらず、未だにこのようなプランが新規に導入され、向こう何年も使い続けられる。自分で契約を変えるにも共用部工事が必要で、理事会の承認が必要だ。ベランダに何かを置くことにもうるさいので、Starlink の設置も難しそうだ。
こうしたところに、v6 移行を阻む要因が未だに残っている。
筆者は Cloudflare WARP を入れることで、大外に v6 アドレスをもらい、このブログに接続している。
生きているうちに、誰も何もしなくてもこのブログにアクセスでき、A レコードを削除しても障害報告が来ない日は、来るのだろうか。
なお、この記事をシェアする際は、あえて主語を省いたコメントを添えることが、より多くのユーザに「自分が置かれた状況」を認識させることに繋がるだろう。
2026 年 4 月 1 日 Jxck
Retrospective
4/1 を終えたため制限を解除した。
まず、本記事を Chat/SNS に貼った際の OGP 展開が失敗するという報告が届く(Discord, X, Slack, mixi2 etc)。また筆者のつかっている inoreader で RSS の更新がされなかったことも確認。
A レコード経由で 403 を取得した結果と考えられるが、これらのクローラが AAAA のみを取得していたら、無事に表示されていたかどうかは不明。
そこで、途中から UA ベースで Crawler, Bot 系の制限を外し、feed のパスも対象外として様子見をした。
4/1 中のステータスコード 200 と 403 の比率は 56.5% 対 43.5% であり、半々だった。200 の中には IPv4 を緩和したクローラ系のリクエストもある。
そもそも、一日のアクセス数としては、本サイトで記事を公開した日のアクセスとしては最低レベルのトラフィックだった。おそらく、記事の拡散部分が詰まり、多くの人が記事の更新自体に気づかず、アクセスが激減していたことがわかる。
2026-01-04/donation-for-web.html ***********************************
2026-01-24/web-exam-2025.html ***************************
2026-02-05/gpc.html ******************************
2026-02-11/text-scale.html *****************************
2026-02-17/conference-know-how.html ****************************************
2026-02-25/sptth.html ****************************************************************************************************
2026-03-03/scheduled-and-periodic-ex *************************************************
2026-03-23/https-certificate-chronic *******************************************
2026-04-01/cognitive-saturation.html ****
結論としては想定通りで、A を返しつつ 403 にする方針は、かなりエコシステムが壊れる。
できれば A を落とす方向にしたいが、それでは「サイトが落ちている」と勘違いされる可能性が高く、そのフェーズで意図を伝える方法がないため、なかなか難しい。
その場合、やはりクライアント側が v6 のサポートと、そちらの優先を行わない限りは、サーバ側から移行を促すのは難しそうだ。
このケースの場合は HTTP で IPv6 への移行を示唆するような方法が欲しくなるが、レイヤバイオレーションになるため難しいだろう。
今度実験するときは、思い切って A レコードを落とす方を試したい。