LoginSignup
3
4

広告ブロックができるDNS Over HTTPS(DoH) サーバーを構築する

Last updated at Posted at 2023-09-19

はじめに

本稿はDNS Over HTTPS(DoH) サーバーを構築したログを記載するものです。
Cloudflare, Tailscale, dns-over-https, Pi-holeで構成しています。

このDoHサーバーの主な目的はDNSリクエストをコントロールすることで、ブラウザに表示される不要な広告を除去(ブロック)することです。
マシン全体ではなく特定のブラウザのみに構築したDoHサーバーを設定できるため、システムや他アプリケーションの安定性を損なうことなくDNSを使用した広告の除去が可能です。

メインのソリューションとなるPi-holeはDNSアクセスをコントロールするためソフトウェアで、十分な機能を揃えたWeb 管理画面からステータスやログを確認したり設定の変更を行うことができます。
100.89.62.104_8080_admin_(Surface Pro 7)_2.png

ブラウザなどのソフトウェアに設定を行うことで、それらのDNSリクエストについてPi-holeを経由させ、Pi-holeはフィルタ条件に基づき不適切なリクエストを遮断します。この仕組みにより、DNS単位での広告のブロックが可能になります。
デフォルトで事前定義されたブロックリストが読み込まれるため、インストール直後からすぐに広告ブロックのために使うことができます。この手のソフトウェアの例に漏れず定義はやや強めの基準で作られていますが、ブロックの解除も管理画面から簡単に行うことができます。

image.png

注記

  • この用途で同様のスペックのものとしては例えばADGUARD DNSというマネージドのソリューションが存在しますが、月額$20程度とそれなりによいお値段がします。
  • サーバーにはグローバルIPを割り当てる必要があります。
  • HTTPS化のためにCloudflare DNS Proxyを使用しているため、Cloudflare上でドメインのAレコードとしてサブドメインを1つサーバーに割り当てる必要があります。
  • 検証/運用環境としてOracle Cloud Infrastructure(OCI) のUbuntu 22.04 LTSを使用しています。

想定運用コスト

  • ドメイン購入/維持費(サブドメインを1つ使えればよいので既にあれば実質無料)
  • Cloudflare - Free Plan(無料)
  • Tailscale - Free Plan(無料)
  • Oracle Cloud Infrastructure(OCI)
    • AMD Compute VM - Free Tier - Always Free(無料)
    • Outbound Data Transfer - First 10 TB / Month(無料)

構成図

graphviz.png

Pi-hole インストール

curl -sSL https://install.pi-hole.net | bash

インタラクティブなインストールを実施する。
必要があればパスワードをより長いものにする。

pihole -a -p new_passward

全てのインターフェイスからの通信を許可する。

pihole -a -i all

lighttpd 設定

sudo vi /etc/lighttpd/conf-enabled/15-pihole-admin.conf

次の行を追加しポートを8080に変更する。

server.port := 8080
sudo vi /etc/lighttpd/lighttpd.conf

デフォルトのポートが80となっていて、後述するdns-over-httpsでの設定とコンフリクトするため次の行のように適当なポートに変更する。

server.port = 8000

サービスを再起動する。

sudo systemctl restart lighttpd

ファイアウォール 設定

iptablesでDNS(UDP 53), HTTP(TCP 80, 8080)の通信を許可する。

-A INPUT -p udp --dport 53 -j ACCEPT
-A OUTPUT -p udp --sport 53 -j ACCEPT

-A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

-A INPUT -p tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp --sport 8080 -m state --state ESTABLISHED -j ACCEPT

注記: 53, 8080ポートはVMの外側のクラウドサービス側のファイアーウォールで遮断され、SSH以外ではTCP 80ポートのみがインターネットからアクセス可能となる想定です。

現在の設定の保存

sudo netfilter-persistent save

設定の編集

sudo vi /etc/iptables/rules.v4

変更の反映

sudo iptables -F
sudo netfilter-persistent reload

DNSサーバーと8080ポートの管理画面にローカルからアクセスできることを確認する。

Tailscale インストール

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

表示された次のようなURLから認証を行う。

https://login.tailscale.com/a/xxxxxxxxxx

設定後、Tailnet内の他端末から管理画面にアクセスできることを確認する。

dns-over-https インストール

sudo apt install make git golang
git clone https://github.com/m13253/dns-over-https.git
cd dns-over-https
make
sudo make install
sudo vi /etc/dns-over-https/doh-server.conf

次の2箇所の設定を変更し、セキュアではないHTTP 80ポートで問い合わせを受けるサーバーを立て、上流のDNSサーバーとしてローカルのPi-holeを使うようにする。

# HTTP listen port
listen = [
    ":80",

    ## To listen on both 0.0.0.0:8053 and [::]:8053, use the following line
    # ":8053",
]
upstream = [
    "udp:127.0.0.1:53",
]

サービスを開始する。

sudo systemctl start doh-server
sudo systemctl status doh-server

サービスが正常に動作することを確認したら常に動作するように有効化する。

sudo systemctl enable doh-server

クラウドサービス側 セキュリティ設定

必要があれば80ポートを開ける作業を実施する。

Cloudflare DNS Proxy設定

Aレコードとして適当なサブドメイン名と対象のサーバーのグローバルIPを指定する。
HTTPS化のため、DNS ProxyがProxiedになっていることを確認する。
image.png

DoH(DNS Over HTTPS)サーバー 動作確認

例えば次のようなURLへのGETで200 OKが返ることを確認する。

https://your-domain-name/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB

レスポンスのバイナリの例。
image.png

参考:
「4.1.1. HTTP Request Examples」
「4.2.2. HTTP Response Example」

ブラウザへのDoH(DNS Over HTTPS)サーバー 設定

参考:

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4