2024年8月31日土曜日

rsyslogでリモートサーバーのログを集約管理する

大半のLinuxディストリビューションに導入されているrsyslogはリモートサーバーへログを送信したり、受信したりする機能がある。この機能を活用すると、1台のサーバーにてログの集約管理が実現できる。

本記事では、rsyslogでリモートサーバーのログを集約管理する手順を記載する。

環境

今回の環境の構成概要図を以下に記載する。赤枠個所が本記事の設定個所となる。

設定手順はAlmaLinux 9にて確認しているが、他のディストリビューションのrsyslogでも、同じ設定で対応が可能と思われる。

受信側設定

1. ログ保管用ディレクトリの作成

リモートサーバーのログを保管するディレクトリとして、/remotelogを作成する。また、ローテーションしたファイルを保管するディレクトリとして、配下に_oldディレクトリを作成する。

# mkdir /remotelog
# mkdir /remotelog/_old

2. rsyslogの設定

/etc/rsyslog.confの以下個所をアンコメントし、TCP及びUDPにてsyslog受信をできるよう設定する。

/etc/rsyslog.conf

module(load="imudp") # needs to be done just once
input(type="imudp" port="514")

module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514")

次に、受信したsyslogに記載されているホスト名の情報をもとに、個別のファイルを作成する設定をrsyslogに対して行う。

templateにて動的にファイル名を設定するルールを作成し、それをactionDynaFile(動的ファイル名)にて指定することで、リモートサーバーからsyslogを受信すると、自動的に/remotelog/[ホスト名].logというファイルを作成しログが保存される。

なお、ログ集約サーバー自身のログは、通常通り/var/log配下に出力させるため、if文で127.0.0.1のIPアドレスを除外するように設定した。

/etc/rsyslog.d/41-recieve-log.conf

# Template
template(name="TmplRemoteLogFile" type="string"
  string="/remotelog/%HOSTNAME%.log"
)

# Other remote servers
if $fromhost-ip != '127.0.0.1' then {
  action(type="omfile" DynaFile="TmplRemoteLogFile")
  stop
}

3. 設定反映

rsyslogの設定内容に問題がないことを以下コマンドで確認する。-Nオプションはコンフィグチェックのオプションとなる。

# rsyslogd -N 1
rsyslogd: version 8.2310.0-4.el9, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: End of config validation run. Bye.

問題なければrsyslogのサービス再起動を行い、設定を反映させる。

# systemctl restart rsyslog

設定反映後、TCP/514、UDP/514のポートでLISTENされていることを確認しておこう。

# ss -nl | grep 514
udp   UNCONN 0      0            0.0.0.0:514            0.0.0.0:*
udp   UNCONN 0      0            [::]:514               [::]:*
tcp   LISTEN 0      25           0.0.0.0:514            0.0.0.0:*
tcp   LISTEN 0      25           [::]:514               [::]:*

4. logrotateの設定

ファイルを日次でログローテートするよう、以下の通りlogrotateの設定を行う。olddirにてローテーション先のディレクトリを同一ディレクトリから変更している。

/etc/logrotate.d/remotelog

