まえがき
もりやまです。2 年ぶりの登場です。
今回は、社内のルータの制限による、社内から社内サーバにアクセスできない問題と、その解決方法について書いてみようと思います。
「あれ、前回の最後で EBS-Backed イメージの作り方書くって言ってたのに!」って覚えてた方は、シーズさんのブログで書かれていますので、そちらをご覧ください。
EC2でCentOS6のEBS-Backed AMIをゼロから作る | シーズクリエイターズブログ
今まで
弊社のネットワーク構成は以下のようになっています。
グローバル IP の数が限られているため、各開発サーバは、グローバル IP を割り当てている 1 台のホストで動いている nginx をリバースプロキシにして、アクセスできるようにしています。
外部 DNS には各開発サーバの IP は、リバースプロキシのホストとと同じグローバル IP を登録しているのですが、使用しているルータに NAT ループバック機能が無いため、社内からホスト名でアクセスしようとすると、ルータの設定ページが表示されてしまうという状況でした。
これを回避するため、社内ネットワークからアクセスするときは、ルータを経由せず直接プロキシサーバにパケットが飛ぶように、静的ルートを設定していました。
各自の PC へは DHCP で IP を割り当てているので、DHCP サーバから静的ルートを配信すれば解決できそうなものなのですが、OSX の DHCP クライアントは対応していないようです。。。
仕方がないので、各自出社したら route add、退社時に route del するという方法で運用してきました。
しかし、社内の「ふりかえり」でもこれが Problem として挙がってきたので、内部 DNS を立てる方向で解決してみました。
内部DNSサーバを立てる
PowerDNS インストール
kray.jp の外部 DNS サーバでは PowerDNS を使っているので、内部 DNS も同様に PowerDNS を使用しました。
CentOS 6.x のホストにインストールするので、EPEL をリポジトリに追加して、yum install pdns でインストール完了です。
バックエンドには MySQL を使うので、pdns-backend-mysql もインストールします。
kray.jp 以外のドメインについては上位 DNS に聞く必要があるので、あわせて pdns-recursor もインストールします。
データベースの構築については公式のドキュメントを参照してください。
3. Generic MySQL and PgSQL backends
コンテンツサーバの設定
デフォルトの設定から変更するのは以下のとおりです。
# LAN 内からの再帰リクエストを許可
allow-recursion=192.168.0.0/24
# バインドする IP を LAN 側の IP に限定
local-address=192.168.0.2
# 再帰リクエストを投げる先を pdns-recursor をバインドする IP に指定
recursor=127.0.0.1
リカーサーの設定
デフォルトの設定から変更するのは以下のとおり。
# 再帰リクエストを許可する IP を localhost からに限定
allow-from=127.0.0.1/32
たったこれだけで、内部 DNS としての設定は完了です。
DNS レコードの同期の仕組みを作る
kray.jp ドメインのリクエストをすべて内部 DNS で捌く必要があるので、AXFR で外部 DNS サーバからゾーン情報を取得して、必要な部分だけ IP を書き換えた上で、内部 DNS に反映させます。
「必要な部分」というのは、nginx がリバースプロキシとして動いているホストの IP です。
ということは、nginx のバーチャルホストの設定を見れば、どのホスト名がどのローカル IP で待ち受けているかわかるはずです。
ということで、AXFR で取得したゾーン情報から、nginx が持っているバーチャルホストに該当するレコードの IP だけローカル IP に書き換えて、内部 DNS のデータベースを更新する ruby スクリプトを書いてみました。
https://github.com/morimori/powerdns-local-sync
nginx のバーチャルホストの部分は、ファイル名のルールベースでホスト名を判別しています。
今後の課題
弊社で公開している Sortie も開発サーバが社内にあるのですが、Sortie でネームサーバとして使用している Amazon Route53 では AXFR が使えないので対応できていません。
aws-sdk を使って、API 経由でゾーン情報を取得できそうなので、今後実装して行きたいと思います。
あ、先に実装して pull req. 投げてくれてもいいんですよ?
このエントリーに対するコメント
日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)
- トラックバック
「いいね!」で応援よろしくお願いします!