Dnsmasq を広告ブロックツールとして使う

DnsmasqDNS サービスを提供することができるソフトウェアだ。簡単な設定で名前解決のレコードほ書き換えることができる。これを利用して広告をブロックする。

この記事の対象読者は、次のすべてに当てはまることを想定している。

  • OS X を使っている(ここで試したのは 10.9.5/Mavericks, 10.10.5/Yosemite)
  • 今使っているマシンのネットワーク設定ができる
  • ターミナル上での操作に慣れている
  • ローカルに Web サーバを設定して使っている、あるいは設定できる

Dnsmasq のインストール

Dnsmasq のインストールには OS X であれば Homebrew で行える。次のコマンドを実行するだけだ。

brew install dnsmasq

(しばらく Homebrew を更新していない場合はこの前に brew update を実行するとよい)

Dnsmasq の初期設定

Dnsmasq の設定ファイルをコピーする。

cp -a `brew --prefix dnsmasq`/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf

設定ファイルは初期状態ではほぼコメントだった。なので、役立ちそうなコメントを除いてすべて消し、次の行を書き加えた。

# /usr/local/etc/dnsmasq.conf

# LaunchAgents で動かすため、常にforgroundで起動
keep-in-foreground  

# Dnsmasq 用の resolv.conf
resolv-file=/etc/resolv.dnsmasq.conf

# ローカルからの問い合わせのみ受け付ける
listen-address=127.0.0.1

Launchctl から起動できるように plist ファイルを LaunchAgents ディレクトリにコピーする。

sudo cp `brew --prefix dnsmasq`/homebrew.mxcl.dnsmasq.plist /Library/LaunchAgents

OS X で使われている resolv.conf を dnsmasq 用にコピーする。

sudo cp /etc/resolv.conf /etc/dnsmasq.conf

resolv.conf には OS X の環境設定で設定されている DNS サーバのアドレスが登録されている。DHCPDNS サーバを自動取得している場合、取得したサーバのアドレスが登録される。そのため、もし MacBook をいろいろな場所で複数のネットワークに接続する必要がある場合は面倒かもしれない。ただし LAN 上の DNS を参照する必要がない場合、Google の提供する Public DNS に向けておくという手もある。

Dnsmasq の起動と終了

Dnsmasq の起動と終了には launchctl を用いる。ps ax | grep [d]nsmasq などで起動を確認できる。

# 起動
sudo launchctl load -w /Library/LaunchAgents/homebrew.mxcl.dnsmasq.plist

# 終了
sudo launchctl unload -w /Library/LaunchAgents/homebrew.mxcl.dnsmasq.plist

もし OS X 起動時に自動的に起動させたい場合は、LaunchAgents のかわりに LaunchDaemons に homebrew.mxcl.dnsmasq.plist をコピーする。(LauchDaemons は OS の起動時、LaunchAgents は各ユーザのログイン時に実行される。dnsmasq の起動にはスーパーユーザ権限が必要なため、各ユーザの権限で実行される LaunchAgents では自動起動しない)

OS X が参照する DNS サーバを dnsmasq に向ける

次のコマンドのほか、OS X の環境設定パネルからも可能。“Wi-Fi” の部分は適宜書き換えてほしい。

sudo networksetup -setdnsservers Wi-Fi 127.0.0.1

Dnsmasq を使うのをやめ、DHCP での自動取得に戻したい場合は次のコマンドを使う。

sudo networksetup -setdnsservers Wi-Fi Empty

広告を提供しているドメインをローカルに向ける

dnsmasq.conf に次の設定を追記した。これで設定したドメインおよびそのサブドメインがローカルへ向く。