/remotelog/*.log
{
    daily
    rotate 7
    dateext
    compress
    delaycompress
    create 644 root root
    missingok
    olddir=/remotelog/_old
    sharedscripts
    postrotate
        /usr/bin/systemctl -s HUP kill rsyslog.service >/dev/null 2>&1 || true
    endscript
}

送信側設定

1. rsyslogの設定

先ほど設定したrsyslogサーバーにログを送信するため、以下ファイルを作成する。TCP送信とUDP送信で、微妙に記載方法が異なる。syslogというとUDPによる送信というイメージが強いが、ログの欠落が発生しづらい点からTCPによる送信が個人的にはお勧めの設定となる。

/etc/rsyslog.d/40-send-log.conf

TCPで送信する場合

*.* @@[rsyslogサーバーのIPアドレス]:514

UDPで送信する場合。

*.* @[rsyslogサーバーのIPアドレス]:514

2. 設定反映

rsyslogの設定内容に問題がないことを以下コマンドで確認する。-Nオプションはコンフィグチェックのオプションとなる。

# rsyslogd -N 1
rsyslogd: version 8.2310.0-4.el9, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: End of config validation run. Bye.

問題なければrsyslogのサービス再起動を行い、設定を反映させる。

# systemctl restart rsyslog

動作確認

送信元サーバーにてloggerコマンドを実行し、想定通りログが送信させることを確認する。

# logger "test syslog message"

rsyslogサーバーにてログが表示されれば成功となる。

# tail /remotelog/test-server.log
Aug 31 07:29:06 test-server root[605149]: test syslog message

以上で、rsyslogでリモートサーバーのログを集約管理する手順は完了となる。

2024年8月25日日曜日

Splunk本体とUniversal ForwarderをAlmaLinux 9にインストールする手順

自宅環境にてログ集約と解析ができるようにログ管理基盤を作ることにした。ログ解析にはSplunk を利用する方針とした。本記事では、Splunk本体とUniversal ForwarderをAlmaLinux 9にインストールする手順を記載する。

以下は自宅のログ管理基盤の構成概要図となる。赤枠個所が本記事の範囲となる。

環境

環境は以下の通りとなる。Splunk本体とUniversal Forwarderを導入するサーバーは別サーバーとしている。

  • OS : AlmaLinux 9.4
  • Splunk : 9.0.3
  • Splunk Universal Forwarder : 9.0.3

Splunkのインストール

1. Splunkインストーラのダウンロード

Splunkは以下URLからダウンロードできる。ダウンロードするためにはアカウント作成が必要となる。

https://www.splunk.com/ja_jp/download/splunk-enterprise.html

Linux版は、.deb.rpm.tgzの3点が選べるが、個人的お勧めは.tgzとなる。本手順も.tgzによるインストールを記載する。

2. インストール

ダウンロードしたファイル(本手順ではsplunk-9.3.0-51ccf43db5bd-Linux-x86_64.tgzというファイル名となる)をサーバーに配置し、以下コマンドで展開するのみでインストールは完了する。

tar xvzf splunk-9.3.0-51ccf43db5bd-Linux-x86_64.tgz -C /opt

3. Splunkの初回起動と初期設定

/opt/splunk/binディレクトリにSplunk本体の実行ファイルがあるので、以下の通り実行することで、初回起動時の以下処理が実行される。

  • ライセンス条項に同意
  • 管理ユーザ名の設定 (デフォルトはadmin)
  • 管理ユーザのパスワードの設定
# cd /opt/splunk/bin/
# ./splunk start
SPLUNK GENERAL TERMS

Last Updated: August 12, 2021

These Splunk General Terms ("General Terms") between Splunk Inc., a Delaware
corporation, with its principal place of business at 270 Brannan Street, San
Francisco, California 94107, U.S.A ("Splunk" or "we" or "us" or "our") and you
("Customer" or "you" or "your") apply to the purchase of licenses and
subscriptions for Splunk's Offerings. By clicking on the appropriate button,
or by downloading, installing, accessing or using the Offerings, you agree to
these General Terms. If you are entering into these General Terms on behalf of
Customer, you represent that you have the authority to bind Customer. If you
do not agree to these General Terms, or if you are not authorized to accept
the General Terms on behalf of the Customer, do not download, install, access,
or use any of the Offerings.

~(中略)~

Do you agree with this license? [y/n]: y ←★"y"を入力

This appears to be your first time running this version of Splunk.

Splunk software must create an administrator account during startup. Otherwise, you cannot log in.
Create credentials for the administrator account.
Characters do not appear on the screen when you type in credentials.

Please enter an administrator username: admin ←★管理者ユーザ名を入力
Password must contain at least:
   * 8 total printable ASCII character(s).
Please enter a new password:     ←★パスワードを入力
Please confirm new password:     ←★パスワードを再入力
Copying '/opt/splunk/etc/openldap/ldap.conf.default' to '/opt/splunk/etc/openldap/ldap.conf'.

~(中略)~

The Splunk web interface is at http://example:8000

5. 自動起動設定

.tgzファイルを解凍しただけなので、これだけではサーバ再起動時に自動起動してくれないため、コマンドで自動起動するよう設定する。ただし、AlmaLinux 9などのRHEL 9系においてchkconfigパッケージがインストールされていない場合、以下の通りエラーが発生する。

# /opt/splunk/bin/splunk enable boot-start
Can't create RC file "/etc/init.d/splunk": No such file or directory

そのため、chkconfigパッケージがインストールされていない場合はインストールを事前に行っておく。

# dnf install chkconfig -y

chkconfigインストール後、以下の通り実行し、自動起動設定を行う。

# /opt/splunk/bin/splunk enable boot-start
Init script installed at /etc/init.d/splunk.
Init script is configured to run at boot.

試しに再起動を行ったのちステータスを確認したところ、問題なくSplunkが「running」ステータスとなっていた。

# reboot

# uptime
 10:26:23 up 0 min,  1 user,  load average: 0.14, 0.03, 0.01
# /opt/splunk/bin/splunk status
splunkd is running (PID: 1411).
splunk helpers are running (PIDs: 1412 1565 1570 1799 1864).

6. 管理Web画面にアクセス

以上を実施したのち「http://<インストールしたホスト名 or IPアドレス>:8000」にアクセスすると、管理画面が表示されるはずなので、初回起動時に設定した管理者ユーザとパスワードでログインしてみよう。

ログインに成功すると、以下のようなSplunk の管理画面が表示される。

7. Splunk Universal Forwarderからの受信許可設定

管理画面の右上の「設定」 > 「転送と受信」を選択し、「受信の設定」の「+新規追加」ボタンを押しておく。

受信ポートは9997を設定し、「保存」を選択する。

Splunk Universal Forwarderのインストール

1. Splunk Universal Forwarderインストーラのダウンロード

Splunk Universal Forwarderは以下URLからダウンロードできる。ダウンロードするためにはアカウント作成が必要となる。

https://www.splunk.com/ja_jp/download/universal-forwarder.html

Linux版は、.deb.rpm.tgzの3点が選べるが、個人的お勧めは.tgzとなる。本手順も.tgzによるインストールを記載する。

2. インストール

ダウンロードしたファイル(本手順ではsplunkforwarder-9.3.0-51ccf43db5bd-Linux-x86_64.tgzというファイル名となる)をサーバーに配置し、以下コマンドで展開するのみでインストールは完了する。

# tar xvzf splunkforwarder-9.3.0-51ccf43db5bd-Linux-x86_64.tgz -C /opt/

3. Splunkの初回起動と初期設定

/opt/splunk/binディレクトリにSplunk本体の実行ファイルがあるので、以下の通り実行することで、初回起動時の以下処理が実行される。

  • ライセンス条項に同意
  • 管理ユーザ名の設定 (デフォルトはadmin)
  • 管理ユーザのパスワードの設定
# cd /opt/splunkforwarder/bin/
# ./splunk start
SPLUNK GENERAL TERMS

Last Updated: August 12, 2021

These Splunk General Terms ("General Terms") between Splunk Inc., a Delaware
corporation, with its principal place of business at 270 Brannan Street, San
Francisco, California 94107, U.S.A ("Splunk" or "we" or "us" or "our") and you
("Customer" or "you" or "your") apply to the purchase of licenses and
subscriptions for Splunk's Offerings. By clicking on the appropriate button,
or by downloading, installing, accessing or using the Offerings, you agree to
these General Terms. If you are entering into these General Terms on behalf of
Customer, you represent that you have the authority to bind Customer. If you
do not agree to these General Terms, or if you are not authorized to accept
the General Terms on behalf of the Customer, do not download, install, access,
or use any of the Offerings.

~(中略)~

Do you agree with this license? [y/n]: y ←★"y"を入力

This appears to be your first time running this version of Splunk.

Splunk software must create an administrator account during startup. Otherwise, you cannot log in.
Create credentials for the administrator account.
Characters do not appear on the screen when you type in credentials.

Please enter an administrator username: admin ←★管理者ユーザ名を入力
Password must contain at least:
   * 8 total printable ASCII character(s).
Please enter a new password:      ←★パスワードを入力
Please confirm new password:      ←★パスワードを再入力
Creating unit file...
Initd script /etc/init.d/splunk exists. splunk is currently enabled as init.d bootstart service.
Please run "splunk disable boot-start" first to disable it as init.d boot-start service
Failed to create the unit file. Please do it manually later.

~(中略)~

All preliminary checks passed.

Starting splunk server daemon (splunkd)...  
PYTHONHTTPSVERIFY is set to 0 in splunk-launch.conf disabling certificate validation for the httplib and urllib libraries shipped with the embedded Python interpreter; must be set to "1" for increased security
Done

5. 自動起動設定

.tgzファイルを解凍しただけなので、これだけではサーバ再起動時に自動起動してくれないため、コマンドで自動起動するよう設定する。Splunk本体と異なり、-user rootによる起動時の実行ユーザー指定が必要であり、かつsystemdによる登録となっており、chkconfigパッケージの導入は不要となる。

# /opt/splunkforwarder/bin/splunk stop
# /opt/splunkforwarder/bin/splunk enable boot-start -user root
Systemd unit file installed by user at /etc/systemd/system/SplunkForwarder.service.
Configured as systemd managed service.
# systemctl status SplunkForwarder
○ SplunkForwarder.service - Systemd service file for Splunk, generated by 'splunk enable boot-start'
     Loaded: loaded (/etc/systemd/system/SplunkForwarder.service; enabled; preset: disabled)
     Active: inactive (dead)
# systemctl start SplunkForwarder

6. 送信先のサーバ (インデクサー) を設定

Splunkのログ受信および解析を行う機能を「インデクサー」と呼ぶ。Universal Forwarderのログ送信先としてインデクサーを指定する必要があるため、splunk add forward-server <インデクサーのIPアドレス or ホスト名>:<ポート番号>コマンドにて行う。

# cd /opt/splunkforwarder/bin/
# ./splunk add forward-server 192.168.1.1:9997
Splunk username: admin
Password:
Added forwarding to: 192.168.1.1:9997.
# ./splunk list forward-server
Active forwards:
        None
Configured but inactive forwards:
        192.168.1.1:9997

本設定は、/opt/splunkforwarder/etc/system/local/outputs.confに記述される。

# cat /opt/splunkforwarder/etc/system/local/outputs.conf
[tcpout]
defaultGroup = default-autolb-group

[tcpout:default-autolb-group]
server = 192.168.1.1:9997

[tcpout-server://192.168.1.1:9997]

7. モニター対象のログを追加

今回は例として/var/log配下のログをすべて監視対象として、Splunk本体のインデクサーに送信する。splunk add monitor <モニター対象のファイル or ディレクトリ>コマンドで設定する。なお、本設定は再起動は不要で反映される。

# cd /opt/splunkforwarder/bin/
# ./splunk add monitor /var/log
Added monitor of '/var/log'.

splunk list monitorで設定確認を行う。ディレクトリが登録され、ディレクトリ内の各ファイルが表示されていれば問題ない。

# ./splunk list monitor
Monitored Directories:
	$SPLUNK_HOME/var/log/splunk
		/opt/splunkforwarder/var/log/splunk/audit.log
		/opt/splunkforwarder/var/log/splunk/btool.log
		/opt/splunkforwarder/var/log/splunk/conf.log

~(中略)~
	$SPLUNK_HOME/var/run/splunk/search_telemetry/*search_telemetry.json
	$SPLUNK_HOME/var/spool/splunk/tracker.log*
		/opt/splunkforwarder/var/spool/splunk/tracker.log
	/var/log ←★/var/log配下のログが追加されている。
		/var/log/anaconda
		/var/log/anaconda/anaconda.log
		/var/log/anaconda/dbus.log

~(以下略)~

8. 受信確認

Splunkにログインし「Search & Reporting」にて、index=*にてサーチを行い、ログが表示されることを確認しよう。

以上で、Splunk本体とUniversal ForwarderをAlmaLinux 9にインストールする手順は完了となる。

2024年8月11日日曜日

OpenAI APIを使ってZabbixの障害イベントを生成AIに連携する

ChatGPTでおなじみのOpenAIは、OpenAI APIと呼ばれるAPIによる利用が可能となっている。APIを利用することで、curlコマンドなどを用いて手軽に生成AIの機能をシステムに組み込んで利用することができる。

本記事では、OpenAI APIを使ってZabbixの障害アラートを生成AIに連携する手順を記載する。

具体的には、OpenAI APIを用いて以下のプロンプトを連携し、Zabbixの障害アラートの原因の問い合わせを行う。問い合わせで得られた生成AIの応答をZabbixのメッセージとして表示できるようにする。

Please tell me the cause of the error message below.
[障害アラートの内容]

なお、本記事の作成にあたり、以下の記事も参考にさせていただいた。

環境

今回の環境は以下の通り。

  • Zabbix 7.0

OpenAIのアカウントを作成していない場合は、事前に作成をしておこう。ChatGPTを利用している場合は、すでにアカウント作成済みとなるため、新たにアカウント作成は不要となる。

OpenAI APIのAPI keyを取得

1. OpenAI API keyの作成画面にログイン

以下URLにアクセスすると、OpenAI API keyの作成画面が表示される。

2. API keyを作成

「Create new secret key」ボタンを押し、API keyを作成する。

作成時にkeyの名前の入力を求められるが、未入力でも問題ない。

作成完了後、API keyが表示されるので、必ずコピーして控えること。ここでコピーしておかないと、以降確認することができないため、API keyを再作成する必要がある。

3. OpenAI APIの利用状況を確認

OpenAI APIはリクエストや応答に含まれるトークンの数によって課金される。トークンは英語の場合は1単語がおおよそ1トークンとなるようだが、日本語の場合は1文字が1トークン以上の場合があるとの情報があるので注意する。

トークンの使用状況は以下URLから確認することができる。

なお、アカウントを新規作成した際は、5.00 USD分の無料利用枠がある(3か月の期限付き)。テストする際にかなりAPIを使用してみたが、それでも0.03 USDしか消費しなかったので、5.00 USDあれば検証用途としては十分だろう。

OpenAI API連携用スクリプトの作成

1. curlによるOpenAI API実行方法

curlを使う場合は以下の通り実行すればOpenAI APIによる問い合わせができる。

# API keyを設定
export OPENAI_API_KEY='sk-********'

header='Content-Type: application/json'
apiurl='https://api.openai.com/v1/chat/completions'
prompt="ここに問い合わせしたい内容を記載。"
json='{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "'${prompt}'"}]}'

# API実行
curl ${apiurl} -sS -H "Authorization: Bearer ${OPENAI_API_KEY}" -H "${header}" -d "${json}"

実行結果は以下の通り。.choices[0].message.contentがAIの回答となる。

# curl ${apiurl} -sS -H "Authorization: Bearer ${OPENAI_API_KEY}" -H "${header}" -d "${json}"
{
  "id": "chatcmpl-xxxxxxxx",
  "object": "chat.completion",
  "created": 1723324974,
  "model": "gpt-4o-mini-2024-07-18",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "もちろんです!問い合わせ内容をお知らせいただければ、適切な回答やアドバイスをお伝えいたします。どのようなことについてお尋ねですか?",
        "refusal": null
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 17,
    "completion_tokens": 40,
    "total_tokens": 57
  },
  "system_fingerprint": "fp_48196bc67a"
}

2. スクリプト作成

curlによるOpenAI APIの実行方法を用いて、Zabbixの障害アラートを連携するスクリプトを以下の通り作成した。各環境に合わせて、OpenAIのAPI keyやZabbix API実行用のユーザとパスワードを設定すること。

障害アラートへのメッセージ追加はZabbix APIを使用する。Zabbix APIの使い方は、以下別記事を参考にしていただきたい。

また、OpenAI APIで同時に多数のリクエストを実行すると、応答がうまく得られずnullが返ってくる場合があったため、負荷分散を目的として、実行間隔制御の待機時間(最小10秒~最大120秒)を設定した。

send_chatgpt_api.sh

#!/bin/bash

# アラート内容を引数に代入
eventid=$1
alert=$(echo $2 | sed -e 's/"/\\"/g')

# 実行間隔制御 (10秒+ランダム時間)
sleep $(( 10 + ($RANDOM % 110) ))

# API keyを設定
export OPENAI_API_KEY='sk-********'

# モデルを選択
#model="gpt-3.5-turbo"
model="gpt-4o-mini"

header='Content-Type: application/json'
apiurl='https://api.openai.com/v1/chat/completions'
prompt="Zabbixで検知した以下イベントメッセージの原因及び解消方法を簡潔に教えてください。\n\n${alert}"
json='{"model": "'${model}'", "messages": [{"role": "user", "content": "'${prompt}'"}]}'

# API実行
result=$(curl ${apiurl} -sS -H "Authorization: Bearer ${OPENAI_API_KEY}" -H "${header}" -d "${json}")

# 出力
result_message=$(echo $result | jq -r '.choices[0].message.content')

# Zabbix APIログイン
header='Content-Type:application/json-rpc'
apiurl='http://[ZabbixサーバのURL]/zabbix/api_jsonrpc.php'
json='{"jsonrpc": "2.0","method": "user.login","params": {"username": "Admin","password": "********"},"id": 1,"auth": null}'
zbxauth=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r ".result")

# Zabbix APIでイベントにメッセージ追加
json='{"jsonrpc": "2.0","method": "event.acknowledge","params": {"eventids": "'${eventid}'","action": 4,"message": "'$(echo ${result_message} | sed -e 's/"/\\"/g')'"},"auth": "'${zbxauth}'","id": 1}'
curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq

# Zabbix APIログオフ
json='{"jsonrpc": "2.0","method": "user.logout","params": [],"id": 4,"auth": "'$zbxauth'"}'
curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq

exit 0

3. スクリプトをZabbixサーバに配置

本スクリプトは、Zabbixサーバの/usr/local/binに配置し、実行権限を付与しておく。

# cp send_chatgpt_api.sh /usr/local/bin/
# chmod +x /usr/local/bin/send_chatgpt_api.sh
# ls -l /usr/local/bin/send_chatgpt_api.sh
-rwxr-xr-x 1 root root 1753  9月 23 07:41 /usr/local/bin/send_chatgpt_api.sh

実行方法は以下の通りとなる。

/usr/local/bin/send_chatgpt_api.sh '[イベントID]' '[アラート内容]'

Zabbixのトリガーアクションを設定

1. スクリプト設定

Zabbixのスクリプト設定を以下の通り行う。

設定項目 設定値
名前 Send ChatGPT
タイプ スクリプト
次で実行 Zabbixサーバー
コマンド /usr/local/bin/send_chatgpt_api.sh '{EVENT.ID}' '{ITEM.VALUE}'

2. トリガーアクション設定

Zabbixのトリガーアクション設定を以下の通り行う。今回は、「軽度の障害」以上の場合にスクリプトを実行するよう設定する。

設定項目 設定値
名前 Send ChatGPT
実行条件 「メンテナンス期間外」 AND 「トリガーの深刻度 以上 軽度の障害」

アクションの実行内容は以下の通り、先ほど作成したスクリプトを指定する。

設定項目 設定値
処理内容 Send ChatGPT
ターゲットリスト Zabbix server

動作確認

実際に障害アラートを発生させて、動作を確認してみよう。

例として、以下の障害アラートを発生させてみた。ポートチャネルPo1からgi3が除外されたアラートとなる。

SNMP Trap from t1250c250 : 2024/02/10 15:11:26. .1.3.6.1.4.1.9.6.1.101.0.161 
Normal General event UNKNOWN - %TRUNK-W-PORTREMOVED: Port gi3 removed from Po1 1

しばらくするとスクリプトが実行され、以下の通りOpenAI APIで取得した生成AIの回答がメッセージとして表示された。

このイベントメッセージの原因は、ポートgi3がPo1 1から削除されたことです。 
解決方法は、次のいずれかです。

  1. ネットワーク上でポートを再接続し、Po1 1にgi3を再度追加します。
  2. システムの設定を確認し、ポートが正しく構成されていることを確認します。
  3. 他のネットワークデバイスとの接続に問題がある場合は、接続を確認し、
     必要に応じて修正します。

これらの手順を実行することで、問題が解決する可能性があります。
ただし、具体的な状況に応じて解決方法が異なる場合もあるため、
詳細な情報があれば助かります。

以上で、OpenAI APIを使ってZabbixの障害アラートを生成AIに連携する手順は完了となる。

参考

更新履歴

  • 2023/9/23 新規作成
  • 2024/2/10 OpenAI APIに送るプロンプトを日本語に変更
  • 2024/6/24 send_chatgpt_api.shをZabbix 7.0に対応するように修正
  • 2024/8/11 生成AIモデルをgpt-3.5-turboからgpt-4o-miniに変更
2024年7月26日金曜日

Windows Serverの設定情報を一括取得するスクリプト

先日、Linuxの設定情報を1つのテキストファイルに出力するスクリプトを作成した。

Linuxに引き続き、今回はWindows Serverの設定情報を1つのテキストファイルに出力し、一括取得するスクリプトを作ってみた。このスクリプトを使うことで、Windows Serverの設定に関しても、ネットワーク機器のように設定変更時の差分をdiffツールにて比較をできるようにする。

環境

本スクリプトの動作確認をしたOSは以下の通り。

  • OS : Windows Server 2022 または 2019
  • 実行シェル : PowerShell 5.1

Windows Server設定項目一覧

本スクリプトで取得する設定項目は以下となる。

取得設定項目 取得設定内容
ホスト名・OSバージョン情報 OSのバージョン、カーネル番号、稼働時間など
ハードウェア情報 CPUのコアやソケット数、メモリ容量、PCIデバイス一覧
OS基本設定 Get-ComputerInfoで取得できる情報取得とページングファイルのサイズ設定
ネットワーク設定 各種ネットワーク関連設定。DNSやhostsファイルの設定を含む
ディスク設定 各種ディスク情報
光学ドライブ設定 CD/DVDドライブ情報
ユーザ・グループ設定 ローカルユーザー一覧、ローカルグループ一覧
リモートデスクトップ設定 リモートデスクトップに関する設定
時刻設定 タイムゾーン設定、時刻同期 (w32tm) に関する設定
OS言語設定 使用している言語
サービス設定 サービス一覧
役割・機能 Windowsの役割・機能の一覧
更新プログラム 適用済み更新プログラムの一覧
インストールソフトウェア インストールソフトウェア一覧
PowerShellモジュール インストール済みPowerShellモジュールの一覧
イベントビューアー イベントビューアーの設定情報。セキュリティイベントログの設定情報取得の際は管理者で実行が必要
Windows Defenderファイアウォール Windows Defenderファイアウォールの設定・ルール一覧

上記は一般的なWindows Serverの設定項目となっている。追加した役割・機能に応じて、適宜情報取得コマンドを追加するといったカスタマイズが必要となる。

スクリプト

今回作成したスクリプトはGitHubに置いてあるので、そちらを参照いただきたい。なお。Gitからダウンロードした際は文字コードがUTF-8になるため、Shift JISに変換して保存しなおしてから実行すること。

スクリプトには以下の関数を用意しており、効率よく設定値を取得できるようにしている。以下に関数の動作概要を記載する。

関数名 内容
show_title 取得対象の設定項目のタイトルを表示
get_command コマンドを実行して、その結果を取得
get_command_bat コマンドを実行して、その結果を取得(コマンドプロンプト用)
get_config 設定ファイルからコメント(#から始まる行)及び空行を削除して内容を取得

使い方

任意のディレクトリに配置したのち、PowerShellを「管理者として実行」で開き、配置ディレクトリに移動する。あとは以下の通り実行すれば情報取得が開始する。実行時間は環境にもよるが、10秒程度もあれば終了する。

PS> .\get_windows_config.ps1

なお本スクリプトは、PowerShellを「管理者として実行」せずとも、Administrators権限があればほとんどの情報取得には成功するよう作ってある。
※セキュリティイベントログの設定情報のみ取得に失敗する。

同じディレクトリ内に以下のファイル名でログが出力される。

[ホスト名]_config_[yyyyMMdd-HHmmss].log

情報取得結果のサンプル

以下に取得とした設定情報を例として記載する。
Start-Transcriptのヘッダーは省略している。

コマンドによる情報取得の場合は(command)# [実行コマンド]または(command_bat)# [実行コマンド]、設定ファイルの情報取得の場合は(config)# [ファイルのフルパス]と表示することで、どのように情報取得をしたかわかるようにしている。

################################
ホスト名・OSバージョン情報
################################

(command_bat)# cmd /C 'hostname'
WIN-K7OLL2H57TT

(command_bat)# cmd /C 'whoami.exe /user'

USER INFORMATION
----------------

User Name     SID
============================= =============================================
win-k7oll2h57tt\administrator S-1-5-21-3230081072-2687372604-3793060616-500


(command)# Get-WmiObject Win32_OperatingSystem | Select-Object Caption, OSArchitecture, Version, CodeSet, CountryCode, LastBootUpTime

Caption                                           OSArchitecture Version    CodeSet CountryCode LastBootUpTime
-------                                           -------------- -------    ------- ----------- --------------
Microsoft Windows Server 2022 Standard Evaluation 64 ビット         10.0.20348 932     81          20220516063525.500000+540

~(中略)~

################################
ディスク設定
################################

(command)# Get-Disk

Number Friendly Name       Serial Number                    HealthStatus OperationalStatus Total Size Partition Style
------ -------------       -------------                    ------------ ----------------- ---------- ---------------
0      VMware Virtual disk 6000c29703b80e9e48cca37b8d165c0b Healthy      Online                 80 GB GPT


(command)# Get-WmiObject Win32_DiskDrive | Select-Object Index, DeviceID, Model, @{N='SizeGB'; E={[Math]::Round($_.Size/1GB, 2)}}, Partitions | sort Index

Index DeviceID           Model                                SizeGB Partitions
----- --------           -----                                ------ ----------
    0 \\.\PHYSICALDRIVE0 VMware Virtual disk SCSI Disk Device     80          3


(command)# Get-WmiObject Win32_DiskPartition | Select-Object DiskIndex, Index, Name, BlockSize, Bootable, @{N='SizeGB'; E={[Math]::Round($_.Size/1GB, 2)}}, Type, Description | sort DiskIndex, Index

DiskIndex Index Name                BlockSize Bootable SizeGB Type            Description
--------- ----- ----                --------- -------- ------ ----            -----------
        0     0 ディスク #0, パーティション #0       512     True    0.1 GPT: System     GPT: システム
        0     1 ディスク #0, パーティション #1       512    False   79.3 GPT: Basic Data GPT: ベーシック データ
        0     2 ディスク #0, パーティション #2       512    False   0.58 GPT: Unknown    GPT: 不明

~(以下略)~

以上。

更新履歴

  • 2022/5/28 新規作成
  • 2024/7/26 スクリプトの文字コードをShift JISにする旨を追記

2024年7月15日月曜日

PostgreSQLのログ出力先と保管期間を設定する

PostgreSQLのデフォルト設定では、ログファイル/var/lib/pgsql/data/log/に、曜日単位で出力される。

# ls -l /var/lib/pgsql/data/log/
-rw-------. 1 postgres postgres    0  7月  5 00:00 postgresql-Fri.log
-rw-------. 1 postgres postgres    0  7月  8 00:00 postgresql-Mon.log
-rw-------. 1 postgres postgres    0  7月  6 00:00 postgresql-Sat.log
-rw-------. 1 postgres postgres    0  7月  7 00:00 postgresql-Sun.log
-rw-------. 1 postgres postgres    0  7月  4 00:00 postgresql-Thu.log
-rw-------. 1 postgres postgres    0  7月  9 00:00 postgresql-Tue.log
-rw-------. 1 postgres postgres 4943  7月 10 15:52 postgresql-Wed.log

デフォルト設定では、ログが1週間分しか保管されずログが上書きされてしまうことや、そもそもLinuxの標準のログ出力先である/var/log/ディレクトリに出力されていないことなど、管理面で問題がある。

そこで本記事では、PostgreSQLのログ出力設定を変更し、ログの出力先と保管期間の設定変更を行う。出力手順は大きく2つの方法があるため、両方の設定手順を記載する。

  • syslog経由で出力する方法
  • stderr経由で出力する方法 (デフォルト)

環境

  • OS : AlmaLinux 9.4
  • PostgreSQL : 13.14

ログ出力設定手順① (syslog)

1. ログ出力先のディレクトリを作成

ログ出力先のディレクトリを作成する。今回は、/var/log/postgresql/とした。

# mkdir /var/log/postgresql
# chown postgres:postgres /var/log/postgresql

# ls -ld /var/log/postgresql/
drwxr-xr-x. 2 postgres postgres 6  7月 14 17:24 /var/log/postgresql/

2. postgresql.confを修正

ログ出力先や出力時のファイル名を変更するため、postgresql.confを修正する。syslogのファシリティは任意でよいが、本記事ではlocal3を指定した。

# vi /var/lib/pgsql/data/postgresql.conf
------------------------------
# ログの出力先をsyslogに変更
#log_destination = 'stderr'
↓
log_destination = 'syslog'

# ログファイルのフォーマットをpostgresql.logに変更
log_filename = 'postgresql-%a.log'
   ↓
log_filename = 'postgresql.log'

# syslogの各種設定を追加
#syslog_facility = 'LOCAL0'
#syslog_ident = 'postgres'
#syslog_sequence_numbers = on
#syslog_split_messages = on
   ↓
syslog_facility = 'LOCAL3'
syslog_ident = 'postgres'
syslog_sequence_numbers = on
syslog_split_messages = on

3. rsyslog設定

PostgreSQLが出力したsyslogをログファイルに出力するよう、rsyslogの設定を行う。

rsyslog.confに以下行を追記する。先ほどのPostgreSQLの設定と合わせて、ファシリティはlocal3を指定する。

# vi /etc/rsyslog.conf
------------------------------
# Log PostgreSQL
local3.*                                                /var/log/postgres/postgres.log

4. 反映

設定を反映させるため、rsyslogとPostgreSQLを再起動する。

systemctl restart rsyslog
systemctl restart postgresql

PostgreSQLの再起動時にログが出力されていることを確認しておこう。

# cat /var/log/postgres/postgres.log
Jul 15 06:49:20 t1023zabi postgres[1540934]: [1-1] 2024-07-15 06:49:20.312 JST [1540934] LOG:  ログ出力をログ収集プロセスにリダイレクトしています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [1-2] 2024-07-15 06:49:20.312 JST [1540934] ヒント:  ここからのログ出力はディレクトリ"/var/log/postgresql"に現れます。
Jul 15 06:49:20 t1023zabi postgres[1540934]: [2-1] 2024-07-15 06:49:20.312 JST [1540934] LOG:  標準エラー出力へのログ出力を終了しています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [2-2] 2024-07-15 06:49:20.312 JST [1540934] ヒント:  この後のログ出力はログ配送先"syslog"に出力されます。
Jul 15 06:49:20 t1023zabi postgres[1540934]: [3-1] 2024-07-15 06:49:20.312 JST [1540934] LOG:  PostgreSQL 13.14 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 11.4.1 20230605 (Red Hat 11.4.1-2), 64-bit を起動しています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [4-1] 2024-07-15 06:49:20.312 JST [1540934] LOG:  IPv6アドレス"::1"、ポート5432で待ち受けています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [5-1] 2024-07-15 06:49:20.312 JST [1540934] LOG:  IPv4アドレス"127.0.0.1"、ポート5432で待ち受けています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [6-1] 2024-07-15 06:49:20.313 JST [1540934] LOG:  Unixソケット"/var/run/postgresql/.s.PGSQL.5432"で待ち受けています
Jul 15 06:49:20 t1023zabi postgres[1540934]: [7-1] 2024-07-15 06:49:20.313 JST [1540934] LOG:  Unixソケット"/tmp/.s.PGSQL.5432"で待ち受けています
Jul 15 06:49:20 t1023zabi postgres[1540936]: [8-1] 2024-07-15 06:49:20.315 JST [1540936] LOG:  データベースシステムは 2024-07-15 06:49:20 JST にシャットダウンしました
Jul 15 06:49:20 t1023zabi postgres[1540934]: [8-1] 2024-07-15 06:49:20.317 JST [1540934] LOG:  データベースシステムの接続受け付け準備が整いました

5. logrotate設定

出力されたログに対してlogrotateの機能を用いてログローテートするよう設定する。

今回は、毎日ログローテートを行い31日間保管する設定とした。容量削減のため、翌々日のログから圧縮する設定としている。また、ログファイルの切り替わり時にログを正常に出力できるよう、ログローテート時にrsyslogサービスのリロード(kill -HUP)を設定した。

# vi /etc/logrotate.d/postgresql
------------------------------
/var/log/postgresql/*.log {
  daily
  rotate 31
  dateext
  compress
  delaycompress
  create 644 postgres postgres
  missingok
  sharedscripts
  postrotate
    /usr/bin/systemctl -s HUP kill rsyslog.service >/dev/null 2>&1 || true
  endscript
}

以上で、syslogを用いたPostgreSQLのログ出力設定手順は完了となる。

ログ出力設定手順② (stderr出力パターン)

1. ログ出力先のディレクトリを作成

ログ出力先のディレクトリを作成する。今回は、/var/log/postgresql/とした。

# mkdir /var/log/postgresql
# chown postgres:postgres /var/log/postgresql

# ls -ld /var/log/postgresql/
drwxr-xr-x. 2 postgres postgres 6  7月 14 17:24 /var/log/postgresql/

2. postgresql.confを修正

ログ出力先や出力時のファイル名を変更するため、postgresql.confを修正する。

# vi /var/lib/pgsql/data/postgresql.conf
------------------------------
# ログディレクトリを/var/log/postgresql/に変更
#log_directory = 'log'
   ↓
log_directory = '/var/log/postgresql'

# ログファイルのフォーマットをpostgresql.logに変更
log_filename = 'postgresql-%a.log'
   ↓
log_filename = 'postgresql.log'

# PostgreSQLの機能のログローテーションを無効化
log_rotation_age = 1d
   ↓
log_rotation_age = 0

3. 設定反映

PostgreSQLを再起動して、設定反映を行う。

# systemctl restart postgresql

PostgreSQLの再起動時に起動ログが出力されるので、問題なく新しいディレクトリでファイルに出力されていることを確認しておこう。

# ls -l /var/log/postgresql/
-rw-------. 1 postgres postgres 893  7月 14 17:27 postgresql-20240714.log

# cat /var/log/postgresql/postgresql-20240714.log
2024-07-14 17:27:47.517 JST [1507397] LOG:  PostgreSQL 13.14 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 11.4.1 20230605 (Red Hat 11.4.1-2), 64-bit を起動しています
2024-07-14 17:27:47.517 JST [1507397] LOG:  IPv6アドレス"::1"、ポート5432で待ち受けています
2024-07-14 17:27:47.517 JST [1507397] LOG:  IPv4アドレス"127.0.0.1"、ポート5432で待ち受けています
2024-07-14 17:27:47.518 JST [1507397] LOG:  Unixソケット"/var/run/postgresql/.s.PGSQL.5432"で待ち受けています
2024-07-14 17:27:47.518 JST [1507397] LOG:  Unixソケット"/tmp/.s.PGSQL.5432"で待ち受けています
2024-07-14 17:27:47.519 JST [1507399] LOG:  データベースシステムは 2024-07-14 17:27:47 JST にシャットダウンしました
2024-07-14 17:27:47.522 JST [1507397] LOG:  データベースシステムの接続受け付け準備が整いました

4. logrotate設定

PostgreSQLはログローテート機能はあるが、保管期間を超えたログを削除する機能がないため、logrotateの機能を用いてログローテートを実装する。

今回は、毎日ログローテートを行い31日間保管する設定とした。容量削減のため、翌々日のログから圧縮する設定としている。また、ログファイルの切り替わり時にログを正常に出力できるよう、copytruncateオプションを設定している。

# vi /etc/logrotate.d/postgresql
------------------------------
/var/log/postgresql/*.log {
  daily
  rotate 31
  dateext
  compress
  delaycompress
  create 0640 postgres postgres
  missingok
  copytruncate
}

以上で、stderrを用いたPostgreSQLのログ出力設定手順は完了となる。

参考

人気の投稿