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]
192.168.205.9 ansible_ssh_user=username
[wazuh_agents]
192.168.205.4 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@192.168.205.9
ssh-copy-id -i ~/.ssh/id_rsa.pub username@192.168.205.4
Verify the communication.
$ ansible all -m ping
192.168.205.4 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.168.205.9 | 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
wazuh-ansible
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:
roles
├── 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:
playbooks/
├── 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
roles:
- role: ../roles/wazuh/wazuh-indexer
vars:
instances: # A certificate will be generated for every node using the name as CN.
node1:
name: node-1
ip: <node-1 IP>
role: indexer
node2:
name: node-2
ip: <node-2 IP>
role: indexer
node3:
name: node-3
ip: <node-3 IP>
role: indexer
- The dashboard file:
$ cat /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-dashboard.yml
---
- hosts: wi1
roles:
- role: ../roles/wazuh/wazuh-dashboard
vars:
ansible_shell_allow_world_readable_temp: true
- The Manager file:
$ cat /etc/ansible/roles/wazuh-ansible/playbooks/wazuh-manager-oss.yml
---
- hosts: managers
roles:
- role: ../roles/wazuh/ansible-wazuh-manager
- role: ../roles/wazuh/ansible-filebeat-oss
filebeat_output_indexer_hosts:
- "<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
roles:
- role: ../roles/wazuh/wazuh-indexer
perform_installation: false
become: no
vars:
indexer_node_master: true
instances:
node1:
name: node-1 # Important: must be equal to indexer_node_name.
ip: 127.0.0.1
role: indexer
tags:
- generate-certs
- hosts: wazuh_server
become: yes
become_user: root
roles:
- role: ../roles/wazuh/wazuh-indexer
- role: ../roles/wazuh/wazuh-dashboard
vars:
single_node: true
indexer_network_host: 127.0.0.1
ansible_shell_allow_world_readable_temp: true
instances: # A certificate will be generated for every node using the name as CN.
node1:
name: node-1
ip: 127.0.0.1
role: indexer
wazuh_api_credentials:
- id: default
url: https://<your manager IP>
port: 55000
- hosts: wazuh_server
roles:
- role: ../roles/wazuh/ansible-wazuh-manager
- role: ../roles/wazuh/ansible-filebeat-oss
filebeat_node_name: node-1
filebeat_output_indexer_hosts:
- "127.0.0.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 2023-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 2023-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 2023-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 2023-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
elasticsearch: https://127.0.0.1:9200...
parse url... OK
connection...
parse host... OK
dns lookup... OK
addresses: 127.0.0.1
dial up... OK
TLS...
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" : "2023-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:
- ../roles/wazuh/ansible-wazuh-agent
vars:
wazuh_managers:
- 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 2023-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:
- Deploy Graylog Server using Ansible on Ubuntu/Debian/CentOS
- How To Manage PostgreSQL Database with Ansible
- Automate Graylog Server installation using Puppet
- How to upgrade Ansible AWX running in Kubernetes