Configuration management of Wazuh endpoints using Ansible

| by | Wazuh 4.7.0
Post icon

Configuration management is the process of maintaining computer systems, servers, network devices, and software in a desired and consistent state. Configuration management tools allow you to quickly and remotely control large numbers of different endpoints in an automated way from a centralized location. There are several popular configuration management tools. These include Ansible, Chef, Puppet, and more. In this blog post, we have chosen Ansible for its little operational resource consumption.

Ansible is a free and open source configuration management tool that is agentless and extensible. Ansible is simple to configure and does not require an agent installed on the remote device you are configuring. It communicates by default over SSH channels to retrieve information from remote systems, execute commands, and copy files. Additionally, you can write modules in any language to extend their functionality for your use case.

Wazuh is an open source security platform with unified XDR and SIEM capabilities for endpoints and cloud workloads protection. It provides capabilities to remotely manage endpoints from the Wazuh server. However, you can’t provision Wazuh agents and configure some of the capabilities remotely from the Wazuh server. Wazuh is extensible and easily integrates with third-party platforms to enhance its detection capabilities. Some of these third-party applications are endpoint-dependent and need to be explicitly installed and configured.

In this blog post, we show how to automate the provisioning and configuration of multiple Wazuh agents with Ansible. This automation helps to easily manage endpoints and minimize time constraints thereby improving your organization’s resilience and security posture.

Overview of Ansible terminology

Getting started with Ansible requires full understanding of some key concepts used in its configuration management. These are listed below:

  • Control node: This is the management endpoint that runs Ansible.
  • Managed node: The endpoint that is managed by the control node.
  • Inventory file: A file that defines the specific nodes and groups of nodes to manage. It can also be used to define variables.
  • Playbook: A top-level set of plays that Ansible automates in sequential order. It is written in YAML format.
  • Play: An ordered list of tasks that maps to managed nodes in an inventory.
  • Tasks: A list of one or more modules that defines the operations that Ansible performs in a declarative manner.
  • Modules: A binary or script that Ansible runs on managed nodes. They can be written in any programming language as long as they return JSON key-value pairs.

Prerequisites

To demonstrate how we can provision and configure multiple Wazuh endpoints with Ansible, we use the following infrastructure.

  • A CentOS 7 endpoint with the Wazuh central components (Wazuh server, Wazuh indexer, and Wazuh dashboard) installed. Follow the Quickstart guide to install Wazuh 4.7.0.
  • A CentOS 7 endpoint to install Ansible.
  • An Ubuntu 23.04 endpoint to deploy and configure the Wazuh Linux agent 4.7.0
  • A Windows 11 endpoint to deploy and configure the Wazuh Windows agent 4.7.0.

Architecture

The architecture diagram below provides an overview of a sample deployment.

Configuration management Architecture Diagram

The following table shows the parameters we used to demonstrate our deployment.

EndpointsPurposeIP addressSoftware
CentOS 7Control node172.16.1.11Ansible
Ubuntu 23.04Managed node172.16.1.13SSH
Windows 11Managed node172.16.1.12WinRM

We create and use the non-root user account, ansible, and password, pass123, to manage all the endpoints.

Note: You can use any user credentials and IP addresses as it suits your environment. In which case, ensure to change the parameters where necessary in the blog post.

Setting up Ansible for configuration management

In this section, we show how to install and configure Ansible for configuration management.

Installing Ansible

Perform the following steps to install Ansible on the control node.

1. Update and install the CentOS 7 EPEL repository:

$ sudo yum update -y
$ sudo yum install epel-release -y

2. Install the latest version of Ansible:

$ sudo yum install ansible -y

3. Confirm the installation by checking the installed version:

$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

Configuring Ansible nodes

Ansible manages its nodes through an inventory file. We configure the inventory file with the nodes we want to manage with Ansible.

Perform the following steps as the root user to configure Ansible on the control node.

1. Define the nodes to be managed in the /etc/ansible/hosts inventory file using the following format:

[unix]
Ubuntu-23.04 ansible_ssh_host=172.16.1.13

[windows]
Windows-11 ansible_host=172.16.1.12

2. Reference the inventory file in the /etc/ansible/ansible.cfg Ansible configuration file:

