2022年5月22日日曜日

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

ネットワーク機器などの設定値はshow runなどコマンド実行結果をテキストファイルとして残すことで、変更作業を行った前後のファイルでdiffツールによる比較を行うことができる。

OSの設定については、設定内容が多岐にわたるため、なかなかテキストファイルに残すといったことは難しく、都度コマンドを実行して情報を取得するというパターンが多い。
※Red Hat系のLinuxであれば、ログの取得ツールとしてsosreportがある。こちらは必要な設定やファイルを1つの圧縮ファイルにまとめるものとなり、設定の比較という観点では使いづらい。

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

環境

本スクリプトの動作確認をしたOSは以下の通り。Red Hat系のLinuxディストリビューションであるCentOS、AlmaLinux、Rocky Linuxでも動作するはずだ。

  • OS : Red Hat Enterprise Linux 8 または 7
  • 実行シェル : Bash

Linux設定項目一覧

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

取得設定項目 取得設定内容
ホスト名・OSバージョン情報 OSのバージョン、カーネル番号、稼働時間など
ハードウェア情報 CPUのコアやソケット数、メモリ容量、PCIデバイス一覧
インストール設定 インストール時の設定 (/root/anaconda-ks.cfg)
OS基本設定 grubkdump、SELinuxの設定
カーネルパラメータ カーネルパラメータとシステムリソース制限(ulimit)設定
ネットワーク設定 各種ネットワーク関連設定。DNSやhostsファイルの設定を含む
ディスク設定 各種ディスク情報、LVM関連設定、fstabの設定
ユーザ・グループ設定 ユーザー一覧、グループ一覧、sudoの設定
sshd設定 sshdに関する設定
時刻設定 時刻同期 (Chrony) に関する設定
OS言語設定 使用している言語とインストール済み言語
サービス設定 systemdのサービス一覧
パッケージ設定 yumdnfの設定、インストールされているrpm一覧
rsyslog設定 rsyslogに関する設定
logrotate設定 logrotateに関する設定
Postfix設定 Postfixに関する設定
Dovecot設定 Dovecotに関する設定
Squid設定 Squidに関する設定
Unbound設定 Unboundに関する設定
Apache (httpd) 設定 Apache (httpd) に関する設定
Zabbix Agent設定 Zabbix Agentに関する設定

PostfixやDovecotなどのソフトウェアについては、パッケージのインストール有無によって設定値の取得判断をする。これ以外にもインストールしているソフトウェアがある場合は、適宜追加するといったカスタマイズが必要となる。

スクリプト

今回作成したスクリプトはGitHubに置いてあるので、そちらを参照いただきたい。

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

