bertvv.bind
Ansible ロール BIND
ISC BINDを複数のドメイン用の権威DNSサーバーとして設定するためのAnsibleロールです。このロールの主な役割は以下の通りです。
- BINDのインストール
- メインの設定ファイルの設定(プライマリ/セカンダリ/フォワーダーサーバー)
- フォワードおよびリバースルックアップゾーンファイルの設定
このロールは、IPv6を含む複数のフォワードとリバースゾーンをサポートしています。再帰を有効にすることもできますが(強く推奨はしません)、キャッシングまたはフォワーディングの名前サーバーを設定したい場合は、別のロールを使用することを検討してください。
このロールが気に入ったら、スターや役立つ評価をAnsible Galaxyページでお願いします。ありがとうございます!
バージョン間の重要な変更については変更ログをご覧ください。
警告: v5.0.0 より前からこのロールを使用している場合、壊れている変更に関する重要な情報のために変更ログを確認してください。v5.0.0にアップグレードすると、古いプレイブックは動作しなくなります。
対応プラットフォーム
このロールは複数のプラットフォームで使用できます。最新のリストはmeta/main.ymlをご覧ください。すべてのサポートされているプラットフォームに対して自動テストを設定することを目指していますが(ci.ymlを参照)、常に可能とは限りません。
自動テストに含まれていないサポートされているロールに関するいくつかの注意点
- Arch Linux および FreeBSDは動作するはずですが、現在のところ、適切なDockerイメージが利用できないため、これらのディストリビューションでロールをテストすることはできません。
- CentOS 6は動作するはずですが、BINDが正常にインストールされ、受け入れテストが成功しても無効性テストが失敗します。
要件
python-netaddr
(ipaddr
フィルターに必要)とdnspython
は、管理ノードにインストールする必要があります。
ロール変数
変数 | デフォルト | コメント(型) |
---|---|---|
bind_acls |
[] |
ACL定義のリスト。これはname: とmatch_list: というキーを持つマッピングです。以下に例を示します。 |
bind_allow_query |
['localhost'] |
このDNSサーバーにクエリできるホストのリスト。すべてのホストを許可するには['any'] に設定します。 |
bind_allow_recursion |
['any'] |
bind_allow_query と同様の経路をたどります。このオプションは再帰クエリに適用されます。 |
bind_check_names |
[] |
RFC 952およびRFC 1123に準拠してホスト名をチェックし、定義されたアクション(例:warn 、ignore 、fail )を実行します。 |
bind_dns_keys |
[] |
バインディングキーのリスト。これはname: 、algorithm: 、およびsecret: というキーを持つマッピングです。以下に例を示します。 |
bind_dns64 |
false |
true の場合、DNS64のサポートが有効になります。 |
bind_dns64_clients |
['any'] |
DNS64機能が適用されるクライアントのリスト(任意のACLを使用できます) |
bind_dnssec_enable |
true |
true の場合、DNSSECが有効になります。 |
bind_dnssec_validation |
true |
true の場合、DNSSECバリデーションが有効になります。 |
bind_extra_include_files |
[] |
メイン設定ファイルから含めるカスタム設定ファイルのリスト |
bind_forward_only |
false |
true に設定すると、BINDはキャッシング名前サーバーとして設定されます。 |
bind_forwarders |
[] |
DNSリクエストをフォワードする名前サーバーのリスト。 |
bind_listen_ipv4 |
['127.0.0.1'] |
リッスンするネットワークインターフェースのIPv4アドレスのリスト。すべてのインターフェースでリッスンするには['any'] に設定します。 |
bind_listen_ipv4_port |
[53] |
IPv4アドレス用にリッスンするポート番号のリスト。 |
bind_listen_ipv6 |
['::1'] |
リッスンするネットワークインターフェースのIPv6アドレスのリスト。 |
bind_listen_ipv6_port |
[53] |
IPv6アドレス用にリッスンするポート番号のリスト。 |
bind_log |
data/named.run |
ログファイルへのパス。 |
bind_other_logs |
- | 各ゾーンの関連詳細を含むロギングチャネルのリスト。 |
bind_query_log |
- | キーfile: (例:data/query.log )、versions: 、size: を持つマッピング。定義すると、クエリログが有効になります。 |
bind_recursion |
false |
DNSサーバーが権威を持たないリクエストが転送されるかどうかを決定します。 |
bind_rrset_order |
random |
DNSラウンドロビンの順序を定義します(random またはcyclic のいずれか)。 |
bind_statistics_channels |
false |
true の場合、BINDはstatistics-channels 句で設定されます(現在は単一のインターフェースでのリッスンのみをサポートしています)。 |
bind_statistics_allow |
['127.0.0.1'] |
統計にアクセスできるホストのリスト。 |
bind_statistics_host |
127.0.0.1 |
統計サービスがリッスンすべきネットワークインターフェースのIPアドレス。 |
bind_statistics_port |
8053 | 統計サービスがリッスンすべきネットワークポート。 |
bind_zone_dir |
- | 定義されている場合、サーバーディレクトリ(ゾーンファイルなど)へのカスタム絶対パスを設定します。 |
bind_key_mapping |
[] | Primary: Keyname - 特定のプライマリ用に使用するTSIGキーのマッピング。 |
bind_zones |
n/a | ゾーン定義のマッピングのリスト。以下のテーブルの下にある例を参照してください。 |
- allow_update |
['none'] |
このDNSゾーンを動的に更新できるホストのリスト。 |
- also_notify |
- | プライマリゾーンファイルが再読み込みされると通知を受け取るサーバーのリスト。 |
- create_forward_zones |
- | 初期化されfalse に設定されると、フォワードゾーンの作成がスキップされます(結果としてリバース専用ゾーンになります)。 |
- create_reverse_zones |
- | 初期化されfalse に設定されると、リバースゾーンの作成がスキップされます(結果としてフォワード専用ゾーンになります)。 |
- delegate |
[] |
ゾーンデリゲーション。 |
- forwarders |
- | フォワードタイプゾーンのためのフォワーダーのリスト。 |
- hostmaster_email |
hostmaster |
ゾーンのシステム管理者のメールアドレス。 |
- hosts |
[] |
ホスト定義。 |
- ipv6_networks |
[] |
ドメインの一部であるIPv6ネットワークのリスト(CIDR表記、例: 2001:db8::/48)。 |
- mail_servers |
[] |
このドメインのメールサーバーを指定するマッピングのリスト(name: とpreference: のキーを持つ)。 |
- name_servers |
[ansible_hostname] |
このドメインのDNSサーバーのリスト。 |
- name |
example.com |
ドメイン名。 |
- naptr |
[] |
NAPTRレコードを指定するマッピングのリスト。name: 、order: 、pref: 、flags: 、service: 、regex: 、およびreplacement: のキーを持つ。 |
- networks |
['10.0.2'] |
ドメインの一部であるネットワークのリスト。 |
- other_name_servers |
[] |
このドメインの外のDNSサーバーのリスト。 |
- primaries |
- | このゾーンのプライマリDNSサーバーのリスト。 |
- services |
[] |
SRVレコードで宣伝されるサービスのリスト。 |
- text |
[] |
TXTレコードを指定するマッピングのリスト。text: はリストまたは文字列にできます。 |
- caa |
[] |
CAAレコードを指定するマッピングのリスト。text: はリストまたは文字列にできます。 |
- type |
- | オプションのゾーンタイプ。指定されていない場合、自動検出が使用されます。可能な値にはprimary 、secondary またはforward があります。 |
bind_zone_file_mode |
0640 | メイン設定ファイル(named.conf)のファイル権限。 |
bind_zone_minimum_ttl |
1D |
SOAレコードの最小TTLフィールド。 |
bind_zone_time_to_expire |
1W |
SOAレコードの有効期限フィールド。 |
bind_zone_time_to_refresh |
1D |
SOAレコードのリフレッシュ時間フィールド。 |
bind_zone_time_to_retry |
1H |
SOAレコードの再試行時間フィールド。 |
bind_zone_ttl |
1W |
SOAレコードのTTLフィールド。 |
bind_python_version |
- | ansibleに使用されるPythonのバージョン。ディストリビューションに依存し、2 または3 のいずれかになります。OS標準でデフォルト値となる。 |
† 権威のある名前サーバーのベストプラクティスは、再帰をオフにしておくことです。しかし、特定のケースにおいて一部のケースでは、再帰をオンにする必要がある場合があります。
動作するゾーンの最小変数
クライアントに利用可能な権威名前サーバーを設定するためには、少なくとも以下の変数を定義してください:
変数 | プライマリ | セカンダリ | フォワード |
---|---|---|---|
bind_allow_query |
V | V | V |
bind_listen_ipv4 |
V | V | V |
bind_zones |
V | V | V |
- hosts |
V | -- | -- |
- name_servers |
V | -- | -- |
- name |
V | V | -- |
- networks |
V | V | V |
- primaries |
V | V | -- |
- forwarders |
-- | -- | V |
ドメイン定義
bind_zones:
# プライマリゾーンの例(hosts:およびname_servers:が定義されている)
- name: mydomain.com # ドメイン名
create_reverse_zones: false # リバースゾーンの作成をスキップ
primaries:
- 192.0.2.1 # このゾーンのプライマリサーバー
name_servers:
- pub01.mydomain.com.
- pub02.mydomain.com.
hosts:
- name: pub01
ip: 192.0.2.1
ipv6: 2001:db8::1
aliases:
- ns1
- name: pub02
ip: 192.0.2.2
ipv6: 2001:db8::2
aliases:
- ns2
- name: '@' # "http://mydomain.com/"を有効にする
ip:
- 192.0.2.3 # 複数のIPアドレスで単一のホスト
- 192.0.2.4 # DNSラウンドロビン
sshfp: # セキュアシェルフィンガープリント
- "3 1 1262006f9a45bb36b1aa14f45f354b694b77d7c3"
- "3 2 e5921564252fe10d2dbafeb243733ed8b1d165b8fa6d5a0e29198e5793f0623b"
ipv6:
- 2001:db8::2
- 2001:db8::3
aliases:
- www
- name: priv01 # このIPは別のサブネットにあり、それにより
ip: 10.0.0.1 # 複数のリバースゾーンが生成されます。
- name: mydomain.net.
aliases:
- name: sub01
type: DNAME # DNAMEエイリアスレコードの例
networks:
- '192.0.2'
- '10'
- '172.16'
delegate:
- zone: foo
dns: 192.0.2.1
services:
- name: _ldap._tcp
weight: 100
port: 88
target: dc001
naptr: # 名前権限ポインタレコード、IP
- name: "sip" # テレフォニー用
order: 100
pref: 10
flags: "S"
service: "SIP+D2T"
regex: "!^.*$!sip:[email protected]!"
replacement: "_sip._tcp.example.com."
# セカンダリゾーンの最小例
- name: acme.com
primaries:
- 172.17.0.2
networks:
- "172.17"
# フォワードゾーンの最小例
- name: acme.com
forwarders:
- 172.17.0.2
networks:
- "172.17"
ホスト
このDNSサーバーが解決すべきホスト名は、bind_zones.hosts
にname:
、ip:
、aliases:
、およびsshfp:
のキーを持つマッピングのリストとして指定できます。エイリアスはCNAME(デフォルト)またはDNAMEレコードにすることができます。
http://example.com/
にアクセスを許可するには、Webサーバーのホスト名を'@'
に設定します(引用符で囲む必要があります!)。BINDの構文では、@
はドメイン名自体を示します。
ホストに対して複数のIPアドレスを指定したい場合は、同じ名前のbind_zones.hosts
にエントリを追加します(例: コードスニペット内のpriv01
)。これにより、そのホストのために複数のA/AAAAレコードが生成され、DNSラウンドロビン(簡単な負荷分散技術)が可能となります。返されるIPアドレスの順序は、ロール変数bind_rrset_order
で設定できます。
ネットワーク
ご覧の通り、すべてのホストが同じサブネットにあるわけではありません。このロールは各サブネットに対して適切なリバースルックアップゾーンを生成します。ただし、すべてのサブネットはbind_zones.networks
で指定する必要があります。そうしないと、ホストに対してPTRレコードが取得できません。
ここではネットワーク部分だけを指定する必要があります!クラスB IPアドレス(例:"172.16")を変数ファイルで指定する際は、必ず引用符で囲まなければなりません。さもなくば、Yamlパーサーはこれを浮動小数点数として解釈してしまいます。
このアイデアや詳しい例については、https://linuxmonk.ch/wordpress/index.php/2016/managing-dns-zones-with-ansible/に詳しい情報があります。ゾーンファイルは完全に冪等性があり、"実際の"コンテンツが変更された場合のみ更新されます。
ゾーンタイプとゾーンタイプの自動検出
ゾーンtype
はオプションのゾーンパラメーターで、ゾーンタイプがprimary
、secondary
、またはforward
タイプであるかどうかを定義します。type
パラメータが省略されると、プライマリまたはセカンダリゾーンを構成する際にホストIPアドレスとprimaries
レコードの交差に基づいてゾーンタイプが自動検出されます。primaries
が定義されていない場合、forwarders
が定義されていると、ゾーンタイプはforward
に設定されます。
ゾーンの自動検出機能は、マルチサイトDNSインフラストラクチャを展開する際特に便利です。すべてのDNSサーバーに対して単一のグループインベントリファイルに「共有」されたbind_zones
定義を持つことが便利です(例:group_vars\dns.yml
)。このアプローチにより、primaries
レコードを更新してプレイブックを再実行することで、プライマリサーバーとセカンダリサーバーの役割を切り替えることができます。ゾーンタイプの自動検出は、次のコマンドで「shared_inventory」モレキュールシナリオをテストできます:molecule test --scenario-name shared_inventory
注意
- bindは自動化されたマルチマスター構成をサポートしておらず、
primaries
リストには単一のエントリのみが必要です。 primaries
レコードが更新されてプライマリからセカンダリサーバーの役割に切り替えられた場合、ゾーンはワイプされ、テンプレートから再作成されます。既存のゾーンの動的更新はまだサポートされていません。
ゾーンタイプは、ホストインベントリごとに明示的に定義することもでき、自動検出をスキップできます:
# プライマリサーバー
bind_zones:
- name: mydomain.com
type: primary
primaries:
- 192.0.2.1
...
# セカンダリサーバー
bind_zones:
- name: mydomain.com
type: secondary
primaries:
- 192.0.2.1
...
# フォワードサーバー
bind_zones:
- name: anotherdomain.com
type: forward
forwarders:
- 192.0.3.1
ゾーンデリゲーション
ゾーンをDNSサーバーにデリゲートするには、NS
レコード(デリゲートの下)を作成するだけで済みます。これは次のように等価です:
foo IN NS 192.0.2.1
サービスレコード
サービス(SRV)レコードは、サービスのリストで追加できます。これは、必須キーname:
(サービス名)、target:
(サービスを提供するホスト)、port:
(サービスのTCP/UDPポート)、およびオプションのキーpriority:
(デフォルトは0)とweight:
(デフォルトは0)を持つマッピングのリストです。
ACLs
ACLは次のように定義できます:
bind_acls:
- name: acl1
match_list:
- 192.0.2.0/24
- 10.0.0.0/8
ACLの名前は、グローバルオプションにおけるallow-transfer
句に追加されます。
バインディングキー
バインディングキーは次のように定義できます:
bind_dns_keys:
- name: primary_key
algorithm: hmac-sha256
secret: "azertyAZERTY123456"
bind_extra_include_files:
- "{{ bind_auth_file }}"
ヒント:追加のインクルードファイルは、ファイルがOS依存のため、ansible変数として設定する必要があります。
これにより、ファイル *"{{ bind_auth_file }}*(例:Debianの/etc/bind/auth_transfer.conf
)に設定され、変数 bind_extra_include_filesのリストに追加する必要があります。
TSIGを使用したゾーン転送(XFR)認証
プライマリとセカンダリサーバー間でのゾーン転送をTSIGキーに基づいて認可するには、変数bind_key_mapping
にマッピングを設定します:
bind_key_mapping:
primary_ip: TSIG-keyname
各プライマリには一つのキーしか持てません(ビューごと)。
キーが実際にbind_dns_keys
マッピングに存在することを確認するチェックが行われます。これにより、セカンダリサーバーのbind_auth_file
で指定されたキーを持つa
のサーバーステートメントが追加されます。
依存関係
依存関係はありません。
例プレイブック
ほとんどの機能を示す詳しい例については、テストプレイブックおよびインベントリをご覧ください。
標準インベントリ
❯ tree --dirsfirst molecule/default
molecule/default
├── group_vars
│ └── all.yml
├── host_vars
│ ├── ns1.yml # プライマリ
│ ├── ns2.yml # セカンダリ
│ └── ns3.yml # フォワーダー
├── converge.yml
...
共有インベントリ
プライマリとセカンダリサーバーに共通の変数はall.ymlに定義されています。
❯ tree --dirsfirst molecule/shared_inventory
molecule/shared_inventory
├── group_vars
│ └── all.yml
├── converge.yml
...
テスト
このロールはAnsible Moleculeを使用してテストされています。テストはコミットやPRごとに自動的にGithub Actionsで実行されます。
このMolecule構成は次を行います:
- YamllintとAnsible Lintを実行
- 一つのプライマリ(
ns1
)、一つのセカンダリ(ns2
)DNSサーバー、およびフォワーダー(ns3
)となる3つのDockerコンテナを作成します -default
モレキュールシナリオ - 構文チェックを実行
- test playbookを使用してロールを適用し、冪等性をチェック
- verify playbookを使って受け入れテストを実行
- もう二つのDockerコンテナを作成し、一つはプライマリ(
ns4
)、もう一つはセカンダリ(ns5
)としてshared_inventory
シナリオを実行します。
このプロセスは、サポートされているすべてのLinuxディストリビューションに対して繰り返されます。
ローカルテスト環境
このロールでローカルに受け入れテストを実行するには、必要なツールをマシンにインストールするか、Vagrantで設定されたVirtualBox VMの再現可能なセットアップを使用することができます:https://github.com/bertvv/ansible-testenv。
ツールを手動でインストールする手順:
- マシンにDockerをインストールします。
- Moleculeの推奨に従って、Pythonの仮想環境を作成します。
- ソフトウェアツールをインストールします:
python3 -m pip install molecule molecule-docker docker netaddr dnspython yamllint ansible-lint
- ロールディレクトリのルートに移動し、
molecule test
を実行します。
Moleculeはテスト後にコンテナを自動的に削除します。コンテナをチェックしたい場合は、molecule converge
の後にmolecule login --host HOSTNAME
を実行します。
Dockerコンテナは、Ansibleテスト用にJeff Geerlingによって作成されたイメージに基づいています(geerlingguy/docker-DISTRO-ansible
という名前のイメージを探してください)。彼のイメージのいずれかを使用できますが、meta/main.ymlで言及されているディストリビューションのみがサポートされます。
デフォルトの構成では、3つのCentOS 8コンテナ(現時点でのプライマリサポートプラットフォーム)が起動します。他のディストリビューションを選択するには、コマンドでMOLECULE_DISTRO
変数を設定してください。例えば:
MOLECULE_DISTRO=debian9 molecule test
または
MOLECULE_DISTRO=debian9 molecule converge
すべてのサーバーで受け入れテストを実行するにはmolecule verify
を実行します。
検証テストは、「dig」ルックアップモジュールを使用してDNSレコードをクエリし、応答を検証します。これには、Ansibleコントローラーノード(Ansibleを実行しているマシン)とターゲットDockerコンテナ間の直接ネットワーク通信が必要です。
注意
Moleculeのverifyテストは、MacOSでDockerが実行されている場合に失敗します。MacOSはコンテナIPに直接アクセスできないため、これは既知の問題です。#2670を参照してください。
ワークアラウンド:
- Moleculeリントを実行:
molecule lint
- コンテナをプロビジョニング:
molecule converge
- コンテナに接続:
molecule login --host ns1
- ロールディレクトリに移動:
cd /etc/ansible/roles/bertvv.bind
- 検証プレイブックを実行:
ansible-playbook -c local -i "`hostname`," -i molecule/default/inventory.ini molecule/default/verify.yml
ns2
およびns3
のために手順2-4を繰り返します。
ライセンス
BSD
貢献者
このロールは多くの人々の貢献のおかげで実現されました。さらに改善するアイデアがあれば、ぜひ提案してください!
問題、機能リクエスト、アイデア、提案などは、Issuesセクションに投稿できます。
プルリクエストも大歓迎です。提案する変更のためにトピックブランチを作成してください。そうしないと、マージ後にフォークに競合が発生する可能性があります。プルリクエスト内で貢献者リストに追加することを躊躇しないでください!
メンテナ:
貢献者:
- Aido
- Angel Barrera
- B. Verschueren
- Boris Momčilović
- Brad Durrow
- Christopher Hicks
- David J. Haines
- Fabio Rocha
- Fazle Arefin
- flora-five
- Greg Cockburn
- Guillaume Darmont
- itbane
- jadjay
- Jascha Sticher
- Joanna Delaporte
- Jörg Eichhorn
- Jose Taas
- Lennart Weller
- Loic Dachary
- Mario Ciccarelli
- Miroslav Hudec
- Otto Sabart
- Paulius Mazeika
- Paulo E. Castro
- Peter Janes
- psa
- Rafael Bodill
- Rayford Johnson
- Robin Ophalvens
- Romuald
- roumano
- Shawn Wilsher
- Tom Meinlschmidt
- Jascha Sticher
- Zephyr82
Sets up ISC BIND as an authoritative DNS server for one or more domains (primary and/or secondary).
ansible-galaxy install bertvv.bind