# echo "inventory = /etc/ansible/hosts" >> /etc/ansible/ansible.cfg

Creating an Ansible user

The root user is the administrative user in Linux endpoints with elevated privileges. For management purposes, we create a non-root user with administrative privileges to run Ansible automation.

Perform the steps below to create an Ansible user for the control and managed nodes.

Control node

1. Create a user, ansible, with sudo rights:

$ useradd -m -G wheel -s /bin/bash ansible

2. Assign a password to the user. Enter the password, pass123, when prompted:

$ sudo passwd ansible

3. Verify the created user:

$ getent passwd | grep ansible
ansible:x:1001:1001::/home/ansible:/bin/bash

Ubuntu endpoint

1. Create a user, ansible, with sudo rights:

$ sudo useradd -m -G sudo -s /bin/bash ansible

2. Assign a password to the user. Enter the password, pass123, when prompted.

$ sudo passwd ansible

3. Verify the created user:

$ getent passwd | grep ansible
ansible:x:1001:1001::/home/ansible:/bin/bash

Windows endpoint

Run the commands in PowerShell as Administrator.

1. Run the command below and enter the password, pass123, for the new local administrator account. This command stores the password in the $Password variable to use in step 2.

> $Password = Read-Host -AsSecureString

2. Create the new administrator account:

> New-LocalUser "ansible" -Password $Password -FullName "Ansible User" -Description "Local admin"

3. Add the user account to the Administrators user group:

> Add-LocalGroupMember -Group "Administrators" -Member "ansible"

4. Verify the created account:

> Get-LocalUser | findstr ansible
ansible   	True	Local admin

Configuring authentication for the Ansible user

The control node needs to authenticate to the managed nodes to establish communication. We can authenticate to the managed nodes using passwordless or password-based authentication.

SSH key-based authentication

Public key authentication provides cryptographic strength that allows automated and passwordless login ensuring better security. Linux endpoints are preconfigured with SSH which Ansible uses for authentication.

Perform the steps below to set up SSH key-based authentication for Ansible.

Ubuntu endpoint

By default, Linux endpoints are shipped with SSH clients. So, we don’t need to perform anything on this endpoint.

Control node

1. Switch to the ansible user and enter the password, pass123, when prompted:

$ su - ansible

2. Generate an SSH key pair. Press the Enter key when prompted to keep the default settings.

$ ssh-keygen -t ed25519

The command generates a private key, id_ed25519, and a public key, id_ed25519.pub, in the /home/ansible/.ssh/ directory.

Note: If you enter a passphrase, you will need both the private key and the passphrase to log in to the managed nodes. In our case, we leave the passphrase blank to use just the private key for authentication.

3. Copy the public key to the Ubuntu endpoint while entering the password, pass123, when prompted:

$ ssh-copy-id -i ~/.ssh/id_ed25519.pub ansible@172.16.1.13

For multiple Linux endpoints, perform the steps below to create a playbook and install the SSH public key to the endpoints.

a. Test the connectivity to the Linux endpoints.

b. Create a playbook file, deploy-sshkey.yml, in the /home/ansible/ directory:

$ touch ~/deploy-sshkey.yml

a. Add the following configuration to the /home/ansible/deploy-sshkey.yml playbook file:

---
  - name: "DEPLOY SSH PUBLIC KEY ON UNIX ENDPOINTS"
    hosts: unix

    tasks:
      - name: "Deploy SSH public key to the Ubuntu endpoint"
        authorized_key:
          user: ansible
          state: present
          key: "{{lookup('file','/home/ansible/.ssh/id_ed25519.pub')}}"

b. Verify the syntax of the playbook to ensure that it is valid:

$ ansible-playbook --syntax-check ~/deploy-sshkey.yml
playbook: /home/ansible/ansible/deploy-sshkey.yml

c. Run the playbook and enter the password of the user, ansible, when prompted:

$ ansible-playbook --ask-pass ~/deploy-sshkey.yml
PLAY [DEPLOY SSH PUBLIC KEY ON UNIX ENDPOINTS] **************************

TASK [Gathering Facts] **************************************************
ok: [Ubuntu-23.04]

TASK [Deploy SSH public key to the Ubuntu endpoint] ********************
changed: [Ubuntu-23.04]

