頭の中は異空間

ものづくり中心

【Zabbix】【自分用】障害が上がったときにメールを送る

前提として現行の最新版Zabbix 7.2を使うものとする

全部で以下3ステップ

  1. ホストorテンプレートにアイテム、トリガー設定
  2. メディアタイプ設定
  3. トリガーアクション設定

ホストorテンプレートにアイテム、トリガー設定

テスト時には待つのが怠いのでアイテムの監視間隔を10sとか短めに設定する
テスト時には例えばCPUやディスクなど強引に負荷を上げてもいいが、トリガーのしきい値の方をいじるほうが楽
CPU5%以上とかに設定すれば大概引っかかる

障害が上がること自体を確認するには、監視データ>障害を開く
最新データが取れているかを確認するには、監視データ>最新データを開く

メディアタイプ設定

ここではGmailに送信する想定としている

Gmailの設定をしたいなら以下がわかりやすいので従う
ZabbixからGmailを使用してメールを送信する手順 - なっくの徒然日記

トリガーアクション設定

ここではCPU使用率が80%を超えた場合に障害が上がり、その際のメッセージをメールで送信する例を載せる

  1. 通知>アクション>トリガーアクション
  2. アクションの作成

面倒なので設定結果↓↓





※送信メディアタイプ「test」は、事前に通知>メディアタイプで設定した

しきい値が80%と90%のように複数ある場合や、ディスク使用率監視、SNMPトラップ監視等は別途作る必要がある

【Zabbix】WindowsホストOSにzabbix_agentdをインストールして、VirtualboxのRocky Linux9上のZabbixで監視する

前提として、以下の通りRockyLinux9をインストール済みかつzabbix_server起動済みであること
notwodaily.hatenablog.com

zabbix_agentdのMSIインストール

ホストOS(Windows)側で、以下からzabbix_agentdをDL
→zabbix_agent-7.2.3-windows-amd64-openssl.msi
Download Zabbix agents
※64bitなのでamd64の方を選択


Windowsインストーラをダブルクリックして実行

Nextをクリック



I accept ~にチェックを入れてNextをクリック



Nextをクリック



以下の通り入力してNextをクリック

  • Host name: ホストOS名
  • Zabbix server IP/DNS: ゲストOSのIP
  • Agent listen port: 10050
  • Server or Proxy for active checks: ゲストOSのIP(画像はミス)
  • チェックボックスはチェックなし



Installをクリック


インストールが完了したら、Finishをクリックして閉じる

Zabbixフロントエンドにアイテム追加

Zabbixにログインしてダッシュボードを開き、データ収集>ホストをクリック
デフォルトで100超えのアイテムが登録されているので、まずはこれらを一括削除する
(本当に監視したいアイテムだけ個別でつけたほうが良い)

  1. 名前欄のZabbix Serverをクリックして、ホストダイアログを開く
  2. テンプレートを全てxをクリックして削除
  3. インターフェース>エージェントのIPアドレスを、ホストOSのIPにして更新
  4. アイテムをクリック
  5. まだアイテムが残っているので、全て選択して削除

削除し終わったら、画面右上のアイテムの作成をクリック
以下の通り入力して作成

※監視間隔は数分でいいが、最初の確認はすぐにできたほうがいいので30sにしている
作成するとこんな感じ

データが取れているか確認

監視データ>最新データ
… > 最新500個の値をクリック

値が取れていればOK、設定に問題ある場合は取得不可となりエラーが出ているので、中身を確認する


こんな感じでメモリ、ディスク、スワップ、イベントログとかも監視できる
詳細は
1 Zabbix agentで確認

【Zabbix】Windows11のVirtualbox上のRockyLinux9にZabbix7.2+agentdを構築する

zabbix server構築

zabbix serverのパッケージをDL
Download and install Zabbix

同リンク内のa.~g. の部分を実行
参考までに、画面上で、以下の通り選択されている

c実行前に以下確認

インストール直後はmysqldが存在しないので、別途インストール
バージョン制限があるので、
2 Requirements
Required software > MySQL/Percona
より、8.0.30-9.0.Xが対象


DLリンク
https://dev.mysql.com/downloads/mysql/
以下の通り選択

Select Version 8.0.41
Select Operating System Red Hat Enterprise Linux / Oracle Linux
Select OS Version Red Hat Enterprise Linux 9 / Oracle Linux 9 (x86, 64-bit)

以下パッケージをDL


teratermとかWinSCPでRockyLinux上に移動して以下実行
※/tmp/以下に移動したものとする

