We are committed to provide service 24 X 7

Deals, Shopping, Training, Tools

Learn how to – Deploy Wazuh Security Platform on Linux using Ansible

Learn how to – Deploy Wazuh Security Platform on Linux using Ansible.

Wazuh Security Platform is a free and open-source enterprise-ready platform that can be used to perform real-time integrity monitoring, threat detection, incident response, and compliance. It helps collect, index, aggregate, and analyze the security data which may contain system threats or abnormalities. What makes it niftier is that it can be used to protect workloads on both private and public clouds as well as on-premise data centers.

The Wazuh solution is made of the following components:

  • Wazuh Server – It is used to analyze the data received from the agents. It processes this data through decoders and rules.
  • Wazuh indexer – This is a full-text search and analytics engine with high scalability. Its main function is to index and store alerts from the Wazuh server
  • Wazuh dashboard – a web-based UI used to visualize the data analysis.
  • Wazuh agents – it is installed on endpoints. These are desktops, laptops, servers, cloud instances, or virtual machines.

The Wazuh Security Platform finds its use in the following areas:

  • Cloud Security by offering posture management, Workload protection, and Container security
  • Security Operations that include; Malware Detection, Log Data Analysis, Audit, Compliance e.t.c
  • Endpoint Security with Configuration Assessment, Extended Detection and Response, and File Integrity Monitoring
  • Threat Intelligence through Threat hunting, IT Hygiene, and Vulnerability Detection

Ansible is an open-source automation tool that simplifies the deployment and management of repetitive tasks. The tasks are defined/described in a descriptive language based on YAML.

This guide offers the required steps on how to deploy the Wazuh Security Platform on Linux using Ansible.

Getting Started

For this guide, we will have the following:

  • Ansible Control Node
  • Wazuh server – For the Wazuh stack installation
  • Wazuh agent – For the Wazuh agent installation

Update your server and install the required tools:

## On Debian/Ubuntu
sudo apt update && sudo apt upgrade
sudo apt install curl vim git

## On RHEL/CentOS/RockyLinux 8
sudo yum -y update
sudo yum -y install curl vim git

## On Fedora
sudo dnf update
sudo dnf -y install curl vim git

#1. Install and Configure Ansible on Linux

The first step involves installing Ansible and configuring the agents. This guide offers an easy method to install Ansible on your control node.

Ensure that PIP is installed on your system.

##On Debian/Ubuntu
sudo apt update
sudo apt install python3 python3-pip -y

##On CentOS/Rocky Linux/Alma Linux
sudo yum install python3 python3-pip -y

Using PIP, install Ansible with the command:

sudo pip3 install ansible

Alternatively, you can install Ansible from your package manager as shown.

##On Ubuntu
sudo apt install ansible

##On Debian
echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" | sudo tee -a /etc/apt/sources.list.d/ansible-debian.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
sudo apt-get update
sudo apt-get install ansible

##On CentOS/Rocky Linux/Alma Linux
sudo yum install epel-release
sudo yum install ansible

Verify the installation.

$ ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov  9 2021, 14:44:26) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]

Configuring SSH key-pairing.

For the Ansible control node to communicate with the endpoints, we need to configure and export SSH keys for each managed node.

First, create the Ansible hosts inventory file.

$ sudo vim /etc/ansible/hosts
[wazuh_server] ansible_ssh_user=username

[wazuh_agents] ansible_ssh_user=username

Remember to replace the username with the exact SSH username on the managed node. Generate and copy SSH keys of the managed nodes.

ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub username@
ssh-copy-id -i ~/.ssh/id_rsa.pub username@

Verify the communication.

$ ansible all -m ping | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    "changed": false,
    "ping": "pong"
} | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    "changed": false,
    "ping": "pong"

#2. Obtain the Wazuh Ansible Playbooks and Roles

We need to obtain the required playbooks and roles for this installation. First, navigate to the Ansible roles directory.

cd /etc/ansible/roles/

Git clone the repository:

