オフラインでの
インストールとアップグレード

GitHub にも PyPI にも接続できない Wazuh Manager 向けの手順です。インターネットに接続できるマシンで、リリース本体と必要な Python パッケージを 1 つのアーカイブにまとめて持ち込み、その中のインストーラーを実行します。Manager 側からネットワークへの接続は一切発生しません。

はじめに

必要なもの

  • Python 3 と pip のあるインターネットに接続できるマシン(Linux・macOS・Windows のいずれでも可)。 いちばん簡単なのは Docker のある Linux マシンです。
  • ファイル 1 つ(約 10 MB)を Manager へ運ぶ手段:USB メモリ、踏み台経由の scp など。
  • Wazuh Manager の root 権限。クラスタ構成ではマスターノードです。ワーカーやエージェントには何も入れません。

まず Manager で 2 つの値を確認する

Wazuh Manager Python パッケージは Python のバージョンと CPU ごとにビルドされているため、アーカイブをこれに合わせる必要があります:

/usr/bin/python3 -V
uname -m

サービスは /usr/bin/python3 で動くので、基準になるのはそのバージョンです。たとえば Python 3.9.25 → 3.9、そして x86_64。Manager に pip は不要です。

リリースを選ぶ。リリース一覧は GitHub Releases にあります。以下の X.Y.Z は選んだバージョン(先頭の v なし)です。 install.sh --offline は v1.19.0 より後のリリースで使えます。v1.19.0 以前は 手動の手順を使ってください。

1. アーカイブを作る

リリースをダウンロードする

接続できるマシン

VER=X.Y.Z
curl -fsSLO https://github.com/jasoncheng7115/jt-wazuh-mgr/archive/refs/tags/v$VER.tar.gz
tar xzf v$VER.tar.gz                  # jt-wazuh-mgr-$VER/ ができる

GitHub が作るアーカイブの中のディレクトリ名は jt-wazuh-mgr-X.Y.Z(v なし)です。

Python パッケージ(wheel)をダウンロードする —— 推奨の方法

接続できるマシン Manager と同じ Python バージョンで pip download を実行します。使い捨てのコンテナを使うのが いちばん簡単です。3.9 は Manager のバージョンに置き換えてください:

docker run --rm -v "$PWD":/w -w /w python:3.9-slim \
    pip download --only-binary=:all: -r jt-wazuh-mgr-$VER/requirements.txt -d jt-wazuh-mgr-$VER/wheels

Manager と同じ OS リリースのマシンで同じ pip download を実行しても構いません。 --only-binary=:all: を付けると、wheel が無い場合に Manager ではなくこの接続できるマシンの上で失敗します。 コンテナは起動したマシンの CPU で動くので、x86 のマシンで ARM の Manager 向けに準備する場合は次の方法を使ってください。

Docker が無い場合:別の Python バージョン向けにダウンロードする

接続できるマシン pip は自分とは異なるバージョン向けの wheel も取得できます:

python3 -m pip download -r jt-wazuh-mgr-$VER/requirements.txt "importlib-metadata>=3.6" \
    --only-binary=:all: --implementation cp --python-version 3.9 \
    --platform manylinux2014_x86_64 --platform manylinux_2_17_x86_64 \
    -d jt-wazuh-mgr-$VER/wheels
  • --python-version には最初に確認した Manager のバージョンを指定します。
  • ARM の Manager(aarch64)では manylinux2014_aarch64 と manylinux_2_17_aarch64 にします。
  • "importlib-metadata>=3.6" は消さないでください。この方法では pip が条件付きの依存関係を 自分自身の Python で判定するため、Flask が Python 3.9 でだけ必要とするパッケージが抜け落ちます。 その結果、3.9 の Manager(RHEL 9、Rocky/Alma 9、Amazon Linux 2023、Wazuh manager コンテナ)では No matching distribution found for importlib-metadata で止まります。他のバージョンでは害はありません。
wheels/ ディレクトリ 1 つにつき Python バージョンは 1 つ。Manager ごとに Python の バージョンが異なる場合は、バージョンごとにアーカイブを作ってください。

まとめる

接続できるマシン

tar czf jt-wazuh-mgr-$VER-offline.tar.gz jt-wazuh-mgr-$VER
sha256sum jt-wazuh-mgr-$VER-offline.tar.gz > jt-wazuh-mgr-$VER-offline.tar.gz.sha256

2. Manager にインストールする

コピー、検証、展開、インストール

Wazuh Manager 2 つのファイルを(たとえば /root に)コピーし、root で実行します:

