AWSを使って広告をブロックするDNSサーバを構築する

本記事では、AWSのEC2を使い、広告をブロックするDNSキャッシュサーバを構築します。
DNSを用いることで、ブラウザだけでなくスマホアプリでも広告をブロックすることができます。
具体的な設定を通して、実際に広告がブロックされている様子を紹介していきます。

本記事では広告を対象としていますが、SNSなど特定のサイトをブロックしたい場合も同様の方法で行うことができます。

# DNSを使った広告ブロックについて
広告のブロック方法はいくつかあります。
最もメジャーなのがブラウザの拡張機能として行う広告ブロックですが、この方法ではブラウザ以外では広告をブロックできません。
例えば、スマホのゲームアプリなどの広告はブロックできません。

本記事では、ブラウザの拡張機能ではなくDNSキャッシュサーバを使った広告ブロックを行います。
DNSはドメインが送られてきたらIPアドレスを返す仕組みで、そのIPアドレスからWebページを読み込んだりAPI通信を行います。
例えば下記のようにドメインにはそれぞれIPアドレスが振られています。
```
www.google.com -> 142.251.42.168
twitter.com -> 104.244.42.61
```
巨大なサービスは1つのドメインに対して多くのIPアドレスが割り振られ、ユーザによって最適なサーバにアクセスするようになっているので、上記はあくまでも一例です。

このようにDNSはドメインに対してIPアドレスを返すのですが、広告の通信に使われているドメインが分かっているのであれば、IPアドレスを返さなければ通信は行われず、結果的に広告をブロックすることができます。

```
ads.mopub.com -> IPアドレスを返さない (通信ができないので広告はダウンロードされない)
```

本記事では実際に広告のドメインのみを拒否するDNSキャッシュサーバ (フルサービスリゾルバ) を構築し、ブラウザだけでなくゲームアプリなどでも広告をブロックする環境を作ります。

# unboundを使ったDNSキャッシュサーバの構築
EC2を使ってDNSキャッシュサーバを構築していきます。
DNSキャッシュサーバの構築にはunboundというオープンソースのソフトウェアを利用します。
DNSキャッシュサーバのソフトウェアとしてはBINDというライブラリが最も有名ですが、今回はDNSコンテンツサーバ (権威サーバ) の構築が不要であり、またサクッと構築したいためunboundを選択しました。

まずはEC2を立ち上げるのですが、DNSはUDPを使って通信するので (最近ではDoH/DoTもありますが)、ポート53番を開放しておきます。

![](https://storage.googleapis.com/zenn-user-upload/eaf1052fd28e-20220731.png)

OSはAmazon Linuxを選択しました。

EC2インスタンスが立ち上がったらunboundをインストールします。

```
# yum install unbound
```

インストールできたらunboundの設定ファイルを編集していきます。

```
# vi /etc/unbound/unbound.conf
```

デフォルトではローカルネットワークのリクエストのみ許可しているので、アクセスできる対象を変更するため、以下のように編集します。

```
	interface: 0.0.0.0
	interface: ::0
	...
	access-control: 0.0.0.0/0 allow
```

上記の設定ではどこからでもアクセスできるようになっていますが、お好みでアクセスできるIPアドレスなどを絞って、よりセキュアにすることもできます。

また、同じ `unbound.conf` ファイルでフォワードゾーンの設定も行っていきます。
一旦すべての問い合わせをGoogleのパブリックDNS (8.8.8.8、8.8.4.4) にフォワードします。

```
forward-zone:
	name: "."
	forward-addr: 8.8.8.8
	forward-addr: 8.8.4.4
```

今回はGoogleのパブリックDNSを使いましたが、Cloudflareの`1.1.1.1`などでも大丈夫です。

さて、これで最低限の設定はできたのでunboundを立ち上げます。

```
# stemctl start unbound
```

EC2インスタンスのIPアドレスを、端末のネットワーク設定のDNSに入力して、通信が問題なくできていれば成功です。
この段階ではまだ広告ブロックは行っておらず、単純にDNSキャッシュサーバを構築したのみとなっています。

# 広告のドメインをブロックする

前項でDNSキャッシュサーバを構築できたので本項では広告をブロックする設定を行っていきます。

まず、ブロックする広告の一覧を入手する必要があります。
ここでは広告ブロックアプリとして有名な280blockerさんの公開している広告ドメインリストを利用します。

https://280blocker.net/download/

ファイルのダウンロードでは、「`ファイルのURLはそのままでは開けません。URL中の6桁のｘを現在の年・月の6桁の数字へ変更してください。令和3年11月なら202111です。`」となっているのでご注意ください。

ドメインテキスト形式のファイルの中身は以下のように広告ドメインのリストになっています。
```
abcde.com
fgh.ijk.net
lmn-opqrstu.com
vw.xyz.com
...
```

このドメインリストを使って広告をブロックする設定をunboundで行います。
unboundには、特定のドメインの名前解決を上書きする機能があります。
例えば、`example.com` というドメインを拒否したい場合、以下のように書くことができます

```
	local-zone: "example.com." static
```

この機能を使って、上述の広告ドメインリストをブロックします。
`ad_block.conf` というファイルを `/etc/unbound/local.d/` に配置し、そこに設定を書き込んでいきます。
`/etc/unbound/local.d` 内の `.conf` ファイルは自動で読み込まれるため、unboundに追加の設定は不要です。

`ad_block.conf` は上述の広告ドメインリストを使って以下のように書いていきます (ドメインの末尾に `.` を付けます)。

```
	local-zone: "abcde.com." static
	local-zone: "fgh.ijk.net." static
	local-zone: "lmn-opqrstu.com." static
	local-zone: "vw.xyz.com." static
	...
```

これで設定は全て完了しました。
unboundを再起動します。

```
# systemctl restart unbound
```

# 結果

unboundで構築した、広告をブロックするDNS経由で実際に通信した例が以下になります。

下記はPCのブラウザでWebページを開いた例です。

| 適用前 | 適用後 |
| ---- | ---- |
|　 ![325d5867b752-20220731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42150/edd0ecc2-ea63-bdb6-d1e6-0415a8af1e61.png) | ![6886eee8569a-20220731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42150/551e6030-9637-c71e-9d21-6212e973ba21.png) |

ブラウザの拡張機能のように広告欄がトルツメされることはないですが、広告自体は非表示になっています。

下記はスマホでゲームアプリを開いた例です。

| 適用前 | 適用後 |
| ---- | ---- |
| 　![df32dbfb0d1e-20220731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42150/db0657d3-4da7-1983-ef88-8c7f9bcf7c96.png) | ![f6f452d60ef2-20220731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42150/c0d46c26-901b-ed46-6cb2-dc0d295ef382.png) |

広告が全てブロックされていることが分かります。

この方法はドメイン経由で広告をブロックしているので、逆に言うとドメインをブロックできない場合は広告もブロックできません。
例えばYouTubeやTwitterの広告は、ドメインがサービス名のものと同じためブロックすることはできません。
あくまでもアドネットワークの広告をブロックするものと考えてください。

# まとめ

unboundを使って広告をブロックするDNSキャッシュサーバの構築について紹介しました。
非常に簡単な設定で構築できることが分かると思います。

本記事では広告のブロックでしたが、SNSをブロックする場合も同様の方法で構築することができます。

DNSを活用することで、特定のブラウザだけでなく通信自体から特定のドメインを拒否することができるので、活用の幅は広いのではないかと思います。