diff --git a/apps/api/src/services/awooop_ansible_post_verifier.py b/apps/api/src/services/awooop_ansible_post_verifier.py index 2d74a0d10..13bb5a944 100644 --- a/apps/api/src/services/awooop_ansible_post_verifier.py +++ b/apps/api/src/services/awooop_ansible_post_verifier.py @@ -46,10 +46,10 @@ ProbeRunner = Callable[..., Awaitable[ReadOnlyProbeResult]] _POSTCONDITION_REGISTRY: dict[str, tuple[AssetPostcondition, ...]] = { "ansible:wazuh-manager-posture-readback": ( AssetPostcondition( - "host_112_wazuh_manager_control_binary", + "host_112_wazuh_manager_unit_loaded", "security", "host_112", - "test -f /var/ossec/bin/wazuh-control", + "systemctl show --property=LoadState --value wazuh-manager.service | grep -Fxq loaded", ), AssetPostcondition( "host_112_wazuh_manager_runtime", diff --git a/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py b/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py index ec46fc3d7..9094f0a11 100644 --- a/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py +++ b/apps/api/tests/test_iwooos_wazuh_controlled_executor_runtime.py @@ -7,6 +7,7 @@ from pathlib import Path from unittest.mock import AsyncMock, MagicMock import pytest +import yaml from fastapi import FastAPI from fastapi.testclient import TestClient @@ -158,14 +159,14 @@ def test_wazuh_posture_catalog_and_playbook_are_bounded_no_write() -> None: "ansible:wazuh-manager-posture-readback" ) assert {condition.condition_id for condition in postconditions} == { - "host_112_wazuh_manager_control_binary", + "host_112_wazuh_manager_unit_loaded", "host_112_wazuh_manager_runtime", } assert {condition.inventory_host for condition in postconditions} == { "host_112" } assert {condition.probe for condition in postconditions} == { - "test -f /var/ossec/bin/wazuh-control", + "systemctl show --property=LoadState --value wazuh-manager.service | grep -Fxq loaded", "systemctl is-active --quiet wazuh-manager.service", } @@ -187,6 +188,25 @@ def test_wazuh_posture_catalog_and_playbook_are_bounded_no_write() -> None: ): assert forbidden not in source + inventory = yaml.safe_load( + (repo_root / "infra/ansible/inventory/hosts.yml").read_text() + ) + host_112 = inventory["all"]["children"]["security"]["hosts"]["host_112"] + assert host_112["ansible_user"] == "kali" + assert "ansible_skip_tags" not in host_112 + + service_registry = yaml.safe_load( + (repo_root / "ops/monitoring/service-registry.yaml").read_text() + ) + wazuh_manager = next( + node + for node in service_registry["nodes"] + if node.get("name") == "wazuh-manager" + ) + assert wazuh_manager["ip"] == "192.168.0.112" + assert wazuh_manager["port"] == 55000 + assert wazuh_manager["criticality"] == "P0" + @pytest.mark.asyncio async def test_wazuh_posture_scheduler_enqueues_after_mcp_and_log_evidence( diff --git a/infra/ansible/inventory/hosts.yml b/infra/ansible/inventory/hosts.yml index 3b27b3131..0e8e65a78 100644 --- a/infra/ansible/inventory/hosts.yml +++ b/infra/ansible/inventory/hosts.yml @@ -43,6 +43,5 @@ all: hosts: host_112: ansible_host: 192.168.0.112 - ansible_user: wooo + ansible_user: kali ansible_ssh_private_key_file: "~/.ssh/id_ed25519" - ansible_skip_tags: "all" # 預留,本次不執行 diff --git a/infra/ansible/playbooks/wazuh-manager-posture-readback.yml b/infra/ansible/playbooks/wazuh-manager-posture-readback.yml index 6c01af070..c8c27253a 100644 --- a/infra/ansible/playbooks/wazuh-manager-posture-readback.yml +++ b/infra/ansible/playbooks/wazuh-manager-posture-readback.yml @@ -7,20 +7,19 @@ any_errors_fatal: true tasks: - - name: Verify the Wazuh manager control binary is present - ansible.builtin.stat: - path: /var/ossec/bin/wazuh-control - register: wazuh_control_binary - changed_when: false - - - name: Require a local Wazuh manager installation - ansible.builtin.assert: - that: - - wazuh_control_binary.stat.exists - - wazuh_control_binary.stat.isreg - fail_msg: wazuh_manager_control_binary_missing - success_msg: wazuh_manager_control_binary_present + - name: Verify the Wazuh manager unit is loaded + ansible.builtin.command: + argv: + - /usr/bin/systemctl + - show + - --property=LoadState + - --value + - wazuh-manager.service + register: wazuh_manager_load_state + check_mode: false changed_when: false + failed_when: wazuh_manager_load_state.stdout | trim != 'loaded' + no_log: true - name: Verify the Wazuh manager service is active ansible.builtin.command: diff --git a/ops/monitoring/service-registry.yaml b/ops/monitoring/service-registry.yaml index e566ab8c8..10bafca81 100644 --- a/ops/monitoring/service-registry.yaml +++ b/ops/monitoring/service-registry.yaml @@ -498,6 +498,19 @@ nodes: - service_down owner: security-team + - name: wazuh-manager + ip: 192.168.0.112 + port: 55000 + role: security-manager + monitoring: + blackbox_tcp: true + prometheus_scrape: false + alerts: + - node_down + - service_down + criticality: P0 + owner: security-team + # Phase O-1.3 2026-04-02: MinIO 備份儲存 (Phase O 補完) - name: minio ip: 192.168.0.188