cd /tmp/
dnf install -y mysql-community-server-8.0.41-1.el9.x86_64.rpm mysql-community-client-8.0.41-1.el9.x86_64.rpm mysql-community-client-plugins-8.0.41-1.el9.x86_64.rpm mysql-community-common-8.0.41-1.el9.x86_64.rpm mysql-community-icu-data-files-8.0.41-1.el9.x86_64.rpm mysql-community-libs-8.0.41-1.el9.x86_64.rpm


インストール完了したら、

sudo systemctl start mysqld
sudo systemctl enable mysqld

で立ち上げる。更に、以下を実行してmysqlに初期rootパスワードを設定する

# 初期パスワード確認
grep "temporary password" /var/log/mysqld.log



ここまでが完了したら、以下でmysqlにログインして、rootの初期パスワードを変更する

sudo mysql -uroot -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'パスワード';


php-fpm等が落ちたら
ERROR: [pool www] cannot get uid for user 'nginx': Success (0)

nginxユーザがないとか言われるので、nginxを追加

id nginx
useradd -r -s /sbin/nologin nginx
systemctl restart php-fpm


zabbix_serverの設定変更

zabbix serverの設定ファイルを修正

vi /etc/zabbix/zabbix_server.conf

以下の通りに設定する

DBName=zabbix
DBUser=zabbix
DBPassword=さっき設定したパスワード


zabbixユーザがないと言われるので、zabbixを追加

Feb 24 05:14:53 localhost.localdomain zabbix_server[6454]: zabbix_server [6454]: user zabbix does not exist
Feb 24 05:14:53 localhost.localdomain zabbix_server[6454]: zabbix_server [6454]: cannot run as root!
id zabbix
useradd -r -s /sbin/nologin zabbix
systemctl restart zabbix-server.service


更にログファイルの書き込み権限がないと言われた場合は、chmodする
ファイル自体がなかったら、ファイルを作成する
また、PIDファイルが作成できない場合はディレクトリに権限追加する

ll /var/log/zabbix/zabbix_server.log
touch /var/log/zabbix/zabbix_server.log
chmod 766 /var/log/zabbix/zabbix_server.log

ll -a /run/zabbix/
chmod 777 /run/zabbix/
systemctl restart zabbix-server.service

# zabbix_agentdも同様
ll /var/log/zabbix/zabbix_agentd.log
touch /var/log/zabbix/zabbix_agentd.log
chmod 766 /var/log/zabbix/zabbix_agentd.log


サービスが全て起動したか確認

systemctl status zabbix-server zabbix-agentd php-fpm


画面アクセス用にnginx設定ファイル修正

vi /etc/nginx/conf.d/zabbix.conf

以下設定を追加

listen          0.0.0.0:8080;
server_name     _;


画面アクセス~インストール続行

後はhttp://ゲストOSのIP:8080/でZabbixフロントエンドにアクセスできるはずだが、うまくいかないことがある
ここでタイムアウトする場合、そもそも/var/log/nginx/access.logと/var/log/nginx/error.logにログが吐かれていないはず(アクセスログ、エラーログ)
→アクセス自体ができていない
そんなときは以下コマンドでポートを開けておく

firewall-cmd --list-all
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload

# ついでにagentdのアクティブチェック、パッシブチェック用のポートも開ける
firewall-cmd --add-port=10050/tcp --zone=public --permanent
firewall-cmd --add-port=10051/tcp --zone=public --permanent
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload

更に、Virtualbox本体の設定でポートフォワーディング追加


ホストOS側でhttp://127.0.0.1:8080/にアクセス
ここまででzabbixフロントエンドにアクセスできるはず

日本語等、複数の言語がまだ選択できない場合は、警告が出ているため、以下実行して画面リロードする

dnf install glibc-all-langpacks glibc-langpack-ja
localectl set-locale LANG=ja_JP.UTF-8
source /etc/locale.conf
systemctl status nginx php-fpm zabbix-server



ここからは画面の案内に従ってインストールを進める

  1. デフォルトの言語が日本語になっていることを確認して、次のステップ
  2. 要求文字列が全てOKになっていることを確認して、次のステップ
  3. 以下の通りにして、次のステップ
    1. データベースタイプ: MySQL
    2. データベースホスト: localhost
    3. データベースポート: 0
    4. データベース名: zabbix
    5. 資格情報保存: プレーンテキスト
    6. ユーザー: zabbix
    7. パスワード: zabbixのパスワード
  4. 以下の通りにして、次のステップ
    1. Zabbixサーバー名: localhost
    2. デフォルトのタイムゾーン: Asia/Tokyo
    3. デフォルトのテーマ: 好きなもの何でもいいので選ぶ
  5. 入力内容を確認して、次のステップ
  6. 設定ファイルのダウンロードリンクから落としたファイルをゲストOSまで移動して、以下コマンド実行
