すべての投稿に戻る
公開日 · 著者 Renaud Deraison

Bromureは、ページが目にする前に広告を遮断します

ほとんどの広告ブロッカーはブラウザ拡張機能であり、そしてほとんどのブラウザ拡張機能は、守ろうとしているページと同じプロセスの中で動いています。Bromureはそれを違うやり方でこなします。その方法と、なぜそれが重要なのかをお話しします。

ブラウザの内側に住む広告ブロッカーは、リングの中から試合を裁こうとする審判のようなものです。Bromureはその審判を、ページが届かず、スクリプトが触れられず、「アンチ広告ブロック」のバナーが言い返すこともできない場所 — ネットワークそのもの — に移しました。

広告ブロックは、ブラウザに標準搭載されていないブラウザ機能のなかで、もっとも広く使われている機能です。現代のウェブは、何らかの広告ブロッカーなしではまともに使えません。だからこそ何億人もの人が、初日にサードパーティの拡張機能をインストールしてしまうのです。それ自体が、設計のおかしさを示すサインです。しかし、ほぼすべての広告ブロッカーが取っている仕組みには注目する価値があります。そのアーキテクチャが、動作の良し悪しにも、ページ側が積極的に対抗してきたときの結末にも、実は大きく関わってくるからです。

本記事では、広告ブロッカーがふつうどのように動作するのか、なぜその形には実質的な限界があるのか、そしてBromureがどのように異なるアプローチを取っているのか — その核となる発想を、誰かの地下室のRaspberry Piで動いているあのツールから借りてきた経緯も含めて — をたどっていきます。

広告は単にうっとうしいだけではありません。読み込みの問題であり、プライバシーの問題であり、攻撃経路でもあります。

何年も広告ブロックに慣れきってしまうと、フィルタリングなしの素のウェブが実際どんな姿をしているか、忘れてしまいがちです。人気ニュース記事を何もフィルタリングせずに読み込むと、たいてい30から80ものサードパーティドメインからリソースが取得されます。その大半は、解析ツール、トラッキングピクセル、そしてリアルタイム入札のエンドポイントです。これらはページを重くし、レイテンシを増やし、あなたが名前も聞いたことのない企業のクッキーを勝手に置いていき、そして — 今月初めのランサムウェアの記事で触れたとおり — マルウェアの静かな配送経路のひとつになっています。広告ネットワークが、正規サイト上で悪意あるクリエイティブを配信させられてしまうことが、ときおり起きるからです。

news.example.com記事ひとつdoubleclick.netgoogletagmanager.comfacebook.netadnxs.comscorecardresearch.comcriteo.nethotjar.comsegment.comchartbeat.compubmatic.comrubiconproject.comliveramp.comtaboola.comoutbrain.comnewrelic.comamplitude.commixpanel.com… ほか40ロゴの一つひとつが、新しいドメイン、新しいDNS、新しいTLS、新しいクッキーです。誰も頼んでなどいません。
2026年、ページを一度開いたときに、フィルタリングなしで実際に読み込まれるもの。あなたが読んでいる記事は、ふつうページ上で最も軽いリクエストです。それ以外はすべて、その記事がくるまれている機構そのものです。

したがって、これらのリクエストを止めることは、単なる見た目の問題ではありません。パフォーマンス上のメリットであり、プライバシー上のメリットであり、そして — 広告ネットワークがマルウェア配布の常連のチャネルである以上 — 実際にセキュリティ上のメリットでもあります。問題はただ一つ、どうやって止めるか、です。

典型的なブラウザ拡張機能は、どのように広告を止めているのか。

主流の広告ブロッカーは、あなたがたぶんインストールしている有名どころも含めて、ほぼすべてがブラウザ拡張機能です。つまり、アーキテクチャとしてはブラウザの内側に住んでいる、ということです。ブラウザプロセスの中でJavaScriptを走らせ、ブラウザのネットワーク関連API(webRequestdeclarativeNetRequest)にコールバックを登録し、ブラウザがいまから出そうとしている一つひとつのリクエストを検査します。

