環境
- OS : Mac OSX 10.10.5
- Docker : 1.8.1 (docker-machine)
- Ruby : 2.2.3
- Rails : 4.2.4
- PostgreSQL : 9.4
- Bind-SDB : 9.9.4
Bind-SDB について
通常の bind だと zone ファイルとかを更新したりする必要があるのですが、 sdb インターフェースというものを使うと zone ファイルではなくてDBのレコードを使って名前解決とかできるらしいです。
具体的には CentOS とかだと bind-sdb(bind-sdb-chroot) パッケージ。
バックエンドはデフォルトでは PostgreSQL なので PostgreSQL で。 一応 MySQL のアダプタもあります。
レコードに要求されるカラムは以下の4つ。
- name : DNS を引く時の key。 A record ならFQDNとか。
- rdtype : レコードの種類。 A とか AAAA とか SOA とか。
- rdata : DNS を引く時の value。 A record ならIPとか。
- ttl : レコードのTTL
この4つがきちんと引けていれば動くようなので、この構造を持ったモデルを作ってしまえば Rails で管理できそうだな、ということで実際に作ってみました。
サンプルアプリケーション
サンプルとしてちょこっと書いてみました。(https://github.com/atton-/bind_sdb_with_rails)
*.hoge.com を解決できるようなDNSを作れます。
一応逆引きもできるようにしてるのでアドレス帯域は 10.100.200.0/24 くらい。
rails server して、 domain を入れて IP の最後のオクテットを数値で入れると名前が解決できます。
例えば、 rake db:seed では aaa.hoge.com というレコードを入れるので
$ dig aaa.hoge.com @<your-dns-ip>とかすると 10.100.200.1 と返します。
実行コマンドは README.md に書いてますが、コンテナのIPが環境によって違うのでちょっと書き換えが必要です。
あと DOCKER_HOST が設定されていること前提。OSX で docker-machine を使っていれば設定されているはずです。
やってること
やっていることはドメインの文字列とIPの組から A レコードと PTR レコードを作ってるだけです。
ドメインとIPが入る record モデルを作って
A レコードが入る forward_record モデルと PTR レコードが入る reverse_record モデルを作って has_one で持たせる。
record モデルの after_save くらいで forward_record と reverse_record を生成してやります。
あとは bind-sdb 側がやってくれます。
bind-sdb 側の設定として、 /var/named/chroot_sdb/etc/named.conf にDBサーバのIPを指定する必要があります。
どうやら名前で書くのはダメなようで、IPで直接指定します。
今回は docker container で DB を持っているので、 docker の host か DB の container の IP を書いてから build するようにしてます。ちょっと面倒。
bind-sdb は特定の zone を特定のテーブルから引く、という処理をするようなので、正引き用の zone は forward_records テーブルを、逆引き用のzoneは reverse_records テーブルを見るようにします。
あとは forward_records/reverse_records に SOA/NS を突っこんでやれば動きます。
ただ、ゾーンを転送する際はテーブルの中に入っているもの全てを転送してしまうようなので、複数のゾーンを1つのテーブルに入れてしまわないように注意。一応転送しないのなら動きはしますが……
ちなみに select するだけのようなので、 read only の view とかを切って複数のゾーンに対応することもできます。そうすれば Rails 側の association が多くなることも無いです。
もちろん AAAA レコードも追加できるので IPv6 も対応可能。今回はゾーンを書くのが面倒だったので v4 のみで。
あとは転送とかするのなら SOA のシリアルの管理もきちんと。 record モデルの after_update くらいに SOA のシリアルを上げる処理を書いてやる形とか。
ということで、 Rails でドメインとIPを申請すると名前が解決できるようになりました。
実行コマンド例
一応置換してね、みたいな記述をしているつもりなのですけれど、具体的な値で実行してみた時の例を載せておきます。
- $ git clone https://github.com/atton-/bind_sdb_with_rails
- $ cd bind_sdb_with_rails
- $ echo $DOCKER_HOST
- tcp://192.168.99.100:2376
- docker のホストのIP は 192.168.99.100 のようなのでこれを使います。
- $ docker build -t pg94 docker/postgres
- $ docker run -itd --name postgres-server -p 5432:5432 -e POSTGRES_PASSWORD=hogehoge pg94
- $ rake db:create db:migrate db:seed
- ここで aaa.hoge.com, 10.100.200.1 が追加される。
- $ rails server
- http://localhost:3000 でレコードの追加とかができます。
- $ sed -i -e 's/postgres-server/192.168.99.100/'
-
$ docker build -t bind_sdb_with_rails/bind-sdb docker/bind-sdb
- $ docker run -itd --name name-server -p 53:53 -p 53:53/udp bind_sdb_with_rails/bind-sdb
- この段階でDNSが立ち上がります
- $ dig @192.168.99.100 aaa.hoge.com
- 正引きチェック
- $ dig @192.168.99.100 -x 10.100.200.1
- 逆引きチェック
0 件のコメント:
コメントを投稿