PLAY RECAP *************************************************************************
Ubuntu-23.04               	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0

Password-based authentication

This authentication method requires the user to enter their credentials (username and password) to confirm their identity. Unlike UNIX endpoints, Ansible has added SSH authentication for Windows 10+ and Windows Server 2019+ endpoints but it is experimental. So, we use the Windows Remote Management (WinRM) service.

Windows endpoint

Ansible requires the following prerequisites to communicate with a Windows endpoint to use its modules via WinRM:

  • Powershell 3.0 or newer.
  • NET Framework 4.0 or newer.

It’s necessary to preconfigure WinRM for use with Ansible.

We create an HTTPS listener for WinRM using self-signed certificates. This is to enable secure communication between the control node and the Windows endpoint. Then, we enable the basic authentication option of the service. We recommend using a more secure authentication option like certificates, Kerberos, NTLM, and CredSSP.

Run the commands in PowerShell as Administrator to configure WinRM with Ansible.

1. By default, only the HTTP listener runs on the WinRM service:

> winrm enumerate winrm/config/Listener
Listener
	Address = *
	Transport = HTTP
	Port = 5985
	Hostname
	Enabled = true
	URLPrefix = wsman
	CertificateThumbprint
	ListeningOn = 10.0.2.15, 127.0.0.1, 172.16.1.12, ::1, fe80::79bd:5d38:88f1:1d94%15, fe80::9a15:b31b:6da:c704%14

2. Get the hostname of the Windows endpoint:

> Write-Output $env:COMPUTERNAME
DESKTOP-RIRUMBD

3. Create a self-signed certificate and get its thumbprint. Replace <DNS_NAME> in the command below with the hostname gotten in step 2:

> New-SelfSignedCertificate -DnsName "<DNS_NAME>" -CertStoreLocation Cert:\LocalMachine\My
   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\My

Thumbprint                            	Subject
----------                            	-------
40B103A047AC9960F2488B4E244D86AD2DEE7A38  CN=DESKTOP-RIRUMBD

4. Register the HTTPS listener in WinRM:

> winrm create winrm/config/Listener?Address=*+Transport=HTTPS '@{Hostname="<DNS_NAME>"; CertificateThumbprint="<CERTIFICATE_THUMBPRINT>"}'

Replace:

  • <DNS_NAME> with the Windows endpoint hostname obtained above.
  • <CERTIFICATE_THUMBPRINT> with the thumbprint of the certificate.

5. Open port 5986 on the firewall to allow traffic from the control node:

> netsh advfirewall firewall add rule name="Windows Remote Management (HTTPS-In)" dir=in action=allow protocol=TCP localport=5986

6. Verify the listeners running on the WinRM service:

> winrm enumerate winrm/config/Listener
Listener
	Address = *
	Transport = HTTP
	Port = 5985
	Hostname
	Enabled = true
	URLPrefix = wsman
	CertificateThumbprint
	ListeningOn = 10.0.2.15, 127.0.0.1, 172.16.1.12, ::1, fe80::79bd:5d38:88f1:1d94%15, fe80::9a15:b31b:6da:c704%14

Listener
	Address = *
	Transport = HTTPS
	Port = 5986
	Hostname = DESKTOP-RIRUMBD
	Enabled = true
	URLPrefix = wsman
	CertificateThumbprint = 40B103A047AC9960F2488B4E244D86AD2DEE7A38
	ListeningOn = 10.0.2.15, 127.0.0.1, 172.16.1.12, ::1, fe80::79bd:5d38:88f1:1d94%15, fe80::9a15:b31b:6da:c704%14

We now have two listeners, the default WinRM HTTP listener (listening on port 5985) and the new Ansible HTTPS listener (listening on port 5986).

Optional: Remove the default HTTP listener since Ansible uses the more secure HTTPS listener:

> winrm delete winrm/config/Listener?Address=*+Transport=HTTP

7. Enable basic authentication if it is not enabled by default:

> Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true

Control node

1. Install the python2-winrm.noarch package for Ansible to communicate with Windows over WinRM and support its modules:

$ sudo yum install python2-winrm.noarch

2. Append the configurations below to the /etc/ansible/hosts inventory file:

