iPhoneのSafariから「小説家になろう」を開くと403になる現象を調べている途中で、Private Relayの出口IPだけでなく、配信先そのものも気になってきた。

最初の記事では、Safariで403になったときの症状と対処方法をまとめた。

その後、WAFやDDoS対策としてこの403をどう考えるか、一般読者まで巻き込むIPベースのアクセス制御にどこまで意味があるかを別の記事で考えた。

さらに調査を続けると、最初に考えていた「IDCFとさくらインターネットのどちらへ接続されるかで403が変わる」という理解が違っていたことが分かった。

2026年9月23日時点で外から確認できたのは、次の構成だった。

対象観測結果
syosetu.com の権威DNSAmazon Route 53
ncode.syosetu.comIDCF側の複数IPv4アドレス
ncode.syosetu.com のAAAA確認できず
ncode.syosetu.com の本文HTMLIDCF側へ接続
static.syosetu.comさくらインターネット側へ接続
images.hinaproject.comさくらインターネット側へ接続
static.syosetu.comApache Traffic Serverのキャッシュ配信を確認

この記事では、ここまでをどう確認したのかをコマンドとHARを含めて残す。

内部の構成図を入手したわけではないので、書くのは公開DNSとブラウザから観測できた範囲だ。ただし、少なくとも「本文HTMLの配信先」と「静的ファイルの配信先」は分けて考える必要があることは確認できた。

まず権威DNSを確認した

最初に syosetu.com のNSレコードを確認した。

dig syosetu.com NS +short

結果は次の通りだった。

ns-1166.awsdns-17.org.
ns-818.awsdns-38.net.
ns-447.awsdns-55.com.
ns-1550.awsdns-01.co.uk.

4つともAWSの awsdns-* なので、syosetu.com の権威DNSにはAmazon Route 53が使われている。

ここで確認できるのはDNSの話であって、WebサーバーがAWS上にあるという意味ではない。

実際、このあと ncode.syosetu.com のAレコードを追うと、接続先として見えてくるのはAWSではなくIDCF側だった。

Route 53の権威DNSへ直接問い合わせた

通常の dig ncode.syosetu.com では、その時点で返された一部のIPしか見えない。

そこで4つの権威DNSへ直接、Aレコードを繰り返し問い合わせた。

手元のIPv6経路で一部の問い合わせがタイムアウトすることがあったため、ここでは -4 を付けてIPv4で問い合わせている。

for ns in \
  ns-1166.awsdns-17.org \
  ns-818.awsdns-38.net \
  ns-447.awsdns-55.com \
  ns-1550.awsdns-01.co.uk
do
  echo "=== $ns ==="
  for i in {1..50}; do
    dig -4 @"$ns" ncode.syosetu.com A +norecurse +short
  done | sort | uniq -c
done

この調査で確認できたIPv4アドレスは次の通りだった。

203.137.161.72
203.137.163.182
203.137.163.253
203.137.164.4
203.137.167.151
203.137.192.156
203.137.192.158
203.137.192.168
203.137.193.203
203.137.193.225
203.137.193.57
203.137.194.13
203.137.195.68
203.137.197.91
203.137.198.199
210.152.14.33

1つのIPだけに固定されているわけではなく、複数のIPv4アドレスが返る。

uniq -c で回数も出しているが、この回数をRoute 53の設定上のWeightとみなすことはできない。DNSキャッシュや応答の選択を含む、そのときのサンプル結果にすぎない。

Public DNSを変えてもIDCF側だった

権威DNSへ直接問い合わせた場合だけの結果ではないかも確認した。

Cloudflare DNS、Google Public DNS、Quad9へ、それぞれ50回ずつ問い合わせた。

for dns in 1.1.1.1 8.8.8.8 9.9.9.9; do
  echo "=== $dns ==="
  for i in {1..50}; do
    dig @"$dns" ncode.syosetu.com A +short
  done | sort | uniq -c
done

1.1.1.1と8.8.8.8では複数の 203.137.* が返り、9.9.9.9では同じアドレスが繰り返し返る状態だった。

リゾルバごとにキャッシュの状態は違うが、今回の問い合わせで確認できた接続先はいずれもIDCF側だった。

少なくとも、「Cloudflare DNSならIDCF、別のDNSならさくら」というような分かれ方は確認できなかった。

AAAAレコードも確認した

IPv4とIPv6で配信先を分けている可能性も考えて、AAAAレコードを確認した。

dig ncode.syosetu.com AAAA +short

通常の問い合わせでは何も返らなかった。

権威DNSへ直接問い合わせても同じだった。

for ns in \
  ns-1166.awsdns-17.org \
  ns-818.awsdns-38.net \
  ns-447.awsdns-55.com \
  ns-1550.awsdns-01.co.uk
do
  echo "=== $ns ==="
  dig -4 @"$ns" ncode.syosetu.com AAAA +norecurse +short