mv /tmp/zabbix.conf.php /etc/zabbix/web/zabbix.conf.php
systemctl restart zabbix-server


ここまで正常に実行できていれば、ログイン画面に遷移する

ログイン後、ダッシュボード画面が出てればOK


ログローテート設定

設定ファイル/etc/logrotate.d/zabbix-serverがあるはずなので中身を確認

[root@localhost ~]# cat /etc/logrotate.d/zabbix-server
/var/log/zabbix/zabbix_server.log {
        weekly
        rotate 12
        compress
        delaycompress
        missingok
        notifempty
        create 0664 zabbix zabbix
}
[root@localhost ~]#

最初のweeklyをdailyに変えれば、日毎ログローテートになる。デフォルトで12日分

Windows上でWSL環境を有効化して、sshやexpectを使えるようにする

ディストリビューションは適当

  1. https://github.com/yuk7/ArchWSL/releases
    から最新版をダウンロード(Arch_Online.zip)
  2. Arch.exeを実行
  3. ERR: WSL 2 requires an update to its kernel component
    
    が出る場合は、 wsl --list --verbose を実行してWSLバージョンを確認する。恐らくWSL2がインストールされていないはず その場合は、以下を進める
    1. https://aka.ms/wsl2kernel
      「x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ」リンクからダウンロード
    2. wsl_update_x64.msiを実行して、Linuxカーネルを更新する
    3. インストールが始まる
    4. Finishをクリック
    5. PCを再起動する
    6. 更に以下実行
    7. wsl --install -d Kali-Linux
      
      うまくいかなかった...
      Installing, this may take a few minutes...
      WslRegisterDistribution failed with error: 0x80004005
      Error: 0x80004005 ???????????
      
      Press any key to continue...
      
      現行のバージョン確認
      PS C:\Users\ユーザ名> wsl --status
      既定のバージョン: 2
      
      Linux 用 Windows サブシステムの最終更新日: 2024/12/08
      Linux 用 Windows サブシステム カーネルは、'wsl --update' を使用して手動で更新できますが、システム設定が原因で自動更新が 発生することはありません。
      カーネルの自動更新を受け取るには、 Windows Update の設定を有効にしてください:' Windowsの更新に、その他のMicrosoftの製品 の更新情報を受け取る'。
      詳細については、 https://aka.ms/wsl2kernel.
       を参照してください
      カーネル バージョン: 5.10.16
      入っている...?ことにしよう
    8. 改めて、Arch.exeを実行
    9. Using: https://github.com/yuk7/ArchWSL-FS/releases/download/24042800/rootfs.tar.gz
      Downloading...
       100% |███████████████████████████████████| (232/232 MB, 8.6 MB/s)
      Installing...
      Installation complete
      Press enter to continue...
      今度はうまくいった
  4. WSLを起動(以降、WSL上で実行すること)
  5. yes | sudo pacman -S openssh
  6. yes | sudo pacman -S expect

これで利用可能になる

デスクトップは
/mnt/c/Users/ユーザ名/Desktop/
でアクセス可

【Linux】VirtualBox上のKali LinuxへSSHできるようになるまで:

前提として、kali linuxを起動してログインできる状態になっていること、SSHログインではパスワード認証を用いることとします
※パスワードスキップ
あと、私個人がネットワークに疎いこともあって正確な情報と言える自信があまりないです。(一応できることは確認した)



やることは以下

  1. VirtualBox自体のネットワーク設定
  2. kali linux側でネットワーク設定



1. VirtualBox自体のネットワーク設定

  1. Oracle VM VirtualBox マネージャーから仮想マシン>設定を開く
  2. ネットワーク>アダプター1がNATになっていることを確認して、ポートフォワーディングをクリック
  3. 下画像の通りに設定する(ホストIPは、あらかじめip aでeth0のIPをメモしておいて、それを入力)
  4. kali linuxを起動する

2. kali linux側でネットワーク設定

/etc/ssh/sshd_configを、以下の通り編集する

  1. 以下設定を追加
  2. Port 22 # 22番ポートで受け付ける
    PermitRootLogin no # rootによるログインを禁止
    PasswordAuthentication yes # パスワード認証を有効にする
    PermitEmptyPasswords no # 空パスワードを拒否
    
  3. sshサービスを再起動する
  4. sudo systemctl enable ssh
    sudo systemctl start ssh
    sudo systemctl status ssh
    

このあと、TeratermやPutty、Git Bash等でssh kali@<ホストOSのip(eth1)>
でログインできる

例)