[windows:vars]
ansible_user=ansible
ansible_password=pass123
ansible_port=5986
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_server_cert_validation=ignore

Where:

  • ansible_user defines the username created in the Windows node.
  • ansible_password defines the password for that user.
  • ansible_port defines the port to use for the connection.
  • ansible_connection=winrm defines winrm as the connection to use and not SSH.
  • ansible_winrm_transport defines the authentication type.
  • ansible_winrm_server_cert_validation is set to ignore enabling Ansible to ignore server certificate validation. We do not recommend this approach in production environments.

Note: We recommend storing the ansible_user and ansible_password parameters in an Ansible Vault file for better security.

Testing the connectivity to the managed nodes

The connection between the control node and every managed node is paramount to configuring the managed nodes. From the control node, we test the connectivity to the managed nodes to ensure that Ansible can successfully communicate with them. Ansible provides the ping and the win_ping modules to check the connection from the control node to remote UNIX and Windows nodes respectively.

On the control node, perform the following steps to check the connectivity between nodes.

1. Test the connectivity to UNIX nodes using the Ansible ping module:

$ ansible unix -m ping
Ubuntu-23.04 | SUCCESS => {
	"ansible_facts": {
    	     "discovered_interpreter_python": "/usr/bin/python3"
	},
	"changed": false,
	"ping": "pong"
}

2. Test the connectivity to Windows nodes using the Ansible win_ping module:

> ansible windows -m win_ping
Windows-11 | SUCCESS => {
	"changed": false,
	"ping": "pong"
}

The test shows that there is now connectivity between the control node and the managed nodes.

Use cases

Ansible allows you to manage nodes in two different ways: via ad hoc commands and via playbooks. We implement playbooks in the following use cases to execute a list of ordered tasks on the managed nodes.

Perform the following initial steps on the control node before proceeding to the use cases.

1. Switch to the Ansible management user, ansible, and enter the password, pass123, when prompted:

$ su - ansible

2. Create a directory, ~/ansible/playbooks/, to store the playbooks:

$ mkdir -p ~/ansible/playbooks

Standalone Wazuh agents deployment

Some organizations keep critical systems and data offline to maintain regulatory compliance requirements and to provide an additional layer of security. This significantly reduces their exposure to online threats minimizing the risk of unauthorized access and data breaches.

In this use case, we deploy the Wazuh agents in offline mode to the Ubuntu and the Windows endpoints.

Configuration

Perform the following steps on the control node.

1. Download the Wazuh Linux and Windows packages for offline installation:

$ wget -P /tmp https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.7.0-1_amd64.deb
$ wget -P /tmp https://packages.wazuh.com/4.x/windows/wazuh-agent-4.7.0-1.msi 

2. Create a playbook file, deploy-agent.yml, in the /home/ansible/playbooks/ directory:

$ touch ~/ansible/playbooks/deploy-agent.yml

3. Add the following configuration to the /home/ansible/playbooks/deploy-agent.yml playbook file. Replace <WAZUH_SERVER_IP> with the IP address of the Wazuh server:

---
  - name: "1 - DEPLOY WAZUH AGENT 4.7.0 ON UNIX ENDPOINTS"
    hosts: unix
    become: yes
    remote_user: ansible
    vars:
      wazuh_server: "<WAZUH_SERVER_IP>"

    tasks:
      - name: "1 - Copy the Wazuh agent package to the Ubuntu endpoint"
        tags: copy_wazuh_deb
        copy:
          src: /tmp/wazuh-agent_4.7.0-1_amd64.deb
          dest: /tmp
          mode: '0774'

      - name: "2 - Deploy the Wazuh agent on the Ubuntu endpoint"
        ansible.builtin.shell: WAZUH_MANAGER={{wazuh_server}} WAZUH_AGENT_NAME="Ubuntu-23.04" sudo dpkg -i /tmp/wazuh-agent_4.7.0-1_amd64.deb
        when: ansible_os_family == "Debian"

      - name: "3 - Start and enable the Wazuh agent service"
        systemd:
          name: wazuh-agent
          state: started
          enabled: yes

  - name: "2 - DEPLOY WAZUH AGENT 4.7.0 ON WINDOWS ENDPOINTS"
    hosts: windows
    remote_user: ansible
    vars:
      wazuh_server: "<WAZUH_SERVER_IP>"

    tasks:
      - name: "1 - Copy the Wazuh package to the Windows endpoint"
        tags: copy_wazuh_win
        win_copy:
          src: /tmp/wazuh-agent-4.7.0-1.msi
          dest: C:\Users\ansible\AppData\Local\Temp\
          mode: '0774'

      - name: "2 - Deploy the Wazuh agent on the Windows endpoint"
        win_package:
          path: C:\Users\ansible\AppData\Local\Temp\wazuh-agent-4.7.0-1.msi
          product_id: Wazuh-4.7.0
          arguments: '/q WAZUH_MANAGER={{wazuh_server}} WAZUH_AGENT_NAME="Windows-11"'
          state: present

      - name: "3 - Start and enable the Wazuh agent service"
        win_service:
          name: wazuh
          start_mode: auto
          state: restarted