done

2026年9月23日の観測では、ncode.syosetu.com の公開AAAAレコードは確認できなかった。

そのため、「IPv4はIDCF、IPv6はさくらインターネット」という構成でもなかった。

IPの所属をASNで確認する

DNSで得られたIPと、あとでHARから確認したIPについてはASNも確認した。

例えばTeam CymruのWHOISを使うと、次のように確認できる。

for ip in \
  203.137.198.199 \
  133.167.30.2 \
  133.167.6.1
do
  whois -h whois.cymru.com " -v $ip"
done

今回確認した 203.137.* と 210.152.14.* はAS4694のIDC Frontier、133.167.* はAS9370のSAKURA Internetとして確認できる。

さくらインターネットも公式のPeering Policyで、東京系ネットワークにAS9370を利用していることを公開している。

DNSだけを見る限り、ncode.syosetu.com はIDCF側の複数IPv4アドレスへ向いていた。

ここで、最初に見えていた「さくらインターネット側の通信は何だったのか」が次の疑問になる。

HARを見ると、さくら側は静的ファイルだった

ブラウザで実際に小説ページを開いたときのHARを確認した。

確認したページでは、メインドキュメントの接続先は次のようになっていた。

https://ncode.syosetu.com/n8310ms/1/
serverIPAddress: 203.137.198.199
Server: Apache

203.137.198.199 は、DNS調査でも確認したIDCF側のIPだ。

一方、JavaScriptやCSSなどは別ホストから読み込まれていた。

static.syosetu.com
serverIPAddress: 133.167.30.2

画像も別ホストだった。

images.hinaproject.com
serverIPAddress: 133.167.6.1

この2つの 133.167.* がさくらインターネット側だった。

つまり、今回確認したページでは次のように役割が分かれている。

ブラウザ
  ├─ ncode.syosetu.com
  │    └─ IDCF
  │         └─ 本文を含むHTML
  │
  ├─ static.syosetu.com
  │    └─ さくらインターネット
  │         └─ JavaScript / CSS / Font
  │
  └─ images.hinaproject.com
       └─ さくらインターネット
            └─ 画像

最初は 133.167.* への通信がページ内に見えていたため、ncode.syosetu.com 自体がIDCFとさくらインターネットの両方へ振り分けられていると考えていた。

HARをホスト名ごとに見直すと、そうではなかった。

さくらインターネット側へ接続していたのは、本文HTMLではなく静的ファイルと画像だった。

静的ファイル側ではすでにキャッシュ配信されている

static.syosetu.com のレスポンスには、次のようなヘッダーも確認できた。

server: nginx
x-cache: HIT
via: ... ApacheTrafficServer ...

x-cache: HIT が返っており、Via にはApache Traffic Serverが記録されている。

そのため、JavaScriptやCSSなどの静的ファイルについては、さくらインターネット側のキャッシュ層から配信されていることが分かる。

ここは、以前のWAF・配信設計の記事で考えていた「キャッシュをもっと使えないか」という話とも関係する。

「小説家になろう」がキャッシュを使っていないわけではない。少なくとも静的ファイルにはすでにキャッシュ配信が入っている。

次に論点になるのは、本文を含むHTMLをどこまでオリジンの手前で処理できるか、という部分だ。

公開されている「マルチクラウド」と今回見えた構成

IDCフロンティアが2024年4月に公開した導入事例では、ヒナプロジェクトは「サービス提供を途切れさせない」ことを前提に、複数の国内クラウドサービスを契約し、マルチクラウドでリスク分散していると説明している。

同じ導入事例では、「小説家になろう」は月間約24億PVの規模とされている。

一方、今回外から確認できた通常時の配信経路は、

本文HTML
→ IDCF

静的ファイル・画像
→ さくらインターネット

という役割分担だった。

これは、少なくとも今回観測した経路では、同じ機能をIDCFとさくらインターネットで二重化している形ではない。

複数のクラウド事業者を利用することと、片方の事業者が停止したときにもう片方で同じサービスを継続できることは別の話になる。

VM障害、LB障害、事業者障害は分けて考える

Webサービスの可用性は、どこが壊れたかで対応するレイヤーが違う。

一般的には次のように考えられる。

障害吸収するレイヤーの例
バックエンドVM 1台の障害LBが正常なVMへ振り分ける
LB・公開エンドポイント単位の障害DNSフェイルオーバーで別エンドポイントへ切り替える
クラウド事業者全体に影響する障害別事業者側で同じサービスを引き継ぐ

VMが1台停止しただけなら、通常はロードバランサーがヘルスチェックで対象から外す。

IDCFのロードバランサーにも、HTTP/TCPでバックエンドサーバーを監視するヘルスチェック機能が用意されている。

さらに上位のエンドポイントを切り替える場合は、Route 53のヘルスチェックとDNSルーティングを組み合わせる方法がある。

