サーバを数十台程度扱うようなお仕事も、Ansibleの力で複数台まとめて操作をおこなったり、Fluentdの力で全体の情報集約をできたりと、とても楽になってきました。
こういった自動化を考えていく中で少し手間がかかってくれるのがWindows Server。
Linuxで統一したいところではあるわけですが、どうしても用途によりWindows Serverで構築したほうが楽な場面があり、数台のWindows Serverがまぎれこんだりして非常に悩ましいところがあります。
そんなわけで今回は、Windows Serverのイベントログを集約するようなソフトウェアのインストール・設定を、Ansibleを使って実施することを試してみました。で、割と簡単にできそうだという感触が得られたのでそのメモ。
関連する技術
AnsibleによるWindowsの操作
Ansibleは基本的には、対象サーバにSSHして、対象サーバのPython環境を使っていろいろな処理を実行してくれます。対して対象サーバがWindowsの場合には、対象サーバにWinRM (Windows Remote Management)で接続してPowerShellを使っていろいろ実行してくれるようになっています。
Windows環境にはPowerShell 3.0が必要だったりネットワーク設定が必要だったりしますが、以下にとてもわかりやすくまとめられています。
今回はお試しとして、Microsoft Azure上にWindows Server 2012 R2の仮想マシンを用意し、Ansibleから操作してみることにします。
##Windowsのイベントログを集める
WindowsのイベントログをFluentdに集める方法はいくつかありそうですが、以下を参考にNXLogを使ってsyslogで集めることにしました。
なお、今回は試さなかったのですが、 fluent-plugin-winevtlog
というのもあるようで、非常に面白そう・・・!
試してみる
試してみたPlaybookは https://github.com/yacchin1205/nxlog-ansible に置きました。
Playbookは割と単純で、 roles/nxlog/tasks/main.yml
で、
- name: Download NXLog
win_get_url: url=http://nxlog.org/system/files/products/files/1/nxlog-ce-2.9.1347.msi dest="C:\Users\{{ ansible_ssh_user }}\Downloads\nxlog-ce.msi"
- name: Install NXLog
win_msi: path="C:\Users\{{ ansible_ssh_user }}\Downloads\nxlog-ce.msi"
- name: Copy configuration for NXLog
win_template: src=nxlog.conf.j2 dest="C:\Program Files (x86)\nxlog\conf\nxlog.conf"
notify: Restart NXLog
- name: Start NXLog
win_service: name=nxlog start_mode=auto state=started
こんな感じで、 win_* モジュールを使うことでやりたいことがかなり素直に書ける印象。
NXLogの設定ファイルを変更する場合は roles/nxlog/templates/nxlog.conf.j2
をいじればOK。
以下、試した構成と手順について、簡単に残しておきます。
構成
今回は失敗しても死なないように、Microsoft Azure上で仮想マシンを作成して試してみました。構成は以下のような感じ。
ここではAzureの1つの仮想ネットワーク内に2つの仮想マシンを用意しています。
- CoreOS Stable ... Ansibleを動かすコンテナ / Fluentdを動かすコンテナ
- Windows Server 2012 R2 ... イベントログの監視対象
CoreOS側にsyslogの受け口としてFluentdコンテナを用意しておいて、CoreOS上のAnsibleコンテナからWindows ServerにNXLogをインストールし、このFluentdにsyslog経由でイベントログを流させる、という格好です。
手順
仮想マシンの起動
今回はMicrosoft Azureのダッシュボードから操作してみます。
-
Windows Server 2012 R2の仮想マシンを用意する。今回のパラメータは以下のような感じ
- イメージ: Windows Server 2012 R2 Datacenter
- バージョンのリリース日: 2015/07/26 (最新のものを選択)
- 仮想マシン名: 適当につける
- 階層: STANDARD
- サイズ: D1 (1コア、3.5GBメモリ)
- 新しいユーザ名: 適当につける
- 新しいパスワード: 適切なものを設定
-
CoreOSの仮想マシンを用意する。パラメータは以下
- イメージ: CoreOS Stable
- バージョンのリリース日: 2015/08/04 (最新のものを選択)
- 仮想マシン名: 適当につける
- 階層: STANDARD
- サイズ: A2 (2コア、3.5GBメモリ)
- 新しいユーザ名: 適当につける
- 認証: 適切なものを設定
今回はWindows ServerとAnsible環境を同じ仮想ネットワーク内に置いているのであまり気にしてはいないのですが、Windows Serverに対して仮想ネットワーク外のAnsible環境から操作する場合は、エンドポイントに PowerShell(5986ポート)が設定されていることを確認する必要があります。
Fluentdの準備
今回はsyslogで受け取った内容をとりあえず標準出力で確認できればよかったので、syslog inputとstdout outputプラグインのみの単純な設定にしました。
イメージは https://github.com/fluent/fluentd-docker-image イメージを使わせてもらいます。
Azure上に作成したCoreOSの仮想マシンにSSHし、以下のように操作します。
-
設定ファイルを記述する。今回は、
/home/(user)/fluentd/test-syslog.conf
というファイルに、以下のような内容を記述<source> @type syslog port 5140 bind 0.0.0.0 tag system </source> <filter **> @type stdout </filter>
-
Fluentdコンテナを実行する。イメージは
fluent/fluentd
を指定すればOK$ sudo docker run -d -p 5140:5140/udp -v /home/(user)/fluentd:/fluentd/etc -e FLUENTD_CONF=test-syslog.conf fluent/fluentd
これでFluentdコンテナが起動され、syslog inputプラグインがホストのUDP 5140ポートからのパケットを受けつけてくれるようになります。
送られてきたsyslogの内容は標準出力に出力されるので、 docker logs
コマンドで確認できます。
Windows Serverの準備
Windows Serverが、AnsibleからのWinRM経由での要求を受けつけてくれるように設定変更をおこないます。
詳細は AnsibleでWindowsを操作する準備をする#Windows側の準備 を参照してください。
仮想マシンにRemote Desktopで接続し、以下のように操作します。
-
ログイン時にNetworkに関して、PCやデバイスの発見に関する問い合わせが表示されるので、[Yes]を選択する。
もしくは、PowerShellから以下のコマンドを入力し、ネットワークをPrivateに変更するPS > Set-NetConnectionProfile -InterfaceAlias (Get-NetConnectionProfile -IPv4Connectivity Internet).InterfaceAlias -NetworkCategory Private
-
PowerShellを開き、以下のコマンドを入力する
PS > cd Downloads PS > Invoke-WebRequest -Uri https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 -OutFile ConfigureRemotingForAnsible.ps1 PS > powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1
これで [Ok.]
と出力されれば、WinRM経由でAnsibleで操作可能な状態になったはずです。
続いてAnsible環境を作って、このWindows Serverを操作できるか確認してみます。
Ansibleの準備
CoreOSのマシンにSSHし、以下のように作業していきます。
-
pipを使って
ansible
とpywinrm
をインストールする。今回はubuntu:14.04のコンテナを使って準備したので以下のような感じ$ sudo docker run -it ubuntu:14.04 # apt-get update && apt-get install -y python-pip python-dev git vim # pip install ansible pywinrm
-
インベントリファイルを作成する。適当なディレクトリに
test-hosts
というファイルを作成し、以下のようにWindows Serverの情報を記述する[windows] 10.0.0.5 # Windows Serverホストの名前/アドレス [windows:vars] ansible_ssh_user=<Windows Serverのユーザ名> ansible_ssh_pass=<Windows Serverのパスワード> ansible_ssh_port=5986 ansible_connection=winrm
-
記述したインベントリを指定し、
win_ping
モジュールを実行する# ansible -i test-hosts -m win_ping all
これで "ping": "pong"
などと出力されればOK。エラーが発生した場合は -vvv
などオプションをつけて処理を追っかけるなどして原因を突き止めます。
AnsibleによりWindows ServerにNXLogをインストール・設定
Ansibleをインストールしたコンテナ内で、リポジトリ https://github.com/yacchin1205/nxlog-ansible をcloneして実行すればOK。
試したのは以下のような流れ。
-
お試しPlaybookをcloneする
# git clone https://github.com/yacchin1205/nxlog-ansible.git
-
インベントリを作成する。
hosts.template
というファイルがリポジトリにあるので、これをベースに・・・# cd nxlog-ansible # cp hosts.template hosts # vim hosts
hosts
を以下のような内容に編集する。この例ではsyslog送信先の情報はインベントリに書いている。[windows] 10.0.0.5 # Windows Serverホストの名前/アドレス [windows:vars] ansible_ssh_user=<Windows Serverのユーザ名> ansible_ssh_pass=<Windows Serverのパスワード> ansible_ssh_port=5986 ansible_connection=winrm # syslogが動作しているホストとポート syslog_host=10.0.0.4 syslog_port=5140
-
Playbookを実行する
# ansible-playbook -i hosts nxlog.yml ... 10.0.0.5 : ok=6 changed=5 unreachable=0 failed=0
こんな感じでfailedなものなく処理が完了すればOK。
動作確認
あとは、Fluentdコンテナの標準出力の内容を見て、Windows Serverのイベントログらしきものが出力されていることを確認。
たとえば、Windows ServerにRDPしようとしたときなどは以下のような感じのログが出力されます。
$ sudo docker ps | grep fluentd
19140d80315a fluent/fluentd:latest "/bin/sh -c 'fluentd 3 minutes ago Up 3 minutes 0.0.0.0:5140->5140/udp, 24224/tcp serene_jang
$ sudo docker logs 19140d80315a
...
2015-08-29 01:27:30 +0000 system.user.info: {"host":"yzwlab-win","ident":"MSWinEventLog","message":"27:29 2015\t131\tMicrosoft-Windows-RemoteDesktopServices-RdpCoreTS\tNETWORK SERVICE\tWell Known Group\tInformation\tyzwlab-win\tRemoteFX module\t\tThe server accepted a new TCP connection from client xxx.xxx.xxx.xxx:yyyy.\t53"}
2015-08-29 01:27:30 +0000 system.user.info: {"host":"yzwlab-win","ident":"MSWinEventLog","message":"27:29 2015\t65\tMicrosoft-Windows-RemoteDesktopServices-RdpCoreTS\tNETWORK SERVICE\tWell Known Group\tInformation\tyzwlab-win\tRemoteFX module\t\tConnection RDP-Tcp#2 created \t54"}
これでFluentd経由でWindows Serverで起きたイベントを追っかけられそう・・・!
実用にはPlaybookのroles/nxlog/templates/nxlog.conf.j2
をいじる必要があるかもしれません。(文字セットとか・・・)
とはいえ、このような流れでWindows Serverのイベントログをsyslogで集約するようAnsibleからまとめて操作、みたいなことができそうでした。ということで。