unboundでネットワーク内まるごと広告ブロック

WindowsやLinuxなどのPC個別、あるいはスマートフォンなどでhostsファイルに広告サーバのホスト名を書いて広告ブロックをすることはよくあるが、個別にやらないといけなかったりroot取って(とは限らないが)アプリでやったりと結構面倒くさい。
手法はhostsファイルみたいなもので、端末個別じゃなくネットワーク丸ごとだと少しは管理も楽というもの。hostsファイルのような方式なら非常に単純な仕組みなので、広告ブロック(アプリ)が裏でどんな動作をしてるかわからないという不安もないし。

今回は導入・設定・運用が簡単なキャッシュ機能付きDNSリゾルバであるunboundで広告ブロックを実現。要するにDNSシンクホールだとかDNSブラックホールだとか呼ばれてるやつ。

まず、名前解決のおさらい

名前解決おさらい 1
名前解決1:
OSのhostsファイルで名前解決を行う場合はこんな感じ。
一般的なOSの標準状態ではリゾルバの優先順位はDNSよりhostsの方が高くなっていることが多いので、殆どの場合にこちらの「名前解決1」が先に行われる。調べたいホスト名がhostsファイルに記載されていればhostsファイルを参照するだけで名前解決完了。
上の画像ではad.example.comホスト名からIPアドレスを引くためにhostsファイルを参照したら「ad.example.comは0.0.0.0」であるとの記載があったので名前解決終了。ただし、実際ののad.example.comのIPアドレスはxxx.xxx.xxx.xxxなので、0.0.0.0ではad.example.comのサーバにはアクセスできない。これがhostsファイルでの広告ブロックのやり方。
hostsファイルに記載されていないホストであれば下の「名前解決2」が行われる。

名前解決おさらい 2
名前解決2:
DNSによる基本的な名前解決。設定で指定しているDNSリゾルバから順次問い合わせを繰り返す。最終的にad.example.comのIPアドレスがxxx.xxx.xxx.xxxであることか判るのでad.example.comにアクセスできる(広告が表示される)。
なお、広告サーバであるad.example.com自体は名前解決には参加しない。名前解決で得たIPアドレスを使ってブラウザやアプリでad.example.comのサーバにアクセスする。

この記事では、端末それぞれのhostsファイルの代わりを、下の「名前解決3」のようにネットワーク内のunboundにやらせたい。

名前解決おさらい 3
名前解決3:
unboundを入れた場合。各端末のリゾルバにはunboundのサーバを指定しているとする。
最初に端末のhostsファイルを調べて(hostsファイルには記載が無いとして)、次にDNSで名前解決を行おうとしてunboundに問い合わせる。 unboundのlocal-dataに記載されている場合やキャッシュ済みであればunboundがIPアドレスを返答して名前解決は完了となる。(緑の①と②)
local-dataやキャッシュでは名前解決できない場合はunboundの設定で指定しているISPのDNSサーバなどに問い合わせを行う。(オレンジの①②③)
そこからはunboundが主体となって「名前解決2」を実行し(オレンジの③以降は図では省略)、unboundが名前解決を完了したところで元々の名前解決の依頼主である上の画像内のオレンジの①に返答する。

unboundのインストール (FreeBSDの場合)

# cd /usr/ports/dns/unbound
# make install
/etc/rc.confの最後に1行追記
unbound_enable="YES"

インストール終わり

unboundの設定

/usr/local/etc/unbound/unbound.conf (FreeBSDではこのPath)
server:
	verbosity: 1
	interface:127.0.0.1
	interface: ::0
	interface: 0.0.0.0 # or Unbound IPv4 Address exp:192.168.0.1
	interface: 2001:xxxx:xxxx:xxxx::1000 #Unbound IPv6 address

	#アクセスコントロール
	access-control: 0.0.0.0/0 refuse  #IPv4全拒否
	access-control: ::0/0 refuse      #IPv6全拒否
	access-control: 127.0.0.0/8 allow #許可(以下3行も)
	access-control: ::1 allow
	access-control: 192.168.0.0/24 allow  #LAN
	access-control: 2001:xxxx:xxxx:xxxx/64 allow  # IPv6 LAN

	#インクルードするファイル指定 (server:の中でインクルードする場合)
	include: /usr/local/etc/unbound/local_zone.conf
	include: /usr/local/etc/unbound/local_data.conf

forward-zone:
	name: "."
	forward-addr: 8.8.8.8   #or ISPのDNSサーバなど(IPv4) 
	forward-addr: 8.8.4.4   #or ISPのDNSサーバなど(IPv4)
	forward-addr: 2001:4860:4860::8888 #or ISPのDNSサーバなど(IPv6)
	forward-addr: 2001:4860:4860::8844 #or ISPのDNSサーバなど(IPv6)

