How to Deploy Wazuh Agents using Ansible

How can you deploy Wazuh agents? In this tutorial, you will learn how to Deploy Wazuh agents using Ansible. Ansible is a simple IT automation tool that can be used to provision the underlying infrastructure of your environment, virtualized hosts and hypervisors, network devices, and bare metal servers. It can also install services, add compute hosts, and provision resources, services, and applications inside of your cloud.

How to Deploy Wazuh Agents using Ansible

In my test environment, I have a number of systems that we can use to demonstrate how you can deploy Wazuh agents using Ansible on.

  1. A Oracle Linux VM (192.168.100.145)
  2. Ubuntu (192.168.100.154)
  3. Debian (192.168.100.126)

So, how to deploy Wazuh agents using Ansible?

Install Ansible on Control Node

On the node that you want to use to control other nodes in your infrastructure, you have to install ansible.

python3 -m pip install --upgrade pip
python3 -m pip install ansible

Confirm your installation by checking installed version;

ansible --version

Enable Ansible command autocomplete;

python3 -m pip install argcomplete

Create Ansible User

On the controller and all other managed nodes, create a non root user account with sudo rights (username can be anything meaningful to you);

Debian systems;

useradd -m -G sudo -s /bin/bash itnixpro

RHEL systems

useradd -m -G wheel -s /bin/bash itnixpro
passwd itnixpro

Configure SSH Key Authentication for Ansible User

On the control node, generate password-less SSH keys as the ansible user created above;

su - intnixpro
ssh-keygen

Copy the keys to the managed nodes;

for i in 192.168.100.126 192.168.100.154 192.168.100.145; do ssh-copy-id itnixpro@$i; done

Define Ansible Hosts Inventory on Control Node

Ansible automates tasks on managed nodes or hosts in your infrastructure, using a list or group of lists known as inventory.

To begin with, create Ansible working directory;

mkdir ~/ansible

Next, create config file for ansible;

touch ~/ansible/ansible.cfg

Next, define Ansible hosts inventory.

vim ~/ansible/ansible.cfg
[defaults]
inventory      = ~/ansible/hosts
interpreter_python      = /usr/bin/python3

Note that we also defined the path to the default Python interpreter.

Since we are not using the default global config file, you can set your custom path using the ANSIBLE_CONFIG variable ;

export ANSIBLE_CONFIG=~/ansible/ansible.cfg

To ensure that the environment variable is loaded every time you login, set it on your bashrc file;

echo 'export ANSIBLE_CONFIG=~/ansible/ansible.cfg' \
>> ~/.bashrc
source .bashrc

Now, define the managed hosts addresses on the inventory file;

vim ~/ansible/hosts

hosts addresses can be IPs or resolveable hostnames;

[linux_nodes]
192.168.100.126
192.168.100.154
192.168.100.145

Save and exit the file.

Note that we created a group of nodes called linux_nodes with their respective IP addresses;

You can list nodes;

ansible-inventory --list --yaml

Sample output;

all:
  children:
    linux_nodes:
      hosts:
        192.168.100.126: {}
        192.168.100.154: {}
        192.168.100.145: {}
    ungrouped: {}

You can pass option -i path-to-hosts file if you want.

Test Connectivity to Managed Hosts

You can ping the managed hosts using the ansible ping module to confirm if they are reachable from the control node;

ansible linux_nodes -m ping

Sample output;

192.168.100.126 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.100.154 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.100.145 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Create Wazuh Agent Installation Playbook Roles and Tasks

Now that all seems good, proceed to create an Ansible role that installs and configures the Wazuh agent on remote managed hosts;

See our setup tree;

tree ~/ansible/
/home/itnixpro/ansible/
├── ansible.cfg
├── hosts
├── main.yml
└── roles
    └── wazuh-agent
        └── tasks
            ├── Debian.yml
            ├── main.yml
            └── RedHat.yml

3 directories, 6 files

Let’s create Ansible roles path;

mkdir ~/ansible/roles

Update the roles path in the Ansible configuration file;

echo "roles_path    = ~/ansible/roles" >> ~/ansible/ansible.cfg

Next, create wazuh-agent installation specific role and tasks. Tasks defines an ‘action’ to be applied to the managed host.

mkdir -p ~/ansible/roles/wazuh-agent/tasks

To begin with, we will create a task to Download and install Wazuh agent Debian systems;

vim ~/ansible/roles/wazuh-agent/tasks/Debian.yml
---
- name: Download Wazuh Agent for Debian/Ubuntu
  get_url:
    url: "https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_{{ wazuh_version }}-1_amd64.deb"
    dest: "/tmp/wazuh-agent-{{ wazuh_version }}.deb"

- name: Install Wazuh Agent on Debian/Ubuntu
  ansible.builtin.shell: |
    WAZUH_MANAGER={{ wazuh_manager }} dpkg -i /tmp/wazuh-agent-{{ wazuh_version }}.deb

Next, create a task to Download and install Wazuh agent on Rocky/Oracle/CentOS/RedHat systems;