ブラウザプロセスページ読み込み、スクリプト実行、リソース要求広告ブロッカー拡張機能各リクエストを検査し、許可か遮断かを返すネットワークTCP / TLSサイトへ(遮断)拡張機能は、ブラウザに読み込まれたコードにすぎません。レンダラーが侵害されたり権限が取り消されたりすれば、機能しなくなります。敵対的なページは、それが入っているかを見抜き、読み込みを拒否することもできます。インターネット広告サーバー・トラッカー・解析
拡張機能型の広告ブロッカーがふつうどう動いているか。拡張機能はブラウザの中に住んでいます。外へ出ていこうとするすべてのリクエストは、いったん拡張機能に渡されて承認を求められ、URLがルールに一致したものは拒否されます。ページと拡張機能は、同じプロセスを共有し、多くの場合は同じ権限も共有しています。

この形はちゃんと機能します — 何しろ、多くの人が毎日頼りにしている形なのですから — が、構造的な限界があります。

ページ側から気づかれる

拡張機能はページと同じプロセスに住んでいるので、ページ自身のJavaScriptから存在を探ることができます。「自分が出したリクエストは本当に外に出ていったか? この変数はきちんと定義されたか?」と。サイト全体(そしてペイウォール付きニュースサイトの多く)は、リクエストが消えていることを検知し、ユーザーに「広告ブロッカーを無効化してください」と迫って記事を読ませないようにしています。

ページと同じ信頼境界にいる

拡張機能と、それがフィルタリングしようとしている敵対的なページは、ブラウザプロセスを共有し、レンダラーを共有し、場合によっては権限セットまで共有しています。ページ側に十分に悪質なブラウザ脆弱性が使われれば、拡張機能もほかのすべてと一緒に無力化されます。拡張機能はコードであり、つまり攻撃面でもあるのです。

リクエストはすでに生まれてしまっている

拡張機能がリクエストを見る時点では、ブラウザはすでにそれを送ると決断し、URLを解析し、(APIによっては)DNSルックアップまで済ませています。その段階での遮断は、予防ではなくフィルタリングでしかありません。

フィルタリングAPIはどんどん弱くなっている

ChromeのManifest v3への書き換えは、フィルタリング系拡張機能にできることを縛り、ルール件数に上限を設け、動的なwebRequestdeclarativeNetRequestに置き換える形になりました。拡張機能APIのアーキテクチャを決めるのはブラウザベンダーであって、あなたではありません。

Bromureのやり方:壁は拡張機能ではない。

Bromureの広告ブロッカーは拡張機能ではありません。ブラウザそのものには、広告ブロック用のコードが一切入っていません。代わりに、ブラウザが走っている使い捨てLinux VMのネットワークスタックそのものが広告ブロッカーになっています。そしてブラウザの視点からは、広告ドメインはそもそも名前解決されません。

ゲストVM・プロファイルのネットワークブラウザ広告ブロック用の拡張機能は入っていないSquidプロキシ:3128・HTTP/HTTPSローカルDNSで名前解決dnsmasqローカルDNSリゾルバー該当ドメインを吸い込むブロックリストgravity.list10万以上のドメイン0.0.0.0 に吸い込むインターネットnews.example.comdoubleclick.netadnxs.comブロックページもそのスクリプトも、プロキシの向こう側は見えません。ブラウザの内側から見れば、広告ドメインはそもそも存在しないのです。
BromureプロファイルのVMの内側では、ブラウザからの外向き接続はすべて、ローカルHTTPプロキシ経由に流し込まれます。そのプロキシは、あらゆるドメインをローカルDNSサーバーに解決させます。その『ノー』リストの中身がブロックリストです。ドメインがリストに載っていれば、ブラウザには到達不能なアドレスが返され、接続はそもそも確立されません — ページ自身のスクリプトも含めて。

仕組みとしては、二つの小さく地味なソフトウェアが仕事をこなしています。

ローカルHTTPプロキシ(Squid)

