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のログ出力設定手順は完了となる。

参考

2024年6月30日日曜日

Zabbix APIを使って未クローズの障害イベントをクローズする

Zabbixではトリガーによって検知した障害は、復旧条件を満たさなければクローズされることはなく、いつまでも障害として残り続けてしまう。

Zabbix 4.0以降では、管理画面から手動による障害のクローズができるようになったため、復旧条件の記載が難しいログ監視やSNMP Trap監視などにおいても、クローズができるようになりかなり便利になった。

とはいえ、大量の監視対象がある環境においては、障害のクローズを手作業で実施すること自体が負荷となるケースが存在すると考えられるため、今回はZabbix APIを使って未クローズの障害イベントを一気にクローズする手順を検証した。

環境

環境は以下の通りZabbix 5.0を使用している。ただし、Zabbix 4.0以降でも利用できることを確認するため、Zabbix APIのマニュアルはZabbix 4.0のものを確認して検証を行った。

  • OS : CentOS 8.1
  • Zabbix : 5.0.8
  • APIのURL : http://192.168.11.24/zabbix/api_jsonrpc.php

Zabbix APIを使用する際に、jqコマンドが必要となるため、事前にインストールをしておく。jqコマンドは、Zabbix APIやREST APIなどで利用されているJSON形式のデータを整形して出力したり、必要なデータのみ抽出するのに利用するコマンドとなる。

# dnf install epel-release
# dnf install jq

手順

Zabbix APIを実行する際に送信するJSON形式のデータは、以下構文となる。

{
  "jsonrpc": "2.0",
  "method": "メソッド名",
  "params": {
    "パラメータ1 Key": "パラメータ1 Value",
    "パラメータ2 Key": "パラメータ2 Value",
    ...
  },
  "auth": "Zabbix認証トークン",
  "id": 任意の数字
}

以降の手順では、上記構文の送信データを作成したのち、curlコマンドでそのデータを送信してAPIを実行する、という流れとなる。

また、Zabbix APIのURLやヘッダ情報などは、毎回同一となることから、あらかじめ変数として利用できるようにしておこう。

# header='Content-Type:application/json-rpc'
# apiurl='http://192.168.11.24/zabbix/api_jsonrpc.php'

1. Zabbix APIの認証トークンを取得

Zabbix APIの実行は、認証トークンが必要となる。認証トークンは、user.loginメソッドで取得できる。Zabbixの管理者権限を持つユーザとパスワードを指定して、以下のようにAPIを実行するためのデータを作成する。

# json='{"jsonrpc": "2.0","method": "user.login","params": {"username": "Admin","password": "XXXXXXXX"},"id": 1,"auth": null}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "user.login",
  "params": {
    "user": "Admin",
    "password": "XXXXXXXX"
  },
  "id": 1,
  "auth": null
}

認証トークンは、以降の作業で常に指定して利用することから、実行結果を変数$zbxauthに代入しておく。

# zbxauth=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r ".result")
# echo $zbxauth
e2519a6fbc680a87affc8382b65cdcb7

2. 未クローズの障害イベントを取得

障害イベントのクローズには、eventidが必要となる。problem.getメソッドを使うことで一覧として取得できるので、以下の通り送信データを作成する。
※Zabbix 6.0ではoutputeventidを指定しても動作していたが、Zabbix 7.0では動作しなくなったため、extendを指定する必要がある。

# json='{"jsonrpc": "2.0","method": "problem.get","params": {"output": "extend"},"id": 3,"auth": "'$zbxauth'"}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "problem.get",
  "params": {
    "output": "extend"
  },
  "id": 3,
  "auth": "e2519a6fbc680a87affc8382b65cdcb7"
}

取得したeventidは、次の手順で配列として利用できるようにするため、jqコマンドを使って出力結果を整形して変数$eventidsに格納する。以下コマンドの実行例では、6件の障害イベントが対象となる。

# eventids=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -c '[ .result[].eventid ]')
# echo $eventids
["34308","50073","50875","50876","50877","50954"]

3. 障害イベントを手動クローズ

イベントに対する捜査はevent.acknowledgeメソッドを使う。event.acknowledgeメソッドでは、イベントに対して実行する処理をactionにて指定するが、その際に指定できる値は以下の通りとなる。

  • 1 - close problem;
  • 2 - acknowledge event;
  • 4 - add message;
  • 8 - change severity.

上記は組み合わせることが可能であり、今回は「1 : 障害のクローズ」と「4 : メッセージ追加」の2つを同時に実行するため、actionを1 + 4 = 5で指定する。

# json='{"jsonrpc": "2.0", "method": "event.acknowledge", "params": {"eventids": '$eventids', "action": 5, "message": "Closed problem by API"}, "auth": "'$zbxauth'", "id": 1}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "event.acknowledge",
  "params": {
    "eventids": [
      "34308",
      "50073",
      "50875",
      "50876",
      "50877",
      "50954"
    ],
    "action": 5,
    "message": "Closed problem by API"
  },
  "auth": "e2519a6fbc680a87affc8382b65cdcb7",
  "id": 1
}

