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.
- A Oracle Linux VM (192.168.100.145)
- Ubuntu (192.168.100.154)
- 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;
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