vim ~/ansible/roles/wazuh-agent/tasks/RedHat.yml
---
- name: Download and Install RedHat/CentOS Wazuh Agent
  ansible.builtin.shell: |
    WAZUH_MANAGER={{ wazuh_manager }} yum install https://packages.wazuh.com/4.x/yum/wazuh-agent-{{ wazuh_version }}-1.x86_64.rpm -y

Create a main tasks file to include the above tasks and to define how to start the Wazuh agent service.

vim ~/ansible/roles/wazuh-agent/tasks/main.yml
---
- name: Debian/Ubuntu Agent Install Task
  include_tasks: "Debian.yml"
  when: ansible_distribution in ['Debian', 'Ubuntu']

- name: RedHat/Rocky/CentOS Agent Install Task
  include_tasks: "RedHat.yml"
  when: ansible_os_family == "RedHat"

- name: Start and enable Wazuh Agent Service
  systemd:
    name: wazuh-agent
    state: started
    enabled: yes
  when: ansible_distribution in ['Debian', 'Ubuntu'] or ansible_os_family == "RedHat"

Next, define the main Wazuh agent deployment playbook;

vim ~/ansible/main.yml
---
#
# Sample Main Playbook
#
- hosts: all
  gather_facts: True
  vars:
    wazuh_manager: "192.168.100.159"
    wazuh_version: "4.3.10"
  remote_user: itnixpro
  become: yes
  roles:
    - wazuh-agent

Perform Ansible Wazuh Agent Deployment Dry Run

Run dry run to confirm if all is good without actually doing anything;

ansible-playbook ~/ansible/main.yml -C --ask-become-pass

Note that we didn’t setup passwordless sudo and hence the use of --ask-become-pass option.

PLAY [all] *****************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [192.168.100.126]
ok: [192.168.100.154]
ok: [192.168.100.145]

TASK [wazuh-agent : Debian/Ubuntu Agent Install Task] **********************************************************************************************************************
skipping: [192.168.100.145]
included: /home/itnixpro/ansible/roles/wazuh-agent/tasks/Debian.yml for 192.168.100.126, 192.168.100.154

TASK [wazuh-agent : Download Wazuh Agent for Debian/Ubuntu] ****************************************************************************************************************
changed: [192.168.100.126]
changed: [192.168.100.154]

TASK [wazuh-agent : Install Wazuh Agent on Debian/Ubuntu] ******************************************************************************************************************
skipping: [192.168.100.126]
skipping: [192.168.100.154]

TASK [wazuh-agent : RedHat/Rocky/CentOS Agent Install Task] ****************************************************************************************************************
skipping: [192.168.100.126]
skipping: [192.168.100.154]
included: /home/itnixpro/ansible/roles/wazuh-agent/tasks/RedHat.yml for 192.168.100.145

TASK [wazuh-agent : Download and Install RedHat/CentOS Wazuh Agent] ********************************************************************************************************
skipping: [192.168.100.145]

TASK [wazuh-agent : Start and enable Wazuh Agent Service] ******************************************************************************************************************
fatal: [192.168.100.126]: FAILED! => {"changed": false, "msg": "Could not find the requested service wazuh-agent: host"}
fatal: [192.168.100.154]: FAILED! => {"changed": false, "msg": "Could not find the requested service wazuh-agent: host"}
fatal: [192.168.100.145]: FAILED! => {"changed": false, "msg": "Could not find the requested service wazuh-agent: host"}

PLAY RECAP *****************************************************************************************************************************************************************
192.168.100.126            : ok=3    changed=1    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0   
192.168.100.145            : ok=2    changed=0    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0   
192.168.100.154            : ok=3    changed=1    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0

It is now time to deploy Wazuh agents using Ansible playbooks;

ansible-playbook ~/ansible/main.yml --ask-become-pass
PLAY [all] *****************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [192.168.100.126]
ok: [192.168.100.154]
ok: [192.168.100.145]

TASK [wazuh-agent : Debian/Ubuntu Agent Install Task] **********************************************************************************************************************
skipping: [192.168.100.145]
included: /home/itnixpro/ansible/roles/wazuh-agent/tasks/Debian.yml for 192.168.100.126, 192.168.100.154

TASK [wazuh-agent : Download Wazuh Agent for Debian/Ubuntu] ****************************************************************************************************************
ok: [192.168.100.126]
ok: [192.168.100.154]

TASK [wazuh-agent : Install Wazuh Agent on Debian/Ubuntu] ******************************************************************************************************************
changed: [192.168.100.126]
changed: [192.168.100.154]

TASK [wazuh-agent : RedHat/Rocky/CentOS Agent Install Task] ****************************************************************************************************************
skipping: [192.168.100.126]
skipping: [192.168.100.154]
included: /home/itnixpro/ansible/roles/wazuh-agent/tasks/RedHat.yml for 192.168.100.145

TASK [wazuh-agent : Download and Install RedHat/CentOS Wazuh Agent] ********************************************************************************************************
changed: [192.168.100.145]

TASK [wazuh-agent : Start and enable Wazuh Agent Service] ******************************************************************************************************************
changed: [192.168.100.126]
changed: [192.168.100.154]
changed: [192.168.100.145]

