「ネットワークに新規のサーバーを追加した」や、「サーバーの入れ替えをした」など、DNS の設定を変更する場合があります。追加・変更する際には bind のゾーンファイルを書き換えることになりますが、これは運用上、最も気を使う作業の一つです。本稿では、Kompira Enterprise を利用して DNS の登録情報の変更を行ってみましょう。
※ named の設定と Python に関する簡単な知識が前提となります。
環境情報
本稿は、以下の環境で検証しています。
ソフトウェア | バージョン |
---|---|
Kompira Enterprise | 1.5.5.post11 |
OS | CentOS 7.8.2003 |
dnspython | 1.16.0 |
または
ソフトウェア | バージョン |
---|---|
Kompira Enterprise | 1.6.2.post4 |
OS | CentOS 7.8.2003 |
dnspython | 2.1.0 |
事前準備
単純にサーバーの追加であれば、ゾーンファイルに A レコードを追加するのみですが、今回のような既存登録の変更となると単純ではありません。
本稿では Python の “dnspython” を利用し、ゾーンファイルにおける既存登録の変更を行っていきます。
流れとしては以下のようになります。
1. DNS サーバーから、ゾーンファイルを Kompira Enterprise サーバーに転送
2. Kompira Enterprise サーバーで、dnspython の機能を使って編集
3. 編集したファイルを DNS サーバーに再転送
dnspython のインストール
Kompira Enterprise サーバーにシェルログインを行った後、管理者権限のアカウントで以下のようにインストールしてください。
Kompira Enterprise 1.6系の場合
$ /opt/kompira/bin/pip install dnspython=2.1.0
Kompira Enterprise 1.5系の場合
$ /opt/kompira/bin/pip install dnspython=1.16.0
※ Kompira Enterprise 1.4系では /opt/kompira/bin/pip install の代わりに easy_install を用います。
ライブラリの作成
Kompira Enterprise から dnspython を利用するためのラッパーライブラリを作成していきます。ここでは「DNSレコード編集」という名前の「ライブラリ型」のオブジェクトを作成します。
ライブラリ「DNSレコード編集」
import dns.rdata import dns.rdataset import dns.zone from dns.exception import DNSException from dns.rdataclass import * from dns.rdatatype import * def change_A_record(oldzone, newzone, domain, key, new_IP): """ oldzone: 変更前のゾーンファイル newzone: 変更後のゾーンファイル domain: ドメイン名 key: キー (www 、mail 、ftp など) new_IP: 変更後の IP アドレス """ try: zone = dns.zone.from_file(oldzone, domain) print("Zone origin: {}".format(zone.origin)) except DNSException as e: print(e.__class__, e) print("Changing A record for {} to {}".format(key, new_IP)) rdataset = zone.find_rdataset(key, rdtype=A) # 対象となる A レコードがなければ終了 if not rdataset: return() # zone を置き換えるための新規 Rdataset を作成 rdclass, rdtype = rdataset[0].rdclass, rdataset[0].rdtype new_rdataset = dns.rdataset.Rdataset(rdclass, rdtype) # IP Address を変更した新規 Rdata オブジェクトを作成 for rdata in rdataset: new_rdata = dns.rdata.from_text(rdclass, rdtype, new_IP) new_rdataset.add(new_rdata) # zone の更新 zone.replace_rdataset(zone.origin, new_rdataset) print("Writing modified zone to file {}".format(newzone)) zone.to_file(newzone)
これで指定したドメイン名、キーに該当するレコードの IP アドレスを変更して、新しいゾーンファイルに保存する “change_A_record” というメソッドが利用できるようになりました。
ジョブフローの作成
次にライブラリを利用するジョブフローを作成します。
| oldzone = "/var/named/mykompira.com.db" | # DNS上のゾーンファイル | domain = "mykompira.com" | # ドメイン名 | key = "mail" | # キー | ip = "192.168.99.99" | # 変更後のIPアドレス | tmpzone = "/tmp/tmpzone" | # 作業用の一時ファイル(変更前) | newzone = "/tmp/mykompira.com.db.new" | # 作業用一時ファイル(変更後) [ __host__ = "<DNS サーバー>", __user__ = "<ユーザー名>", __password__ = "<パスワード>", __sudo__ = true ] -> get(oldzone, tmpzone) -> ["cat $tmpzone"] -> print($RESULT) -> # 変更前のゾーン [./DNSレコード編集.change_A_record: tmpzone, newzone, domain, key, ip] -> put(newzone, oldzone) -> ["cat $newzone"] -> print($RESULT) -> # 変更後のゾーン ["rndc reload"]
上記のジョブフローの流れは以下の通りです。
1. get() を利用し、DNS サーバーからゾーンファイルを Kompira Enterprise サーバーにダウンロード
2. change_A_record() を呼び出し、ゾーン情報内のレコードの更新
3. 変更後のゾーンファイル /tmp/mykompira.com.db.new を DNS サーバーに再アップロード
(必要に応じて rndc コマンドでゾーン情報の再読み込みを行わせるなどの対応が必要です。)
本稿では dnspython を利用して既存のゾーン情報内のレコードの更新を行いましたが、他にも TTL の変更、ドメインの追加、ホストの追加・削除などを行うことができます。上記と同様にライブラリにメソッドを追加してジョブフローから利用することができますので、詳細に関しては「dnspython」を参照してください。
今回の例では Kompira Enterprise サーバー上に dnspython をインストールしました。しかし、dnspython を DNS サーバー上にインストールすることができれば、Kompira Enterprise からはコマンド発行のみでゾーン情報の変更が出来るため、get/put のようなファイル転送は不要になります。また、DNS サーバーの認証情報についても「ノード情報」型オブジェクトを使用しても結構です。