4. Verify the syntax of the playbook to ensure that it is valid:

$ ansible-playbook --syntax-check ~/ansible/playbooks/deploy-agent.yml
playbook: /home/ansible/ansible/playbooks/deploy-agent.yml

5. Run the playbook:

$ ansible-playbook ~/ansible/playbooks/deploy-agent.yml --extra-vars "ansible_sudo_pass=pass123"
PLAY [1 - DEPLOY WAZUH AGENT 4.7.0 ON UNIX ENDPOINTS] *************

TASK [Gathering Facts] ********************************************
ok: [Ubuntu-23.04]

TASK [1 - Copy the Wazuh agent package to the Ubuntu endpoint] ****
changed: [Ubuntu-23.04]

TASK [2 - Deploy the Wazuh agent on the Ubuntu endpoint] **********
changed: [Ubuntu-23.04]

TASK [3 - Start and enable the Wazuh agent service] ***************
changed: [Ubuntu-23.04]

PLAY [2 - DEPLOY WAZUH AGENT 4.7.0 ON WINDOWS ENDPOINTS] **********

TASK [Gathering Facts] ********************************************
ok: [Windows-11]

TASK [1 - Copy the Wazuh package to the Windows endpoint] *********
changed: [Windows-11]

TASK [2 - Deploy the Wazuh agent on the Windows endpoint] *********
changed: [Windows-11]

TASK [3 - Start and enable the Wazuh agent service] ***************
changed: [Windows-11]

PLAY RECAP *******************************************************************
Ubuntu-23.04              	: ok=4	changed=3	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0
Windows-11             	: ok=4	changed=3	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0

Validating the Wazuh agents deployment

Visit the Wazuh dashboard and click on Agents to view the deployed agents.

Wazuh Agents Deployment

Configuring Wazuh modules on multiple endpoints

The Wazuh Security Configuration Assessment (SCA) and command monitoring capabilities require explicit configuration on endpoints to execute remote commands from the Wazuh server.

In this use case, we configure the Ubuntu and the Windows endpoints with command monitoring to receive remote commands from the Wazuh server. Additionally, we show how to modify and remove the configurations.

Adding a configuration to a file if it does not exist

Configuration

1. Create a playbook file, config-agent-01.yml, in the /home/ansible/playbooks/ directory:

$ touch ~/ansible/playbooks/config-agent-01.yml

2. Add the following configuration to the /home/ansible/playbooks/config-agent-01.yml playbook file:

---
  - name: "1 - ADD CONFIG ON UNIX NODES IF NOT PRESENT"
    hosts: unix
    
    tasks:
      - name: "Add the config, [wazuh_command.remote_commands=1] if not present"
        become: yes
        remote_user: ansible
        tags: addUnixConfig
        lineinfile:
          path: /var/ossec/etc/local_internal_options.conf
          line: "wazuh_command.remote_commands=1"
          state: present
          backup: yes
        register: addUnixConfigOut

  - name: "2 - ADD CONFIG ON WINDOWS NODES IF NOT PRESENT"
    hosts: windows
    
    tasks:
      - name: "Add the config, [wazuh_command.remote_commands=1] if not present"
        remote_user: ansible
        tags: addWinConfig
        win_lineinfile:
          path: C:\Program Files (x86)\ossec-agent\local_internal_options.conf
          line: "wazuh_command.remote_commands=1"
          state: present
          backup: yes
        register: addUnixConfigOut