障害イベントのクローズ前に、GUI上でも障害一覧を確認しておく。1件はホストを無効化しているため障害が表示されていないが、GUI上では5件の障害が表示されている。後ほど、API実行後に赤枠で示したアラートがクローズされることを確認する。

curlにてAPIを実行する。resultに処理を実行したイベントIDの一覧が表示されればOKとなる。

# curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
{
  "jsonrpc": "2.0",
  "result": {
    "eventids": [
      34308,
      50073,
      50875,
      50876,
      50877,
      50954
    ]
  },
  "id": 1
}

GUI上にて再度障害一覧を確認すると、すべての障害がクローズされ、一覧から消えていることが確認できた。

また、クローズされたイベントを確認すると、APIで指定した「Closed problem by API」のメッセージとともに、ステータスが「解決済」になっていることが確認できた。

4. Zabbix APIの認証トークンを削除

最後に認証トークンを削除するため、user.logoutメソッドを使用する。

# json='{"jsonrpc": "2.0","method": "user.logout","params": [],"id": 4,"auth": "'$zbxauth'"}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "user.logout",
  "params": [],
  "id": 4,
  "auth": "e2519a6fbc680a87affc8382b65cdcb7"
}

curlにてAPIを実行し、resulttrueであれば、認証トークンの削除が正常に実施されている。

# curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
{
  "jsonrpc": "2.0",
  "result": true,
  "id": 4
}

スクリプト化してみる

クローズ処理を定期的に実行できるようclose_zabbix_problem.shという名前のスクリプトを作成し、cronに登録して定期的に古い障害イベントをクローズできるようにしてみた。

7日前の未分類、情報、警告ステータスのイベントをクローズする処理となり、クローズする対象を限定するため、イベントID取得時に、time_tillseveritiesといったパラメータを指定している。

#!/bin/bash

# クローズ対象の日付
clode_date=$(date +%s --date '7 day ago')
close_message="Closed problem by API"

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

# イベント一覧(未解決の障害、指定日以前のもの、未分類・情報・警告イベント)を取得
json='{"jsonrpc": "2.0","method": "problem.get","params": {"output": "extend","time_till": '${clode_date}',"severities": [0,1,2]},"auth": "'${zbxauth}'","id": 1}'
eventids=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r '.result[].eventid' | tr '\n' ' ')

# Zabbix APIでイベントにメッセージ追加しクローズ
for eventid in ${eventids}; do
  json='{"jsonrpc": "2.0","method": "event.acknowledge","params": {"eventids": '${eventid}',"action": 5,"message": "'${close_message}'"},"auth": "'${zbxauth}'","id": 1}'
  curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
done

# 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

参考

更新履歴

  • 2021/2/17 新規作成
  • 2024/1/20 クローズ処理のスクリプト化の記載を追記
  • 2024/6/30 Zabbix 7.0に対応するため、イベント一覧取得時のコマンドを修正
2024年6月27日木曜日

Zabbix 7.0でZabbixサーバーに対するスクリプト実行が設定できない問題の解消手順

ZabbixではZabbixサーバーやZabbixエージェントを経由して、スクリプトを実行する機能がある。

しかし、Zabbix 7.0をクリーンインストールした後にスクリプトを設定しようとしたところ、「次で実行」の設定項目にて以下のメッセージが表示され、Zabbixサーバーにおけるスクリプト実行が設定できなくなっていた。

Zabbixサーバーによるスクリプト実行は設定により無効化されています。

本記事では、Zabbix 7.0でZabbixサーバーに対するスクリプト実行が設定できない問題の解消手順を記載する。

環境

導入環境は以下となる。事前にZabbixサーバーがインストールされていることが前提となる。

  • OS : AlmaLinux 9.4
  • Zabbix : 7.0

原因

Zabbix 7.0のWhat’s newを見ると、以下の記載がある。どうやら、EnableGlobalScripts=0という設定が実施されており、デフォルトではZabbixサーバーにおいてスクリプト実行ができないようになっているとのこと。

global script execution on Zabbix server can be disabled by setting EnableGlobalScripts=0 in server configuration. For new installations, global script execution on Zabbix server is disabled by default.

解消方法

1. 設定を修正

/etc/zabbix/zabbix_server.confのファイルを開き、EnableGlobalScriptsを1に修正する。デフォルト値は1に設定されている旨が設定ファイルのコメントに記載されているが、実際はZabbix 7.0ではデフォルト値が0となっていた。

### Option: EnableGlobalScripts
#    Enable global scripts on Zabbix server.
#       0 - disable
#       1 - enable
#
# Mandatory: no
# Default:
# EnableGlobalScripts=1
EnableGlobalScripts=1 # ★0→1に修正

2. Zabbixサーバーのサービスを再起動

修正後、設定反映のため、Zabbixサーバーのサービスを再起動する。

# systemctl restart zabbix-server

3. 動作確認