cd /root
sha256sum -c jt-wazuh-mgr-X.Y.Z-offline.tar.gz.sha256
tar xzf /root/jt-wazuh-mgr-X.Y.Z-offline.tar.gz -C /root
bash /root/jt-wazuh-mgr-X.Y.Z/install.sh --offline

展開には必ず -C を付け、インストーラーはフルパスで実行してください。そうすれば、 その時いるディレクトリによって結果が変わることはありません。

--offline が行うこと

  • 展開したディレクトリから、プログラム、ルールパックのカタログ、アイコン、サービスファイル、uninstall.sh を /opt/jt-wazuh-mgr にコピーします。curl・apt/dnf・PyPI は使いません。
  • config.yaml はまだ存在しない場合にだけ書き込みます。
  • wheels/ の Python パッケージを /opt/jt-wazuh-mgr/vendor に入れます。システムの Python には 書き込みません。pip があれば pip install --no-index、無ければこの Python に合う wheel をそのまま展開します (wheel は zip です)。まず vendor.new に作り、import できることを確かめてから入れ替えるので、 アーカイブに問題があっても動いている環境は変わりません。
  • /etc/systemd/system/jt-wazuh-mgr.service を配置して有効化・起動し、2 秒後にまだ動いているかを確認します。

wheel を別の場所に置いた場合:install.sh --offline --wheels /path/to/wheels

3. 確認する

インストーラーの表示ではなく、システムから結果を読み戻す

Wazuh Manager

grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py     # インストールしたバージョン
systemctl is-active jt-wazuh-mgr                       # active
curl -ks -o /dev/null -w '%{http_code}\n' https://127.0.0.1:5000/login   # 200
journalctl -u jt-wazuh-mgr -n 20 --no-pager            # 上のどれかがおかしいとき

続いて https://YOUR_WAZUH_MANAGER_IP:5000 を開き、Wazuh API ユーザーでログインします(Dashboard が使う wazuh-wui アカウントは避けてください)。上の curl が 200 を返すのにブラウザーから届かない場合は、 Manager のファイアウォールで TCP 5000 を開けてください。

4. アップグレード

同じ手順で、新しいバージョンのアーカイブを使う

  1. 接続できるマシン 新しい X.Y.Z のアーカイブを手順 1 とまったく同じように作ります。
  2. Wazuh Manager 現在のインストールとサービスファイルをバックアップします:
    tar czf /root/jt-wazuh-mgr-backup-$(date +%F).tar.gz -C /opt jt-wazuh-mgr
    cp /etc/systemd/system/jt-wazuh-mgr.service /root/jt-wazuh-mgr.service.bak-$(date +%F)
  3. Wazuh Manager 新しいリリースを展開し、そのインストーラーを実行します:
    tar xzf /root/jt-wazuh-mgr-X.Y.Z-offline.tar.gz -C /root
    bash /root/jt-wazuh-mgr-X.Y.Z/install.sh --offline
  4. Wazuh Manager 手順 3 のとおり確認します。バージョンは必ず /opt/jt-wazuh-mgr から読み戻し、 ブラウザーは Ctrl+Shift+R で再読み込みしてください。

アップグレードで残るもの、置き換わるもの

残るconfig.yaml、--ssl-auto が生成した証明書(ssl_cert.pem・ ssl_key.pem)、wazuh_agent_mgr.log、 /etc/systemd/system/jt-wazuh-mgr.service.d/ に置いたドロップイン、Manager にインストール済みのルールパック (/var/ossec/etc/...、状態は /var/ossec/etc/jt-packs/)。
置き換わるプログラムファイル、/opt/jt-wazuh-mgr/packs のルールパックのカタログ、アイコン、 /etc/systemd/system/jt-wazuh-mgr.service、アーカイブに wheel がある場合は vendor/。

ルールパックは「ルールパック」タブから別途更新します。カタログのバージョンが Manager 上のものより新しいパックに印が付き、 何かを変更する前に計画が表示されます。更新後は全ノードでルールセットを再読み込みしてください。

新しいリリースの requirements.txt がインストール済みのものと同じなら (diff /opt/jt-wazuh-mgr/requirements.txt /root/jt-wazuh-mgr-X.Y.Z/requirements.txt)、wheel は省略できます。 wheels/ ディレクトリが無いとき、インストーラーは現在の vendor/ が import できる限りそれを残します。 とはいえ、毎回 wheel を持ち込むほうが単純です。

5. 切り戻し

手順 4 のバックアップに戻す

Wazuh Manager 失敗したバージョンは削除せず脇へ移しておくと、あとから調べられます:

systemctl stop jt-wazuh-mgr
mv /opt/jt-wazuh-mgr /opt/jt-wazuh-mgr.failed
tar xzf /root/jt-wazuh-mgr-backup-YYYY-MM-DD.tar.gz -C /opt
cp /root/jt-wazuh-mgr.service.bak-YYYY-MM-DD /etc/systemd/system/jt-wazuh-mgr.service
systemctl daemon-reload
systemctl start jt-wazuh-mgr
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py

YYYY-MM-DD はバックアップのファイル名にある日付に置き換えます。旧バージョンが再び動いたら /opt/jt-wazuh-mgr.failed は削除して構いません。

手動の手順(--offline を使わない場合)

v1.19.0 以前、または各ステップを自分で確認したい場合

Wazuh Manager install.sh --offline が行うことを書き出したものです。root で、手順 2 のとおり アーカイブを展開した後に実行します(アップグレードの場合は手順 4 のバックアップも先に):

VER=X.Y.Z
SRC=/root/jt-wazuh-mgr-$VER
DST=/opt/jt-wazuh-mgr
mkdir -p "$DST"
cp -r "$SRC"/wazuh_agent_mgr.py "$SRC"/create_api_user.py "$SRC"/requirements.txt \
      "$SRC"/lib "$SRC"/packs "$SRC"/images "$SRC"/jt-wazuh-mgr.service "$SRC"/uninstall.sh "$DST"/
[ -f "$DST/config.yaml" ] || cp "$SRC/config.yaml" "$DST/"      # 既存の設定は上書きしない
rm -rf "$DST/vendor.new"

次に Python パッケージを vendor.new に入れます。どちらか一方を実行してください:

# a) Manager に pip がある
python3 -m pip install --no-index --find-links "$SRC/wheels" --target "$DST/vendor.new" -r "$DST/requirements.txt"