ただし、Route 53がAレコードのIPを自動的に監視して、応答しないIPを勝手に除外するわけではない。ヘルスチェックやルーティングポリシーをそのように設定している場合に、異常なエンドポイントをDNS応答から外せる。

このレイヤーまでなら、

VM障害
→ LB

LB / エンドポイント障害
→ Route 53

と分けられる。

問題は、IDCFという事業者単位で広い障害が起きた場合だ。

フェイルオーバー先は「存在する」だけでは足りない

事業者障害を別クラウドで引き継ぐ場合、DNS上で切り替えられるだけでは足りない。

導入事例にある月間約24億PVという規模を前提にするなら、切り替え先が実際のトラフィックを受け切れる必要がある。

例えば、

通常時
IDCF       99%
別クラウド  1%

IDCF障害
↓
別クラウドへ100%流入

という構成で、別クラウド側が1%相当の容量しか持っていなければ、DNSの切り替え自体が成功してもサービス継続にはならない。

必要なのはWebサーバーの台数だけではない。

LB、ネットワーク帯域、DB、キャッシュ、ストレージ、セッション、アプリケーションの起動時間、オートスケールの立ち上がりまで含めて、残った系で必要な負荷を処理できる必要がある。

AWSのRoute 53ドキュメントでも、不健全なエンドポイントを外した結果、残ったエンドポイントへ負荷が集中し、それらまで処理不能になるカスケード障害について説明されている。

マルチクラウドを障害耐性として評価するなら、何社のクラウドを契約しているかよりも、

1つの障害ドメインを失ったとき、残った系だけで必要な機能と負荷を引き継げるか

を見る必要がある。

今回見えた構成では、IDCFとさくらは相互の代替にはなっていない

今回観測した通常系では、IDCFとさくらインターネットが別々の役割を担当している。

IDCF障害
→ ncode.syosetu.com の本文HTMLに影響

さくら側の静的配信障害
→ CSS / JavaScript / Font / 画像に影響

本文そのものは初期HTMLに含まれているため、静的配信側の障害がそのまま本文取得不能になるとは限らない。

ただし、表示やJavaScript依存の機能には影響が出る。

逆にIDCF側で本文HTMLを取得できなければ、さくら側の静的ファイルが正常でも小説ページは成立しない。

この通常経路を見る限り、両者は同じ機能を相互に代替しているのではなく、サービスを構成する別の役割を担当している。

IDCフロンティアの導入事例が説明する「他の事業者のクラウドサービスでカバーしてサービス提供を継続する」という仕組みが、現在どのサービス・どのレイヤーで実装されているかまでは公開情報から確認できなかった。

ここは、単に「マルチクラウドだから障害に強い」と見るより、どの障害ドメインに対して何が冗長化されているのかを分けて見た方がよい。

Private Relayの403についても見方が変わった

今回の調査をする前は、

Private Relay
↓
IDCFなら403
さくらなら正常

という構図を考えていた。

しかし、本文HTMLの ncode.syosetu.com は今回確認したDNSとHARの両方でIDCF側だった。

その状態でも、Private Relayの出口IPによって403と正常表示が分かれている。

そのため、現在は次のように考えている。

Safari
↓
iCloud Private Relay
↓
出口IP
↓
ncode.syosetu.com
↓
IDCF側
↓
403 / 正常表示

403の違いを説明する主な変数は、IDCFとさくらのどちらへ接続されたかではなく、Private Relayの出口IP側にある。

この点は最初の記事も調査結果に合わせて修正している。

外からでも、ここまでは分かった

今回の調査で確認できたのは、内部の完全な構成図ではない。

それでも、DNSとHARを組み合わせることで、少なくとも次のことまでは追えた。

  • syosetu.com の権威DNSはAmazon Route 53
  • ncode.syosetu.com は複数のIDCF側IPv4アドレスを返す
  • ncode.syosetu.com の公開AAAAレコードは確認できない
  • 実際の本文HTMLもIDCF側へ接続している
  • JavaScriptやCSSなどは static.syosetu.com からさくらインターネット側へ配信される
  • 画像は images.hinaproject.com からさくらインターネット側へ配信される
  • 静的ファイル側ではApache Traffic Serverを使ったキャッシュ配信が確認できる
  • 今回観測した通常経路では、IDCFとさくらインターネットは同じ役割を二重化するのではなく、別の役割を担当している

最初はPrivate Relayの403を切り分けるために配信先を調べ始めた。

結果として、403の原因候補を一つ修正できただけでなく、「複数クラウドを使っている」という情報だけでは可用性の設計までは分からないことも見えてきた。

DNS、LB、クラウド事業者、静的配信は、それぞれ別の障害ドメインを持つ。

どこまでを冗長化しているのかを見るには、サービス名ではなく、どの機能がどこで動き、何が止まったときに何へ切り替わるのかを追う必要がある。