間違ってもオープンリゾルバにならないよう9~14行目のaccess-controlの指定はしっかり行う。
Unboundで行わない名前解決(広告ホスト以外)は他所のDNSにフォワードする。上の例ではGoogleの公開DNSを指定しているが、なるべくISPのDNSを指定。

unbound用のサーバリストの書き方

hostsファイルではワイルドカードが使えないので、例えば302br.netをリスト化しようとしたら18,000行ちかくもの大量のホスト名とIPアドレスの組み合わせを記載しなければならない。
これはunboundでも同じ。

例:
local-data: "servedby.flashtalking.com.16508.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16510.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16514.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16516.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16518.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16520.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16521.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16522.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16524.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16525.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16526.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16529.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.16530.9069.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.23979.9167.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.23981.9167.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.23983.9167.302br.net. IN A 0.0.0.0"
local-data: "servedby.flashtalking.com.23989.9167.302br.net. IN A 0.0.0.0"
# 以下18000行ほど

あまりにも大量。しかも302br.netに新しいホストが追加されたらそれもフォローしなければならない。正直手間が過ぎる。そこで、unboundで使えるゾーン設定とリダイレクトで一気に簡略化する。

local-zone: "302br.net." redirect
local-data: "302br.net A 0.0.0.0"

18,000行がわずか2行になった。しかも302br.netに新しくホストが追加されても設定行を追加する必要が無い。
1つのドメインに対しlocal-zone:とlocal-dataが1行づつ必要。
こんな感じでホスト名の多いドメインをリスト化する。これを1つのファイルにして、上のunbound.confの8行目でインクルードする。

すでにリスト化したものを提供しているので悪いインターネットから取っていただければ良いかと。

個別の広告サーバもリスト化する。

local-data: "123ads.nl. IN A 0.0.0.0"
local-data: "123advertising.nl. IN A 0.0.0.0"
local-data: "123appz.com. IN A 0.0.0.0"
local-data: "123banners.com. IN A 0.0.0.0"
local-data: "123count.com. IN A 0.0.0.0"
local-data: "123counter.mycomputer.com. IN A 0.0.0.0"
local-data: "123counter.superstats.com. IN A 0.0.0.0"
local-data: "123counts.com. IN A 0.0.0.0"
local-data: "123direct.info. IN A 0.0.0.0"
local-data: "123found.com. IN A 0.0.0.0"
local-data: "123go.com. IN A 0.0.0.0"
local-data: "123pagerank.com. IN A 0.0.0.0"
# ありったけの広告ホストを延々と記載

こんな感じで広告ホストをリスト化する。これを1つのファイルにして、上のunbound.confの9行目でインクルードする。
こちらも、すでにリスト化したものを提供しているので悪いインターネットから取っていただければ良いかと。

もちろんインクルードせずに全てをunbound.confに書いてもよいが、メンテナンス性が良くないと思う。

unboundの起動・停止・再起動・設定のリロード (FreeBSDの場合)

# /usr/local/etc/rc.d/unbound start    #起動
# /usr/local/etc/rc.d/unbound stop     #停止
# /usr/local/etc/rc.d/unbound restart  #再起動
# /usr/local/etc/rc.d/unbound reload   #設定のリロード

ネットワーク内の端末のリゾルバ変更

ネットワーク内の個別の端末側はDNSサーバの設定でunboundのサーバのIPアドレスを指定する。DHCPサーバがあるならDHCPサーバの設定でunboundのIPアドレスを指定する。

ホワイトリスト?

広告ホストをブロックしたつもりが他に悪い影響を及ぼすホストがあるかもしれないので必要に応じてリスト中のホストの行頭に#を付けるなどして除外する。
設定を触った後はunboundの設定のリロードを行う。
どのようなホストが影響するかは「広告ブロック ホワイトリスト」「adaway white list」などのキーワードで検索する。

たとえば、「がとらぼ」で導入しているのと同じ方式のアンチ広告ブロックが効いてウェブサイトの閲覧が出来ない場合は、リスト内のpagead2.googlesyndication.comとwww.googleadservices.comの2つだけ無効にすれば広告は表示されないままページは閲覧できるようになる。Yahoo関係で表示が変なのはai.yimg.jpを無効とか。(2016.11.1現在)
意外と面倒なのはBing系かも。

以上、ネットワーク内にunboundを置いて名前解決をさせることで、PCやスマートフォン・タブレットだけでなくインターネット対応のゲーム機やテレビでも広告表示をブロックできる。ただし、スマートフォンなどの携帯端末はWi-FiでLANの中にある間は広告ブロックが効くが、外に持ち出して3G/LTEに切り替わるとLANではなくなるのでunboundでの名前解決ではなくなり、当然ながら広告が表示されてしまう。持ち出す端末については素直に広告ブロックアプリを使う方が良さ気。

「がとらぼ」が広告有りのサイトなので一応遠慮して広告ブロックのリストファイルを「悪いインターネット」に置いている。