2026年10月4日

2026年10月4日

UnboundのインストールとキャッシュDNS設定|Linuxサーバーに名前解決キャッシュを置く手順

Unbound は、DNSSEC 検証に対応した軽量なキャッシュDNSサーバー(フルリゾルバー)です。この記事では、Linux サーバーに Unbound をインストールし、自分自身または社内ネットワーク向けのキャッシュDNSとして動かすまでを、設定の意味・つまずきやすい点・動作確認の方法とあわせて説明します。WordPress サーバーで外部 API や更新サーバーへの名前解決が遅い、上位の DNS が不安定で接続エラーが出る、といった場面の対策として使えます。

キャッシュDNSを置くと何が変わるか

PHP が wp_remote_get() などで外部に接続するとき、名前解決は OS のリゾルバーを通じて /etc/resolv.conf に書かれた DNS サーバーへ問い合わせます。PHP 自体は名前解決の結果を長く保持しないため、同じホスト名でも問い合わせが繰り返されます。サーバー内に Unbound を置くと、TTL の範囲で応答をキャッシュするので、2回目以降はローカルで即座に返せます。上位 DNS の一時的な遅延の影響も受けにくくなります。

一方で、キャッシュDNSを外部から使える状態で公開すると「オープンリゾルバー」となり、DNS アンプ攻撃の踏み台にされます。この記事では、問い合わせ元を自分自身と特定の社内ネットワークに限定する前提で進めます。

インストール

主要なディストリビューションでは、標準のリポジトリから入れられます。作業前に、現在の /etc/resolv.conf の内容を控えておくと、問題が起きたときに元へ戻しやすくなります。

# Debian / Ubuntu
sudo apt update
sudo apt install unbound

# RHEL / AlmaLinux / Rocky Linux
sudo dnf install unbound

# バージョンの確認
unbound -V

設定ファイルは /etc/unbound/unbound.conf です。Debian 系では、このファイルが /etc/unbound/unbound.conf.d/ 配下の *.conf を読み込む構成になっているため、独自設定はそのディレクトリに別ファイルで置くと、パッケージ更新時に競合しにくくなります。RHEL 系では本体ファイルに多くの設定が書かれているので、編集前にコピーを取っておきます。

ポート53の競合を確認する

Ubuntu などでは systemd-resolved が 127.0.0.53 で待ち受けています。Unbound を 0.0.0.0 で待ち受けさせると、環境によっては「address already in use」で起動に失敗します。

sudo ss -lunp 'sport = :53'

この記事のように、Unbound が待ち受けるアドレスを 127.0.0.1 や特定の社内向けアドレスに明示しておけば、多くの場合は共存できます。

基本設定

次は、サーバー自身と 192.168.10.0/24 からの問い合わせを受け付けるキャッシュDNSの例です。Debian 系なら /etc/unbound/unbound.conf.d/local-cache.conf として保存します。

server:
    # 待ち受けアドレス(使わないものは書かない)
    interface: 127.0.0.1
    interface: 192.168.10.53
    port: 53

    # 問い合わせを許可する範囲。それ以外は拒否する
    access-control: 127.0.0.0/8 allow
    access-control: 192.168.10.0/24 allow
    access-control: 0.0.0.0/0 refuse

    # IPv6 を使わない環境では無効にして、無駄な問い合わせを減らす
    do-ip6: no

    # キャッシュサイズ(rrset は msg の 2 倍程度が目安)
    msg-cache-size: 64m
    rrset-cache-size: 128m

    # TTL が切れる直前に人気のある名前を先回りして更新する
    prefetch: yes

    # バージョン情報などを外部に返さない
    hide-identity: yes
    hide-version: yes

設定の要点は次のとおりです。

  • interface と access-control:待ち受けアドレスと、問い合わせを許可する送信元は別の設定です。interface で社内向けアドレスを開いても、access-control で許可していなければ REFUSED が返ります。逆に、許可範囲を広げすぎるとオープンリゾルバーになるため、許可するのは必要なネットワークだけにします。
  • キャッシュサイズ:既定値は小さめなので、問い合わせが多い環境では増やします。ただしメモリを圧迫しない範囲にとどめ、unbound-control stats のキャッシュヒット率を見ながら調整します。
  • prefetch:キャッシュが切れる直前にアクセスされた名前を裏で更新するため、ヒット率が上がる代わりに上位への問い合わせが少し増えます。

cache-min-ttl で TTL を強制的に延ばす設定もありますが、相手側が DNS を切り替えたときに古い IP アドレスへ接続し続ける原因になります。WordPress サーバーの用途であれば、既定値のまま使うのが無難です。

フルリゾルバーとして動かすか、上位へ転送するか