PLAY RECAP *****************************************************************************************************************************************************************
192.168.100.126            : ok=5    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.100.145            : ok=4    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.100.154            : ok=5    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

The agents have been successfully deployed;

You can check status using ansible as well;

ansible -m shell -a "systemctl status wazuh-agent" linux_nodes

Sample output;

192.168.100.126 | CHANGED | rc=0 >>
● wazuh-agent.service - Wazuh agent
     Loaded: loaded (/lib/systemd/system/wazuh-agent.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-02-24 20:19:23 EAT; 28min ago
    Process: 563 ExecStart=/usr/bin/env /var/ossec/bin/wazuh-control start (code=exited, status=0/SUCCESS)
      Tasks: 30 (limit: 1133)
     Memory: 426.2M
        CPU: 20.020s
     CGroup: /system.slice/wazuh-agent.service
             ├─1245 /var/ossec/bin/wazuh-execd
             ├─1256 /var/ossec/bin/wazuh-agentd
             ├─1270 /var/ossec/bin/wazuh-syscheckd
             ├─1281 /var/ossec/bin/wazuh-logcollector
             └─1298 /var/ossec/bin/wazuh-modulesd

Warning: some journal files were not opened due to insufficient permissions.
192.168.100.145 | CHANGED | rc=0 >>
● wazuh-agent.service - Wazuh agent
     Loaded: loaded (/usr/lib/systemd/system/wazuh-agent.service; enabled; vendor preset: disabled)
     Active: active (running) since Fri 2023-02-24 21:42:12 +04; 5min ago
    Process: 791 ExecStart=/usr/bin/env /var/ossec/bin/wazuh-control start (code=exited, status=0/SUCCESS)
      Tasks: 30 (limit: 5843)
     Memory: 568.8M
        CPU: 18.023s
     CGroup: /system.slice/wazuh-agent.service
             ├─908 /var/ossec/bin/wazuh-execd
             ├─925 /var/ossec/bin/wazuh-agentd
             ├─941 /var/ossec/bin/wazuh-syscheckd
             ├─954 /var/ossec/bin/wazuh-logcollector
             └─982 /var/ossec/bin/wazuh-modulesd

Feb 24 21:42:05 localhost.localdomain env[791]: Deleting PID file '/var/ossec/var/run/wazuh-agentd-922.pid' not used...
Feb 24 21:42:05 localhost.localdomain env[791]: Deleting PID file '/var/ossec/var/run/wazuh-execd-910.pid' not used...
Feb 24 21:42:06 localhost.localdomain env[791]: Started wazuh-execd...
Feb 24 21:42:07 localhost.localdomain env[791]: Started wazuh-agentd...
Feb 24 21:42:08 localhost.localdomain env[791]: Started wazuh-syscheckd...
Feb 24 21:42:09 localhost.localdomain env[791]: Started wazuh-logcollector...
Feb 24 21:42:10 localhost.localdomain crontab[1080]: (root) LIST (root)
Feb 24 21:42:10 localhost.localdomain env[791]: Started wazuh-modulesd...
Feb 24 21:42:12 localhost.localdomain env[791]: Completed.
Feb 24 21:42:12 localhost.localdomain systemd[1]: Started Wazuh agent.
192.168.100.154 | CHANGED | rc=0 >>
● wazuh-agent.service - Wazuh agent
     Loaded: loaded (/lib/systemd/system/wazuh-agent.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2023-02-24 17:03:22 UTC; 44min ago
    Process: 756 ExecStart=/usr/bin/env /var/ossec/bin/wazuh-control start (code=exited, status=0/SUCCESS)
      Tasks: 31 (limit: 2237)
     Memory: 612.4M
        CPU: 31.788s
     CGroup: /system.slice/wazuh-agent.service
             ├─13020 /var/ossec/bin/wazuh-execd
             ├─13035 /var/ossec/bin/wazuh-agentd
             ├─13049 /var/ossec/bin/wazuh-syscheckd
             ├─13060 /var/ossec/bin/wazuh-logcollector
             └─13071 /var/ossec/bin/wazuh-modulesd

Warning: some journal files were not opened due to insufficient permissions.

You can also login to the Wazuh manager and check agent status;

From CLI;

/var/ossec/bin/agent_control -l

Output;


Wazuh agent_control. List of available agents:
   ID: 000, Name: rocky9 (server), IP: 127.0.0.1, Active/Local
   ID: 004, Name: localhost.localdomain, IP: any, Active
   ID: 003, Name: swarm02, IP: any, Active
   ID: 005, Name: debian11, IP: any, Active

List of agentless devices:

From Kibana Wazuh App;

Agents;

How to Deploy Wazuh Agents using Ansible
How to Deploy Wazuh Agents using Ansible

And that is how easy it is to deploy Wazuh Agents using Ansible.

Other Tutorials

Install Wazuh Server on Rocky Linux

Configure Elastic Endpoint Security Malware Detection and Prevention

Install Elastic Agents on Windows Systems

Founder of itnixpro.com|Linux Engineer|Author at Itnixpro.com

Leave a Comment