# AD Block
address=/2o7.net/127.0.0.1
address=/a.adroll.com/127.0.0.1
address=/ad-arata.com/127.0.0.1
address=/adcash.com/127.0.0.1
address=/addthis.com/127.0.0.1
address=/adlantis.jp/127.0.0.1
address=/adkengage.com/127.0.0.1
address=/adjust-net.jp/127.0.0.1
address=/adresult.jp/127.0.0.1
address=/adtechjp.com/127.0.0.1
address=/advertising.com/127.0.0.1
address=/advg.jp/127.0.0.1
address=/agkn.com/127.0.0.1
address=/api.flipdesk.jp/127.0.0.1
address=/api.unthem.com/127.0.0.1
address=/apvdr.com/127.0.0.1
address=/atwola.com/127.0.0.1
address=/b3.yahoo.co.jp/127.0.0.1
address=/bidswitch.net/127.0.0.1
address=/bigmining.com/127.0.0.1
address=/bktrx.com/127.0.0.1
address=/bluekai.com/127.0.0.1
address=/brightcove.com/127.0.0.1
address=/cas.criteo.com/127.0.0.1
address=/cdn.bigmining.com/127.0.0.1
address=/cdn.cxense.com/127.0.0.1
address=/cdn.optimizely.com/127.0.0.1
address=/company-target.com/127.0.0.1
address=/coremetrics.com/127.0.0.1
address=/criteo.com/127.0.0.1
address=/d.adroll.com/127.0.0.1
address=/deqwas.net/127.0.0.1
address=/domdex.com/127.0.0.1
address=/doubleclick.net/127.0.0.1
address=/dsum-sec.casalemedia.com/127.0.0.1
address=/edge.simplereach.com/127.0.0.1
address=/eimg.jp/127.0.0.1
address=/exoclick.com/127.0.0.1
address=/fout.jp/127.0.0.1
address=/genieesspv.jp/127.0.0.1
address=/gmossp-sp.jp/127.0.0.1
address=/googleadservices.com/127.0.0.1
address=/googlesyndication.com/127.0.0.1
address=/googletagmanager.com/127.0.0.1
address=/googletagservices.com/127.0.0.1
address=/gssp.asia/127.0.0.1
address=/gsspat.jp/127.0.0.1
address=/gsspcln.jp/127.0.0.1
address=/gssprt.jp/127.0.0.1
address=/i-mobile.co.jp/127.0.0.1
address=/im-apps.net/127.0.0.1
address=/img.macromill.com/127.0.0.1
address=/impact-ad.jp/127.0.0.1
address=/js.ptengine.jp/127.0.0.1
address=/js.revsci.net/127.0.0.1
address=/loading-delivery1.com/127.0.0.1
address=/logly.co.jp/127.0.0.1
address=/microad.jp/127.0.0.1
address=/moatads.com/127.0.0.1
address=/mtcs.nhk.or.jp/127.0.0.1
address=/nakanohito.jp/127.0.0.1
address=/native.sharethrough.com/127.0.0.1
address=/nr-data.net/127.0.0.1
address=/omt.shinobi.jp/127.0.0.1
address=/openx.net/127.0.0.1
address=/openxmarket.jp/127.0.0.1
address=/outbrain.com/127.0.0.1
address=/pixel.facebook.com/127.0.0.1
address=/popin.cc/127.0.0.1
address=/pubmatic.com/127.0.0.1
address=/quantumads.com/127.0.0.1
address=/revcontent.com/127.0.0.1
address=/revsci.net/127.0.0.1
address=/rlcdn.com/127.0.0.1
address=/rtoaster.jp/127.0.0.1
address=/rubiconproject.com/127.0.0.1
address=/s.adroll.com/127.0.0.1
address=/s.thebrighttag.com/127.0.0.1
address=/scorecardresearch.com/127.0.0.1
address=/secure.eloqua.com/127.0.0.1
address=/sh.adingo.jp/127.0.0.1
address=/skimresources.com/127.0.0.1
address=/socdm.com/127.0.0.1
address=/spdeliver.i-mobile.co.jp/127.0.0.1
address=/static.quant.jp/127.0.0.1
address=/taboola.com/127.0.0.1
address=/tacoda.net/127.0.0.1
address=/textad.net/127.0.0.1
address=/trafficfactory.biz/127.0.0.1
address=/uliza.jp/127.0.0.1
address=/xml.affiliate.rakuten.co.jp/127.0.0.1
address=/yads.c.yimg.jp/127.0.0.1
address=/b90.yahoo.co.jp/127.0.0.1
address=/b91.yahoo.co.jp/127.0.0.1
address=/yads.yahoo.co.jp/127.0.0.1
address=/ybx.yahoo.co.jp/127.0.0.1
address=/yjtag.jp/127.0.0.1
address=/ziyu.net/127.0.0.1

ローカル Web サーバを設定する

OS X では Apache が入っているのでそれを使った。設定ファイルは /etc/apache2/httpd.conf にある。
ローカル Web サーバを使っていない場合は次の設定をする。

# デフォルトではこうなっているはずだ
DocumentRoot "/Library/WebServer/Documents"

# このセクションに記述する
<Directory "/Library/WebServer/Documents">
    ...

    # この2行を追記
    ErrorDocument 403 "404 AD Block"
    ErrorDocument 404 "404 AD Block"

    ...
</Directory>

すでにローカル Web サーバを使っている場合はバーチャルホストを設定し、特に名前を設定したホスト以外はダミーページを表示するようにする。

<VirtualHost *:80>
    ServerName localhost
    ServerAdmin webmaster@localhost
    DocumentRoot "/Users/theUser/Sites/dummy"
    ErrorLog /dev/null
    CustomLog /dev/null common env=0

    <Directory "/Users/theUser/Sites/dummy">
        ErrorDocument 403 "404 AD Block"
        ErrorDocument 404 "404 AD Block"
    </Directory>
</VirtualHost>

効果測定

これで大半の広告がブロックされたので、ためしに広告がいくつか入ったページの読み込み速度を測定した。

広告スクリプトの配置されているドメインの名前解決が必要なくなったぶん、かなり高速になった。