ブラウザからの外向きリクエストはすべて、VM内のlocalhost:3128で動いているSquidプロキシへ透過的に流し込まれます。Squidは配管にすぎません。何が広告かを判定するのではなく、ブラウザに代わってDNS名前解決と転送を行うだけです。

ローカルDNSリゾルバー(dnsmasq)

Squidは、どんなドメインでも127.0.0.1で動くローカルのdnsmasqインスタンスを通して名前解決するように設定されています。dnsmasqの設定には、およそ10万件のドメイン — 広告ネットワーク、トラッカー、解析、既知の悪質ホスト — からなるブロックリストが含まれています。そこに載っているものは0.0.0.0に解決され、どこにも行きません。

結果として、ブラウザから見れば、ネットワークはインターネットそのものの形をしているのに、広告やトラッキングのドメインだけはDNSレコードが一切存在しない、という世界になります。ブラウザがdoubleclick.netを問い合わせれば「経路なし」が返り、そのまま通り過ぎる。接続は一切開かれません。TLSハンドシェイクも試みられません。クッキーはどこにも送られません。なぜなら、送る先の「どこか」が存在しないからです。

何年も地下室で動いてきたのと同じ発想。

家庭内ネットワーク全体から広告を追い出すために、Raspberry Piの上でpi-holeという小箱DNSシンクホールを仕立てたことがある方なら、Bromureのアーキテクチャはとても親しく感じられるはずです。下敷きになっているブロックリストは、Steven Blackが整備している統合hostsファイルで、それらの家庭導入で何年も前から使われてきたのと同じものです。発想の核は同じです。ページから広告を取り除こうとするのではなく、広告サーバーの所在をブラウザに教えること自体を拒む、ということです。

重要な違いは、シンクホールがどこに置かれているかです。家庭全体のシンクホールは、家のネットワーク上のすべての端末を守ります。Bromureのシンクホールはブラウザプロファイル一つだけを守ります。ニュースを読むためのプロファイルではオンにして、銀行のように「変な中継は挟まれたくない」プロファイルではオフのままにしておく、といった使い分けができるわけです。

これが実際に何を手に入れさせてくれるのか。

拡張機能が遮断ブラウザが広告URLを解析する。広告ドメインのDNSルックアップが走る。接続試行が始まることもある。拡張機能が最後の瞬間に拒否する。ページは欠落したリクエストを検知できる。広告サーバーが知ること「IP Xから誰かが来ようとして、途中で引き返した」Bromureは問い合わせないブラウザがローカルDNSにドメインを問い合わせる。dnsmasqが0.0.0.0を返す。ネットワーク接続は一切開かれない。TLSなし、SNIなし、HTTPリクエストなし。ページはDNS障害との区別がつかない。広告サーバーが知ること何もなし。観測すべき接続そのものが存在しない。
同じページを開いていても、アーキテクチャが違えば結果も変わります。拡張機能方式は、リクエストをいったん始めさせたうえで最後の最後にフィルタリングします。Bromureは、そもそも問いを発することを拒みます。広告サーバーはBromureの利用者について何も知りません — 試みがあったことすら。

実用上のメリットはこう積み上がります。

侵害されたページに無効化されない

ブロックリストは、ブラウザに読み込まれているコードではなく、ブラウザのネットワークそのものです。レンダラーの脆弱性も、敵対的なスクリプトも、行儀の悪いサードパーティライブラリも — どれ一つとして、ブラウザプロセスの外に出てVMのネットワークスタックに手を伸ばせない以上、dnsmasqの設定には届きません。

ページ側から回り込めない

ページのJavaScriptはいくらでもnavigatorのプロパティを調べられますが、自分が乗っているネットワークのDNS設定を見ることはできません。それはJavaScriptが知ってよいこととされていないからです。ページにしてみれば、遮断された広告は、広告ドメインが1分ほどダウンしているのとまったく同じに見えます。

拡張機能の攻撃面がない

