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.1DNSブロッキング
応用すればVPN接続時だけDNSブロッキングも可能です。
template IN ANY example.jp {
rcode NXDOMAIN
}templateプラグインのrcodeでレスポンスコードを指定できるので、NXDOMAINやNODATAを指定することで名前解決できなくなります。
カテゴリ: ネットワーク