sudo git clone https://github.com/wazuh/wazuh-ansible.git

The file below should be available:

$ ls

#3. Install Wazuh Stack using Ansible

The Wazuh stack consist of the Wazuh server, Wazuh indexer and Wazuh dashboard. All these are deployed on the node intended to act as your Wazuh server.

First, ensure you are in the wazuh-ansible directory.

cd /etc/ansible/roles/wazuh-ansible/
tree roles -d

Sample Output:

├── ansible-galaxy
│   └── meta
└── wazuh
    ├── ansible-filebeat-oss
    │   ├── defaults
    │   ├── handlers
    │   ├── meta
    │   ├── tasks
    │   └── templates
    ├── ansible-wazuh-agent
    │   ├── defaults
    │   ├── handlers
    │   ├── meta
    │   ├── tasks
    │   └── templates
    ├── ansible-wazuh-manager
    │   ├── defaults
    │   ├── files
    │   │   └── custom_ruleset
    │   │       ├── decoders
    │   │       └── rules
    │   ├── handlers
    │   ├── meta
    │   ├── tasks
    │   ├── templates
    │   └── vars
    ├── vars
    ├── wazuh-dashboard
    │   ├── defaults
    │   ├── handlers
    │   ├── tasks
    │   ├── templates
    │   └── vars
    └── wazuh-indexer
        ├── defaults
        ├── handlers
        ├── meta
        ├── tasks
        └── templates

39 directories

You can see all the preconfigured playbooks with the command:

tree playbooks/

Sample Output:

├── ansible.cfg
├── wazuh-agent.yml
├── wazuh-dashboard.yml
├── wazuh-indexer.yml
├── wazuh-manager-oss.yml
├── wazuh-production-ready.yml
└── wazuh-single.yml

0 directories, 7 files

We will configure the wazuh-manager-oss, dashboard, and indexer YAML files. Let us see the content of the files:

  • The Indexer file:
$ cat /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-indexer.yml
- hosts: wi_cluster
    - role: ../roles/wazuh/wazuh-indexer

    instances:           # A certificate will be generated for every node using the name as CN.
        name: node-1
        ip: <node-1 IP>
        role: indexer
        name: node-2
        ip: <node-2 IP>
        role: indexer
        name: node-3
        ip: <node-3 IP>
        role: indexer
  • The dashboard file:
$ cat /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-dashboard.yml
- hosts: wi1
    - role: ../roles/wazuh/wazuh-dashboard
    ansible_shell_allow_world_readable_temp: true
  • The Manager file:
$ cat /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-manager-oss.yml
- hosts: managers
    - role: ../roles/wazuh/ansible-wazuh-manager
    - role: ../roles/wazuh/ansible-filebeat-oss
      - "<indexer-node-1>:9200"
      - "<indexer-node-2>:9200"
      - "<indexer-node-2>:9200"

These files are designed to run the services individually, but here, we will create a single file with all the 3 services configured.

sudo vim playbooks/wazuh-stack.yml

Add the below lines to the file:

- hosts: wazuh_server
    - role: ../roles/wazuh/wazuh-indexer
      perform_installation: false
  become: no
    indexer_node_master: true
        name: node-1       # Important: must be equal to indexer_node_name.
        role: indexer
    - generate-certs

- hosts: wazuh_server
  become: yes
  become_user: root
    - role: ../roles/wazuh/wazuh-indexer
    - role: ../roles/wazuh/wazuh-dashboard

    single_node: true
    ansible_shell_allow_world_readable_temp: true
    instances:           # A certificate will be generated for every node using the name as CN.
        name: node-1
        role: indexer
      - id: default
        url: https://<your manager IP>
        port: 55000

- hosts: wazuh_server
    - role: ../roles/wazuh/ansible-wazuh-manager
    - role: ../roles/wazuh/ansible-filebeat-oss
      filebeat_node_name: node-1
      - ""

Now the file contains 3 deployments. We have the IP address of the dashboard and indexer defined with the indexer_network_host entry.