広告ブロッカー拡張機能は、これまでに何度か侵害されてきました — ストア経由だったり、買収経由だったり、悪意あるアップデート経由だったり。Bromureにはそもそも拡張機能がないので、侵害しようにも侵害できる拡張機能が存在しません。

プロファイル単位で、他の機能と同じように切り替え可能

広告ブロックはプロファイルごとの設定(「プライバシーとセーフティ」内の「広告をブロック」)で、既定はオフ、オンにしたいプロファイルだけでオンにできます。銀行用プロファイルはフィルタリングなしのまま、日常の記事閲覧用プロファイルはすっきり、という具合に。

正直に言う限界。

この領域に無料で手に入るものはありません。ネットワーク層のアプローチが意図的にやらないことがいくつかあります。先にはっきりさせておくべきでしょう。

コスメティックフィルタリングはしない

古典的な拡張機能なら、かつてバナーがあった空き箱を非表示にできます。Bromureはページを書き換えないので、もし掲載元が728×90の枠を確保していれば、その枠は空のまま残ります。一部のサイトでちょっと見た目が気になる、程度の小さな不都合です。代わりに、スクリプトが気づける手がかりがページ上に何も残りません。

ファーストパーティ広告は残る

サイトが自前のドメインから自前の広告を配信している場合(一部の大手プラットフォームはいま実際にそうしています)、ドメイン単位のブロックでは「記事」と「広告」を区別できません。どちらも同じホスト名の上にあるからです。これは本当に穴であり、ここが問題になる場面の答えは、その上にコンテンツスクリプトの層を足すことであって、そちらは現在検討中です。

アンチ広告ブロックの壁は「不在」を検知する

なかには、広告ブロッカーを見つけようとすらしないサイトもあります。特定のスクリプトが読み込まれたかだけをチェックし、読み込まれていなければ記事を表示しない、というやり方です。そうしたサイトでは、拡張機能型であれネットワーク型であれ、どのブロッカーもつかまります。それは掲載元との方針上の議論であって、ブロッカーとの技術的な議論ではありません。

ブロックリストはBromureと一緒に配布される

gravity.listはイメージビルド時に焼き込まれ、Bromureをアップデートするタイミングで更新されます。常時稼働の専用家庭用シンクホールのように、毎時最新ルールを取りにいく仕組みではありません。ホスト名ベースのリストであれば、これはだいたい問題になりません — 広告ドメインは、たとえばマルウェアドメインほどには頻繁に入れ替わらないからです — が、知っておく価値はあります。

ものごとの形。

もっと広い論点は、Bromureの広告ブロッカーがuBlock Originよりも魔法のようにうまくルールをマッチングできる、という話ではありません。uBlockのルールエンジンのほうが、実のところ洗練されています。論点は「どこで遮断が起きるか」です。拡張機能は、ブラウザに「どうかこれは読み込まないでください」とお願いする礼儀正しい審判です。Bromureは、そのリクエストが通るはずだった道路そのものを、ドライバーがまだ車にも乗らないうちに、高速の入口で静かに封鎖してしまうのです。

密閉VMのなかで広告をブロックする、これはBromureに新しく加わった機能ではありません。初日からそこにあったアーキテクチャの帰結です。各プロファイルのネットワーク層は、それ自体が独立した小さな世界なのです。その世界にWARPを入れることもできます。有料VPNを入れることもできます。Torのトランスポートを入れることもできます。そして、何年ものあいだ人々の地下室で静かに広告を濾し続けてきたのと同じDNSシンクホールを、無料で、あらかじめインストールされ、設定済みで、あなたが指定したまさにそのブラウザセッションにだけ適用される形で入れることもできます。

長いほうが知りたい方へ。このブロックリストはVMイメージの中にプレーンテキストで同梱されており、次のリリースでそのまま開いて、あなたのブラウザにとって静かに存在しなくなる十万件のドメインを、一つずつすべて確かめることができます。短いほうでいい、という方へ。どのBromureプロファイルでも「プライバシーとセーフティ」を開き、「広告をブロック」をオンにしてください。道路はすでに封鎖されています。あとは、あなたが運転するだけです。