3. Verify the syntax of the playbook to ensure that it is valid:

$ ansible-playbook --syntax-check ~/ansible/playbooks/config-agent-01.yml
playbook: /home/ansible/ansible/playbooks/config-agent-01.yml

4. Run the playbook:

$ ansible-playbook ~/ansible/playbooks/config-agent-01.yml --extra-vars "ansible_sudo_pass=pass123"
PLAY [1 - ADD CONFIG ON UNIX NODES IF NOT PRESENT] *************************

TASK [Gathering Facts] *****************************************************
ok: [Ubuntu-23.04]

TASK [Add the config, [wazuh_command.remote_commands=1] if not present] ****
changed: [Ubuntu-23.04]

PLAY [2 - ADD CONFIG ON WINDOWS NODES IF NOT PRESENT] **********************

TASK [Gathering Facts] *****************************************************
ok: [Windows-11]

TASK [Add the config, [wazuh_command.remote_commands=1] if not present] ****
changed: [Windows-11]

PLAY RECAP ****************************************************************************
Ubuntu-23.04       	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0   
Windows-11             	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0

Validating the configuration

1. Verify the added configuration on the Ubuntu node with the command below:

$ sudo cat /var/ossec/etc/local_internal_options.conf
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades.
wazuh_command.remote_commands=1

2. Verify the added configuration on the Windows node with the PowerShell command below:

> cat "C:\Program Files (x86)\ossec-agent\local_internal_options.conf"
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades
# but will be removed when the agent is un-installed.
wazuh_command.remote_commands=1

Modifying a configuration file

Configuration

1. Create a playbook file, config-agent-02.yml, in the /home/ansible/playbooks/ directory:

$ touch ~/ansible/playbooks/config-agent-02.yml

2. Add the following configuration to the /home/ansible/playbooks/config-agent-02.yml playbook file.

---
  - name: "1 - MODIFY CONFIG ON UNIX NODES"
    hosts: unix
    
    tasks:
      - name: "Modify the config, [wazuh_command.remote_commands=1]"
        become: yes
        remote_user: ansible
        tags: modifyUnixConfig
        lineinfile:
          path: /var/ossec/etc/local_internal_options.conf
          # The config to search
          regexp: "wazuh_command.remote_commands=1" 
          # The config to replace
          line: "wazuh_command.remote_commands=0"
          state: present
          backup: yes
        register: modifyUnixConfigOut

  - name: "2 - MODIFY CONFIG ON WINDOWS NODES"
    hosts: windows
    
    tasks:
      - name: "Modify the config, [wazuh_command.remote_commands=1]"
        remote_user: ansible
        tags: modifyWinConfig
        win_lineinfile:
          path: C:\Program Files (x86)\ossec-agent\local_internal_options.conf
          # The config to search
          regexp: "wazuh_command.remote_commands=1" 
          # The config to replace
          line: "wazuh_command.remote_commands=0"
          state: present
          backup: yes
        register: modifyWinConfigOut

3. Verify the syntax of the playbook to ensure that it is valid:

$ ansible-playbook --syntax-check ~/ansible/playbooks/config-agent-02.yml
playbook: /home/ansible/ansible/playbooks/config-agent-02.yml

4. Run the playbook:

$ ansible-playbook ~/ansible/playbooks/config-agent-02.yml --extra-vars "ansible_sudo_pass=pass123"
PLAY [1 - MODIFY CONFIG ON UNIX NODES] *************************************

TASK [Gathering Facts] *****************************************************
ok: [Ubuntu-23.04]

TASK [Modify the config, [wazuh_command.remote_commands=1]] ****************
changed: [Ubuntu-23.04]

PLAY [2 - MODIFY CONFIG ON WINDOWS NODES] **********************************

TASK [Gathering Facts] *****************************************************
ok: [Windows-11]

TASK [Modify the config, [wazuh_command.remote_commands=1]] ****************
changed: [Windows-11]

PLAY RECAP ****************************************************************************
Ubuntu-23.04       	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0   
Windows-11             	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0

Validating the configuration