Set the required permissions.

sudo chown -R $USER:$USER /etc/ansible/roles/wazuh-ansible/playbooks/

Now run the playbook.

ansible-playbook playbooks/wazuh-stack.yml -b -K

Sample Output:

Once deployed, verify the status of the:

  • Wazuh indexer:
$ systemctl status wazuh-indexer
● wazuh-indexer.service - Wazuh-indexer
   Loaded: loaded (/usr/lib/systemd/system/wazuh-indexer.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-05-27 13:10:01 EDT; 3min 53s ago
     Docs: https://documentation.wazuh.com
 Main PID: 14150 (java)
    Tasks: 42 (limit: 23505)
   Memory: 1.4G
   CGroup: /system.slice/wazuh-indexer.service
           └─14150 /usr/share/wazuh-indexer/jdk/bin/java -Xshare:auto -Dopensearch.networkaddress.cache.ttl=60 -Dopensearch.networkaddress.>
  • Wazuh dashboard
$ systemctl status wazuh-dashboard
● wazuh-dashboard.service - wazuh-dashboard
   Loaded: loaded (/etc/systemd/system/wazuh-dashboard.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-05-27 13:10:03 EDT; 4min 9s ago
 Main PID: 14499 (node)
    Tasks: 11 (limit: 23505)
   Memory: 139.1M
   CGroup: /system.slice/wazuh-dashboard.service
           └─14499 /usr/share/wazuh-dashboard/bin/../node/bin/node --no-warnings --max-http-header-size=65536 --unhandled-rejections=warn
  • Wazuh manager
$ systemctl status wazuh-manager
● wazuh-manager.service - Wazuh manager
   Loaded: loaded (/usr/lib/systemd/system/wazuh-manager.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-05-27 13:12:40 EDT; 1min 54s ago
  Process: 23638 ExecStop=/usr/bin/env /var/ossec/bin/wazuh-control stop (code=exited, status=0/SUCCESS)
  Process: 23784 ExecStart=/usr/bin/env /var/ossec/bin/wazuh-control start (code=exited, status=0/SUCCESS)
    Tasks: 104 (limit: 23505)
   Memory: 240.0M
   CGroup: /system.slice/wazuh-manager.service
           ├─23841 /var/ossec/framework/python/bin/python3 /var/ossec/api/scripts/wazuh-apid.py
           ├─23883 /var/ossec/bin/wazuh-authd
           ├─23900 /var/ossec/bin/wazuh-db
           ├─23912 /var/ossec/framework/python/bin/python3 /var/ossec/api/scripts/wazuh-apid.py
           ├─23915 /var/ossec/framework/python/bin/python3 /var/ossec/api/scripts/wazuh-apid.py
           ├─23930 /var/ossec/bin/wazuh-execd
           ├─23945 /var/ossec/bin/wazuh-analysisd
           ├─23959 /var/ossec/bin/wazuh-syscheckd
           ├─23996 /var/ossec/bin/wazuh-remoted
           ├─24033 /var/ossec/bin/wazuh-logcollector
           ├─24053 /var/ossec/bin/wazuh-monitord
           └─24073 /var/ossec/bin/wazuh-modulesd
  • Filebeat
$ systemctl status filebeat
● filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch.
   Loaded: loaded (/usr/lib/systemd/system/filebeat.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-05-27 13:12:42 EDT; 2min 7s ago
     Docs: https://www.elastic.co/products/beats/filebeat
 Main PID: 24376 (filebeat)
    Tasks: 6 (limit: 23505)
   Memory: 11.7M
   CGroup: /system.slice/filebeat.service
           └─24376 /usr/share/filebeat/bin/filebeat --environment systemd -c /etc/filebeat/filebeat.yml --path.home /usr/share/filebeat --

Ensure that the required ports are allowed through the firewall.

sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --add-port=514/udp --permanent
sudo firewall-cmd --add-port=1514/udp --permanent
sudo firewall-cmd --add-port=1515/udp --permanent
sudo firewall-cmd --add-port=1514/tcp --permanent
sudo firewall-cmd --add-port=1515/tcp --permanent
sudo firewall-cmd --add-port=55000/tcp --permanent
sudo firewall-cmd --reload

You can also verify if the components are working as desired.

For Filebeat

$ sudo filebeat test output
  parse url... OK
    parse host... OK
    dns lookup... OK
    dial up... OK
    security: server's certificate chain verification is enabled
    handshake... OK
    TLS version: TLSv1.3
    dial up... OK
  talk to server... OK
  version: 7.10.2

For Wazuh indexer.

$ curl -k -u admin:changeme https://localhost:9200
  "name" : "node-1",
  "cluster_name" : "wazuh",
  "cluster_uuid" : "jbbo5MxLRJCuyXu1hV-jKQ",
  "version" : {
    "number" : "7.10.2",
    "build_type" : "rpm",
    "build_hash" : "e505b10357c03ae8d26d675172402f2f2144ef0f",
    "build_date" : "2022-01-14T03:38:06.881862Z",
    "build_snapshot" : false,
    "lucene_version" : "8.10.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  "tagline" : "The OpenSearch Project: https://opensearch.org/"

The Wazuh cluster can be deployed by editing the wazuh-production-ready.yml appropriately.

#4. Install Wazuh Agent using Ansible

The Wazuh Agent role and playbook are still provided by the cloned repository. Ensure you are on the path.

cd /etc/ansible/roles/wazuh-ansible/

We will proceed and create a copy of the YAML file.

cp /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-agent.yml /etc/ansible/roles/wazuh-ansible/playbooks/wazuh_agent.yml

Now edit the new file:

sudo vim playbooks/wazuh_agent.yml

Ensure the required details are provided:

- hosts: wazuh_agents
  become: yes
  become_user: root
    - ../roles/wazuh/ansible-wazuh-agent
      - address: <your manager IP>
        port: 1514
        protocol: tcp
        api_port: 55000
        api_proto: 'https'
        api_user: ansible
        max_retries: 5
        retry_interval: 5

Once the correct details are provided for the Manager Ip and host, run the playbook.

ansible-playbook playbooks/wazuh_agent.yml -b -K

Sample Output:

Once the deployment is successful, check the status of the Wazuh agent:

$ systemctl status wazuh-agent
● wazuh-agent.service - Wazuh agent
     Loaded: loaded (/lib/systemd/system/wazuh-agent.service; enabled; vendor preset: enabled)
     Active: active (running) since Fri 2022-05-27 13:18:23 EDT; 19s ago
    Process: 5244 ExecStart=/usr/bin/env /var/ossec/bin/wazuh-control start (code=exited, status=0/SUCCESS)
      Tasks: 33 (limit: 4663)
     Memory: 253.5M
        CPU: 8.293s
     CGroup: /system.slice/wazuh-agent.service
             ├─5267 /var/ossec/bin/wazuh-execd
             ├─5278 /var/ossec/bin/wazuh-agentd
             ├─5292 /var/ossec/bin/wazuh-syscheckd
             ├─5304 /var/ossec/bin/wazuh-logcollector
             ├─5321 /var/ossec/bin/wazuh-modulesd
             ├─6336 sh -c /bin/ps -p 966 > /dev/null 2>&1
             └─6337 /bin/ps -p 966

#5. Access the Wazuh Dashboard.

The Wazuh dashboard is available on the URL https://wazuh_server_IP.

Login using the below credentials:

Username: admin
Password: changeme

On successful login. Several components will be loaded as shown.

Continue and access the dashboard.

Click on the Wazuh agents to view the status.

Visualize dashboards on the agent.

The end!

That marks the end of this guide on how to deploy the Wazuh Security Platform on Linux using Ansible. Using the guide, you can deploy the solution on more servers in your environment at once. I hope this was significant.

See more:


Your Cart is Empty

Back To Shop