Windows 7の入ったノートPCでDNSサーバ(forwarder)を動かす話

以下、半年以上前に試行錯誤した結果、「うまくいかなかった」のですが、せっかくある程度やったので、公開しておきます。しかも話が閉じてないかもしれませんが、その点を留意した上で参考にしてください。
ソケットまわりでエラーが出たか何かでunboundの再起動がうまくいかなかった、というようなトラブルだったと思うのですが.....

      • -

ノートPCでVirtualBoxを使っていると, ゲスト側のDNSの情報をどう設定すればいいか困った. ホスト側のネットワークが切り替わるたびにゲスト側で何かしら操作する必要がある(/etc/resolv.confを書き換えるとか). それは嫌なので, ホスト側でDNSサーバを起動しておいて, それを参照するようにできれば嬉しい.

そういうわけで, Windows 7上でUnboundを動かして, IPが固定された, ゲストOSに対するDNSサーバを用意することにする.

今回の環境:

まあ下の二つはほとんど関係ないけれど.

Unboundのインストールはhttp://www.unbound.net/から. サービスをインストールするために,

メモ: アイコンのダブルクリックで行けたっけ?

インストールされたら, コントロールパネル -> 管理ツール -> サービスで, Unbound DNS validatorという項目が確認できる. これでWindows起動時に自動実行される.

Unboundを普通にインストールするとC:\Program Files (x86)\Unboundにインストールされるが, 設定ファイル(service.conf)のデフォルト読み込み先はC:\Program Files\Unboundなので注意する. 私は面倒なのでservice.confはC:\Program Files\Unbound以下においた.

service.confは次のようなものを用意.

server:
	use-syslog: yes
	num-threads: 2
	interface: 127.0.0.1
	interface: 192.168.56.1
include: "C:\Users\hoge\.unbound\forward-zone.conf"

use-syslogはお好みで. yesにすると, イベントビューアのWindowsログ -> アプリケーションにログが出る. interfaceでlistenするインターフェースのIPアドレスとポートを指定できる. interface: 127.0.0.1は今回の用途ではなくてもよいが, 問題切り分けのためにWindows上から名前解決したい場合は入れる. このとき, num-threads: 1にすると, 実は上に書いたインターフェースしか有効にならないようだ.
include: では実際のDNSの情報を書いたファイル, forward-zone.confを用意する. 中身は

forward-zone: 
  name: "."
  forward-addr: 192.168.145.1
  forward-addr: 192.168.145.2

という感じ. なのだが, これはネットワークインターフェースの情報が変更された際に逐次自動生成することにする. 次のようなWindows PowershellスクリプトをC:\Users\hoge\.unbound\update.ps1として用意.

# 
# generate forward-zone.conf for unbound
#
# reference: http://www.computerperformance.co.uk/powershell/powershell_ipconfig.htm
#

$filepath = "C:\Users\hoge\.unbound\forward-zone.conf" 

$strComputer = "."
$colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration" `
-computername $strComputer | Where{$_.IpEnabled -Match "True"}

$content = @"
forward-zone: 
  name: "."

"@

foreach ($objItem in $colItems) {
#  write-host "DNSServerSearchOrder: " $objItem.DNSServerSearchOrder
  $dnsservers = [string]$objItem.DNSServerSearchOrder
  if ($dnsservers -ne "") {
    foreach ($d in $dnsservers.split(" ")) {
        $content += "  forward-addr: $d`n"
    }
  }
}

set-content -path $filepath -value $content
#write-host $content

restart-service unbound

get-wmiobject ...のあたりは, 最初のほうに書いたURLの記事を参考にした. $filepathは自分のホームディレクトリにしておかないと, 書き込めないかもしれないので注意.

これを自動実行するため, タスク スケジューラに登録する. コントロールパネル -> 管理ツール -> タスク スケジューラで, メニューから操作 -> 基本タスクの作成. ウィザードが起動するので順番に項目を埋めていく. まずはタスクの名前. これは適当につける. とりあえず「ネットワーク情報が変更された際のUnboundのリスタート」とした. 「トリガー」は「特定イベントのログへの記録時」. 「ログ」は「Microsoft-Windows-NetworkProfile/Operational」, 「ソース」は「NetworkProfile」, 「イベントID」は「10000」とする. 10000は「ネットワークが接続されました」の意味. これは イベントビューアのアプリケーションとサービス ログ -> Microsoft -> Windows -> NetworkProfile -> Operational を見れば確認できる. 「操作」は「プログラムの開始」で, 「プログラム/スクリプト」はpowershell, 引数の追加はC:\Users\hoge\.unbound\update.ps1で開始はなし. 完了をクリックしたときプロパティを開いてもらう.
以下略.

Windows Powershellスクリプトを実行するため, Powershellを管理者権限で実行したうえで,
Set-ExecutionPolicy RemoteSigned
を実行しておく. こうすると, ローカルコンピュータから署名のないスクリプトの実行を許可する.

ゲストOS側ではホストオンリーネットワークのホストOS側IPをDNSサーバとする. /etc/resolv.confに

nameserver 127.0.0.1

などと書いておく.