PowerShellで専用線DNSのレコードを読んでローカルDNSを更新

公開 | 更新 

Powershell を使って、専用線の向こうにあるマスタ DNSサーバ からレコードを読み込んで、社内LANローカル DNSサーバ の レコード を定期的にチェック・ 更新 する仕組みを組んでみました。

CCASS専用線とターミナル

香港の證券商には、中央結算系統(CCASS)から専用線が延びており、担当者はそこへ繋がるクローズドなターミナル(CCASSから割当てられた静的IPアドレスの設定された、単なるWindows PC)を使って、日々の決算処理を行っています。

図1.物理的に隔たれたCCASSネットワーク

図1.物理的に隔たれたCCASSネットワーク

この担当者は、決算処理以外の業務にもPCが必要で、時にそれら2台のPC間でデータのやり取りが必要な際は、USBメモリを使わなければならないといった弊害もありました。

 

ルーティングによる論理的制御

規模が大きくなるにつれ、物理的にネットワークを分けることの煩わしさから、数年前より専用線も一度社内ルータへ取り込み、ルーティングによりトラフィックを制御するようにしています。

図2.ルーティング処理されるCCASSネットワーク

図2.ルーティング処理されるCCASSネットワーク

そして担当者側のPCも統合し、1台のPCに社内LANとCCASS用の2つのIPアドレスを持たせて、どちらのネットワークへもアクセス可能な状態にしています。

 

条件付きフォワーダー

CCASSターミナルはブラウザからインターネットには公開されていない、 www.ccass.com へアクセスして證券の決算処理を進めるわけですが、その名前解決はCCASSネットワーク内にあるDNSサーバが担っています。

そこで、社内LANのローカルDNSサーバに条件付きフォワーダーを設定し、このドメインの名前解決リクエストはCCASS側のDNSサーバへ転送するよう、仕向けていました。

図3.DNSサーバの条件付きフォワーダー

図3.DNSサーバの条件付きフォワーダー

数年間この仕様で問題無く機能していたのが、あるときより名前解決が出来なくなってしまいました。

CCASS側のDNSを相手に、nslookupで直接名前解決するには問題はありませんが、社内LANのローカルDNSサーバ経由のフォワーディングでは REJECTED のレスポンスと共に失敗することから、CCASS側DNSサーバかファイヤウォールのセキュリティ仕様が厳しくなったようです。

 

ローカルDNSサーバにゾーン作成

フォワーディングを受け付けてもらえなくなったので、ひとまず社内LANのローカルDNSサーバが自前で名前解決できるように、正引きゾーンを作成しました(OSはWindows Server 2012)。

図4.ローカルDNSサーバに作成した正引きゾーン

図4.ローカルDNSサーバに作成した正引きゾーン

ローカルセカンダリDNSサーバへ転送設定

社内LANにはもう1機DNSサーバが稼働しているので、ゾーン設定の済んだプライマリサーバからセカンダリへ転送するような、主従関係を両者の間に構築します。

プライマリ側はプロパティの転送タブで、セカンダリへの転送を許可します。

図5.ゾーン転送の許可

図5.ゾーン転送の許可

さらにレコードが更新された場合のセカンダリへの通知を設定。

図6.セカンダリへの自動通知

図6.セカンダリへの自動通知

そしてセカンダリサーバ上で、プライマリと同じ名前のセカンダリゾーンを作成すれば完成です。

図7.セカンダリゾーンを作成

図7.セカンダリゾーンを作成

次に、このレコードのオリジナルを有するCCASSのDNSサーバからレコードを読み取り、ローカルDNSサーバに作った同じレコードを適宜更新する仕組みを、Poweshellを使って組んでみます。

 

Powershell : DNSレコードの取得

nslookup のように、PowershellでDNSサーバからレコードを取得するには、Resolve-DnsNameコマンドレットを使います。

オブジェクト指向なこのコマンドレットの良いところは、特定の要素を取り出せること。例えばIP Addressだけを取り出したいなら、以下のようにコマンドを発行するだけです。

 

Powershell : DNSレコードの内容を書き込み

対してPowershellでDNSサーバのレコード内容を編集するにはまず、Get-DnsServerResourceRecordコマンドレットで現在のレコードをオブジェクトとして取得、それを編集の後、Set-DnsServerResourceRecordコマンドレットへ渡す手順になります。

この時、 Set-DnsServerResourceRecord は更新前・更新後双方のレコードオブジェクトを必要とするので、 Get-DnsServerResourceRecord を実行する際、ワンライナーで一気に2個取得すると、更新時にエラーになります。

これを回避するには、原始的ですが Get-DnsServerResourceRecord を2回に分けてそれぞれ実行するのが確実でした。

(一度取得したオブジェクトをクローンする手もあるようですが、Poweshellのバージョンに依っては機能しないとの指摘もネット上に散見されます。)

 

DNSレコード読込・書込スクリプト

以上で必要な個々のアクションは確認できたので、これらを元に以下のステップで動作する自動化スクリプトを組みました。

  1. CCASSのDNSサーバにあるレコードのIPアドレスを読み取り。
  2. ローカルDNSサーバの同レコードのIPアドレスを読み取り。
  3. 取得した2つのIPアドレスを比較。
  4. 差異のある場合、ローカルDNSサーバのレコードを更新。

予めローカルDNSのレコードをダミーデータに書き換えた上で作成したスクリプトを実行し、期待通りに動作することを確認しました。

CCASS側DNSサーバのレコードに変化が無い場合は、何もせず終了します。

 

タスクスケジューラへ登録

出来上がったスクリプトをローカルDNSサーバへ配置し、以下の要領でタスクスケジューラへ登録します。

図8.タスクスケジューラ アクション設定

図8.タスクスケジューラ アクション設定

Arguments の後方で実行結果をログファイルに出力するように仕向けていますが、単に >> としただけでは何も取り出せないので調べてみると*>> とする必要があるとのことでした。

タスクの実行頻度は平日の日中半日の間、毎時1回としておきました。

図9.タスクスケジューラ トリガ設定

図9.タスクスケジューラ トリガ設定

しばらくしてログファイルを確認してみましたが、そう頻繁に変化する要素でもないので、基本的に変化なしで終わっています。

 

今回のきっかけとなったDNS転送拒否問題は、実は系列の他の證券商では発生していないとの報告を受けており、「どうしてうちだけ?!」とますます不可解なのですが、もし今後発生した際にはこの解決方法が役に立ちそうです。

 

created by Rinker
¥2,495 (2024/04/25 00:19:22時点 Amazon調べ-詳細)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA