安裝與升級
疑難排解

安裝腳本一遇到失敗就立刻中止,所以失敗常常看起來像什麼事都沒發生。 在下面找到你看到的訊息 —— 每個答案都會說明腳本當下正在做什麼,以及改成執行什麼。

先從這裡開始

安裝中斷了,但沒有印出有用的訊息

腳本以 set -e 執行:第一個失敗的指令會立刻結束整個流程, 而那個指令自己的錯誤訊息可能已經捲過去了。加上追蹤重跑一次,留下最後幾行:

curl -fsSL https://raw.githubusercontent.com/jasoncheng7115/jt-wazuh-mgr/main/install.sh -o /tmp/jt-install.sh
sudo bash -x /tmp/jt-install.sh 2>&1 | tail -40

錯誤之前的最後一行 + 就是真正失敗的指令。拿它對照下面的章節。

安裝腳本會動到哪些地方

  • /opt/jt-wazuh-mgr/ —— 程式檔案、規則套件,以及你的 config.yaml
  • /etc/systemd/system/jt-wazuh-mgr.service —— 服務設定檔,每次執行都會被重寫
  • 依 requirements.txt 以 pip 安裝的 Python 套件
你的設定不會被動到。config.yaml 只有在不存在時才會下載, 升級永遠不會覆蓋它。

應該裝在哪一台?

裝在 Wazuh Manager 本機;叢集環境則要裝在 master 節點。 這個工具會從 /var/ossec 讀取規則集與 manager 自己的檔案, 所以沒辦法從別台機器管理一台 manager。

確認你在 manager 上、而不是 agent:

/var/ossec/bin/wazuh-control info
ls /var/ossec/etc/rules/    # manager 有這個目錄,agent 沒有

下載失敗

curl: (6) Could not resolve host / (7) Failed to connect

curl: (6) Could not resolve host: raw.githubusercontent.com

這台 manager 連不到 GitHub。這很正常 —— 很多 Wazuh Manager 本來就刻意放在隔離網段。 兩條路可走:

  • 如果有 proxy,執行前先設定:
    export https_proxy=http://proxy.example.com:3128
    export http_proxy=$https_proxy
    curl -fsSL https://raw.githubusercontent.com/jasoncheng7115/jt-wazuh-mgr/main/install.sh | sudo -E bash
    sudo -E 很重要 —— 少了它,sudo 會把 proxy 變數丟掉。
  • 如果完全沒有對外路由,走下面的離線安裝。

curl: (60) SSL certificate problem

curl: (60) SSL certificate problem: unable to get local issuer certificate

通常是兩種情況之一:CA 憑證庫過舊,或是公司的資安設備在中間攔截 TLS、換上自己的憑證。

# 更新 CA 憑證庫
sudo apt update && sudo apt install --reinstall ca-certificates   # Debian / Ubuntu
sudo dnf reinstall ca-certificates                                  # RHEL / Rocky

如果是設備在檢查流量,請把它的 CA 加進系統憑證庫,而不是關掉驗證。 不要對安裝腳本用 curl -k —— 那等於下載一份你無法驗證來源的程式碼。

裝好了,但「規則套件」分頁是空的

規則套件的檔案是盡力而為地下載:索引或某個檔案抓不到時,安裝腳本會說一聲然後繼續, 而不是讓整個安裝失敗。

- packs (skipped, index unavailable)

等網路恢復後重跑一次安裝腳本即可,不需要先還原任何東西。

Python 相依套件

error: externally-managed-environment

error: externally-managed-environment × This environment is externally managed

Debian 12、Ubuntu 23.04 以後的版本會拒絕 pip install 寫進系統 Python, 以免 pip 與發行版的套件管理程式爭搶同一批檔案。 在較新的作業系統上,這是安裝或升級中斷最常見的原因。

三個做法,建議照這個順序考慮:

  1. 改用發行版的套件安裝相依套件。最乾淨,而且跟著 OS 升級走:
    sudo apt install python3-flask python3-requests python3-yaml
    然後重跑安裝腳本 —— pip 會發現東西都在了。
  2. 明確告訴 pip 你接受風險(發行版套件版本太舊時):
    sudo pip install --break-system-packages -r /opt/jt-wazuh-mgr/requirements.txt
    sudo systemctl restart jt-wazuh-mgr
    這個參數的名字很誠實:pip 可能覆蓋掉套件管理程式擁有的檔案。
  3. 用虛擬環境做完整隔離 —— 見以虛擬環境執行。

pip: command not found

install.sh: line 107: pip: command not found

很多系統只有 pip3 而沒有 pip 這個名稱,有些則兩個都沒有。 裝好之後重跑安裝腳本:

sudo apt install python3-pip     # Debian / Ubuntu
sudo dnf install python3-pip     # RHEL / Rocky / Alma

如果貴單位的政策完全不允許使用 pip,就改用發行版套件安裝那三個相依套件(見上一則)。

pip 連不到 PyPI

WARNING: Retrying ... Connection to pypi.org timed out

跟前面的下載失敗是同一種隔離,只是發生在比較後面的步驟。 此時程式檔案其實已經就位,缺的只有相依套件。 改用發行版套件安裝,或自己把 wheel 檔複製進來 —— 見離線安裝。

以虛擬環境執行

如果你希望完全不碰系統 Python:

sudo python3 -m venv /opt/jt-wazuh-mgr/venv
sudo /opt/jt-wazuh-mgr/venv/bin/pip install -r /opt/jt-wazuh-mgr/requirements.txt

再用 drop-in 讓服務指向它 —— drop-in 不會被日後的升級蓋掉:

sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
Environment=PATH=/opt/jt-wazuh-mgr/venv/bin:/usr/bin:/bin
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr

服務起不來

先把真正的原因讀出來

兩個指令就會說出哪裡出錯,下面幾乎每個答案都是從它們來的:

systemctl status jt-wazuh-mgr --no-pager -l
journalctl -u jt-wazuh-mgr -n 50 --no-pager

ModuleNotFoundError: No module named 'flask'

ModuleNotFoundError: No module named 'flask'

檔案裝好了但相依套件沒有 —— pip 那一步在更早之前就失敗了, 而因為 set -e 的關係你可能沒注意到。 回到 Python 相依套件 處理完後:

sudo systemctl restart jt-wazuh-mgr

Address already in use/5000 埠沒有回應

OSError: [Errno 98] Address already in use

有別的程式占用了這個埠。先找出是誰:

sudo ss -tlnp | grep :5000

要嘛停掉那個服務,要嘛用 drop-in 換一個埠 —— 這樣升級時不會被還原:

sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
ExecStart=
ExecStart=/opt/jt-wazuh-mgr/wazuh_agent_mgr.py --web --ssl-auto --port 5443
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr

那一行空的 ExecStart= 是必要的:它先清掉原本的設定,新的才會生效。

服務有起來,但瀏覽器連不上

從機器本身往外測。如果第一個指令有回應、第二個沒有,那就是防火牆的問題,不是工具的問題:

curl -kIs https://127.0.0.1:5000/ | head -1      # 在 manager 上執行
sudo firewall-cmd --add-port=5000/tcp --permanent && sudo firewall-cmd --reload   # RHEL 系列
sudo ufw allow 5000/tcp                                                            # Ubuntu

注意網址是 https,而且使用 --ssl-auto 時憑證是自簽的, 瀏覽器會警告一次。

升級

升級跑完了,但版本沒有變

不要只看安裝腳本最後那行摘要,直接從安裝路徑本身把版本讀回來:

grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py
systemctl is-active jt-wazuh-mgr

如果檔案顯示的是新版、但介面仍是舊的,清掉過期的位元組碼再重啟:

sudo rm -rf /opt/jt-wazuh-mgr/lib/__pycache__
sudo systemctl restart jt-wazuh-mgr

然後用略過快取的方式重新整理瀏覽器(Ctrl+Shift+R)。

我改過的服務設定檔被升級蓋掉了

這是已知行為。每次執行安裝腳本都會把內建的服務設定檔複製到 /etc/systemd/system/jt-wazuh-mgr.service。 任何你「直接改在那個檔案上」的內容 —— 換埠、User=、Environment= —— 都會在下次升級時消失。

先還原一次,然後把設定搬進 drop-in,安裝腳本永遠不會碰它:

sudo mkdir -p /etc/systemd/system/jt-wazuh-mgr.service.d
sudo tee /etc/systemd/system/jt-wazuh-mgr.service.d/override.conf <<'EOF'
[Service]
Environment=PYTHONPATH=/opt/jt-wazuh-mgr/vendor
EOF
sudo systemctl daemon-reload && sudo systemctl restart jt-wazuh-mgr

改完用 systemctl cat jt-wazuh-mgr 確認實際生效的內容。

升級會動到我的設定或已安裝的規則套件嗎?

不會。config.yaml 已存在時會直接跳過。 你已安裝的規則套件放在 Wazuh manager 自己的目錄裡 (/var/ossec/etc/rules、etc/lists、etc/decoders), 安裝狀態記在 /var/ossec/etc/jt-packs/; 升級工具只會更新它提供給你的套件目錄清單。

退回前一個版本

升級前先備份,隨時可以退回去:

sudo tar czf /root/jt-wazuh-mgr-backup-$(date +%F).tar.gz -C /opt jt-wazuh-mgr
# 退回
sudo systemctl stop jt-wazuh-mgr
sudo tar xzf /root/jt-wazuh-mgr-backup-YYYY-MM-DD.tar.gz -C /opt
sudo systemctl start jt-wazuh-mgr
一定要用 -C。少了它會解壓到當前目錄, 而之後的版本檢查可能剛好讀到解錯位置的那一份,於是顯示「成功」但其實什麼都沒換。

離線與封閉網路安裝

manager 完全沒有對外網路時怎麼裝

在有網路的機器上抓好,再把結果搬過去。

在有網路的機器上:

git clone --depth 1 https://github.com/jasoncheng7115/jt-wazuh-mgr.git
tar czf jt-wazuh-mgr.tgz -C jt-wazuh-mgr lib packs images \
    wazuh_agent_mgr.py create_api_user.py requirements.txt \
    config.yaml jt-wazuh-mgr.service uninstall.sh
pip download -r jt-wazuh-mgr/requirements.txt -d wheels
tar czf wheels.tgz wheels

在 manager 上:

sudo mkdir -p /opt/jt-wazuh-mgr
sudo tar xzf jt-wazuh-mgr.tgz -C /opt/jt-wazuh-mgr
tar xzf wheels.tgz
sudo pip install --no-index --find-links=wheels -r /opt/jt-wazuh-mgr/requirements.txt
sudo cp /opt/jt-wazuh-mgr/jt-wazuh-mgr.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now jt-wazuh-mgr
wheel 要用相同的 Python 版本產生。編譯型套件是綁直譯器版本的: 為 Python 3.10 產生的 wheel 在 3.12 上匯入會失敗。 動手前先在兩台機器上都確認 python3 -V。

離線環境要怎麼升級

不要在那台跑 install.sh —— 它會嘗試連 GitHub 與 PyPI, 而且會覆蓋掉你可能為了這個環境而客製過的服務設定檔。只換程式檔案就好:

sudo systemctl stop jt-wazuh-mgr
sudo tar xzf jt-wazuh-mgr.tgz -C /opt/jt-wazuh-mgr
sudo rm -rf /opt/jt-wazuh-mgr/lib/__pycache__
sudo systemctl start jt-wazuh-mgr
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py

相依套件很少在版本之間變動;若 requirements.txt 真的改了, 再一併把新的 wheel 搬過去。

裝好了,但有地方不對

登入頁出得來,但帳號密碼被拒絕

這裡的帳號密碼是 Wazuh API 使用者,不是作業系統帳號,也不是你的 Dashboard 登入帳號。 先確認 API 本身有回應:

curl -k -u <帳號>:<密碼> https://127.0.0.1:55000/security/user/authenticate

安裝 Wazuh 當時產生的密碼在 wazuh-install-files.tar 裡, 通常就在你執行 Wazuh 安裝程式的那個目錄下。 要替這個工具另外建一個專用帳號:

sudo /opt/jt-wazuh-mgr/create_api_user.py

設定編輯器沒有語法高亮

編輯器元件是從 CDN 載入的,所以在隔離網段取不到。 編輯功能仍然正常,只是少了顏色。這個不需要處理。

完整移除

sudo bash /opt/jt-wazuh-mgr/uninstall.sh

你安裝到 manager 裡的規則套件不會被這個指令移除 —— 如果要一併清掉,請先從「規則套件」分頁移除,這樣被覆蓋的原始檔才會被正確還原。

還是不行

回報時請附上這些

這四項幾乎能讓任何安裝問題一眼看出原因:

cat /etc/os-release | head -2
python3 -V
grep __version__ /opt/jt-wazuh-mgr/lib/__init__.py
journalctl -u jt-wazuh-mgr -n 50 --no-pager

再加上本頁第一則裡 bash -x 輸出的最後 40 行。到 github.com/jasoncheng7115/jt-wazuh-mgr/issues 開一則 issue。

貼上之前請先看過。Wazuh manager 的記錄會帶有你環境中的主機名稱與位址。 凡是你不會放到公開頁面上的內容,請先代換掉。
沒有符合的答案。試試直接用錯誤訊息裡的字詞搜尋。