

DNSVizは、ドメインネームシステム(DNS)の挙動と、そのセキュリティ拡張機能(DNSSEC)を分析・可視化するためのツールスイートです。このツールスイートは、https://dnsviz.net/ で提供されているWebベースの分析を支えています。
DNSVizは、Debian、Ubuntu、Fedora、Gentoo、FreeBSDなどの主要なオペレーティングシステムのパッケージリポジトリで入手できます。また、Red Hat Enterprise Linux (RHEL) 8および9、CentOS 8および9向けのExtra Packages for Linux (EPEL) リポジトリでも提供されています。(RHELおよびCentOSへのインストールについては、注記を参照してください。)いずれの場合も、そのオペレーティングシステムで標準的なパッケージインストールコマンドを使用してインストールできます。DNSVizは、HomebrewまたはMacPortsを使用してMac OS Xにもインストールできます。
このセクションの残りでは、依存関係のリスト、仮想環境へのインストール、およびRHEL 8または9、CentOS Stream 8または9へのインストールに関する注記など、他のインストール方法について説明します。
Dockerコンテナでの実行手順については、このドキュメントの後半でも説明しています。
Python (2.7, 3.5 - 3.12) - https://www.python.org/ (Python 2.7のサポートは将来のリリースで削除される予定です。)
dnspython (1.13.0以降) - https://www.dnspython.org/
pygraphviz (1.3以降) - https://pygraphviz.github.io/
cryptography (36.0.0以降) - https://cryptography.io/
上記に記載されたソフトウェアの古いバージョンでもDNSVizで動作する可能性がありますが、サポート対象外です。例えば、cryptographyの2.6以前のバージョンでも動作するようです。また、DNSViz自体は依然としてPython 2.7で動作しますが、ソフトウェア依存関係の一部のバージョンはPython 2.7のサポートを終了していることにも注意してください:pygraphviz 1.6とdnspython 2.0.0はPython 2.7のサポートを終了しました。
OpenSSL GOST Engine - https://github.com/gost-engine/engine
OpenSSL 1.1.0以降では、アルゴリズム12(GOST R 34.10-2001)によるDNSSEC署名の検証や、タイプ3(GOST R 34.11-94)のダイジェストを作成するためにOpenSSL GOST Engineが必要です。GOSTサポートにはM2Cryptoも必要です。
M2Crypto - https://gitlab.com/m2crypto/m2crypto
DNSVizの暗号化サポートのほぼすべてはcryptography Pythonモジュールで処理されますが、アルゴリズム12(GOST R 34.10-2001)およびダイジェストタイプ3(GOST R 34.11-94)のサポートにはOpenSSL GOST Engineが必要です。このエンジンは動的にロードする必要があり、cryptographyにはそのサポートがありません。したがって、アルゴリズム12またはダイジェストタイプ3をサポートする必要がある場合は、M2Cryptoもインストールする必要があります。
ISC BIND - https://www.isc.org/bind/
コマンドラインでゾーンファイルや代替委任情報を指定して(すなわち、-N、-x、または-Dを使用して)、デプロイ前テストにDNSVizを使用する場合、1つ以上のゾーンを提供するためにnamed(8)が呼び出されます。ISC BINDが必要なのはこの場合のみであり、named(8)は(サーバーとして)実行されている必要はありません。
DebianのデフォルトのAppArmorポリシーは、デプロイ前テストのためにDNSVizからnamed(8)を呼び出す際に問題を引き起こすことが知られています。AppArmorは次のコマンドでnamed(8)に対して一時的に無効にできます:
$ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.named
デプロイ前テストが完了したら、次のコマンドでnamed(8)のAppArmorを再び有効にできます:
DNSVizを仮想環境にインストールするには、最初に仮想環境を作成して有効化し、依存関係をインストールします:
$ virtualenv ~/myenv
$ source ~/myenv/bin/activate
(myenv) $ pip install -r requirements.txt
これによりPythonパッケージである依存関係がインストールされますが、これらのパッケージの一部には自動的にインストールされない非Python依存関係(pygraphvizに必要なGraphvizや、cryptographyに必要なOpenSSLなど)があることに注意してください。
次に、Python Package Index (PyPI)からDNSVizをダウンロードしてインストールします:
(myenv) $ pip install dnsviz
または、ダウンロードまたはクローンしたDNSVizのコピーからローカルにインストールします:
(myenv) $ pip install .
DNSVizは、EPELリポジトリからRHEL 8または9、CentOS Stream 8または9にインストールできます。このセクションの手順に従ってEPELを有効にしてください。
RHEL 8および9のみ:次のコマンドでCodeReady Linux BuilderとExtra Packages for Enterprise Linux (EPEL)を有効にします:
$ sudo subscription-manager repos --enable codeready-builder-for-rhel-$(vers)-$(arch)-rpms
$ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(vers).noarch.rpm
($(vers)はバージョン(8または9)を指し、$(arch)はアーキテクチャ(例:x86_64またはaarch64)を指します。不明な場合は、sudo subscription-manager repos --listを実行して利用可能なオプションを確認してください。)
CentOS Stream 8または9のみ:次のコマンドでPowerToolsまたはCodeReady Linux BuilderとEPELを有効にします:
$ sudo dnf config-manager --set-enabled $(tool)
$ sudo dnf install epel-release
($(tool)はツールを指し、CentOS Stream 8の場合はpowertools、CentOS Stream 9の場合はcrbです。)
RHEL 8または9 および CentOS Stream 8または9の両方で、EPELが有効になったら、dnfを使用してDNSVizをインストールします:
$ sudo dnf install dnsviz
DNSVizは、dnsvizコマンドラインユーティリティを使用して呼び出します。dnsviz自体には、probe、grok、graph、print、queryという複数のサブコマンドがあります。より詳細なドキュメントと使用方法については、各サブコマンドに関連するマニュアルページ("dnsviz-<サブコマンド> (1)"の形式、例:"man dnsviz-probe")を参照してください。
dnsviz probeは、1つ以上のドメイン名を入力として受け取り、再帰的(デフォルト)または権威DNSサーバーのいずれかに一連のクエリを実行し、その結果はJSON形式にシリアライズされます。
設定済みのDNSリゾルバ(つまり、/etc/resolv.conf内)を使用してドメイン名example.comを分析し、クエリと応答を"example.com.json"というファイルに保存します:
$ dnsviz probe example.com > example.com.json
同じ操作:
$ dnsviz probe -o example.com.json example.com
権威サーバーに直接クエリを実行してドメイン名example.comを分析します:
$ dnsviz probe -A -o example.com.json example.com
IANAルートサーバーからのリファラルを通じてサーバーを学習するのではなく、明示的に定義された権威サーバーにクエリを実行してドメイン名example.comを分析します:
$ dnsviz probe -A \
-x example.com:a.iana-servers.org=199.43.132.53,a.iana-servers.org=[2001:500:8c::53] \
-x example.com:b.iana-servers.org=199.43.133.53,b.iana-servers.org=[2001:500:8d::53] \
-o example.com.json example.com
同じですが、dnsviz probeに名前を解決させます:
$ dnsviz probe -A \
-x example.com:a.iana-servers.org,b.iana-servers.org \
-o example.com.json example.com
ルートから開始して、権威サーバーにクエリを実行し委任を辿ることにより、ドメイン名example.comとそのすべての祖先を分析します:
$ dnsviz probe -A -a . -o example.com.json example.com
明示的な再帰リゾルバを使用して複数の名前を並列に(4スレッドで)分析します(192.0.1.2と2001:db8::1を正当なリゾルバアドレスに置き換えてください):
$ dnsviz probe -s 192.0.2.1,[2001:db8::1] -t 4 -o multiple.json \
example.com sandia.gov verisignlabs.com dnsviz.net
dnsviz grokは、JSON形式のシリアライズされたクエリ結果(つまり、dnsviz probeの出力)を入力として受け取り、入力内の対応するコンテンツに基づいて指定されたドメイン名を評価します。出力もJSON形式にシリアライズされます。
dnsviz probeによって生成されたクエリ/応答出力を処理し、シリアライズされた結果を"example.com-chk.json"というファイルに保存します:
$ dnsviz grok < example.com.json > example.com-chk.json
同じ操作:
$ dnsviz grok -r example.com.json -o example.com-chk.json example.com
情報レベルの情報のみを表示します:説明、ステータス、警告、エラー:
$ dnsviz grok -l info -r example.com.json -o example.com-chk.json
関連する警告またはエラーがある場合にのみ説明を表示します:
$ dnsviz grok -l warning -r example.com.json -o example.com-chk.json
関連するエラーがある場合にのみ説明を表示します:
$ dnsviz grok -l error -r example.com.json -o example.com-chk.json
ルートキーをDNSSECトラストアンカーとして使用し、応答の認証ステータスも示します:
$ dig +noall +answer . dnskey | awk '$5 % 2 { print $0 }' > tk.txt
$ dnsviz grok -l info -t tk.txt -r example.com.json -o example.com-chk.json
dnsviz probeの出力を直接dnsviz grokにパイプします:
$ dnsviz probe example.com | \
dnsviz grok -l info -o example.com-chk.json
同じ操作ですが、途中で生の出力を(再利用のために)保存します:
$ dnsviz probe example.com | tee example.com.json | \
dnsviz grok -l info -o example.com-chk.json
一度に複数の名前をエラーレベルで評価します:
$ dnsviz grok -l error -r multiple.json -o example.com-chk.json
dnsviz graphは、JSON形式のシリアライズされたクエリ結果(つまり、dnsviz probeの出力)を入力として受け取り、入力内の対応するコンテンツに基づいて指定されたドメイン名を評価します。出力は、渡されたオプションに応じて、画像ファイル、dot(有向グラフ)ファイル、またはHTMLファイルになります。
dnsviz probeによって生成されたクエリ/応答出力を処理し、結果を視覚的に表すグラフを"example.com.png"というpngファイルに生成します。
$ dnsviz graph -Tpng < example.com.json > example.com.png
同じ操作:
$ dnsviz graph -Tpng -o example.com.png example.com < example.com.json
同じ操作ですが、対話型HTML形式を生成します:"example.com.html"というファイルに対話型HTML出力:
$ dnsviz graph -Thtml < example.com.json > example.com.html
同じ操作(ファイル名はドメイン名と出力形式から生成されます):
$ dnsviz graph -Thtml -O -r example.com.json
代替のDNSSECトラストアンカーを使用します:
$ dig +noall +answer example.com dnskey | awk '$5 % 2 { print $0 }' > tk.txt
$ dnsviz graph -Thtml -O -r example.com.json -t tk.txt
dnsviz probeの出力を直接dnsviz graphにパイプします:
$ dnsviz probe example.com | \
dnsviz graph -Thtml -O
同じ操作ですが、途中で生の出力を(再利用のために)保存します:
$ dnsviz probe example.com | tee example.com.json | \
dnsviz graph -Thtml -O
複数のドメイン名の分析を処理し、処理した各名前の画像を作成します:
$ dnsviz graph -Thtml -O -r multiple.json
複数のドメイン名の分析を処理し、すべての名前に対して単一の画像を作成します。
$ dnsviz graph -Thtml -r multiple.json > multiple.html
dnsviz printは、JSON形式のシリアライズされたクエリ結果(つまり、dnsviz probeの出力)を入力として受け取り、入力内の対応するコンテンツに基づいて指定されたドメイン名を評価します。出力は、ファイルまたはターミナル表示に適したテキスト出力です。
dnsviz probeによって生成されたクエリ/応答出力を処理し、結果をターミナルに出力します:
$ dnsviz print < example.com.json
代替のDNSSECトラストアンカーを使用します:
$ dig +noall +answer example.com dnskey | awk '$5 % 2 { print $0 }' > tk.txt
$ dnsviz print -r example.com.json -t tk.txt
dnsviz probeの出力を直接dnsviz printにパイプします:
$ dnsviz probe example.com | \
dnsviz print
同じ操作ですが、途中で生の出力を(再利用のために)保存します:
$ dnsviz probe example.com | tee example.com.json | \
dnsviz print
dnsviz queryは、dnsviz probeとdnsviz printの機能を組み合わせて、digに似た最小限の使用方法を持つツールにしたラッパーで、分析クエリを実行し、テキスト出力をターミナルまたはファイルに一度に出力するために使用されます。
設定済みのDNSリゾルバ(つまり、/etc/resolv.conf内)の最初のものを使用してドメイン名example.comを分析します:
$ dnsviz query example.com
同じですが、代替トラストアンカーを指定します:
$ dnsviz query +trusted-key=tk.txt example.com
192.0.2.1の再帰リゾルバを介してexample.comを分析します:
$ dnsviz query @192.0.2.1 +trusted-key=tk.txt example.com
このセクションの例では、デプロイ前テストにおけるDNSVizの使用方法を示します。
以下の例では、ゾーンが委任される前に、そのゾーンに対して診断クエリを発行します。
ローカルシステム上のゾーンファイル(example.com.zone)に対してクエリを発行します。named(8)がファイルをローカルで提供するために呼び出されます:
$ dnsviz probe -A -x example.com+:example.com.zone example.com
("+"の使用に注意してください。"+"は、親サーバーにDSレコードをクエリしないことを指定します。)
ゾーンを提供しているサーバーにクエリを発行します:
$ dnsviz probe -A -x example.com+:192.0.2.1 example.com
(このサーバーはexample.comのNS RRset内のサーバーである必要はありません。)
名前および/またはアドレスで指定された権威NS RRset内のサーバーにクエリを発行します:
$ dnsviz probe -A \
-x example.com+:ns1.example.com=192.0.2.1 \
-x example.com+:ns2.example.com=192.0.2.1,ns2.example.com=[2001:db8::1] \
example.com
将来の委任NSレコードと(該当する場合)親ゾーン(com)内のA/AAAAグルーレコードに対応する名前とアドレスを指定します:
$ dnsviz probe -A \
-N example.com:ns1.example.com=192.0.2.1 \
-N example.com:ns2.example.com=192.0.2.1,ns2.example.com=[2001:db8::1] \
example.com
将来のDSレコードも提供します:
$ dnsviz probe -A \
-N example.com:ns1.example.com=192.0.2.1 \
-N example.com:ns2.example.com=192.0.2.1,ns2.example.com=[2001:db8::1] \
-D example.com:dsset-example.com. \
example.com
以下の例では、変更がデプロイされる前に、委任されたゾーンに対して診断クエリを発行します。
作成されたがまだデプロイされていない新しいゾーンファイル(つまり、DNSKEYまたは他のレコードに変更があるもの)に対して診断クエリを発行します:
$ dnsviz probe -A -x example.com:example.com.zone example.com
("+"がないことに注意してください。"+"がない場合、親サーバーにDSレコードがクエリされます。)
ゾーンの新しいバージョンを提供しているサーバーにクエリを発行します:
$ dnsviz probe -A -x example.com:192.0.2.1 example.com
(このサーバーはexample.comのNS RRset内のサーバーである必要はありません。)
以下の例では、そのゾーンの委任、グルー、またはDSレコードに変更がデプロイされる前に、委任されたゾーンに対して診断クエリを発行します。
新しい委任NSレコードと(該当する場合)親ゾーン(com)内のA/AAAAグルーレコードに対応する名前とアドレスを指定します:
$ dnsviz probe -A \
-N example.com:ns1.example.com=192.0.2.1 \
-N example.com:ns2.example.com=192.0.2.1,ns2.example.com=[2001:db8::1] \
example.com
置き換え用のDSレコードも提供します:
$ dnsviz probe -A \
-N example.com:ns1.example.com=192.0.2.1 \
-N example.com:ns2.example.com=192.0.2.1,ns2.example.com=[2001:db8::1] \
-D example.com:dsset-example.com. \
example.com
すぐに使用できるDockerコンテナが提供されています。
docker pull dnsviz/dnsviz
このセクションではDocker関連の例のみを説明します。詳細については使用方法セクションを参照してください。
$ docker run dnsviz/dnsviz help
$ docker run dnsviz/dnsviz query example.com
特に複数のコマンドを組み合わせる場合やゾーンファイルを操作する場合、ローカルの作業ディレクトリをコンテナにマウントすると便利な場合があります。
$ docker run -v "$PWD:/data:rw" dnsviz/dnsviz probe dnsviz.net > probe.json
$ docker run -v "$PWD:/data:rw" dnsviz/dnsviz graph -r probe.json -T png -O
権威クエリを実行する場合は、ホストネットワークを使用することをお勧めします。
$ docker run --network host dnsviz/dnsviz probe -4 -A example.com > example.json
それ以外の場合は、次のエラーが発生する可能性があります:
dnsviz.query.SourceAddressBindError: Unable to bind to local address (EADDRNOTAVAIL)
複数のDNSVizコマンドを組み合わせたり、bashリダイレクションなどを使用したりする複雑な分析を実行する場合は、コンテナを対話的に実行すると便利な場合があります:
$ docker run --network host -v "$PWD:/data:rw" --entrypoint /bin/sh -ti dnsviz/dnsviz
/data # dnsviz --help
$ sudo apparmor_parser /etc/apparmor.d/usr.sbin.named