Wzuh
Wzuh
/bin/bash
# Wazuh installer
# Copyright (C) 2015, Wazuh Inc.
#
# This program is a free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License (version 2) as published by the FSF - Free Software
# Foundation.
readonly repogpg="https://packages.wazuh.com/key/GPG-KEY-WAZUH"
readonly repobaseurl="https://packages.wazuh.com/4.x"
readonly reporelease="stable"
readonly filebeat_wazuh_module="${repobaseurl}/filebeat/wazuh-filebeat-0.2.tar.gz"
readonly bucket="packages.wazuh.com"
readonly repository="4.x"
readonly wazuh_major="4.5"
readonly wazuh_version="4.5.1"
readonly filebeat_version="7.10.2"
readonly wazuh_install_vesion="0.1"
readonly resources="https://${bucket}/${wazuh_major}"
readonly base_url="https://${bucket}/${repository}"
base_path="$(dirname "$(readlink -f "$0")")"
readonly base_path
config_file="${base_path}/config.yml"
readonly tar_file_name="wazuh-install-files.tar"
tar_file="${base_path}/${tar_file_name}"
readonly filebeat_wazuh_template="https://raw.githubusercontent.com/wazuh/wazuh/$
{wazuh_major}/extensions/elasticsearch/7.x/wazuh-template.json"
readonly dashboard_cert_path="/etc/wazuh-dashboard/certs"
readonly filebeat_cert_path="/etc/filebeat/certs"
readonly indexer_cert_path="/etc/wazuh-indexer/certs"
readonly logfile="/var/log/wazuh-install.log"
debug=">> ${logfile} 2>&1"
readonly base_dest_folder="wazuh-offline"
readonly manager_deb_base_url="${base_url}/apt/pool/main/w/wazuh-manager"
readonly filebeat_deb_base_url="${base_url}/apt/pool/main/f/filebeat"
readonly filebeat_deb_package="filebeat-oss-${filebeat_version}-amd64.deb"
readonly indexer_deb_base_url="${base_url}/apt/pool/main/w/wazuh-indexer"
readonly dashboard_deb_base_url="${base_url}/apt/pool/main/w/wazuh-dashboard"
readonly manager_rpm_base_url="${base_url}/yum"
readonly filebeat_rpm_base_url="${base_url}/yum"
readonly filebeat_rpm_package="filebeat-oss-${filebeat_version}-x86_64.rpm"
readonly indexer_rpm_base_url="${base_url}/yum"
readonly dashboard_rpm_base_url="${base_url}/yum"
readonly wazuh_gpg_key="https://${bucket}/key/GPG-KEY-WAZUH"
readonly filebeat_config_file="${resources}/tpl/wazuh/filebeat/filebeat.yml"
adminUser="wazuh"
adminPassword="wazuh"
readonly wazuh_aio_ports=( 9200 9300 1514 1515 1516 55000 443)
readonly wazuh_indexer_ports=( 9200 9300 )
readonly wazuh_manager_ports=( 1514 1515 1516 55000 )
readonly wazuh_dashboard_ports=( 443 )
config_file_certificate_config="nodes:
# Wazuh indexer nodes
indexer:
- name: indexer-1
ip: <indexer-node-ip>
- name: indexer-2
ip: <indexer-node-ip>
- name: indexer-3
ip: <indexer-node-ip>
server:
- name: server-1
ip: <server-node-ip>
node_type: master
- name: server-2
ip: <server-node-ip>
node_type: worker
- name: server-3
ip: <server-node-ip>
node_type: worker
dashboard:
- name: dashboard-1
ip: <dashboard-node-ip>
- name: dashboard-2
ip: <dashboard-node-ip>
- name: dashboard-3
ip: <dashboard-node-ip>"
config_file_certificate_config_aio="nodes:
indexer:
- name: wazuh-indexer
ip: 127.0.0.1
server:
- name: wazuh-server
ip: 127.0.0.1
dashboard:
- name: wazuh-dashboard
ip: 127.0.0.1"
config_file_dashboard_dashboard="server.host: \"<kibana-ip>\"
opensearch.hosts: https://<elasticsearch-ip>:9200
server.port: 443
opensearch.ssl.verificationMode: certificate
# opensearch.username: kibanaserver
# opensearch.password: kibanaserver
opensearch.requestHeadersAllowlist: [\"securitytenant\",\"Authorization\"]
opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: [\"kibana_read_only\"]
server.ssl.enabled: true
server.ssl.key: \"/etc/wazuh-dashboard/certs/kibana-key.pem\"
server.ssl.certificate: \"/etc/wazuh-dashboard/certs/kibana.pem\"
opensearch.ssl.certificateAuthorities: [\"/etc/wazuh-dashboard/certs/root-ca.pem\"]
server.defaultRoute: /app/wazuh
opensearch_security.cookie.secure: true"
config_file_dashboard_dashboard_all_in_one="server.host: 0.0.0.0
server.port: 443
opensearch.hosts: https://localhost:9200
opensearch.ssl.verificationMode: certificate
# opensearch.username: kibanaserver
# opensearch.password: kibanaserver
opensearch.requestHeadersAllowlist: [\"securitytenant\",\"Authorization\"]
opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: [\"kibana_read_only\"]
server.ssl.enabled: true
server.ssl.key: \"/etc/wazuh-dashboard/certs/kibana-key.pem\"
server.ssl.certificate: \"/etc/wazuh-dashboard/certs/kibana.pem\"
opensearch.ssl.certificateAuthorities: [\"/etc/wazuh-dashboard/certs/root-ca.pem\"]
uiSettings.overrides.defaultRoute: /app/wazuh
opensearch_security.cookie.secure: true"
config_file_dashboard_dashboard_unattended="server.host: 0.0.0.0
opensearch.hosts: https://127.0.0.1:9200
server.port: 443
opensearch.ssl.verificationMode: certificate
# opensearch.username: kibanaserver
# opensearch.password: kibanaserver
opensearch.requestHeadersAllowlist: [\"securitytenant\",\"Authorization\"]
opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: [\"kibana_read_only\"]
server.ssl.enabled: true
server.ssl.key: \"/etc/wazuh-dashboard/certs/dashboard-key.pem\"
server.ssl.certificate: \"/etc/wazuh-dashboard/certs/dashboard.pem\"
opensearch.ssl.certificateAuthorities: [\"/etc/wazuh-dashboard/certs/root-ca.pem\"]
uiSettings.overrides.defaultRoute: /app/wazuh
opensearch_security.cookie.secure: true"
config_file_dashboard_dashboard_unattended_distributed="server.port: 443
opensearch.ssl.verificationMode: certificate
# opensearch.username: kibanaserver
# opensearch.password: kibanaserver
opensearch.requestHeadersAllowlist: [\"securitytenant\",\"Authorization\"]
opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: [\"kibana_read_only\"]
server.ssl.enabled: true
server.ssl.key: \"/etc/wazuh-dashboard/certs/dashboard-key.pem\"
server.ssl.certificate: \"/etc/wazuh-dashboard/certs/dashboard.pem\"
opensearch.ssl.certificateAuthorities: [\"/etc/wazuh-dashboard/certs/root-ca.pem\"]
uiSettings.overrides.defaultRoute: /app/wazuh
opensearch_security.cookie.secure: true"
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.metrics.enabled: false
seccomp:
default_action: allow
syscalls:
- action: allow
names:
- rseq"
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.metrics.enabled: false
seccomp:
default_action: allow
syscalls:
- action: allow
names:
- rseq"
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
logging.metrics.enabled: false
seccomp:
default_action: allow
syscalls:
- action: allow
names:
- rseq"
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.metrics.enabled: false
seccomp:
default_action: allow
syscalls:
- action: allow
names:
- rseq"
output.elasticsearch:
protocol: https
username: \${username}
password: \${password}
ssl.certificate_authorities:
- /etc/filebeat/certs/root-ca.pem
ssl.certificate: \"/etc/filebeat/certs/filebeat.pem\"
ssl.key: \"/etc/filebeat/certs/filebeat-key.pem\"
setup.template.json.enabled: true
setup.template.json.path: '/etc/filebeat/wazuh-template.json'
setup.template.json.name: 'wazuh'
setup.ilm.overwrite: true
setup.ilm.enabled: false
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
logging.metrics.enabled: false
seccomp:
default_action: allow
syscalls:
- action: allow
names:
- rseq"
config_file_indexer_indexer="network.host: 0.0.0.0
node.name: node-1
cluster.initial_master_nodes: node-1
plugins.security.ssl.transport.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.transport.resolve_hostname: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.http.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.http.enabled_ciphers:
- \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\"
- \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\"
plugins.security.ssl.http.enabled_protocols:
- \"TLSv1.2\"
plugins.security.nodes_dn:
- CN=node-1,OU=Wazuh,O=Wazuh,L=California,C=US
plugins.security.authcz.admin_dn:
- CN=admin,OU=Wazuh,O=Wazuh,L=California,C=US
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.restapi.roles_enabled: [\"all_access\", \"security_rest_api_access\"]
cluster.routing.allocation.disk.threshold_enabled: false
node.max_local_storage_nodes: 3
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
config_file_indexer_indexer_all_in_one="network.host: \"127.0.0.1\"
node.name: \"node-1\"
cluster.initial_master_nodes:
- \"node-1\"
cluster.name: \"wazuh-cluster\"
node.max_local_storage_nodes: \"3\"
path.data: /var/lib/wazuh-indexer
path.logs: /var/log/wazuh-indexer
plugins.security.ssl.http.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.http.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.transport.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.http.enabled: true
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.transport.resolve_hostname: false
plugins.security.ssl.http.enabled_ciphers:
- \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\"
- \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\"
plugins.security.ssl.http.enabled_protocols:
- \"TLSv1.2\"
plugins.security.authcz.admin_dn:
- \"CN=admin,OU=Wazuh,O=Wazuh,L=California,C=US\"
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.nodes_dn:
- \"CN=indexer,OU=Wazuh,O=Wazuh,L=California,C=US\"
plugins.security.restapi.roles_enabled:
- \"all_access\"
- \"security_rest_api_access\"
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: [\".opendistro-alerting-config\", \".opendistro-alerting-alert*\",
\".opendistro-anomaly-results*\", \".opendistro-anomaly-detector*\", \".opendistro-anomaly-
checkpoints\", \".opendistro-anomaly-detection-state\", \".opendistro-reports-*\", \".opendistro-
notifications-*\", \".opendistro-notebooks\", \".opensearch-observability\", \".opendistro-asynchronous-
search-response*\", \".replication-metadata-store\"]
config_file_indexer_indexer_unattended_distributed="node.master: true
node.data: true
node.ingest: true
cluster.name: wazuh-indexer-cluster
cluster.routing.allocation.disk.threshold_enabled: false
node.max_local_storage_nodes: \"3\"
path.data: /var/lib/wazuh-indexer
path.logs: /var/log/wazuh-indexer
plugins.security.ssl.http.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.http.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.transport.pemcert_filepath: /etc/wazuh-indexer/certs/indexer.pem
plugins.security.ssl.transport.pemkey_filepath: /etc/wazuh-indexer/certs/indexer-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /etc/wazuh-indexer/certs/root-ca.pem
plugins.security.ssl.http.enabled: true
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.transport.resolve_hostname: false
plugins.security.ssl.http.enabled_ciphers:
- \"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\"
- \"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\"
- \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\"
plugins.security.ssl.http.enabled_protocols:
- \"TLSv1.2\"
plugins.security.authcz.admin_dn:
- \"CN=admin,OU=Wazuh,O=Wazuh,L=California,C=US\"
plugins.security.check_snapshot_restore_write_privileges: true
plugins.security.enable_snapshot_restore_privilege: true
plugins.security.restapi.roles_enabled:
- \"all_access\"
- \"security_rest_api_access\"
plugins.security.system_indices.enabled: true
plugins.security.system_indices.indices: [\".opendistro-alerting-config\", \".opendistro-alerting-alert*\",
\".opendistro-anomaly-results*\", \".opendistro-anomaly-detector*\", \".opendistro-anomaly-
checkpoints\", \".opendistro-anomaly-detection-state\", \".opendistro-reports-*\", \".opendistro-
notifications-*\", \".opendistro-notebooks\", \".opensearch-observability\", \".opendistro-asynchronous-
search-response*\", \".replication-metadata-store\"]
config_file_indexer_roles_internal_users="---
# This is the internal user database
# The hash value is a bcrypt hash and can be generated with plugin/tools/hash.sh
_meta:
type: \"internalusers\"
config_version: 2
## Demo users
admin:
hash: \"\$2a\$12\$VcCDgh2NDk07JGN0rjGbM.Ad41qVR/YFJcgHp0UGns5JDymv..TOG\"
reserved: true
backend_roles:
- \"admin\"
description: \"Demo admin user\"
kibanaserver:
hash: \"\$2a\$12\$4AcgAt3xwOWadA5s5blL6ev39OXDNhmOesEoo33eZtrq2N0YrU3H.\"
reserved: true
description: \"Demo kibanaserver user\"
kibanaro:
hash: \"\$2a\$12\$JJSXNfTowz7Uu5ttXfeYpeYE0arACvcwlPBStB1F.MI7f0U9Z4DGC\"
reserved: false
backend_roles:
- \"kibanauser\"
- \"readall\"
attributes:
attribute1: \"value1\"
attribute2: \"value2\"
attribute3: \"value3\"
description: \"Demo kibanaro user\"
logstash:
hash: \"\$2a\$12\$u1ShR4l4uBS3Uv59Pa2y5.1uQuZBrZtmNfqB3iM/.jL0XoV9sghS2\"
reserved: false
backend_roles:
- \"logstash\"
description: \"Demo logstash user\"
readall:
hash: \"\$2a\$12\$ae4ycwzwvLtZxwZ82RmiEunBbIPiAmGZduBAjKN0TXdwQFtCwARz2\"
reserved: false
backend_roles:
- \"readall\"
description: \"Demo readall user\"
snapshotrestore:
hash: \"\$2y\$12\$DpwmetHKwgYnorbgdvORCenv4NAK8cPUg8AI6pxLCuWf/ALc0.v7W\"
reserved: false
backend_roles:
- \"snapshotrestore\"
description: \"Demo snapshotrestore user\""
config_file_indexer_roles_roles="_meta:
type: \"roles\"
config_version: 2
# Restrict users so they can only view visualization and dashboard on kibana
kibana_read_only:
reserved: true
# The security REST API access role is used to assign specific users access to change the security
settings through the REST API.
security_rest_api_access:
reserved: true
config_file_indexer_roles_roles_mapping="---
# In this file users, backendroles and hosts can be mapped to Open Distro Security roles.
# Permissions for Opendistro roles are configured in roles.yml
_meta:
type: \"rolesmapping\"
config_version: 2
all_access:
reserved: true
hidden: false
backend_roles:
- \"admin\"
hosts: []
users: []
and_backend_roles: []
description: \"Maps admin to all_access\"
own_index:
reserved: false
hidden: false
backend_roles: []
hosts: []
users:
- \"*\"
and_backend_roles: []
description: \"Allow full access to an index named like the username\"
logstash:
reserved: false
hidden: false
backend_roles:
- \"logstash\"
hosts: []
users: []
and_backend_roles: []
readall:
reserved: true
hidden: false
backend_roles:
- \"readall\"
hosts: []
users: []
and_backend_roles: []
manage_snapshots:
reserved: true
hidden: false
backend_roles:
- \"snapshotrestore\"
hosts: []
users: []
and_backend_roles: []
kibana_server:
reserved: true
hidden: false
backend_roles: []
hosts: []
users:
- \"kibanaserver\"
and_backend_roles: []
kibana_user:
reserved: false
hidden: false
backend_roles:
- \"kibanauser\"
hosts: []
users: []
and_backend_roles: []
description: \"Maps kibanauser to kibana_user\"
arch=$(uname -m)
if [ -f "${tar_file}" ]; then
if [ -n "${AIO}" ]; then
rm -f "${tar_file}"
fi
if [ -n "${configurations}" ]; then
common_logger -e "File ${tar_file} already exists. Please remove it if you want to use a new
configuration."
exit 1
fi
fi
if [ -n "${uninstall}" ]; then
fi
# -------------- All-In-One -------------------------------------
if [ -n "${AIO}" ]; then
if [ -n "${overwrite}" ]; then
installCommon_rollBack
fi
fi
if [ -n "${indexer}" ]; then
if [ -n "${dashboard}" ]; then
if [ -n "${dashboard_installed}" ] || [ -n "${dashboard_remaining_files}" ]; then
if [ -n "${overwrite}" ]; then
installCommon_rollBack
else
common_logger -e "Wazuh dashboard is already installed in this node or some of its files
have not been removed. Use option -o|--overwrite to overwrite all components."
exit 1
fi
fi
fi
if [ -n "${wazuh}" ]; then
if [ -n "${wazuh_installed}" ] || [ -n "${wazuh_remaining_files}" ] || [ -n "${filebeat_installed}" ]
|| [ -n "${filebeat_remaining_files}" ]; then
if [ -n "${overwrite}" ]; then
installCommon_rollBack
else
common_logger -e "Wazuh server components (wazuh-manager and filebeat) are already
installed in this node or some of their files have not been removed. Use option -o|--overwrite to
overwrite all components."
exit 1
fi
fi
fi
}
function check_dist() {
dist_detect
if [ "${DIST_NAME}" != "centos" ] && [ "${DIST_NAME}" != "rhel" ] && [ "$
{DIST_NAME}" != "amzn" ] && [ "${DIST_NAME}" != "ubuntu" ]; then
notsupported=1
fi
if { [ "${DIST_NAME}" == "centos" ] || [ "${DIST_NAME}" == "rhel" ]; } && { [ "$
{DIST_VER}" -ne "7" ] && [ "${DIST_VER}" -ne "8" ] && [ "${DIST_VER}" -ne "9" ]; }; then
notsupported=1
fi
if [ "${DIST_NAME}" == "amzn" ] && [ "${DIST_VER}" -ne "2" ]; then
notsupported=1
fi
if [ "${DIST_NAME}" == "ubuntu" ]; then
if [ "${DIST_VER}" == "16" ] || [ "${DIST_VER}" == "18" ] ||
[ "${DIST_VER}" == "20" ] || [ "${DIST_VER}" == "22" ]; then
if [ "${DIST_SUBVER}" != "04" ]; then
notsupported=1
fi
else
notsupported=1
fi
fi
if [ -n "${notsupported}" ] && [ -z "${ignore}" ]; then
common_logger -e "The recommended systems are: Red Hat Enterprise Linux 7, 8, 9; CentOS 7,
8; Amazon Linux 2; Ubuntu 16.04, 18.04, 20.04, 22.04. The current system does not match this list.
Use -i|--ignore-check to skip this check."
exit 1
fi
}
function checks_health() {
logger "Verifying that your system meets the recommended minimum hardware requirements."
checks_specifications
if [ -n "${indexer}" ]; then
if [ "${cores}" -lt 2 ] || [ "${ram_gb}" -lt 3700 ]; then
common_logger -e "Your system does not meet the recommended minimum hardware
requirements of 4Gb of RAM and 2 CPU cores. If you want to proceed with the installation use the -i
option to ignore these requirements."
exit 1
fi
fi
if [ -n "${dashboard}" ]; then
if [ "${cores}" -lt 2 ] || [ "${ram_gb}" -lt 3700 ]; then
common_logger -e "Your system does not meet the recommended minimum hardware
requirements of 4Gb of RAM and 2 CPU cores. If you want to proceed with the installation use the -i
option to ignore these requirements."
exit 1
fi
fi
if [ -n "${wazuh}" ]; then
if [ "${cores}" -lt 2 ] || [ "${ram_gb}" -lt 1700 ]; then
common_logger -e "Your system does not meet the recommended minimum hardware
requirements of 2Gb of RAM and 2 CPU cores . If you want to proceed with the installation use the -i
option to ignore these requirements."
exit 1
fi
fi
if [ -n "${AIO}" ]; then
if [ "${cores}" -lt 2 ] || [ "${ram_gb}" -lt 3700 ]; then
common_logger -e "Your system does not meet the recommended minimum hardware
requirements of 4Gb of RAM and 2 CPU cores. If you want to proceed with the installation use the -i
option to ignore these requirements."
exit 1
fi
fi
}
function checks_names() {
}
function checks_previousCertificate() {
if [ ! -f "${tar_file}" ]; then
common_logger -e "Cannot find ${tar_file}. Run the script with the option -g|--generate-config-
files to create it or copy it from another node."
exit 1
fi
if [ -n "${indxname}" ]; then
if ! tar -tf "${tar_file}" | grep -q -E ^wazuh-install-files/"${indxname}".pem || ! tar -tf "$
{tar_file}" | grep -q -E ^wazuh-install-files/"${indxname}"-key.pem; then
common_logger -e "There is no certificate for the indexer node ${indxname} in ${tar_file}."
exit 1
fi
fi
if [ -n "${dashname}" ]; then
if ! tar -tf "${tar_file}" | grep -q -E ^wazuh-install-files/"${dashname}".pem || ! tar -tf "$
{tar_file}" | grep -q -E ^wazuh-install-files/"${dashname}"-key.pem; then
common_logger -e "There is no certificate for the Wazuh dashboard node ${dashname} in $
{tar_file}."
exit 1
fi
fi
if [ -n "${winame}" ]; then
if ! tar -tf "${tar_file}" | grep -q -E ^wazuh-install-files/"${winame}".pem || ! tar -tf "${tar_file}" |
grep -q -E ^wazuh-install-files/"${winame}"-key.pem; then
common_logger -e "There is no certificate for the wazuh server node ${winame} in $
{tar_file}."
exit 1
fi
fi
}
function checks_specifications() {
}
function checks_ports() {
used_port=0
ports=("$@")
for i in "${!ports[@]}"; do
if eval "${port_command}""${ports[i]}" > /dev/null; then
used_port=1
common_logger -e "Port ${ports[i]} is being used by another process. Please, check it before
installing Wazuh."
fi
done
if [ -n "${AIO}" ]; then
eval "installCommon_getConfig dashboard/dashboard_unattended.yml
/etc/wazuh-dashboard/opensearch_dashboards.yml ${debug}"
dashboard_copyCertificates
else
eval "installCommon_getConfig dashboard/dashboard_unattended_distributed.yml /etc/wazuh-
dashboard/opensearch_dashboards.yml ${debug}"
dashboard_copyCertificates
if [ "${#dashboard_node_names[@]}" -eq 1 ]; then
pos=0
ip=${dashboard_node_ips[0]}
else
for i in "${!dashboard_node_names[@]}"; do
if [[ "${dashboard_node_names[i]}" == "${dashname}" ]]; then
pos="${i}";
fi
done
ip=${dashboard_node_ips[pos]}
fi
}
function dashboard_copyCertificates() {
if [ -f "${tar_file}" ]; then
if ! tar -tvf "${tar_file}" | grep -q "${name}" ; then
common_logger -e "Tar file does not contain certificate for the node ${name}."
installCommon_rollBack
exit 1;
fi
eval "mkdir ${dashboard_cert_path} ${debug}"
eval "sed -i s/dashboard.pem/${name}.pem/ /etc/wazuh-dashboard/opensearch_dashboards.yml $
{debug}"
eval "sed -i s/dashboard-key.pem/${name}-key.pem/
/etc/wazuh-dashboard/opensearch_dashboards.yml ${debug}"
eval "tar -xf ${tar_file} -C ${dashboard_cert_path} wazuh-install-files/${name}.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${dashboard_cert_path} wazuh-install-files/${name}-key.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${dashboard_cert_path} wazuh-install-files/root-ca.pem --strip-
components 1 ${debug}"
eval "chown -R wazuh-dashboard:wazuh-dashboard /etc/wazuh-dashboard/ ${debug}"
eval "chmod 500 ${dashboard_cert_path} ${debug}"
eval "chmod 400 ${dashboard_cert_path}/* ${debug}"
eval "chown wazuh-dashboard:wazuh-dashboard ${dashboard_cert_path}/* ${debug}"
common_logger -d "Wazuh dashboard certificate setup finished."
else
common_logger -e "No certificates found. Wazuh dashboard could not be initialized."
exit 1
fi
}
function dashboard_initialize() {
for i in "${!indexer_node_ips[@]}"; do
curl=$(curl -XGET https://"${indexer_node_ips[i]}":9200/ -uadmin:"${u_pass}" -k -s)
exit_code=${PIPESTATUS[0]}
if [[ "${exit_code}" -eq "7" ]]; then
failed_connect=1
failed_nodes+=("${indexer_node_names[i]}")
fi
if [ "${curl}" == "OpenSearch Security not initialized." ]; then
sec_not_initialized=1
fi
done
if [ -n "${failed_connect}" ]; then
common_logger "${flag}" "Failed to connect with ${failed_nodes[*]}. Connection refused."
fi
if [ -n "${sec_not_initialized}" ]; then
common_logger "${flag}" "Wazuh indexer security settings not initialized. Please run the
installation assistant using -s|--start-cluster in one of the wazuh indexer nodes."
fi
if [ -z "${force}" ]; then
common_logger "If you want to install Wazuh dashboard without waiting for the Wazuh
indexer cluster, use the -fd option"
installCommon_rollBack
exit 1
else
common_logger -nl "--- Summary ---"
common_logger -nl "When Wazuh dashboard is able to connect to your Wazuh indexer cluster,
you can access the web interface https://${print_ip}\n User: admin\n Password: ${u_pass}"
fi
fi
}
function dashboard_initializeAIO() {
if [ -n "${AIO}" ]; then
eval "installCommon_getConfig filebeat/filebeat_unattended.yml /etc/filebeat/filebeat.yml $
{debug}"
else
eval "installCommon_getConfig filebeat/filebeat_distributed.yml /etc/filebeat/filebeat.yml $
{debug}"
if [ ${#indexer_node_names[@]} -eq 1 ]; then
echo -e "\noutput.elasticsearch.hosts:" >> /etc/filebeat/filebeat.yml
echo " - ${indexer_node_ips[0]}:9200" >> /etc/filebeat/filebeat.yml
else
echo -e "\noutput.elasticsearch.hosts:" >> /etc/filebeat/filebeat.yml
for i in "${indexer_node_ips[@]}"; do
echo " - ${i}:9200" >> /etc/filebeat/filebeat.yml
done
fi
fi
if [ -f "${tar_file}" ]; then
if [ -n "${AIO}" ]; then
if ! tar -tvf "${tar_file}" | grep -q "${server_node_names[0]}" ; then
common_logger -e "Tar file does not contain certificate for the node $
{server_node_names[0]}."
installCommon_rollBack
exit 1;
fi
eval "sed -i s/filebeat.pem/${server_node_names[0]}.pem/ /etc/filebeat/filebeat.yml ${debug}"
eval "sed -i s/filebeat-key.pem/${server_node_names[0]}-key.pem/ /etc/filebeat/filebeat.yml $
{debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} --wildcards wazuh-install-files/$
{server_node_names[0]}.pem --strip-components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} --wildcards wazuh-install-files/$
{server_node_names[0]}-key.pem --strip-components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} wazuh-install-files/root-ca.pem --strip-
components 1 ${debug}"
eval "rm -rf ${filebeat_cert_path}/wazuh-install-files/ ${debug}"
else
if ! tar -tvf "${tar_file}" | grep -q "${winame}" ; then
common_logger -e "Tar file does not contain certificate for the node ${winame}."
installCommon_rollBack
exit 1;
fi
eval "sed -i s/filebeat.pem/${winame}.pem/ /etc/filebeat/filebeat.yml ${debug}"
eval "sed -i s/filebeat-key.pem/${winame}-key.pem/ /etc/filebeat/filebeat.yml ${debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} wazuh-install-files/${winame}.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} wazuh-install-files/${winame}-key.pem --
strip-components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${filebeat_cert_path} wazuh-install-files/root-ca.pem --strip-
components 1 ${debug}"
eval "rm -rf ${filebeat_cert_path}/wazuh-install-files/ ${debug}"
fi
eval "chmod 500 ${filebeat_cert_path} ${debug}"
eval "chmod 400 ${filebeat_cert_path}/* ${debug}"
eval "chown root:root ${filebeat_cert_path}/* ${debug}"
else
common_logger -e "No certificates found. Could not initialize Filebeat"
exit 1;
fi
}
function filebeat_install() {
install_result="${PIPESTATUS[0]}"
common_checkInstalled
if [ "$install_result" != 0 ] || [ -z "${filebeat_installed}" ]; then
common_logger -e "Filebeat installation failed."
installCommon_rollBack
exit 1
else
common_logger "Filebeat installation finished."
fi
if [ -n "${AIO}" ]; then
eval "installCommon_getConfig indexer/indexer_all_in_one.yml
/etc/wazuh-indexer/opensearch.yml ${debug}"
else
eval "installCommon_getConfig indexer/indexer_unattended_distributed.yml /etc/wazuh-
indexer/opensearch.yml ${debug}"
if [ "${#indexer_node_names[@]}" -eq 1 ]; then
pos=0
{
echo "node.name: ${indxname}"
echo "network.host: ${indexer_node_ips[0]}"
echo "cluster.initial_master_nodes: ${indxname}"
echo "plugins.security.nodes_dn:"
echo ' - CN='"${indxname}"',OU=Wazuh,O=Wazuh,L=California,C=US'
} >> /etc/wazuh-indexer/opensearch.yml
else
echo "node.name: ${indxname}" >> /etc/wazuh-indexer/opensearch.yml
echo "cluster.initial_master_nodes:" >> /etc/wazuh-indexer/opensearch.yml
for i in "${indexer_node_names[@]}"; do
echo " - ${i}" >> /etc/wazuh-indexer/opensearch.yml
done
for i in "${!indexer_node_names[@]}"; do
if [[ "${indexer_node_names[i]}" == "${indxname}" ]]; then
pos="${i}";
fi
done
indexer_copyCertificates
if [ -f "${tar_file}" ]; then
if ! tar -tvf "${tar_file}" | grep -q "${name}" ; then
common_logger -e "Tar file does not contain certificate for the node ${name}."
installCommon_rollBack
exit 1;
fi
eval "mkdir ${indexer_cert_path} ${debug}"
eval "sed -i s/indexer.pem/${name}.pem/ /etc/wazuh-indexer/opensearch.yml ${debug}"
eval "sed -i s/indexer-key.pem/${name}-key.pem/ /etc/wazuh-indexer/opensearch.yml ${debug}"
eval "tar -xf ${tar_file} -C ${indexer_cert_path} wazuh-install-files/${name}.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${indexer_cert_path} wazuh-install-files/${name}-key.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${indexer_cert_path} wazuh-install-files/root-ca.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${indexer_cert_path} wazuh-install-files/admin.pem --strip-
components 1 ${debug}"
eval "tar -xf ${tar_file} -C ${indexer_cert_path} wazuh-install-files/admin-key.pem --strip-
components 1 ${debug}"
eval "rm -rf ${indexer_cert_path}/wazuh-install-files/"
eval "chown -R wazuh-indexer:wazuh-indexer ${indexer_cert_path} ${debug}"
eval "chmod 500 ${indexer_cert_path} ${debug}"
eval "chmod 400 ${indexer_cert_path}/* ${debug}"
else
common_logger -e "No certificates found. Could not initialize Wazuh indexer"
installCommon_rollBack
exit 1;
fi
}
function indexer_initialize() {
if [ -n "${AIO}" ]; then
eval "sudo -u wazuh-indexer JAVA_HOME=/usr/share/wazuh-indexer/jdk/
OPENSEARCH_CONF_DIR=/etc/wazuh-indexer /usr/share/wazuh-indexer/plugins/opensearch-
security/tools/securityadmin.sh -cd /etc/wazuh-indexer/opensearch-security -icl -p 9200 -nhnv -cacert $
{indexer_cert_path}/root-ca.pem -cert ${indexer_cert_path}/admin.pem -key
${indexer_cert_path}/admin-key.pem -h 127.0.0.1 ${debug}"
fi
}
function indexer_install() {
common_checkInstalled
if [ "$install_result" != 0 ] || [ -z "${indexer_installed}" ]; then
common_logger -e "Wazuh indexer installation failed."
installCommon_rollBack
exit 1
else
common_logger "Wazuh indexer installation finished."
fi
retries=0
for ip_to_test in "${indexer_node_ips[@]}"; do
eval "curl -XGET https://"${ip_to_test}":9200/ -k -s -o /dev/null"
e_code="${PIPESTATUS[0]}"
until [ "${e_code}" -ne 7 ] || [ "${retries}" -eq 12 ]; do
sleep 10
retries=$((retries+1))
eval "curl -XGET https://"${ip_to_test}":9200/ -k -s -o /dev/null"
e_code="${PIPESTATUS[0]}"
done
if [ ${retries} -eq 12 ]; then
common_logger -e "Connectivity check failed on node ${ip_to_test} port 9200. Possible
causes: Wazuh indexer not installed on the node, the Wazuh indexer service is not running or you have
connectivity issues with that node. Please check this before trying again."
exit 1
fi
done
eval "wazuh_indexer_ip=( $(cat /etc/wazuh-indexer/opensearch.yml | grep network.host | sed
's/network.host:\s//') )"
eval "sudo -u wazuh-indexer JAVA_HOME=/usr/share/wazuh-indexer/jdk/
OPENSEARCH_CONF_DIR=/etc/wazuh-indexer /usr/share/wazuh-indexer/plugins/opensearch-
security/tools/securityadmin.sh -cd /etc/wazuh-indexer/opensearch-security -icl -p 9200 -nhnv -
cacert /etc/wazuh-indexer/certs/root-ca.pem -cert /etc/wazuh-indexer/certs/admin.pem -key /etc/wazuh-
indexer/certs/admin-key.pem -h ${wazuh_indexer_ip} ${debug}"
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "The Wazuh indexer cluster security configuration could not be initialized."
exit 1
else
common_logger "Wazuh indexer cluster security configuration initialized."
fi
eval "curl --silent ${filebeat_wazuh_template} | curl -X PUT 'https://$
{indexer_node_ips[pos]}:9200/_template/wazuh' -H 'Content-Type: application/json' -d @- -
uadmin:admin -k --silent ${debug}"
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "The wazuh-alerts template could not be inserted into the Wazuh indexer
cluster."
exit 1
else
common_logger -d "Inserted wazuh-alerts template into the Wazuh indexer cluster."
fi
}
# ------------ installCommon.sh ------------
function installCommon_cleanExit() {
rollback_conf=""
if [ -n "$spin_pid" ]; then
eval "kill -9 $spin_pid ${debug}"
fi
}
function installCommon_addWazuhRepo() {
if [ -n "${development}" ]; then
if [ "${sys_type}" == "yum" ]; then
eval "rm -f /etc/yum.repos.d/wazuh.repo ${debug}"
elif [ "${sys_type}" == "apt-get" ]; then
eval "rm -f /etc/apt/sources.list.d/wazuh.list ${debug}"
fi
fi
package="${1}"
version="${2}"
attempt=0
if [ -n "${version}" ]; then
installer=${package}${sep}${version}
else
installer=${package}
fi
command="DEBIAN_FRONTEND=noninteractive apt-get install ${installer} -y -q ${debug}"
seconds=30
eval "${command}"
install_result="${PIPESTATUS[0]}"
eval "tail -n 2 ${logfile} | grep -q 'Could not get lock'"
grep_result="${PIPESTATUS[0]}"
while [ "${grep_result}" -eq 0 ] && [ "${attempt}" -lt 10 ]; do
attempt=$((attempt+1))
common_logger "An external process is using APT. This process has to end to proceed with the
Wazuh installation. Next retry in ${seconds} seconds (${attempt}/10)"
sleep "${seconds}"
eval "${command}"
install_result="${PIPESTATUS[0]}"
eval "tail -n 2 ${logfile} | grep -q 'Could not get lock'"
grep_result="${PIPESTATUS[0]}"
done
}
function installCommon_aptInstallList(){
dependencies=("$@")
not_installed=()
}
function installCommon_changePasswordApi() {
}
function installCommon_createCertificates() {
if [ -n "${AIO}" ]; then
eval "installCommon_getConfig certificate/config_aio.yml ${config_file} ${debug}"
fi
cert_readConfig
if [ -d /tmp/wazuh-certificates/ ]; then
eval "rm -rf /tmp/wazuh-certificates/ ${debug}"
fi
eval "mkdir /tmp/wazuh-certificates/ ${debug}"
cert_tmp_path="/tmp/wazuh-certificates/"
cert_generateRootCAcertificate
cert_generateAdmincertificate
cert_generateIndexercertificates
cert_generateFilebeatcertificates
cert_generateDashboardcertificates
cert_cleanFiles
eval "chmod 400 /tmp/wazuh-certificates/* ${debug}"
eval "mv /tmp/wazuh-certificates/* /tmp/wazuh-install-files ${debug}"
eval "rm -rf /tmp/wazuh-certificates/ ${debug}"
}
function installCommon_createClusterKey() {
}
function installCommon_createInstallFiles() {
if [ -d /tmp/wazuh-install-files ]; then
eval "rm -rf /tmp/wazuh-install-files ${debug}"
fi
passwords_changePassword
}
function installCommon_getConfig() {
for i in "${!users[@]}"; do
if [ "${users[i]}" == "${1}" ]; then
u_pass=${passwords[i]}
fi
done
}
function installCommon_installCheckDependencies() {
}
function installCommon_installPrerequisites() {
if [ "${sys_type}" == "yum" ]; then
dependencies=( libcap gnupg2 )
installCommon_yumInstallList "${dependencies[@]}"
}
function installCommon_readPasswordFileUsers() {
For Wazuh indexer users, the file must have this format:
# Description
indexer_username: <user>
indexer_password: <password>
For Wazuh API users, the file must have this format:
# Description
api_username: <user>
api_password: <password>
"
installCommon_rollBack
exit 1
fi
sfileusers=$(grep indexer_username: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed -e
"s/[\'\"]//g")
sfilepasswords=$(grep indexer_password: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' |
sed -e "s/[\'\"]//g")
sfileapiusers=$(grep api_username: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed -e
"s/[\'\"]//g")
sfileapipasswords=$(grep api_password: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed
-e "s/[\'\"]//g")
if [ -n "${changeall}" ]; then
for j in "${!fileusers[@]}"; do
supported=false
for i in "${!users[@]}"; do
if [[ ${users[i]} == "${fileusers[j]}" ]]; then
passwords_checkPassword "${filepasswords[j]}"
passwords[i]=${filepasswords[j]}
supported=true
fi
done
if [ "${supported}" = false ] && [ -n "${indexer_installed}" ]; then
common_logger -e -d "The given user ${fileusers[j]} does not exist"
fi
done
for j in "${!fileapiusers[@]}"; do
supported=false
for i in "${!api_users[@]}"; do
if [[ "${api_users[i]}" == "${fileapiusers[j]}" ]]; then
passwords_checkPassword "${fileapipasswords[j]}"
api_passwords[i]=${fileapipasswords[j]}
supported=true
fi
done
if [ "${supported}" = false ] && [ -n "${indexer_installed}" ]; then
common_logger -e "The Wazuh API user ${fileapiusers[j]} does not exist"
fi
done
else
finalusers=()
finalpasswords=()
finalapiusers=()
finalapipasswords=()
for j in "${!fileusers[@]}"; do
supported=false
for i in "${!users[@]}"; do
if [[ "${users[i]}" == "${fileusers[j]}" ]]; then
passwords_checkPassword "${filepasswords[j]}"
finalusers+=(${fileusers[j]})
finalpasswords+=(${filepasswords[j]})
supported=true
fi
done
if [ "${supported}" = "false" ] && [ -n "${indexer_installed}" ] && [ -n "${changeall}" ]; then
common_logger -e -d "The given user ${fileusers[j]} does not exist"
fi
done
for j in "${!fileapiusers[@]}"; do
supported=false
for i in "${!api_users[@]}"; do
if [[ "${api_users[i]}" == "${fileapiusers[j]}" ]]; then
passwords_checkPassword "${fileapipasswords[j]}"
finalapiusers+=("${fileapiusers[j]}")
finalapipasswords+=("${fileapipasswords[j]}")
supported=true
fi
done
if [ ${supported} = false ] && [ -n "${indexer_installed}" ]; then
common_logger -e "The Wazuh API user ${fileapiusers[j]} does not exist"
fi
done
users=()
mapfile -t users < <(printf '%s\n' "${finalusers[@]}")
mapfile -t passwords < <(printf '%s\n' "${finalpasswords[@]}")
mapfile -t api_users < <(printf '%s\n' "${finalapiusers[@]}")
mapfile -t api_passwords < <(printf '%s\n' "${finalapipasswords[@]}")
changeall=1
fi
}
function installCommon_restoreWazuhrepo() {
if [ -n "${development}" ]; then
if [ "${sys_type}" == "yum" ] && [ -f "/etc/yum.repos.d/wazuh.repo" ]; then
file="/etc/yum.repos.d/wazuh.repo"
elif [ "${sys_type}" == "apt-get" ] && [ -f "/etc/apt/sources.list.d/wazuh.list" ]; then
file="/etc/apt/sources.list.d/wazuh.list"
else
common_logger -w -d "Wazuh repository does not exists."
fi
eval "sed -i 's/-dev//g' ${file} ${debug}"
eval "sed -i 's/pre-release/4.x/g' ${file} ${debug}"
eval "sed -i 's/unstable/stable/g' ${file} ${debug}"
fi
}
function installCommon_rollBack() {
if [ -z "${uninstall}" ]; then
common_logger "--- Removing existing Wazuh installation ---"
fi
if [ -f "/etc/yum.repos.d/wazuh.repo" ]; then
eval "rm /etc/yum.repos.d/wazuh.repo"
elif [ -f "/etc/zypp/repos.d/wazuh.repo" ]; then
eval "rm /etc/zypp/repos.d/wazuh.repo"
elif [ -f "/etc/apt/sources.list.d/wazuh.list" ]; then
eval "rm /etc/apt/sources.list.d/wazuh.list"
fi
elements_to_remove=( "/var/log/wazuh-indexer/"
"/var/log/filebeat/"
"/etc/systemd/system/opensearch.service.wants/"
"/securityadmin_demo.sh"
"/etc/systemd/system/multi-user.target.wants/wazuh-manager.service"
"/etc/systemd/system/multi-user.target.wants/filebeat.service"
"/etc/systemd/system/multi-user.target.wants/opensearch.service"
"/etc/systemd/system/multi-user.target.wants/wazuh-dashboard.service"
"/etc/systemd/system/wazuh-dashboard.service"
"/lib/firewalld/services/dashboard.xml"
"/lib/firewalld/services/opensearch.xml" )
common_remove_gpg_key
if [ -z "${uninstall}" ]; then
if [ -n "${rollback_conf}" ] || [ -n "${overwrite}" ]; then
common_logger "Installation cleaned."
else
common_logger "Installation cleaned. Check the ${logfile} file to learn more about the issue."
fi
fi
}
function installCommon_startService() {
}
function installCommon_yumInstallList(){
dependencies=("$@")
not_installed=()
for dep in "${dependencies[@]}"; do
if ! yum list installed 2>/dev/null | grep -q -E ^"${dep}"\\.;then
not_installed+=("${dep}")
fi
done
echo -e ""
echo -e "NAME"
echo -e " $(basename "$0") - Install and configure Wazuh central components: Wazuh server,
Wazuh indexer, and Wazuh dashboard."
echo -e ""
echo -e "SYNOPSIS"
echo -e " $(basename "$0") [OPTIONS] -a | -c | -s | -wi <indexer-node-name> | -wd <dashboard-
node-name> | -ws <server-node-name>"
echo -e ""
echo -e "DESCRIPTION"
echo -e " -a, --all-in-one"
echo -e " Install and configure Wazuh server, Wazuh indexer, Wazuh dashboard."
echo -e ""
echo -e " -c, --config-file <path-to-config-yml>"
echo -e " Path to the configuration file used to generate wazuh-install-files.tar file
containing the files that will be needed for installation. By default, the Wazuh installation assistant will
search for a file named config.yml in the same path as the script."
echo -e ""
echo -e " -dw, --download-wazuh <deb|rpm>"
echo -e " Download all the packages necessary for offline installation."
echo -e ""
echo -e " -fd, --force-install-dashboard"
echo -e " Force Wazuh dashboard installation to continue even when it is not capable of
connecting to the Wazuh indexer."
echo -e ""
echo -e " -g, --generate-config-files"
echo -e " Generate wazuh-install-files.tar file containing the files that will be needed for
installation from config.yml. In distributed deployments you will need to copy this file to all hosts."
echo -e ""
echo -e " -h, --help"
echo -e " Display this help and exit."
echo -e ""
echo -e " -i, --ignore-check"
echo -e " Ignore the check for system compatibility and minimum hardware requirements."
echo -e ""
echo -e " -o, --overwrite"
echo -e " Overwrites previously installed components. This will erase all the existing
configuration and data."
echo -e ""
echo -e " -s, --start-cluster"
echo -e " Initialize Wazuh indexer cluster security settings."
echo -e ""
echo -e " -t, --tar <path-to-certs-tar>"
echo -e " Path to tar file containing certificate files. By default, the Wazuh installation
assistant will search for a file named wazuh-install-files.tar in the same path as the script."
echo -e ""
echo -e " -u, --uninstall"
echo -e " Uninstalls all Wazuh components. This will erase all the existing configuration
and data."
echo -e ""
echo -e " -v, --verbose"
echo -e " Shows the complete installation output."
echo -e ""
echo -e " -V, --version"
echo -e " Shows the version of the script and Wazuh packages."
echo -e ""
echo -e " -wd, --wazuh-dashboard <dashboard-node-name>"
echo -e " Install and configure Wazuh dashboard, used for distributed deployments."
echo -e ""
echo -e " -wi, --wazuh-indexer <indexer-node-name>"
echo -e " Install and configure Wazuh indexer, used for distributed deployments."
echo -e ""
echo -e " -ws, --wazuh-server <server-node-name>"
echo -e " Install and configure Wazuh manager and Filebeat, used for distributed
deployments."
exit 1
}
function main() {
umask 177
if [ -z "${1}" ]; then
getHelp
fi
while [ -n "${1}" ]
do
case "${1}" in
"-a"|"--all-in-one")
AIO=1
shift 1
;;
"-c"|"--config-file")
if [ -z "${2}" ]; then
common_logger -e "Error on arguments. Probably missing <path-to-config-yml> after -c|--
config-file"
getHelp
exit 1
fi
file_conf=1
config_file="${2}"
shift 2
;;
"-fd"|"--force-install-dashboard")
force=1
shift 1
;;
"-g"|"--generate-config-files")
configurations=1
shift 1
;;
"-h"|"--help")
getHelp
;;
"-i"|"--ignore-check")
ignore=1
shift 1
;;
"-o"|"--overwrite")
overwrite=1
shift 1
;;
"-s"|"--start-cluster")
start_indexer_cluster=1
shift 1
;;
"-t"|"--tar")
if [ -z "${2}" ]; then
common_logger -e "Error on arguments. Probably missing <path-to-certs-tar> after -t|--
tar"
getHelp
exit 1
fi
tar_conf=1
tar_file="${2}"
shift 2
;;
"-u"|"--uninstall")
uninstall=1
shift 1
;;
"-v"|"--verbose")
debugEnabled=1
debug="2>&1 | tee -a ${logfile}"
shift 1
;;
"-V"|"--version")
showVersion=1
shift 1
;;
"-wd"|"--wazuh-dashboard")
if [ -z "${2}" ]; then
common_logger -e "Error on arguments. Probably missing <node-name> after -wd|---
wazuh-dashboard"
getHelp
exit 1
fi
dashboard=1
dashname="${2}"
shift 2
;;
"-wi"|"--wazuh-indexer")
if [ -z "${2}" ]; then
common_logger -e "Arguments contain errors. Probably missing <node-name> after -wi|--
wazuh-indexer."
getHelp
exit 1
fi
indexer=1
indxname="${2}"
shift 2
;;
"-ws"|"--wazuh-server")
if [ -z "${2}" ]; then
common_logger -e "Error on arguments. Probably missing <node-name> after -ws|--
wazuh-server"
getHelp
exit 1
fi
wazuh=1
winame="${2}"
shift 2
;;
"-dw"|"--download-wazuh")
if [ "${2}" != "deb" ] && [ "${2}" != "rpm" ]; then
common_logger -e "Error on arguments. Probably missing <deb|rpm> after -dw|--
download-wazuh"
getHelp
exit 1
fi
download=1
package_type="${2}"
shift 2
;;
*)
echo "Unknow option: ${1}"
getHelp
esac
done
if [ -n "${showVersion}" ]; then
common_logger "Wazuh version: ${wazuh_version}"
common_logger "Filebeat version: ${filebeat_version}"
common_logger "Wazuh installation assistant version: ${wazuh_install_vesion}"
exit 0
fi
common_checkSystem
if [ -z "${download}" ]; then
check_dist
fi
common_checkInstalled
checks_arguments
if [ -n "${uninstall}" ]; then
installCommon_rollBack
exit 0
fi
if [ -z "${uninstall}" ]; then
installCommon_installCheckDependencies
fi
if [ -n "${indexer}" ]; then
checks_ports "${wazuh_indexer_ports[@]}"
fi
if [ -n "${wazuh}" ]; then
checks_ports "${wazuh_manager_ports[@]}"
fi
if [ -n "${dashboard}" ]; then
checks_ports "${wazuh_dashboard_ports[@]}"
fi
# Creation certificate case: Only AIO and -g option can create certificates.
if [ -n "${configurations}" ] || [ -n "${AIO}" ]; then
common_logger "--- Configuration files ---"
installCommon_createInstallFiles
fi
if [ -n "${indexer}" ]; then
common_logger "--- Wazuh indexer ---"
indexer_install
indexer_configure
installCommon_startService "wazuh-indexer"
indexer_initialize
fi
if [ -n "${dashboard}" ]; then
common_logger "--- Wazuh dashboard ----"
dashboard_install
dashboard_configure
installCommon_startService "wazuh-dashboard"
installCommon_changePasswords
dashboard_initialize
fi
if [ -n "${wazuh}" ]; then
common_logger "--- Wazuh server ---"
manager_install
if [ -n "${server_node_types[*]}" ]; then
manager_startCluster
fi
installCommon_startService "wazuh-manager"
filebeat_install
filebeat_configure
installCommon_changePasswords
installCommon_startService "filebeat"
fi
if [ -n "${AIO}" ]; then
fi
if [ -n "${download}" ]; then
common_logger "--- Download Packages ---"
offline_download
fi
# -------------------------------------------------------------------
for i in "${!server_node_names[@]}"; do
if [[ "${server_node_names[i]}" == "${winame}" ]]; then
pos="${i}";
fi
done
for i in "${!server_node_types[@]}"; do
if [[ "${server_node_types[i],,}" == "master" ]]; then
master_address=${server_node_ips[i]}
fi
done
}
function manager_install() {
common_checkInstalled
if [ "$install_result" != 0 ] || [ -z "${wazuh_installed}" ]; then
common_logger -e "Wazuh installation failed."
installCommon_rollBack
exit 1
else
common_logger "Wazuh manager installation finished."
fi
}
if [ -d "${dest_path}" ]; then
eval "rm -f ${dest_path}/*" # Clean folder before downloading specific versions
eval "chmod 700 ${dest_path}"
else
eval "mkdir -m700 -p ${dest_path}" # Create folder if it does not exist
fi
manager_revision="1"
indexer_revision="1"
dashboard_revision="1"
package_name="${package}_${package_type}_package"
eval "package_base_url=${package}_${package_type}_base_url"
done
# --------------------------------------------------
if [ -d "${dest_path}" ]; then
eval "rm -f ${dest_path}/*" # Clean folder before downloading specific versions
eval "chmod 700 ${dest_path}"
else
eval "mkdir -m700 -p ${dest_path}" # Create folder if it does not exist
fi
done
eval "cd - > /dev/null"
}
function dist_detect() {
DIST_NAME="Linux"
DIST_VER="0"
DIST_SUBVER="0"
if [ -r "/etc/os-release" ]; then
. /etc/os-release
DIST_NAME=$ID
DIST_VER=$(echo $VERSION_ID | sed -rn 's/[^0-9]*([0-9]+).*/\1/p')
if [ "X$DIST_VER" = "X" ]; then
DIST_VER="0"
fi
if [ "$DIST_NAME" = "amzn" ] && [ "$DIST_VER" != "2" ]; then
DIST_VER="1"
fi
DIST_SUBVER=$(echo $VERSION_ID | sed -rn 's/[^0-9]*[0-9]+\.([0-9]+).*/\1/p')
if [ "X$DIST_SUBVER" = "X" ]; then
DIST_SUBVER="0"
fi
fi
# Fedora
elif [ -r "/etc/fedora-release" ]; then
DIST_NAME="fedora"
DIST_VER=`sed -rn 's/.* ([0-9]{1,2}) .*/\1/p' /etc/fedora-release`
# RedHat
elif [ -r "/etc/redhat-release" ]; then
if grep -q "CentOS" /etc/redhat-release; then
DIST_NAME="centos"
else
DIST_NAME="rhel"
fi
DIST_VER=`sed -rn 's/.* ([0-9]{1,2})\.*[0-9]{0,2}.*/\1/p' /etc/redhat-release`
DIST_SUBVER=`sed -rn 's/.* [0-9]{1,2}\.*([0-9]{0,2}).*/\1/p' /etc/redhat-release`
# Ubuntu
elif [ -r "/etc/lsb-release" ]; then
. /etc/lsb-release
DIST_NAME="ubuntu"
DIST_VER=$(echo $DISTRIB_RELEASE | sed -rn 's/.*([0-9][0-9])\.[0-9][0-9].*/\1/p')
DIST_SUBVER=$(echo $DISTRIB_RELEASE | sed -rn 's/.*[0-9][0-9]\.([0-9][0-9]).*/\1/p')
# Gentoo
elif [ -r "/etc/gentoo-release" ]; then
DIST_NAME="gentoo"
DIST_VER=`sed -rn 's/.* ([0-9]{1,2})\.[0-9]{1,2}.*/\1/p' /etc/gentoo-release`
DIST_SUBVER=`sed -rn 's/.* [0-9]{1,2}\.([0-9]{1,2}).*/\1/p' /etc/gentoo-release`
# SuSE
elif [ -r "/etc/SuSE-release" ]; then
DIST_NAME="suse"
DIST_VER=`sed -rn 's/.*VERSION = ([0-9]{1,2}).*/\1/p' /etc/SuSE-release`
DIST_SUBVER=`sed -rn 's/.*PATCHLEVEL = ([0-9]{1,2}).*/\1/p' /etc/SuSE-release`
if [ "$DIST_SUBVER" = "" ]; then #openSuse
DIST_SUBVER=`sed -rn 's/.*VERSION = ([0-9]{1,2})\.([0-9]{1,2}).*/\1/p' /etc/SuSE-release`
fi
# Arch
elif [ -r "/etc/arch-release" ]; then
DIST_NAME="arch"
DIST_VER=$(uname -r | sed -rn 's/[^0-9]*([0-9]+).*/\1/p')
DIST_SUBVER=$(uname -r | sed -rn 's/[^0-9]*[0-9]+\.([0-9]+).*/\1/p')
# Debian
elif [ -r "/etc/debian_version" ]; then
DIST_NAME="debian"
DIST_VER=`sed -rn 's/[^0-9]*([0-9]+).*/\1/p' /etc/debian_version`
DIST_SUBVER=`sed -rn 's/[^0-9]*[0-9]+\.([0-9]+).*/\1/p' /etc/debian_version`
# Slackware
elif [ -r "/etc/slackware-version" ]; then
DIST_NAME="slackware"
DIST_VER=`sed -rn 's/.* ([0-9]{1,2})\.[0-9].*/\1/p' /etc/slackware-version`
DIST_SUBVER=`sed -rn 's/.* [0-9]{1,2}\.([0-9]).*/\1/p' /etc/slackware-version`
# Darwin
elif [ "$(uname)" = "Darwin" ]; then
DIST_NAME="darwin"
DIST_VER=$(uname -r | sed -En 's/[^0-9]*([0-9]+).*/\1/p')
DIST_SUBVER=$(uname -r | sed -En 's/[^0-9]*[0-9]+\.([0-9]+).*/\1/p')
# Solaris / SunOS
elif [ "$(uname)" = "SunOS" ]; then
DIST_NAME="sunos"
DIST_VER=$(uname -r | cut -d\. -f1)
DIST_SUBVER=$(uname -r | cut -d\. -f2)
# HP-UX
elif [ "$(uname)" = "HP-UX" ]; then
DIST_NAME="HP-UX"
DIST_VER=$(uname -r | cut -d\. -f2)
DIST_SUBVER=$(uname -r | cut -d\. -f3)
# AIX
elif [ "$(uname)" = "AIX" ]; then
DIST_NAME="AIX"
DIST_VER=$(oslevel | cut -d\. -f1)
DIST_SUBVER=$(oslevel | cut -d\. -f2)
# BSD
elif [ "X$(uname)" = "XOpenBSD" -o "X$(uname)" = "XNetBSD" -o "X$(uname)" = "XFreeBSD"
-o "X$(uname)" = "XDragonFly" ]; then
DIST_NAME="bsd"
DIST_VER=$(uname -r | sed -rn 's/[^0-9]*([0-9]+).*/\1/p')
DIST_SUBVER=$(uname -r | sed -rn 's/[^0-9]*[0-9]+\.([0-9]+).*/\1/p')
fi
if [ "X$DIST_SUBVER" = "X" ]; then
DIST_SUBVER="0"
fi
fi
}
function common_logger() {
now=$(date +'%d/%m/%Y %H:%M:%S')
mtype="INFO:"
debugLogger=
nolog=
if [ -n "${1}" ]; then
while [ -n "${1}" ]; do
case ${1} in
"-e")
mtype="ERROR:"
shift 1
;;
"-w")
mtype="WARNING:"
shift 1
;;
"-d")
debugLogger=1
mtype="DEBUG:"
shift 1
;;
"-nl")
nolog=1
shift 1
;;
*)
message="${1}"
shift 1
;;
esac
done
fi
}
function common_checkRoot() {
wazuh_installed=""
indexer_installed=""
filebeat_installed=""
dashboard_installed=""
if [ -d "/var/ossec" ]; then
wazuh_remaining_files=1
fi
}
function common_checkWazuhConfigYaml() {
}
function common_remove_gpg_key() {
}
function cert_cleanFiles() {
}
function cert_checkOpenSSL() {
}
function cert_checkRootCA() {
}
function cert_generateAdmincertificate() {
}
function cert_generateCertificateconfiguration() {
[req_distinguished_name]
C = US
L = California
O = Wazuh
OU = Wazuh
CN = cname
[ v3_req ]
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
IP.1 = cip
EOF
}
function cert_generateIndexercertificates() {
for i in "${!indexer_node_names[@]}"; do
indexer_node_name=${indexer_node_names[$i]}
cert_generateCertificateconfiguration "${indexer_node_name}" "${indexer_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/$
{indexer_node_name}-key.pem -out ${cert_tmp_path}/${indexer_node_name}.csr -config $
{cert_tmp_path}/${indexer_node_name}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${indexer_node_name}.csr -CA $
{cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out $
{cert_tmp_path}/${indexer_node_name}.pem -extfile ${cert_tmp_path}/${indexer_node_name}.conf
-extensions v3_req -days 3650 ${debug}"
done
else
return 1
fi
}
function cert_generateFilebeatcertificates() {
for i in "${!server_node_names[@]}"; do
server_name="${server_node_names[i]}"
j=$((i+1))
declare -a server_ips=(server_node_ip_"$j"[@])
cert_generateCertificateconfiguration "${server_name}" "${!server_ips}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/${server_name}-
key.pem -out ${cert_tmp_path}/${server_name}.csr -config ${cert_tmp_path}/${server_name}.conf -
days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${server_name}.csr -CA ${cert_tmp_path}/root-
ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out ${cert_tmp_path}/$
{server_name}.pem -extfile ${cert_tmp_path}/${server_name}.conf -extensions v3_req -days 3650 $
{debug}"
done
else
return 1
fi
}
function cert_generateDashboardcertificates() {
for i in "${!dashboard_node_names[@]}"; do
dashboard_node_name="${dashboard_node_names[i]}"
cert_generateCertificateconfiguration "${dashboard_node_name}" "${dashboard_node_ips[i]}"
eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/$
{dashboard_node_name}-key.pem -out ${cert_tmp_path}/${dashboard_node_name}.csr -config $
{cert_tmp_path}/${dashboard_node_name}.conf -days 3650 ${debug}"
eval "openssl x509 -req -in ${cert_tmp_path}/${dashboard_node_name}.csr -CA $
{cert_tmp_path}/root-ca.pem -CAkey ${cert_tmp_path}/root-ca.key -CAcreateserial -out $
{cert_tmp_path}/${dashboard_node_name}.pem -extfile ${cert_tmp_path}/$
{dashboard_node_name}.conf -extensions v3_req -days 3650 ${debug}"
done
else
return 1
fi
}
function cert_generateRootCAcertificate() {
eval "openssl req -x509 -new -nodes -newkey rsa:2048 -keyout ${cert_tmp_path}/root-ca.key -out $
{cert_tmp_path}/root-ca.pem -batch -subj '/OU=Wazuh/O=Wazuh/L=California/' -days 3650 $
{debug}"
}
function cert_parseYaml() {
local prefix=$2
local separator=${3:-_}
local indexfix
# Detect awk flavor
if awk --version 2>&1 | grep -q "GNU Awk" ; then
# GNU Awk detected
indexfix=-1
elif awk -Wv 2>&1 | grep -q "mawk" ; then
# mawk detected
indexfix=0
fi
}
function cert_readConfig() {
if [ -f "${config_file}" ]; then
if [ ! -s "${config_file}" ]; then
common_logger -e "File ${config_file} is empty"
exit 1
fi
eval "$(cert_convertCRLFtoLF "${config_file}")"
for i in "${server_node_types[@]}"; do
if ! echo "$i" | grep -ioq master && ! echo "$i" | grep -ioq worker; then
common_logger -e "Incorrect node_type $i must be master or worker"
exit 1
fi
done
else
common_logger -e "No configuration file found."
exit 1
fi
}
function cert_setpermisions() {
eval "chmod -R 744 ${cert_tmp_path} ${debug}"
}
function cert_convertCRLFtoLF() {
if [[ ! -d "/tmp/wazuh-install-files" ]]; then
mkdir "/tmp/wazuh-install-files"
fi
eval "chmod -R 755 /tmp/wazuh-install-files ${debug}"
eval "tr -d '\015' < $1 > /tmp/wazuh-install-files/new_config.yml"
eval "mv /tmp/wazuh-install-files/new_config.yml $1"
}
function passwords_changePassword() {
if [ -n "${changeall}" ]; then
if [ -n "${indexer_installed}" ] && [ -z ${no_indexer_backup} ]; then
eval "mkdir /etc/wazuh-indexer/backup/ 2>/dev/null"
eval "cp /etc/wazuh-indexer/opensearch-security/* /etc/wazuh-indexer/backup/ 2>/dev/null"
passwords_createBackUp
fi
for i in "${!passwords[@]}"
do
if [ -n "${indexer_installed}" ] && [ -f "/etc/wazuh-indexer/backup/internal_users.yml" ]; then
awk -v new=${hashes[i]} 'prev=="'${users[i]}':"{sub(/\042.*/,""); $0=$0 new} {prev=$1}
1' /etc/wazuh-indexer/backup/internal_users.yml > internal_users.yml_tmp && mv -f
internal_users.yml_tmp /etc/wazuh-indexer/backup/internal_users.yml
fi
done
else
if [ -z "${api}" ] && [ -n "${indexer_installed}" ]; then
eval "mkdir /etc/wazuh-indexer/backup/ 2>/dev/null"
eval "cp /etc/wazuh-indexer/opensearch-security/* /etc/wazuh-indexer/backup/ 2>/dev/null"
passwords_createBackUp
fi
if [ -n "${indexer_installed}" ] && [ -f "/etc/wazuh-indexer/backup/internal_users.yml" ]; then
awk -v new="${hash}" 'prev=="'${nuser}':"{sub(/\042.*/,""); $0=$0 new} {prev=$1} 1'
/etc/wazuh-indexer/backup/internal_users.yml > internal_users.yml_tmp && mv -f
internal_users.yml_tmp /etc/wazuh-indexer/backup/internal_users.yml
fi
fi
}
function passwords_changePasswordApi() {
#Change API password tool
if [ -n "${changeall}" ]; then
for i in "${!api_passwords[@]}"; do
if [ -n "${wazuh_installed}" ]; then
passwords_getApiUserId "${api_users[i]}"
WAZUH_PASS_API='{"password":"'"${api_passwords[i]}"'"}'
eval 'curl -s -k -X PUT -H "Authorization: Bearer $TOKEN_API" -H "Content-Type:
application/json" -d "$WAZUH_PASS_API" "https://localhost:55000/security/users/${user_id}" -o
/dev/null'
if [ "${api_users[i]}" == "${adminUser}" ]; then
sleep 1
adminPassword="${api_passwords[i]}"
passwords_getApiToken
fi
if [ -z "${AIO}" ] && [ -z "${indexer}" ] && [ -z "${dashboard}" ] && [ -z "${wazuh}" ]
&& [ -z "${start_indexer_cluster}" ]; then
common_logger -nl $"The password for Wazuh API user ${api_users[i]} is $
{api_passwords[i]}"
fi
fi
if [ "${api_users[i]}" == "wazuh-wui" ] && [ -n "${dashboard_installed}" ]; then
passwords_changeDashboardApiPassword "${api_passwords[i]}"
fi
done
else
if [ -n "${wazuh_installed}" ]; then
passwords_getApiUserId "${nuser}"
WAZUH_PASS_API='{"password":"'"${password}"'"}'
eval 'curl -s -k -X PUT -H "Authorization: Bearer $TOKEN_API" -H "Content-Type:
application/json" -d "$WAZUH_PASS_API" "https://localhost:55000/security/users/${user_id}" -o
/dev/null'
if [ -z "${AIO}" ] && [ -z "${indexer}" ] && [ -z "${dashboard}" ] && [ -z "${wazuh}" ] &&
[ -z "${start_indexer_cluster}" ]; then
common_logger -nl $"The password for Wazuh API user ${nuser} is ${password}"
fi
fi
if [ "${nuser}" == "wazuh-wui" ] && [ -n "${dashboard_installed}" ]; then
passwords_changeDashboardApiPassword "${password}"
fi
fi
}
function passwords_changeDashboardApiPassword() {
j=0
until [ -n "${file_exists}" ] || [ "${j}" -eq "12" ]; do
if [ -f "/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml" ]; then
eval "sed -i 's|password: .*|password: \"${1}\"|g'
/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml"
if [ -z "${AIO}" ] && [ -z "${indexer}" ] && [ -z "${dashboard}" ] && [ -z "${wazuh}" ] &&
[ -z "${start_indexer_cluster}" ]; then
common_logger "Updated wazuh-wui user password in wazuh dashboard. Remember to
restart the service."
fi
file_exists=1
fi
sleep 5
j=$((j+1))
done
}
function passwords_checkUser() {
if [ -z "${exists}" ]; then
common_logger -e "The given user does not exist"
exit 1;
fi
}
function passwords_checkPassword() {
if ! echo "$1" | grep -q "[A-Z]" || ! echo "$1" | grep -q "[a-z]" || ! echo "$1" | grep -q "[0-9]" || ! echo
"$1" | grep -q "[.*+?-]" || [ "${#1}" -lt 8 ] || [ "${#1}" -gt 64 ]; then
common_logger -e "The password must have a length between 8 and 64 characters and contain at
least one upper and lower case letter, a number and a symbol(.*+?-)."
if [[ $(type -t installCommon_rollBack) == "function" ]]; then
installCommon_rollBack
fi
exit 1
fi
}
function passwords_createBackUp() {
}
function passwords_generateHash() {
if [ -n "${changeall}" ]; then
common_logger -d "Generating password hashes."
for i in "${!passwords[@]}"
do
nhash=$(bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh -p "$
{passwords[i]}" | grep -A 2 'issues' | tail -n 1)
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "Hash generation failed."
exit 1;
fi
hashes+=("${nhash}")
done
common_logger -d "Password hashes generated."
else
common_logger "Generating password hash"
hash=$(bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/hash.sh -p "$
{password}" | grep -A 2 'issues' | tail -n 1)
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "Hash generation failed."
exit 1;
fi
common_logger -d "Password hash generated."
fi
}
function passwords_generatePassword() {
if [ -n "${nuser}" ]; then
common_logger -d "Generating random password."
pass=$(< /dev/urandom tr -dc "A-Za-z0-9.*+?" | head -c "${1:-28}";echo;)
special_char=$(< /dev/urandom tr -dc ".*+?" | head -c "${1:-1}";echo;)
minus_char=$(< /dev/urandom tr -dc "a-z" | head -c "${1:-1}";echo;)
mayus_char=$(< /dev/urandom tr -dc "A-Z" | head -c "${1:-1}";echo;)
number_char=$(< /dev/urandom tr -dc "0-9" | head -c "${1:-1}";echo;)
password="$(echo "${pass}${special_char}${minus_char}${mayus_char}${number_char}" |
fold -w1 | shuf | tr -d '\n')"
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "The password could not been generated."
exit 1;
fi
else
common_logger -d "Generating random passwords."
for i in "${!users[@]}"; do
pass=$(< /dev/urandom tr -dc "A-Za-z0-9.*+?" | head -c "${1:-28}";echo;)
special_char=$(< /dev/urandom tr -dc ".*+?" | head -c "${1:-1}";echo;)
minus_char=$(< /dev/urandom tr -dc "a-z" | head -c "${1:-1}";echo;)
mayus_char=$(< /dev/urandom tr -dc "A-Z" | head -c "${1:-1}";echo;)
number_char=$(< /dev/urandom tr -dc "0-9" | head -c "${1:-1}";echo;)
passwords+=("$(echo "${pass}${special_char}${minus_char}${mayus_char}$
{number_char}" | fold -w1 | shuf | tr -d '\n')")
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "The password could not been generated."
exit 1;
fi
done
for i in "${!api_users[@]}"; do
pass=$(< /dev/urandom tr -dc "A-Za-z0-9.*+?" | head -c "${1:-28}";echo;)
special_char=$(< /dev/urandom tr -dc ".*+?" | head -c "${1:-1}";echo;)
minus_char=$(< /dev/urandom tr -dc "a-z" | head -c "${1:-1}";echo;)
mayus_char=$(< /dev/urandom tr -dc "A-Z" | head -c "${1:-1}";echo;)
number_char=$(< /dev/urandom tr -dc "0-9" | head -c "${1:-1}";echo;)
api_passwords+=("$(echo "${pass}${special_char}${minus_char}${mayus_char}$
{number_char}" | fold -w1 | shuf | tr -d '\n')")
if [ "${PIPESTATUS[0]}" != 0 ]; then
common_logger -e "The password could not been generated."
exit 1;
fi
done
fi
}
function passwords_generatePasswordFile() {
for i in "${!users[@]}"; do
{
echo "# ${user_description[${i}]}"
echo " indexer_username: '${users[${i}]}'"
echo " indexer_password: '${passwords[${i}]}'"
echo ""
} >> "${gen_file}"
done
for i in "${!api_users[@]}"; do
{
echo "# ${api_user_description[${i}]}"
echo " api_username: '${api_users[${i}]}'"
echo " api_password: '${api_passwords[${i}]}'"
echo ""
} >> "${gen_file}"
done
}
function passwords_getApiToken() {
retries=0
max_internal_error_retries=20
}
function passwords_getApiUsers() {
}
function passwords_getApiIds() {
}
function passwords_getApiUserId() {
user_id="noid"
for u in "${!api_users[@]}"; do
if [ "${1}" == "${api_users[u]}" ]; then
user_id="${api_ids[u]}"
fi
done
}
function passwords_getNetworkHost() {
For Wazuh indexer users, the file must have this format:
# Description
indexer_username: <user>
indexer_password: <password>
For Wazuh API users, the file must have this format:
# Description
api_username: <user>
api_password: <password>
"
exit 1
fi
sfileusers=$(grep indexer_username: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed -e
"s/[\'\"]//g")
sfilepasswords=$(grep indexer_password: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' |
sed -e "s/[\'\"]//g")
sfileapiusers=$(grep api_username: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed -e
"s/[\'\"]//g")
sfileapipasswords=$(grep api_password: "${p_file}" | awk '{ print substr( $2, 1, length($2) ) }' | sed
-e "s/[\'\"]//g")
if [ -n "${changeall}" ]; then
for j in "${!fileusers[@]}"; do
supported=false
for i in "${!users[@]}"; do
if [[ "${users[i]}" == "${fileusers[j]}" ]]; then
passwords_checkPassword "${filepasswords[j]}"
passwords[i]=${filepasswords[j]}
supported=true
fi
done
if [ "${supported}" = false ] && [ -n "${indexer_installed}" ]; then
common_logger -e "The user ${fileusers[j]} does not exist"
fi
done
finalapiusers=()
finalapipasswords=()
for j in "${!fileusers[@]}"; do
supported=false
for i in "${!users[@]}"; do
if [[ "${users[i]}" == "${fileusers[j]}" ]]; then
passwords_checkPassword "${filepasswords[j]}"
finalusers+=("${fileusers[j]}")
finalpasswords+=("${filepasswords[j]}")
supported=true
fi
done
if [ ${supported} = false ] && [ -n "${indexer_installed}" ]; then
common_logger -e "The user ${fileusers[j]} does not exist"
fi
done
users=()
passwords=()
mapfile -t users < <(printf "%s\n" "${finalusers[@]}")
mapfile -t passwords < <(printf "%s\n" "${finalpasswords[@]}")
mapfile -t api_users < <(printf "%s\n" "${finalapiusers[@]}")
mapfile -t api_passwords < <(printf "%s\n" "${finalapipasswords[@]}")
changeall=1
fi
}
function passwords_readUsers() {
}
function passwords_restartService() {
}
function passwords_runSecurityAdmin() {
if [ -n "${changeall}" ]; then
if [ -z "${AIO}" ] && [ -z "${indexer}" ] && [ -z "${dashboard}" ] && [ -z "${wazuh}" ] && [ -
z "${start_indexer_cluster}" ]; then
for i in "${!users[@]}"; do
common_logger -nl "The password for user ${users[i]} is ${passwords[i]}"
done
common_logger -w "Wazuh indexer passwords changed. Remember to update the password in
the Wazuh dashboard and Filebeat nodes if necessary, and restart the services."
else
common_logger -d "Passwords changed."
fi
fi
main "$@"