PowerDNSを使っている際にゾーン情報の一括登録などができません。
※バージョンによるかもしれません。
通常は管理画面から一つ一つ登録するしかありません。
これではたくさんのゾーンを登録したいときに大変なので、
あまりやりたくはないのですが、データベースに直接ゾーンを一括で登録してみました。
基本作業はDNSのマスターサーバーで実施します。
まずはデータベースを触りますので、とにかくDBデータベースのバックアップを取ります。
# /usr/bin/mysqldump -A -uroot -p'DBパスワード' > /tmp/mysql.dump
また実際に操作するPowerDNSのゾーンが書き込まれたレコード一覧を取得
echo "select * from records" |mysql -u root -p"DBパスワード" pdns >> /tmp/records.bf
ここまで準備完了。
■いよいよゾーンを一括で変更します。
ここでは例としてあるサブドメインのCNAMEを一括でAレコードに変更する場合を実施してみます。
変更するサブドメインとCNAMEのゾーンは予め拾っている想定。
ここでは2ドメインのみ実施しますが、実際は変更したいレコード分、行数を足すことになります。
# vi list.txt
,区切りで以下のようなリストを作成
例
SUBDOMAIN,CNAME
----------------------------------------------------------------------------
test.example8.com,testcname.com
test.example9.com,testcname2.com
----------------------------------------------------------------------------
以下コマンドでデータベースから以下の情報を拾ってリスト化します。
for TGT in `cat list.txt`
do
NAME=$(echo $TGT |cut -d , -f 1)
CON=$(echo $TGT |cut -d , -f 2)
echo "select id,domain_id,name,type,content from records WHERE name='$NAME' and content='$CON'" |mysql -u root -p"DBパスワード" pdns |grep CNAME >> cname.list
done
出力されたcname.list
例
id domain_id name type content
----------------------------------------------------------------------------
141 10 test.example8.com CNAME testcname.com
142 11 test.example9.com CNAME testcname2.com
----------------------------------------------------------------------------
それぞれの情報の説明は以下
①id 各ゾーンが一意的に持っているDBのid
②domain_id 各メインドメインごとに持っているドメインのid ※サブドメインなどはメインドメインと同じdomain_idになる
③name ドメインやサブドメイン名
④type レコードのタイプ AレコードやCNAMEなど
⑤content そのドメインのゾーン情報
cname.listのcontentの部分だけ更新をかけてIPアドレスにするので、
リストのcontentの部分だけ加工したupdatelist.txtを作成する
# vi updatelist.txt
以下のように加工
例
id,domain_id,name,type,content
----------------------------------------------------------------------------
141,10,test.example8.com,CNAME,testcname.com,IPアドレス1
142,11,test.example9.com,CNAME,testcname2.com,IPアドレス2
----------------------------------------------------------------------------
以下のコマンドで、update.dumpの作成
for TGT in `cat updatelist.txt`
do
ID=$(echo $TGT |cut -d , -f 1)
DOM=$(echo $TGT |cut -d , -f 2)
NAME=$(echo $TGT |cut -d , -f 3)
TYPE=$(echo $TGT |cut -d , -f 4)
CON=$(echo $TGT |cut -d , -f 5)
IP=$(echo $TGT |cut -d , -f 6)
echo "UPDATE records set content='$IP',type='A' where id='$ID' and domain_id='$DOM' and name='$NAME' and type='$TYPE' and content='$CON';" >> update.dump
done
以下のようなupdate.dumpが作成される
----------------------------------------------------------------------------
UPDATE records set content='IPアドレス1',type='A' where id='141' and domain_id='10' and name='test.example8.com' and type='CNAME' and content='testcname.com';
UPDATE records set content='IPアドレス2',type='A' where id='142' and domain_id='11' and name='test.example9.com' and type='CNAME' and content='testcname2.com';
----------------------------------------------------------------------------
update.dumpを取り込み、DB内の対象CNAMEの削除を実施。
mysql -u root -p -D pdns < update.dump
アップデート後のレコード一覧を取得
echo "select * from records" |mysql -u root -p"DBパスワード" pdns >> records.1af
想定通りの変更であることを確認
diff records.bf records.1af
■Aレコード登録
上記で作成したリストから必要な項目のみ抜き出し
vi arecords.txt
例
domain_id,name,content
----------------------------------------------------------------------------
10,test.example8.com,99.83.170.51
11,test.example9.com,99.83.150.0
----------------------------------------------------------------------------
for TGT in `cat arecords.txt`
do
ID=$(echo $TGT |cut -d , -f 1)
NAME=$(echo $TGT |cut -d , -f 2)
CON=$(echo $TGT |cut -d , -f 3)
echo "INSERT INTO records (domain_id,name,content,type,ttl,prio) VALUES ($ID,'$NAME','$CON','A',600,0);" >> arecords.dump
done
arecords.dumpを取り込み、Aレコードの追加を確認
mysql -u root -p -D pdns < arecords.dump
追加後のレコード一覧を取得
echo "select * from records" |mysql -u root -p"DBパスワード" pdns >> records.2af
想定通りの変更であることを確認
diff records.1af records.2af
■シリアル番号の更新
シリアル番号を更新しないと、変更したゾーン情報がマスターからスレーブに反映されないためシリアル番号を更新する。
※シリアル番号はSOAレコードのドメインの後の「2021053101」の部分。
西暦 月 日 二桁の数字 などで設定するのが一般的です。
こちらの数字が大きいとスレーブがマスターのゾーンの更新を反映することになる。
例えば「2021053102」に変更することで、元の数字より大きくなるので、更新される。
数字は基本的には最後の2桁の数字を大きくすることで対応しないと、
西暦などの部分の数字を大きくしてしまうと、その後のスレーブの更新ができなくなってしまうので注意。
各ドメインのNSレコードの取得
vi dom.txt
例
domain_id,name,
----------------------------------------------------------------------------
10,example8.com
11,example9.com
----------------------------------------------------------------------------
for TGT in `cat dom.txt`
do
DOM=$(echo $TGT |cut -d , -f 1)
NAME=$(echo $TGT |cut -d , -f 2)
echo "select id,content from records WHERE domain_id='$DOM' and name='$NAME' and type='SOA'" |mysql -u root -p"DBパスワード" pdns |grep -v content >> soa.list
done
cat soa.list
以下のように出力される
--------------------------------------------------------------------
97 testns0.example.com testns.example.com. 2021053101 36000 300 360000 36000
113 testns0.example.com testns.example.com 2021053101
--------------------------------------------------------------------
区切りを変換
0,$s/ /,/g
3番目の区切りを"2021053102"に変換
awk '{FS=" ";OFS=" "}{$3="2021053102"}1' soa.list > soaupdate.list
cat soaupdate.list | while read TGT
do
ID=$(echo $TGT |cut -d , -f 1)
CON=$(echo $TGT |cut -d , -f 2)
echo "UPDATE records set content='$CON' where id=$ID and type='SOA';" >> soa.dump
done
soa.dump
UPDATE records set content='testns0.example.com. testns.example.com. 2021053102 36000 300 360000 36000' where id=97;
UPDATE records set content='testns0.example.com testns.example.com 2021053102' where id=113;
soa.dumpを取り込み、SOAレコードのアップデートを確認
mysql -u root -p -D pdns < soa.dump
追加後のレコード一覧を取得
echo "select * from records" |mysql -u root -p"DBパスワード" pdns >> records.3af
想定通りの変更であることを確認
diff records.2af records.3af
最後にマスターのゾーン変更がスレーブサーバーに反映されたことを確認します。