Docker+WireGuardにDNSを構築する
公開日:
カテゴリ: ネットワーク
Dockerで構築したWireGuardに内部用のDNSを構築してみます。
今回作成する構成
- あくまで内部用の補助的なDNSとして位置付け
- VPNで接続しているときだけ使用する
- VPNを使用しない接続(同一LANに接続しているだけ)では使用しない
- このパターンで名前解決が必要な場合はDNSサーバを別途立てる
- 特定のサブドメインの名前解決を、特定のDockerネットワークに流す
LinuxServer.ioのWireGuardイメージ
LinuxServer.ioで構築されたWireGuardのDockerイメージ(以降、linuxserver/wireguard)ではCoreDNSが併用されており、デフォルトのDNSサーバとして動作しています。
デフォルトの設定では、そのままresolv.conf
を参照しに行きます。Dockerコンテナのresolv.conf
には127.0.0.11
がバインドされているため、そのままホストのDockerの内部DNSへと渡っていきます。
CoreDNSの設定
linuxserver/wireguard
を起動すると、設定ファイルの保存先にcorednsというディレクトリと、その中にCorefileというファイル(/config/coredns/Corefile
)が生成されます。WireGuardの設定でDNSサーバを変更していない場合、このCorefileを編集することでDNSの様々な制御が行えます。
/config
ディレクトリはボリュームとしてマウントしているはずですので、Corefileはホスト側から直接編集可能です。
. {
loop
errors
health
forward . /etc/resolv.conf
}
デフォルト設定は前述の通りresolv.conf
にフォワードするだけですが、CoreDNSではtemplate
プラグイン(標準機能)を使用することで、正規表現のパターンマッチングでDNSの応答を行うことができます。
. {
loop
errors
health
template IN ANY myhost.example.com {
match "^([^\.]+)\.myhost\.example\.com\.$"
answer "{{ index .Match 1 }}.myhost.example.com. IN CNAME {{ index .Match 1 }}."
fallthrough
}
forward . /etc/resolv.conf
}
上記の例ではmyhost.example.com
の第4レベルのサブドメインをそのままCNAMEとして応答します。例えばaaa.myhost.example.com
のDNS問い合わせがあった場合、aaa
と返されます。同一Dockerネットワーク内にaaa
という名前のコンテナもしくはホストでサーバが立っていればaaa.myhost.example.com
でアクセスできます。
もちろん、Dockerネットワーク名を指定することもできます。以下の例ではmynetwork
というDockerネットワークに向けた(mynetwork
をTLDとした)応答をします。
# aaa.myhost.example.com -> aaa.mynetwork
answer "{{ index .Match 1 }}.myhost.example.com. IN CNAME {{ index .Match 1 }}.mynetwork."
設定後、コンテナを立ち上げなおすと適用されます。VPNで接続しているときだけ使用するだけであれば、ここまでの手順で完了です。
おまけ
DNSサーバへのフォワード
Docker内部DNSを使用したくない場合は、パブリックDNSを指定してフォワードすることもできます。
#forward . /etc/resolv.conf
forward . 1.1.1.1
DNSブロッキング
応用すればVPN接続時だけDNSブロッキングも可能です。
template IN ANY example.jp {
rcode NXDOMAIN
}
templateプラグインのrcode
でレスポンスコードを指定できるので、NXDOMAIN
やNODATA
を指定することで名前解決できなくなります。
カテゴリ: ネットワーク