# b) pip が無い:wheel は zip
mkdir "$DST/vendor.new"
for w in "$SRC"/wheels/*.whl; do python3 -m zipfile -e "$w" "$DST/vendor.new"; done

import できた場合だけ入れ替え、サービスを(再)起動します:

PYTHONPATH="$DST/vendor.new" /usr/bin/python3 -c 'import flask, yaml, requests, rich, tabulate' \
  && rm -rf "$DST/vendor" && mv "$DST/vendor.new" "$DST/vendor"
cp "$DST/jt-wazuh-mgr.service" /etc/systemd/system/
systemctl daemon-reload
systemctl enable jt-wazuh-mgr
systemctl restart jt-wazuh-mgr

最後に手順 3 のとおり確認します。

wheel が合わないとき

No matching distribution found

ERROR: No matching distribution found for PyYAML>=6.0 The wheels in /root/jt-wazuh-mgr-X.Y.Z/wheels do not cover requirements.txt for Python 3.12.

wheel が別の Python バージョンまたは CPU 向けにダウンロードされています。インストーラーは vendor/ に触れる前、 サービスを再起動する前に止まるので、動いているバージョンはそのまま使えます(プログラムファイルはすでにコピー済みで、 次の再起動で反映されます)。/usr/bin/python3 -V と uname -m を確認し直し、そのバージョン向けに wheels/ を作り直して(手順 1)インストーラーを再実行するか、 切り戻してください。

足りないのが importlib-metadata なら、--python-version の方法でその追加引数なしに wheel を作っています。 手順 1 を参照してください。

wheel が Python 3.x で import できない

The wheels in ... do not import on Python 3.9 (missing, or built for another Python version).

原因は同じで、pip の無い Manager ではこう表示されます。ビルド済みのパッケージ(PyYAML、MarkupSafe、charset-normalizer)は ファイル名に Python バージョン(例:cp39)を含み、合うものだけが使われます。Manager のバージョン向けに wheel を作り直してください。

wheel がまだ公開されていない Python バージョン

非常に新しい、あるいは珍しい Python バージョンでは、PyPI のビルド済み wheel が追いついていないことがあり、 --only-binary=:all: が接続できるマシンの上で失敗します。その場合は Manager と同じ OS リリース・同じ Python バージョンのマシンで wheel を自分で作ります(wheel が公開されていないパッケージはソースからビルドされ、 コンパイラーが必要になることがあります):

python3 -m pip wheel -r jt-wazuh-mgr-$VER/requirements.txt -w jt-wazuh-mgr-$VER/wheels

wheel の代わりにディストリビューションのパッケージを使う

Manager から社内のパッケージミラーを使えるなら、ディストリビューションのパッケージでも動きます。それをインストールし、 アーカイブには wheels/ を入れずにおけば、モジュールがすでに import できるのでインストーラーはそのまま進みます:

apt install python3-flask python3-yaml python3-requests python3-rich python3-tabulate   # Debian / Ubuntu

requirements.txt は Flask 2.3 以上を要求します。この方法を選ぶ前に、ディストリビューションのバージョンを 確認してください(apt-cache policy python3-flask)。

インターネットなしでのルールパック

パックのインストール、更新、削除にインターネットは不要です。パックはツールに同梱されており、「ルールパック」タブからインストールします。接続が必要になりうるのは、一部のパックがインストール後に行う処理です。そうしたパックのデプロイ手順には「マネージャーがインターネットに接続できない場合」(または監視対象ホスト向けの同等の手順)があり、具体的なコマンドが書かれています。

パック接続が必要なものオフラインでの方法
jt-ioc、jt-malware-hash脅威フィード(マスターがダウンロード)接続できるマシンで更新プログラムを実行し、キャッシュをマスターにコピーして --skip-download で実行。スケジュールは --reload-if-stale でダウンロードを止めます。
jt-phpphp.net のリリース情報別の場所でリリースファイルをダウンロードし、etc/jt-packs/offline/php/ にコピーして --source file://… で読み込みます。
jt-runtime-vulnCISA KEV、Node.js・Python・OpenVPN のリリース情報同様に、各ソースに file:// オプションがあります。
jt-alert-digestTeams、Slack、Discord、Telegram、LINEメール(社内 SMTP リレー)、Zulip、Mattermost、汎用 webhook は社内ネットワークで動作します。クラウドのチャネルは https_proxy 経由、または設定しません。
jt-webオプションの Cloudflare ブロックのみproxy= を設定するか、有効にしません。nginx のブロックはオフラインで動作します。
jt-container-vuln各 Docker ホストの Trivy イメージとデータベース社内レジストリにコピーし、スキャナーをそこに向けます。
jt-docker、jt-vc-portalDocker ホストの Python docker ライブラリ社内パッケージミラー、または接続できるマシンで pip download。
jt-portable-detect、jt-linux-integrityホストの Sysmon(Windows)と auditd(Linux)Sysmon64.exe をコピー。auditd は社内ミラーから。
jt-ucs、jt-synology、jt-jitsi監視対象サーバーのパッケージまたはイメージ 1 つ社内リポジトリ、パッケージの手動インストール、または社内レジストリ。
その他不要

パックの更新で消えないオプション

ツールはパックのインストールや更新のたびに /etc/cron.d/jt-<パック> を書き直すため、そのファイルは編集しないでください。サイトのオプションは /var/ossec/etc/jt-packs/<パック>.cron.local(root 所有、他者は書き込み不可)に置きます。<スクリプト>: <オプション> の行はそのスクリプトにオプションを追加し、NAME=value の行は環境変数を設定します。ツールはスケジュールを書くたびにこれを適用します。すぐに適用するには、ルールパックタブでそのパックを開き「スケジュールを書き直す」を押します。ワーカーのスケジュールは手作業でコピーしたものなので、そちらにも同じオプションを追加してください。

# /var/ossec/etc/jt-packs/jt-ioc.cron.local
update-threat-ip-list.py: --reload-if-stale

# /var/ossec/etc/jt-packs/jt-alert-digest.cron.local
https_proxy=http://proxy.example.com:3128
no_proxy=localhost,127.0.0.1

オフラインのコピーは自分では古くなりません。セキュリティリリースのたびに更新し、パックに stale_hours がある場合は設定してください。取り込みが遅れるとアラートになります。

オフライン環境でのその他の注意

インターネットなしで動くもの、動かないもの

  • Wazuh とやり取りする機能はすべて動きます。このツールが使うのは Manager 自身の API とファイルだけです。
  • ルールパックはリリースに同梱のカタログからインストールされます。インストール後に一部のパックが行う処理には接続が必要な場合があります。インターネットなしでのルールパックを参照してください。
  • 設定エディターのシンタックスハイライトはブラウザーが cdnjs から読み込みます。読み込めなくてもエディターは 使え、色が付かないだけです。

アンインストール

オフラインでもそのまま使えます:bash /opt/jt-wazuh-mgr/uninstall.sh。上書きされた元のファイルを 復元したい場合は、先に「ルールパック」タブからインストール済みのパックを削除してください。

ほかの問題はインストールとアップグレードのトラブルシューティングを参照してください。