Raspberry Pi 3 B+ で家庭内 DNS サーバーを構築する
タイトルはちょっと盛りすぎた。本当は家庭内 LAN 用の透過プロキシを組むつもりだったんだ。でも最近時間がなくて、暇を見つけてちょこちょこ弄った結果、最終的に DNS をひとつ立てただけに終わった。透過プロキシゲートウェイのコンパイルとインストールはまた今度にする。
とはいえ、DNS サーバーをひとつ動かすだけでも収穫はそれなりにあった。特に Raspberry Pi の安定性まわりでな。せっかくなので記録しておく。誰かの役に立てばいい。

今、メルカリで Raspberry Pi 3 B+ の値段がどんどん下がってる。最初は Pine 64 を買うつもりだったんだが、向こうのほうが明らかに価格で優位に立っていて、ドキュメントのサポートも充実している。結局こっちにした。
しかも、これを売ってる店の多くは充電器とケース、それに放熱用の銅板までセットにしてくれる。使うかどうかは微妙だが、ないよりマシだろ。

Raspberry Pi 3 B+ の場合、デフォルトの OS は Raspbian だ。Debian ベースの魔改造 Linux で、大体 Debian のやり方に沿って設定すればいい。公式イメージをダウンロードして、TF カードに書き込んで、挿して起動すれば、そこからミニサーバーの旅が始まる。
このラズパイで動かしている DNS サービスは Overture だ。中国人が開発した DNS 分流サービスで、仕組みは単純。一部のホワイトリストに基づいて DNS 解決を振り分ける。国内向けは 114 や DNSPod に、国外向けは Google や OpenDNS とかに流す。DNS 汚染を避けるために、国外の DNS 解決は特定のポートを使うこともできる。
Overture の設定ファイルはシンプルで分かりやすい。デフォルトの記述がかなり丁寧で、国内 IP と国外 IP の分流まで書いてある。
{
"BindAddress": ":53",
"PrimaryDNS": [
{
"Name": "DNSPod",
"Address": "119.29.29.29:53",
"Protocol": "udp",
"SOCKS5Address": "",
"Timeout": 6,
"EDNSClientSubnet": {
"Policy": "disable",
"ExternalIP": ""
}
},
{
"Name": "114DNS",
"Address": "114.114.114.114:53",
"Protocol": "udp",
"SOCKS5Address": "",
"Timeout": 5,
"EDNSClientSubnet": {
"Policy": "disable",
"ExternalIP": ""
}
}
],
"AlternativeDNS": [
{
"Name": "openDNS",
"Address": "208.67.222.222:443",
"Protocol": "tcp",
"SOCKS5Address": "",
"Timeout": 5,
"EDNSClientSubnet":{
"Policy": "disable",
"ExternalIP": ""
}
},
{
"Name": "openDNS2",
"Address": "208.67.222.222:5353",
"Protocol": "tcp",
"SOCKS5Address": "",
"Timeout": 5,
"EDNSClientSubnet": {
"Policy": "disable",
"ExternalIP": ""
}
}
],
"OnlyPrimaryDNS": false,
"IPv6UseAlternativeDNS": false,
"IPNetworkFile": {
"Primary": "/opt/overture/china_ip_list.txt",
"Alternative": "/opt/overture/ip_network_alternative"
},
"DomainFile": {
"Primary": "/opt/overture/domain_primary",
"Alternative": "/opt/overture/gfwlist.txt"
},
"DomainBase64Decode": true,
"HostsFile": "/opt/overture/hosts",
"MinimumTTL": 0,
"CacheSize" : 4096,
"RejectQtype": [255]
}
だが、これだけでは済まない。中の china_ip_list.txt なんかは自分で探してくる必要がある。ネット上に転がってるから、ここではもう提供しない。
特筆すべきは、国外の DNS クエリについて Overture が Socks5 プロキシ経由に対応していることだ。安定性をより確保できる。つまり、上で科学上网を走らせて、その経路で問い合わせることもできる。
Overture は公式に Systemd service を用意している。書かれたファイルをコピーして、Enable するだけでいい。

ここまでで DNS サービスは設定完了だ。必ず動作ログを見て、指定した txt ファイルや分流リストが正常に読み込まれているか確認しろ。でないと悲劇になるぞ。
次はちょっと厄介な問題だ。普通、こういうサービスは 7x24 で動かすべきだが、Raspberry Pi くらいの規模のマシンには限界がある。
- LAN ポート自体が USB の帯域から来ているので、性能に限りがある。
- 小さな開発ボードとして、安定性はまだ未知数だ。
一点目は性能問題で、どうしようもない。ただ家庭内の使用環境なら問題ないと思う。しかも Overture はキャッシュに対応していて、クエリの負荷をかなり緩和できる。将来透過ゲートウェイプロキシを足しても、ネットワークトラフィックはそう悲惨にはならないはずだ。何しろ分流するだけだからな。
二点目も自覚していた。使い始めて三日目、こいつはフリーズした。
その後、なぜか解決策が見つかった……Swap パーティションを追加するのだ。
Raspberry Pi 3 B+ という小さな開発ボードにとって、とても大事なことがある。
このクソ野郎は動いている間ほとんど Swap を使わないが、Swap がないと死ぬ
次に Raspbian OS で Swap を有効にする正しい方法を話す。ネット上には他のやり方がたくさん転がっているが、どれもシステムの設計仕様に沿っていない。
sudo vim /etc/dphys-swapfile
CONF_SWAPSIZE の値をアンコメントして、必要な Swap サイズに変更する。普通は 2G で十分だ。
その後システムを再起動する。再起動を勧める。サービスだけの再起動は勧めない。
さらに crontab -e を組み合わせて、毎日午前 4 時に自動再起動するスケジュールタスクを追加すれば、ほぼ正常な運用が保証できる。

会社で設定した Raspberry Pi 3 B+ はもう 3 ヶ月近くノートラブルで動いている。
家で設定したほうは半月使って、サービスは絶好調。長く続いてほしいものだ。
そういえば、Raspberry Pi 3 B+ の必要電源は 5V 3A だ。普通、売ってくれる店が楽視の充電器を付けてくれるが、実際にはこの基準に達していなくても動く。ただし、あまり多くの外付け機器を載せないことだ。
何しろ 5V 3A はフルパワーの Raspberry Pi 3 B+ を前提にした数字だからな。
コメントは中国語の本家サイトで受け付けています。このミラーは閲覧専用です。