上の設定だけなら、Unbound はルートサーバーから順にたどって自分で名前解決します(フルリゾルバー)。データセンターのポリシーなどで外部の DNS へ直接問い合わせられない場合は、forward-zone で上位の DNS に転送します。

forward-zone:
    name: "."
    forward-addr: 192.0.2.53      # 事業者やデータセンターが指定する DNS
    forward-addr: 192.0.2.54

転送先を DNS over TLS で使いたい場合は、forward-tls-upstream: yes と、forward-addr: 1.1.1.1@853#cloudflare-dns.com のような「アドレス@ポート#証明書のホスト名」形式を組み合わせ、server: 側で tls-cert-bundle に CA 証明書のパスを指定します。CA 証明書のパスはディストリビューションによって異なるので、環境に合わせて確認してください。

DNSSEC 検証

Unbound はトラストアンカー(ルートゾーンの鍵)を設定すると DNSSEC 検証を行います。Debian 系や RHEL 系のパッケージでは、auto-trust-anchor-file がすでに設定されていることが多いため、自分の設定ファイルで二重に書かないよう、先に grep -r trust-anchor /etc/unbound/ で確認します。

設定の確認と起動

設定ファイルを変更したら、再起動する前に構文を確認する習慣を付けてください。誤りがあるまま再起動すると、サーバー全体の名前解決が止まります。

sudo unbound-checkconf
sudo systemctl enable --now unbound
sudo systemctl restart unbound
sudo systemctl status unbound

unbound-checkconf が no errors と表示すれば構文は正しい状態です。起動に失敗する場合は、journalctl -u unbound でログを確認します。

動作確認

dig でローカルの Unbound に問い合わせます。

dig @127.0.0.1 example.com A

# 2回目はキャッシュから返るため、Query time が短くなる
dig @127.0.0.1 example.com A | grep "Query time"

1回目に数十ミリ秒かかった問い合わせが、2回目に 0〜1 ミリ秒程度になっていればキャッシュが効いています。応答の flags に ad が含まれていれば、DNSSEC の検証に成功した応答です(相手のゾーンが DNSSEC に対応している場合に限ります)。

社内の別のホストから dig @192.168.10.53 example.com を実行し、応答が返ることも確認します。あわせて、許可していないネットワークから問い合わせて REFUSED になることを確かめておくと、オープンリゾルバーになっていないことを確認できます。

サーバー自身の名前解決を Unbound に向ける

Unbound が動いても、OS が別の DNS を参照していればキャッシュは使われません。systemd-resolved を使っている環境では、/etc/resolv.conf を直接書き換えても上書きされることがあるため、systemd-resolved 側の設定で上位 DNS を 127.0.0.1 に向けます。

# /etc/systemd/resolved.conf
[Resolve]
DNS=127.0.0.1
sudo systemctl restart systemd-resolved
resolvectl status

Netplan や NetworkManager で DNS を配布している環境では、そちらの設定が優先されることもあります。切り替え後は getent hosts wordpress.org のように OS のリゾルバー経由で引けることを確認してから、WordPress の管理画面で更新確認やプラグイン検索が通常どおり動くかを見てください。

運用:統計とキャッシュの削除

unbound-control を使うと、稼働中の Unbound の統計確認やキャッシュ削除ができます。使う前に、remote-control: セクションで control-enable: yes を設定し、初回は sudo unbound-control-setup で通信用の鍵を作成します(パッケージによっては不要な場合もあります)。

# キャッシュヒット数とミス数
sudo unbound-control stats_noreset | grep -E 'total.num.(queries|cachehits|cachemiss)'

# 特定の名前のキャッシュを消す
sudo unbound-control flush example.com

# 特定ゾーン配下をまとめて消す
sudo unbound-control flush_zone example.com

相手側で DNS を切り替えたのに古い IP アドレスに接続されるときは、flush で該当の名前を消すと、Unbound を再起動せずに最新の応答を取り直せます。

まとめ

  • Unbound をサーバー内に置くと、TTL の範囲で名前解決をキャッシュでき、外部 API への接続の待ち時間を減らせます。主要ディストリビューションの標準リポジトリから導入できます(2026年10月現在)
  • interface で待ち受けアドレスを、access-control で問い合わせ元を限定し、オープンリゾルバーにしないことが最も重要です
  • 変更後は unbound-checkconf で構文を確認してから再起動し、dig の Query time と ad フラグで動作を確かめます
  • OS の参照先を Unbound に向けるときは、systemd-resolved や Netplan の設定を経由し、切り替え前の設定を控えておきます

お気軽にご相談ください

お見積りへ お問い合わせへ
▲