$ ssh kali@<ホストOSのip(eth1)>
kali@<ホストOSのip(eth1)>'s password:
Linux kali 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Dec  7 10:23:20 2024 from <ゲストOSのIP>
┌──(kali㉿kali)-[~]
└─$

【Ruby】Windowsでどうしてもログローテートできない問題

Rubyのコードだと以下のように書くはず

require 'logger'

logfile = File.open('path/to/logfile', 'a')
logger = Logger.new(logfile, 'daily')

しかしこのコードではログローテートされず、エラーを吐く
それどころか、現状のログにも書き込みができなくなってしまう

その様子は以下ログからはっきりする
(ここではdelayed_job.logをローテートしようとしている)

log shifting failed. Permission denied @ rb_file_s_rename - (<sinatra_project_root>/log/delayed_job.log, <sinatra_project_root>/log/delayed_job.log.0)
log writing failed. closed stream


これを解決するためには、ログローテートをLoggerの機能として行うのではなく、Windowsならではのタスクスケジューラを使って解決する
(Linuxならcronを使う)

ã‚„ã‚Šæ–¹

例えば、log/app.logというログファイルを出力している箇所のコードを以下のように修正する

logfile = File.open('log/app.log', 'a')
logger = Logger.new(logfile)

'daily'を外すことで、Loggerはローテートしなくなる
更に、タスクスケジューラで実行するスクリプト(ここではpowershellを想定)を以下のように記述する

:: タスクを停止
schtasks /End /TN "アプリを起動するタスク名"


:: 既存ログのローテート
$currentDate = Get-Date -Format "yyyy-MM-dd"
cd path/to/project_root
cp log/app.log log/app.log.$currentDate
Clear-Content log/app.log


:: タスクを起動
schtasks /Run /TN "アプリを起動するタスク名"


処理内容は以下

  1. ログ(log/app.log)を吐いているアプリを停止
  2. ログをリネームしてコピー
  3. 元々のログの中身をクリア
  4. アプリを起動


※あくまで、Windows上でアプリを起動するためにタスクスケジューラを使っている場合に限る。それ以外の方法で定期実行している場合は、その実行元を止めてから同じことをすれば良い


一見これで解決だが、まだ問題が残る。
本来のLoggerによるログローテートであれば、一定期間より古いログは自動で削除してくれるが、この方法だと明示的にログ削除をしない限り、ログは延々と作り続けられてしまう
よって、先程のスクリプトを以下のように修正することで、例えば6日前のローテート済みログファイルを削除することができる

:: タスクを停止
schtasks /End /TN "アプリを起動するタスク名"


:: 既存ログのローテート
$currentDate = Get-Date
$currentDateFormatted = $currentDate.ToString("yyyy-MM-dd")
$deleteDateFormatted = $currentDate.AddDays(-6).ToString("yyyy-MM-dd")
cd path/to/project_root
cp log/app.log log/app.log.$currentDateFormatted
Clear-Content log/app.log

# 古い(6日前の)ログを削除
rm log/app.log.$deleteDateFormatted

:: タスクを起動
schtasks /Run /TN "アプリを起動するタスク名"


これで、5日前までのログファイルを残しつつログローテートが可能。
もし.tar.gzなど圧縮をしたいなら、それ用のコードを追加すれば良い。


スクリプトが出来上がったら、タスクスケジューラに毎日0:00実行するようにタスク登録すれば完成
※もしサーバ起動タスクを別途作っており同じ時刻にしているなら、念の為時間はずらしたほうが良い
例) サーバ起動タスク0:00、ログローテート0:05

あとがき

WindowsでRubyでの開発はすべきではない

【Sinatra】プロトタイプ用

bootstrap5を使うものとする

Gemfile

gem 'sinatra'
gem 'rackup'
gem 'puma'

app.rb

require 'sinatra'
require 'sinatra/reloader'
require 'logger'

# DB操作するなら追加
require 'sinatra/activerecord'

# ログ設定
log_file = File.join(File.dirname(__FILE__), 'log', 'app.log')
logger = Logger.new(log_file, 'daily')

configure do
  set :logger, logger
end

before do
  logger.info "#{request.request_method} #{request.path} - Params: #{params}"
end

# DB操作するなら追加
ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3', # 実態がファイルなので扱いが楽
  database: './db/db名.db'
)


# ルーティング(ここではindexのみとする)
get '/' do
  # ここに処理
  erb :index
end

views/index.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>タイトル名</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/index.css">
  </head>

  <body>
    <div class="container">
      ここにコンテンツ
    </div>

    <script type="text/javascript" src="/js/index.js"></script>
  </body>
</html>


public/js/index.js

  window.onload = function() {
    ここに処理
  });

public/css/index.css

ここに処理