関数名 内容
show_title 取得対象の設定項目のタイトルを表示
get_command コマンドを実行して、その結果を取得
get_config 設定ファイルからコメント(#から始まる行)及び空行を削除して内容を取得
get_config_files ディレクトリを指定し、その中のファイル及びシンボリックリンクの内容を取得
check_install_package パッケージのインストール状況を確認

使い方

任意のディレクトリに配置しroot権限にて以下の通り実行する。実行時間は環境にもよるが、10秒程度もあれば終了する。

# chmod +x get_linux_config.sh
# ./get_linux_config.sh

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

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

情報取得結果のサンプル

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

################################
情報取得開始 2022/05/22 11:55:25
################################

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

(command)# uname -n
rhel8

(command)# uname -a
Linux rhel8 4.18.0-240.el8.x86_64 #1 SMP Wed Sep 23 05:13:10 EDT 2020 x86_64 x86_64 x86_64 GNU/Linux

(config)# /etc/redhat-release
Red Hat Enterprise Linux release 8.3 (Ootpa)

(command)# uptime
 11:55:25 up 63 days, 20:09,  1 user,  load average: 0.00, 0.00, 0.00

~(中略)~

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

(command)# ls -l /dev/?da*
brw-rw---- 1 root disk 8, 0  5月 22 10:51 /dev/sda
brw-rw---- 1 root disk 8, 1  5月 22 10:51 /dev/sda1
brw-rw---- 1 root disk 8, 2  5月 22 10:51 /dev/sda2
brw-rw---- 1 root disk 8, 3  5月 22 10:51 /dev/sda3

(command)# ls -l /dev/mapper/*
crw------- 1 root root 10, 236  3月 19 15:46 /dev/mapper/control
lrwxrwxrwx 1 root root       7  3月 19 15:46 /dev/mapper/rhel-root -> ../dm-0
lrwxrwxrwx 1 root root       7  3月 19 15:46 /dev/mapper/rhel-swap -> ../dm-1

(command)# fdisk -l
ディスク /dev/sda: 16 GiB, 17179869184 バイト, 33554432 セクタ
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスクラベルのタイプ: gpt
ディスク識別子: A18174EE-DDA9-4DD9-8999-D1225E510848

デバイス   開始位置 終了位置   セクタ サイズ タイプ
/dev/sda1      2048  1230847  1228800   600M EFI システム
/dev/sda2   1230848  3327999  2097152     1G Linux ファイルシステム
/dev/sda3   3328000 33552383 30224384  14.4G Linux LVM

~(以下略)~

以上。

2022年5月14日土曜日

サービス監視スクリプト (Windows版)

サーバーのプロセス監視 (Windowsの場合はサービス監視) は、監視ソフトウェア(ZabbixやJP1など)を使えば当たり前のように実現できる。ただし、環境やライセンスの関係でエージェントの導入ができない場合がある。

そのような場合でも、スクリプトを使ってプロセス監視 (サービス監視) を行うことは可能となる。

今回、Windowsのサービス監視を行うスクリプトを作ってみたので、その内容を記載する。

なお、Linuxのプロセス監視のスクリプトについては、以下記事を参照いただきたい。

実現方法

本スクリプトの設計概要を図示する。

このスクリプトは、確認対象のサービスを設定ファイル(check-service.conf)に記載しておき、Get-ServiceコマンドレットにてサービスがRunningステータスであるかどうかを確認する。

サービスダウンを検知した際は、Write-EventLogコマンドレットでApplicationイベントログにエラーメッセージを出力する。エラーメッセージ出力タイミングは、サービスダウンの初回発生時のみとし、それ以外は情報メッセージとして出力する。

以下に、本スクリプトで発生するメッセージを記載する。

サービス状態 メッセージ
正常時 [INFO] Service XXX up
正常状態継続時 [INFO] Service XXX still up
ダウン時 [ERROR] Service XXX down
ダウン状態継続時 [INFO] Service XXX still down

この処理をタスクスケジューラーで1分間隔で実行するよう登録し、定期的なサービス監視を実現する。

スクリプト実行手順

1. スクリプト実行前にイベントソースを登録

Windowsイベントログにイベントを出力する際に、事前にイベントソースの登録が必要となる。事前に管理者権限でPowerShellのプロンプトを開き、以下コマンドを実行しておくこと。

PS C:\> New-EventLog -LogName Application -Source "Service Check Script"

なお、イベントソースの登録削除は、以下のコマンドとなる。

PS C:\> Remove-EventLog -Source "Service Check Script"

2. スクリプト配置

以下にスクリプトのコードを記載する。GitHubにも配置してある。

スクリプトファイル:check-service.ps1

################
# Scripts name : check-service.ps1
# Usage        : ./check-service.ps1
#                同一ディレクトリにcheck-service.confを配置し、タスクスケジューラーで定期実行する。
#                事前にAdmin権限で以下コマンドをを実行すること。
#                New-EventLog -LogName Application -Source "Service Check Script"
# Description  : Windowsサービスチェックスクリプト
# Create       : 2022/05/02 tech-mmmm (https://tech-mmmm.blogspot.com/)
# Modify       : 
################

$currentdir = Split-Path -Parent $MyInvocation.MyCommand.Path
$conffile = $currentdir + "\check-service.conf"    # 設定ファイル
$tmpfile = $currentdir + "\check-service.tmp"      # サービス情報保存用一時ファイル
$event_source = "Service Check Script"             # スクリプトソース名

# すでにDownしているサービス情報を取得
if ( Test-Path -Path $tmpfile ){
    $down_service = Get-Content $tmpfile
}
Write-Output $null | Out-File $tmpfile

# 設定ファイル読み込み
foreach ($line in (Get-Content $conffile)) {   
    # コメント行と空行を処理しない
    if ( $line -notmatch "^ *#|^$" ){
        # 現在のサービス数を取得
        $count = (Get-Service -Name $line | Where-Object { $_.Status -eq "Running" }).count
        
        # サービス数チェック
        if ( $count -lt 1 ){
            # Down時の処理
            # Downしているサービスか確認
            if ( $down_service -eq $line ){
                # すでにDown
                $message = "Service """ + $line + """ still down"
                $event_type = "Information"
            }else{
                # 初回Down
                $message = "Service """ + $line + """ down"
                $event_type = "Error"
            }
            
            # イベントログに出力
            Write-Output $message
            Write-EventLog -LogName Application -EntryType $event_type -Source $event_source -EventId 100 -Message $message

            # Donwしているサービス情報を出力
            Write-Output $line | Out-File -Append $tmpfile
        }else{
            # Up時の処理
            # Downしていたサービスか確認
            if ( $down_service -eq $line ){
                # Downだった
                $message = "Service """ + $line + """ up"
                $event_type = "Information"                
            }else{
                # すでにUp
                $message = "Service """ + $line + """ still up"
                $event_type = "Information"
            }

            # イベントログに出力
            Write-Output $message
            Write-EventLog -LogName Application -EntryType $event_type -Source $event_source -EventId 100 -Message $message
        }
    }
}

exit 0

設定ファイル例:check-service.conf

# Service mame
Netlogon
W32Time
VMTools

3. タスクスケジューラーへの登録

タスクスケジューラーにて本スクリプトを1分間隔で実行するように設定する。こちらの方法については、以下別記事を参照いただきたい。

4. 監視テスト

実際にサービスを停止させて動作確認をしてみよう。W32Timeを停止させてサービス停止を検知することを確認してみる。

PS C:\> Stop-Service -Name W32Time
PS C:\> Get-EventLog -LogName Application -Source "Service Check Script"

   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
   12652 5 03 06:27    Information Service Check Script          100 Service "VMTools" still up
   12651 5 03 06:27    Error       Service Check Script          100 Service "W32Time" down  ★停止を検知
   12650 5 03 06:27    Information Service Check Script          100 Service "Netlogon" still up
~(以下略)~

次に、復旧時の動作を確認する。

PS C:\> Start-Service -Name W32Time
PS C:\> Get-EventLog -LogName Application -Source "Service Check Script"

   Index Time          EntryType   Source                 InstanceID Message
   ----- ----          ---------   ------                 ---------- -------
   12655 5 03 06:29    Information Service Check Script          100 Service "VMTools" still up
   12654 5 03 06:29    Information Service Check Script          100 Service "W32Time" up ★復旧
   12653 5 03 06:29    Information Service Check Script          100 Service "Netlogon" still up
~(以下略)~

以上。

更新履歴

  • 2017/12/18 新規作成
  • 2022/05/14 全体的にスクリプトの構成を見直し
2022年5月7日土曜日

プロセス監視スクリプト (Linux版)

サーバーのプロセス監視は、監視ソフトウェア(ZabbixやJP1など)を使えば当たり前のように実現できる。ただし、環境やライセンスの関係でエージェントの導入ができない場合がある。

そのような場合でも、スクリプトを使ってプロセス監視を行うことは可能となる。ログに出力さえできれば、Linuxの場合はrsyslogなどでログを別のサーバに転送でき、そのサーバで監視させるといったことも可能である。

今回は、Linuxのプロセス監視を行うスクリプトを作ってみたので、その内容を記載する。

実現方法

本スクリプトの設計概要を図示する。

このスクリプトは、設定ファイル(check-process.conf)に監視対象のプロセス及び起動プロセス数を記載しておき、psコマンドにて監視対象の起動プロセス数を確認する。

プロセスダウンを検知した際は、loggerコマンドで/var/log/messagesにエラーメッセージを出力する。エラーメッセージ出力タイミングは、プロセスダウンの初回発生時のみとし、それ以外は情報メッセージとして出力する。

以下に、本スクリプトで発生するメッセージを記載する。

プロセス状態 メッセージ
正常時 [INFO] Process XXX up
正常状態継続時 [INFO] Process XXX still up
ダウン時 [ERROR] Process XXX down
ダウン状態継続時 [INFO] Process XXX still down

この処理をcronで1分間隔で実行するよう登録し、定期的なプロセス監視を実現する。

スクリプト実行手順

1. スクリプト配置

以下にスクリプトのコードを記載する。GitHubにも配置してある。

スクリプト本体:check-process.sh

#!/bin/bash
################
# Scripts name : check-process.sh
# Usage        : ./check-process.sh
#                同一ディレクトリにcheck-process.confを配置し、cronで定期実行する。
# Description  : Linuxプロセスチェックスクリプト
# Create       : 2017/12/14 tech-mmmm (https://tech-mmmm.blogspot.com/)
# Modify       : 2022/05/01 tech-mmmm (https://tech-mmmm.blogspot.com/)
################

currentdir="$(dirname "$0")"
conffile="${currentdir}/check-process.conf"    # 設定ファイル
tmpfile="${currentdir}/check-process.tmp"      # プロセス情報保存用一時ファイル

# すでにDownしているプロセス情報を取得
if [ -f "${tmpfile}" ]; then
    down_process=$(paste -d "|" -s "${tmpfile}")
fi
echo -n > "${tmpfile}"

# 設定ファイル読み込み
while read line || [ -n "${line}" ]; do
    # 空白区切りで分割
    process_name=$(echo "${line}" | awk '{print $1}')
    process_num=$(echo "${line}" | awk '{print $2}')
    
    # コメント行と空行を処理しない
    if [ "$(echo "${process_name}" | grep -c -v -e '^ *#' -e '^$')" -gt 0 ]; then      
        # 現在のプロセス数を取得
        count=$(ps ahxo args | grep "${process_name}" | grep -c -v -e "^grep")
        
        # プロセス数チェック
        if [ "${count}" -lt "${process_num}" ]; then
            # Down時の処理
            # すでにDownしているプロセスか確認
            if [ -n "${down_process}" ] && [ "$(echo ${process_name} | grep -c -E ${down_process})" -gt 0 ]; then
                # すでにDown
                message="[INFO] Process \"${process_name}\" still down"
            else
                # 初回Down
                message="[ERROR] Process \"${process_name}\" down"
            fi
            # ログへ出力
            echo "${message}"
            logger "${message}"
            
            # Donwしているプロセス情報を出力
            echo "${process_name}" >> "${tmpfile}"
        else
            # Up時の処理
            # Downしていたプロセスか確認
            if [ -n "${down_process}" ] && [ "$(echo ${process_name} | grep -c -E ${down_process})" -gt 0 ]; then
                # Downだった
                message="[INFO] Process \"${process_name}\" up"
            else
                # すでにUp
                message="[INFO] Process \"${process_name}\" still up"
            fi
            # ログへ出力
            echo "${message}"
            logger "${message}"
        fi
    fi
done < "${conffile}"

exit 0

設定ファイル例:check-process.conf

# Process mame Number of process
/usr/sbin/chronyd 1
/usr/sbin/httpd 5

2. cronへの登録

スクリプトを/root/scriptディレクトリに配置した場合を例として、1分間隔で監視させるようcronを以下のように設定する。

# crontab -e
*/1 * * * * /root/script/check-process.sh

3. 監視テスト

実際にプロセスを停止させて動作確認をしてみよう。httpdを停止させてプロセス停止を検知することを確認してみる。

# systemctl stop httpd
# tail -10 /var/log/messages | grep -E "INFO|ERROR"
May  1 15:12:07 t1192rhel root[76941]: [INFO] Process "/usr/sbin/chronyd" still up
May  1 15:12:07 t1192rhel root[76955]: [ERROR] Process "/usr/sbin/httpd" down ★停止を検知

次に、復旧時の動作を確認する。

# systemctl start httpd
# tail -10 /var/log/messages | grep -E "INFO|ERROR"
May  1 15:12:07 t1192rhel root[76941]: [INFO] Process "/usr/sbin/chronyd" still up
May  1 15:12:07 t1192rhel root[76955]: [ERROR] Process "/usr/sbin/httpd" down
May  1 15:13:46 t1192rhel root[77291]: [INFO] Process "/usr/sbin/chronyd" still up
May  1 15:13:46 t1192rhel root[77308]: [INFO] Process "/usr/sbin/httpd" up ★復旧

以上。

更新履歴

  • 2017/12/16 新規作成
  • 2022/05/07 全体的にスクリプトの構成を見直し

2022年4月30日土曜日

Zabbixの「nodata」関数を使って一定期間データが受信できない場合にトリガーで検知させる

自宅ではRaspberry PiにてPC周りの温度・湿度を計測しており、計測した温度・湿度情報は、zabbix_senderコマンドを用いてZabbixに送信して監視を実現している。Zabbixではグラフとして表示させ、年間での温度・湿度の変化を確認できるようにもしている。

Raspberry Piによる温度計測とZabbixへの連携方法の詳細を知りたい場合は、以下別記事にて記載しているので参照いただきたい。

温度・湿度の計測は基本的には問題なくできており満足しているが、まれに不調により計測が長時間失敗することがある(下図の赤枠箇所)。

このような、「一定時間Zabbixへ監視情報が送られてこない」状態は、Zabbixの「nodata」関数を利用することで監視することができる。本記事では、Zabbixの「nodata」関数を使って一定期間データが受信できない場合にトリガーで検知させる方法を記載する。

環境

環境は以下の通り。Zabbix 6.0を利用しているが、nodata関数自体は昔のバージョンから利用可能となる。

  • OS : CentOS Stream 8
  • Zabbix : 6.0.2

手順

1. トリガーを作成

nodata関数の記載は以下の通り。設定した秒数よりも長い時間データが未受信であれば1を返し、受信していれば0を返す。

nodata(監視対象アイテム,データ未受信の秒数)

なお、ZabbixのGUI上では設定単位が「時間」と書いてあるように見えるが、「Hour」の意味ではなく、あくまで設定値は「秒」である点に注意しよう。

データ未受信の秒数は30秒に1回チェックされることから、30秒以上で設定すること。

以上をふまえ、トリガーの設定内容は以下の通りとなる。

設定項目 設定例 説明
名前 No sensor data received 任意で指定する。
深刻度 警告 任意で指定する。
障害の条件式 nodata(/Template Sensor Temperature/rasp_temp,3600)=1 今回は1時間(3600秒)データが未受信の場合、トリガーにて障害検知できるようにする。
正常イベントの生成 復旧条件式 自動で障害復旧できるよう復旧条件式を指定する。
復旧条件式 nodata(/Template Sensor Temperature/rasp_temp,3600)=0 障害の条件式逆にnodata関数の結果が0であることを条件式として設定する。
有効 チェック トリガーを有効にする。

2. 動作確認

実際に設定したトリガーが動作することを確認してみよう。データ受信しないよう監視対象サーバを停止して、nodata関数で設定時間経過するのを待つ。すると、以下の通り正常にトリガーにて障害検知がされた。

監視対象サーバを復旧させ監視データの受信を再開すると、自動で「解決済」ステータスとなった。

以上で、Zabbixの「nodata」関数を使って一定期間データが受信できない場合にトリガーで検知させる手順は完了となる。

参考

2022年4月23日土曜日

「このワークステーションとプライマリドメインとの信頼関係に失敗しました。」のエラーを解消する。

仮想環境に構築したドメイン参加済みのWindows OSに対して、スナップショットなどからリストアすると、以下エラーによりドメインアカウントを用いてもログインができなくなることがある。

「このワークステーションとプライマリドメインとの信頼関係に失敗しました。」

これは「セキュアチャネルの破損」と呼ばれる事象であり、ドメイン再参加または、コマンドによるセキュアチャネルの修復作業が必要となる。

今回はPowerShellのコマンドを用いて本エラーを解消し、再びドメインアカウントにてログインできるようにする手順を記載する。

環境

  • ドメインコントローラ : Windows Server 2016
  • ドメイン参加対象のクライアント : Windows Server 2019

エラー解消手順

1. ロカールアカウントでログイン

ドメインアカウントではログインできないので、ローカルアカウントでログインを行う。

2. PowerShellにてセキュアチャネルの状態を確認

PowerShellを管理者として開き、Test-ComputerSecureChannelを実行する。セキュアチャネルが破損している場合は、以下の通りFalseと表示されるはずだ。

PS C:\> Test-ComputerSecureChannel
False

3. セキュアチャネルを修復

引き続きTest-ComputerSecureChannelを用いてセキュアチャネルの修復を行う。セキュアチャネルの修復には、-Repairオプションと-Credentialで任意のドメインアカウントを指定する。

PS C:\> Test-ComputerSecureChannel -Repair -Credential [ドメイン名]\[ドメインアカウント名]
True

指定したドメインアカウントのパスワード入力を求められるので入力する。

数秒待ちTrueが返ってくれば、セキュアチャネルの修復は完了となる。

4. ドメインアカウントで再ログイン

一度ログアウトし、ドメインアカウントにて再度ログインを行う。問題なくログインできれば作業は完了となる。

参考

人気の投稿