あらためてスクリプトの設定を行うと、先ほどは選択できなかった「次で実行」の設定項目で「Zabbixサーバー」の項目が選択できるようになっている。


2024年6月22日土曜日

Zabbix 7.0をAnsibleで操作するためのcommunity.zabbixモジュール最新化手順

2024年6月4日にリリースされたZabbix 7.0をAnsibleで操作しようとしたところ、以下のようなInvalid paramsのエラーで失敗した。

failed: [t1023zabi] (item={'name': 't3051kube', 'groups': 'Linux servers', 'type': 'agent', 'ip': '192.168.1.1', 
'templates': ['Linux by Zabbix agent']}) => {"ansible_loop_var": "item", "changed": false, "item": {"groups": "Linux servers", 
"ip": "192.168.1.1", "name": "t3051kube", "templates": ["Linux by Zabbix agent"], "type": "agent"}, 
"msg": "connection error occurred: REST API returned {'code': -32602, 'message': 'Invalid params.', 
'data': 'Invalid parameter \"/1/groups/1\": unexpected parameter \"name\".'} 
when sending {\"jsonrpc\": \"2.0\", \"method\": \"host.create\", \"id\": \"706afb46-c4e4-461b-83e9-6e798396b800\", \"params\": {\"host\": \"t3051kube\", 
\"interfaces\": [{\"type\": 1, \"main\": 1, \"useip\": 1, \"ip\": \"192.168.1.1\", \"details\": {}, \"dns\": \"\", \"port\": \"10050\"}], 
\"groups\": [{\"groupid\": \"2\", \"name\": \"Linux servers\", \"flags\": \"0\", 
\"uuid\": \"dc579cd7a1a34222933f24f52a68bcd8\"}], \"status\": 0}, 
\"auth\": \"7922aa3xxxx556615xxxx0344xxxx2fea\"}"}

原因はAnsibleのcommunity.zabbixモジュールが古く、Zabbix 7.0にサポートしていなかったことが原因だった。本記事では、Zabbix 7.0をAnsibleで操作するために必要となるcommunity.zabbixモジュールの最新化手順を記載する。

環境

今回手順確認を行った環境の情報は以下の通り。

  • OS : AlmaLinux 8.5
  • Ansible : 8.1.0 (Ansible core 2.15.3)
  • community.zabbix : 2.1.0 → 3.0.0

community.zabbixモジュールの最新化手順

1. Ansible Galaxyにてモジュールを確認

community.zabbixモジュールは以下URLからバージョン情報を確認することができる。

また、変更内容はGitHubのChangelogから直接確認する。

以下の通り、v3.0.0においてZabbix 7.0で各種モジュールが動作するよう改修がされていることが確認できる。

zabbix_discovery_rule, zabbix_group_events_info, zabbix_host, zabbix_host_events_info, 
zabbix_proxy, zabbix_proxy_info modules updated to work wih Zabbix 7.0

2. 現在のバージョン確認

現在インストールされているcommunity.zabbixモジュールのバージョンを確認する。

# ansible-galaxy collection list community.zabbix
実行結果------------------------------
# /usr/local/lib/python3.9/site-packages/ansible_collections
Collection       Version
---------------- -------
community.zabbix 2.1.0  

3. Ansible Galaxyより最新版モジュールをインストール

以下コマンドで最新版モジュールをインストールする。なお、すでにモジュールがインストールされている場合インストールが実行されない (All requested collections are already installed.と表示されインストールが実施されない) ため、--forceオプションまたはバージョンを指定することでインストールを続行するようにしている。

# ansible-galaxy collection install community.zabbix --force
または
# ansible-galaxy collection install community.zabbix:3.0.0

4. インストール後のバージョン確認

インストール後のcommunity.zabbixモジュールのバージョンを確認する。

# ansible-galaxy collection list community.zabbix
実行結果------------------------------
# /root/.ansible/collections/ansible_collections
Collection       Version
---------------- -------
community.zabbix 3.0.0  

# /usr/local/lib/python3.9/site-packages/ansible_collections
Collection       Version
---------------- -------
community.zabbix 2.1.0  

5. Ansibleを実行

最後にZabbix 7.0に対してPlaybookを実行する。以下は、Zabbix 7.0に対して、community.zabbix.zabbix_hostモジュールを用いて監視対象ホストを登録した際の実行結果となり、問題なく実行できていることがわかる。
# ansible-playbook -i hosts -l t1023zabi zabbix/set_zabbix_host.yml

[root@t1025alma test]# ansible-playbook -i hosts -l t1023zabi zabbix/set_zabbix_host.yml

PLAY [Set zabbix host] **************************************************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************************************************
ok: [t1023zabi]

TASK [Create host] ******************************************************************************************************************************************************************
changed: [t1023zabi] => (item={'name': 't3051kube', 'groups': 'Linux servers', 'type': 'agent', 'ip': '192.168.1.1', 'templates': ['Linux by Zabbix agent']})

PLAY RECAP **************************************************************************************************************************************************************************
t1023zabi                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

人気の投稿