1. Verify the modified configuration on the Ubuntu node with the command below:

$ sudo cat /var/ossec/etc/local_internal_options.conf
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades.
wazuh_command.remote_commands=0

2. Verify the modified configuration on the Windows node with the PowerShell command below:

> cat "C:\Program Files (x86)\ossec-agent\local_internal_options.conf"
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades
# but will be removed when the agent is un-installed.
wazuh_command.remote_commands=0

Removing a configuration from a file

Configuration

1. Create a playbook file, config-agent-03.yml, in the /home/ansible/playbooks/ directory:

$ touch ~/ansible/playbooks/config-agent-03.yml

2. Add the following configuration to the /home/ansible/playbooks/config-agent-03.yml playbook file:

---
  - name: "1 - REMOVE CONFIG ON UNIX NODES"
    hosts: unix
    
    tasks:
      - name: "Remove the config, [wazuh_command.remote_commands=1 or 0]"
        become: yes
        remote_user: ansible
        tags: removeUnixConfig
        lineinfile:
          path: /var/ossec/etc/local_internal_options.conf
          # The config to search
          regexp: "wazuh_command.remote_commands=[10]" 
          # State is set to absent to remove config if found
          state: absent
          backup: yes
        register: removeUnixConfigOut

  - name: "2 - REMOVE CONFIG ON WINDOWS NODES"
    hosts: windows
    
    tasks:
      - name: "Remove the config, [wazuh_command.remote_commands=1 or 0]"
        remote_user: ansible
        tags: removeWinConfig
        win_lineinfile:
          path: C:\Program Files (x86)\ossec-agent\local_internal_options.conf
          # The config to search
          regexp: "wazuh_command.remote_commands=[10]" 
          # State is set to absent to remove config if found
          state: absent
          backup: yes
        register: removeWinConfigOut

3. Verify the syntax of the playbook to ensure that it is valid:

$ ansible-playbook --syntax-check ~/ansible/playbooks/config-agent-03.yml
playbook: /home/ansible/ansible/playbooks/config-agent-03.yml

4. Run the playbook:

$ ansible-playbook ~/ansible/playbooks/config-agent-03.yml --extra-vars "ansible_sudo_pass=pass123"
PLAY [1 - REMOVE CONFIG ON UNIX NODES] *************************************

TASK [Gathering Facts] *****************************************************
ok: [Ubuntu-23.04]

TASK [Remove the config, [wazuh_command.remote_commands=1 or 0]] ***********
changed: [Ubuntu-23.04]

PLAY [2 - REMOVE CONFIG ON WINDOWS NODES] **********************************

TASK [Gathering Facts] *****************************************************
ok: [Windows-11]

TASK [Remove the config, [wazuh_command.remote_commands=1 or 0]] ***********
changed: [Windows-11]

PLAY RECAP ****************************************************************************
Ubuntu-23.04       	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0   
Windows-11             	: ok=2	changed=1	unreachable=0	failed=0	skipped=0	rescued=0	ignored=0

Validating the configuration

1. Verify the removed configuration on the Ubuntu node with the command below:

$ sudo cat /var/ossec/etc/local_internal_options.conf
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades.

2. Verify the removed configuration on the Windows node with the PowerShell command below:

> cat "C:\Program Files (x86)\ossec-agent\local_internal_options.conf"
# local_internal_options.conf
#
# This file should be handled with care. It contains
# run time modifications that can affect the use
# of OSSEC. Only change it if you know what you
# are doing. Look first at ossec.conf
# for most of the things you want to change.
#
# This file will not be overwritten during upgrades
# but will be removed when the agent is un-installed.

Conclusion

In a digital world where threats are constant and resources limited, the ability to efficiently manage your Wazuh endpoints isn’t just a luxury but a necessity. It empowers you to stay ahead of cyber adversaries, minimize vulnerabilities, and respond proactively to security incidents in a timely manner.

We show how to use Ansible, a powerful and versatile toolset to effectively automate the management of Wazuh endpoints with ease.

Learn more about the open source Wazuh security platform and its capabilities to protect against malware and gain visibility of your infrastructure. You can also join our Slack community of professionals and users if you have any questions on this blog post or Wazuh in general.

References