From 9f1dec3338ed0b1db9078a7625b8c56819f50873 Mon Sep 17 00:00:00 2001 From: vcerenu Date: Fri, 4 Mar 2022 18:20:15 -0300 Subject: [PATCH] Update config and certs path --- generate-indexer-certs.yml | 2 +- indexer_certs_creator/Dockerfile | 8 +- indexer_certs_creator/config/entrypoint.sh | 4 +- .../config/unattended_installer.tar.gz | Bin 9234 -> 0 bytes .../config/wazuh-cert-tool.sh | 434 ++++++++++++++++++ production-cluster.yml | 28 +- .../wazuh-indexer/wazuh1.indexer.yml | 12 +- .../wazuh-indexer/wazuh2.indexer.yml | 12 +- .../wazuh-indexer/wazuh3.indexer.yml | 12 +- wazuh-indexer/Dockerfile | 16 +- wazuh-indexer/config/config.sh | 29 +- wazuh-indexer/config/entrypoint.sh | 11 +- wazuh-indexer/config/internal_users.yml | 74 +++ wazuh-indexer/config/opensearch.yml | 12 +- wazuh-indexer/config/roles.yml | 163 +++++++ wazuh-indexer/config/roles_mapping.yml | 71 +++ .../config/unattended_installer.tar.gz | Bin 9234 -> 0 bytes 17 files changed, 818 insertions(+), 70 deletions(-) delete mode 100644 indexer_certs_creator/config/unattended_installer.tar.gz create mode 100644 indexer_certs_creator/config/wazuh-cert-tool.sh create mode 100644 wazuh-indexer/config/internal_users.yml create mode 100644 wazuh-indexer/config/roles.yml create mode 100644 wazuh-indexer/config/roles_mapping.yml delete mode 100644 wazuh-indexer/config/unattended_installer.tar.gz diff --git a/generate-indexer-certs.yml b/generate-indexer-certs.yml index b93dbfff..ce8a0174 100644 --- a/generate-indexer-certs.yml +++ b/generate-indexer-certs.yml @@ -6,5 +6,5 @@ services: image: wazuh/wazuh-certs-generator:0.0.1 hostname: wazuh-certs-generator volumes: - - ./production_cluster/wazuh_indexer_ssl_certs/certs.yml:/unattended_installer/install_functions/config.yml + - ./production_cluster/wazuh_indexer_ssl_certs/certs.yml:/config.yml - ./production_cluster/wazuh_indexer_ssl_certs/:/certificates/ \ No newline at end of file diff --git a/indexer_certs_creator/Dockerfile b/indexer_certs_creator/Dockerfile index eefe7bea..1ed3a78a 100644 --- a/indexer_certs_creator/Dockerfile +++ b/indexer_certs_creator/Dockerfile @@ -1,16 +1,14 @@ # Wazuh Docker Copyright (C) 2021 Wazuh Inc. (License GPLv2) FROM ubuntu:focal -RUN apt-get update && apt-get install openssl -y +RUN apt-get update && apt-get install openssl curl -y WORKDIR / -COPY config/unattended_installer.tar.gz / +RUN curl -o wazuh-cert-tool.sh https://s3.us-west-1.amazonaws.com/packages.wazuh.com/4.x/wazuh-cert-tool.sh COPY config/entrypoint.sh / -RUN tar -xzvf /unattended_installer.tar.gz - -RUN chmod 700 /entrypoint.sh && chmod -R 700 unattended_installer +RUN chmod 700 /entrypoint.sh && chmod 700 /wazuh-cert-tool.sh ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/indexer_certs_creator/config/entrypoint.sh b/indexer_certs_creator/config/entrypoint.sh index 959f9e6d..8642171f 100644 --- a/indexer_certs_creator/config/entrypoint.sh +++ b/indexer_certs_creator/config/entrypoint.sh @@ -5,8 +5,8 @@ # Creating Cluster certificates ############################################################################## -/unattended_installer/install_functions/wazuh-cert-tool.sh +/wazuh-cert-tool.sh echo "Moving created certificates to destination directory" -cp /unattended_installer/install_functions/certs/* /certificates/ +cp /certs/* /certificates/ echo "changing certificate permissions" chmod -R 666 /certificates/* diff --git a/indexer_certs_creator/config/unattended_installer.tar.gz b/indexer_certs_creator/config/unattended_installer.tar.gz deleted file mode 100644 index 0a2de7fdb283502c7b8f2917f9cb068a7a03ad05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9234 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 diff --git a/indexer_certs_creator/config/wazuh-cert-tool.sh b/indexer_certs_creator/config/wazuh-cert-tool.sh new file mode 100644 index 00000000..072369df --- /dev/null +++ b/indexer_certs_creator/config/wazuh-cert-tool.sh @@ -0,0 +1,434 @@ +#!/bin/bash + +# Program to generate the certificates necessary for Wazuh installation +# 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. + +if [ -z "${base_path}" ]; then + readonly base_path="$(dirname "$(readlink -f "$0")")" + readonly config_file="${base_path}/config.yml" +fi + +if [[ -z "${logfile}" ]]; then + readonly logfile="/var/log/wazuh-cert-tool.log" +fi + +debug_cert=">> ${logfile} 2>&1" + +function cleanFiles() { + + eval "rm -f ${base_path}/certs/*.csr ${debug_cert}" + eval "rm -f ${base_path}/certs/*.srl ${debug_cert}" + eval "rm -f ${base_path}/certs/*.conf ${debug_cert}" + eval "rm -f ${base_path}/certs/admin-key-temp.pem ${debug_cert}" + +} + +function checkOpenSSL() { + if [ -z "$(command -v openssl)" ]; then + logger_cert -e "OpenSSL not installed." + exit 1 + fi +} + +function logger_cert() { + now=$(date +'%d/%m/%Y %H:%M:%S') + mtype="INFO:" + debugLogger= + disableHeader= + if [ -n "${1}" ]; then + while [ -n "${1}" ]; do + case ${1} in + "-e") + mtype="ERROR:" + shift 1 + ;; + "-w") + mtype="WARNING:" + shift 1 + ;; + "-dh") + disableHeader=1 + shift 1 + ;; + "-d") + debugLogger=1 + shift 1 + ;; + *) + message="${1}" + shift 1 + ;; + esac + done + fi + + if [ -z "${debugLogger}" ] || ( [ -n "${debugLogger}" ] && [ -n "${debugEnabled}" ] ); then + if [ -n "${disableHeader}" ]; then + echo "${message}" | tee -a ${logfile} + else + echo "${now} ${mtype} ${message}" | tee -a ${logfile} + fi + fi +} + +function generateAdmincertificate() { + + eval "openssl genrsa -out ${base_path}/certs/admin-key-temp.pem 2048 ${debug_cert}" + eval "openssl pkcs8 -inform PEM -outform PEM -in ${base_path}/certs/admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out ${base_path}/certs/admin-key.pem ${debug_cert}" + eval "openssl req -new -key ${base_path}/certs/admin-key.pem -out ${base_path}/certs/admin.csr -batch -subj '/C=US/L=California/O=Wazuh/OU=Wazuh/CN=admin' ${debug_cert}" + eval "openssl x509 -days 3650 -req -in ${base_path}/certs/admin.csr -CA ${base_path}/certs/root-ca.pem -CAkey ${base_path}/certs/root-ca.key -CAcreateserial -sha256 -out ${base_path}/certs/admin.pem ${debug_cert}" + eval "chmod 444 ${base_path}/certs/admin*.pem ${debug_cert}" + +} + +function generateCertificateconfiguration() { + + cat > "${base_path}/certs/${1}.conf" <<- EOF + [ req ] + prompt = no + default_bits = 2048 + default_md = sha256 + distinguished_name = req_distinguished_name + x509_extensions = v3_req + + [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 + + conf="$(awk '{sub("CN = cname", "CN = '${1}'")}1' "${base_path}/certs/${1}.conf")" + echo "${conf}" > "${base_path}/certs/${1}.conf" + + isIP=$(echo "${2}" | grep -P "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$") + isDNS=$(echo "${2}" | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$" ) + + if [[ -n "${isIP}" ]]; then + conf="$(awk '{sub("IP.1 = cip", "IP.1 = '${2}'")}1' "${base_path}/certs/${1}.conf")" + echo "${conf}" > "${base_path}/certs/${1}.conf" + elif [[ -n "${isDNS}" ]]; then + conf="$(awk '{sub("CN = cname", "CN = '${2}'")}1' "${base_path}/certs/${1}.conf")" + echo "${conf}" > "${base_path}/certs/${1}.conf" + conf="$(awk '{sub("IP.1 = cip", "DNS.1 = '${2}'")}1' "${base_path}/certs/${1}.conf")" + echo "${conf}" > "${base_path}/certs/${1}.conf" + else + logger_cert -e "The given information does not match with an IP address or a DNS." + exit 1 + fi + +} + +function generateIndexercertificates() { + + if [ ${#indexer_node_names[@]} -gt 0 ]; then + logger_cert -d "Creating the Wazuh indexer certificates." + + for i in "${!indexer_node_names[@]}"; do + generateCertificateconfiguration "${indexer_node_names[i]}" "${indexer_node_ips[i]}" + eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${base_path}/certs/${indexer_node_names[i]}-key.pem -out ${base_path}/certs/${indexer_node_names[i]}.csr -config ${base_path}/certs/${indexer_node_names[i]}.conf -days 3650 ${debug_cert}" + eval "openssl x509 -req -in ${base_path}/certs/${indexer_node_names[i]}.csr -CA ${base_path}/certs/root-ca.pem -CAkey ${base_path}/certs/root-ca.key -CAcreateserial -out ${base_path}/certs/${indexer_node_names[i]}.pem -extfile ${base_path}/certs/${indexer_node_names[i]}.conf -extensions v3_req -days 3650 ${debug_cert}" + eval "chmod 444 ${base_path}/certs/${indexer_node_names[i]}-key.pem ${debug_cert}" + done + fi + +} + +function generateFilebeatcertificates() { + + if [ ${#wazuh_servers_node_names[@]} -gt 0 ]; then + logger_cert -d "Creating the Wazuh server certificates." + + for i in "${!wazuh_servers_node_names[@]}"; do + generateCertificateconfiguration "${wazuh_servers_node_names[i]}" "${wazuh_servers_node_ips[i]}" + eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${base_path}/certs/${wazuh_servers_node_names[i]}-key.pem -out ${base_path}/certs/${wazuh_servers_node_names[i]}.csr -config ${base_path}/certs/${wazuh_servers_node_names[i]}.conf -days 3650 ${debug_cert}" + eval "openssl x509 -req -in ${base_path}/certs/${wazuh_servers_node_names[i]}.csr -CA ${base_path}/certs/root-ca.pem -CAkey ${base_path}/certs/root-ca.key -CAcreateserial -out ${base_path}/certs/${wazuh_servers_node_names[i]}.pem -extfile ${base_path}/certs/${wazuh_servers_node_names[i]}.conf -extensions v3_req -days 3650 ${debug_cert}" + done + fi + +} + +function generateDashboardcertificates() { + + if [ ${#dashboard_node_names[@]} -gt 0 ]; then + logger_cert -d "Creating the Wazuh dashboard certificates." + + for i in "${!dashboard_node_names[@]}"; do + generateCertificateconfiguration "${dashboard_node_names[i]}" "${dashboard_node_ips[i]}" + eval "openssl req -new -nodes -newkey rsa:2048 -keyout ${base_path}/certs/${dashboard_node_names[i]}-key.pem -out ${base_path}/certs/${dashboard_node_names[i]}.csr -config ${base_path}/certs/${dashboard_node_names[i]}.conf -days 3650 ${debug_cert}" + eval "openssl x509 -req -in ${base_path}/certs/${dashboard_node_names[i]}.csr -CA ${base_path}/certs/root-ca.pem -CAkey ${base_path}/certs/root-ca.key -CAcreateserial -out ${base_path}/certs/${dashboard_node_names[i]}.pem -extfile ${base_path}/certs/${dashboard_node_names[i]}.conf -extensions v3_req -days 3650 ${debug_cert}" + eval "chmod 444 ${base_path}/certs/${dashboard_node_names[i]}-key.pem ${debug_cert}" + done + fi + +} + +function generateRootCAcertificate() { + + logger_cert -d "Creating the root certificate." + + eval "openssl req -x509 -new -nodes -newkey rsa:2048 -keyout ${base_path}/certs/root-ca.key -out ${base_path}/certs/root-ca.pem -batch -subj '/OU=Wazuh/O=Wazuh/L=California/' -days 3650 ${debug_cert}" + +} + +function getHelp() { + + echo -e "" + echo -e "NAME" + echo -e " wazuh-cert-tool.sh - Manages the creation of certificates of the Wazuh components." + echo -e "" + echo -e "SYNOPSIS" + echo -e " wazuh-cert-tool.sh [OPTIONS]" + echo -e "" + echo -e "DESCRIPTION" + echo -e " -a, --admin-certificates" + echo -e " Creates the admin certificates." + echo -e "" + echo -e " -ca, --root-ca-certificates" + echo -e " Creates the root-ca certificates." + echo -e "" + echo -e " -v, --verbose" + echo -e " Enables verbose mode." + echo -e "" + echo -e " -wd, --wazuh-dashboard-certificates" + echo -e " Creates the Wazuh dashboard certificates." + echo -e "" + echo -e " -wi, --wazuh-indexer-certificates" + echo -e " Creates the Wazuh indexer certificates." + echo -e "" + echo -e " -ws, --wazuh-server-certificates" + echo -e " Creates the Wazuh server certificates." + + exit 1 + +} + +function main() { + + if [ "$EUID" -ne 0 ]; then + logger_cert -e "This script must be run as root." + exit 1 + fi + + checkOpenSSL + + if [[ -d ${base_path}/certs ]]; then + logger_cert -e "Folder ${base_path}/certs already exists. Please, remove the /certs folder to create new certificates." + exit 1 + else + mkdir "${base_path}/certs" + fi + + if [ -n "${1}" ]; then + while [ -n "${1}" ] + do + case "${1}" in + "-a"|"--admin-certificates") + cadmin=1 + shift 1 + ;; + "-ca"|"--root-ca-certificate") + ca=1 + shift 1 + ;; + "-h"|"--help") + getHelp + ;; + "-v"|"--verbose") + debugEnabled=1 + shift 1 + ;; + "-wd"|"--wazuh-dashboard-certificates") + cdashboard=1 + shift 1 + ;; + "-wi"|"--wazuh-indexer-certificates") + cindexer=1 + shift 1 + ;; + "-ws"|"--wazuh-server-certificates") + cserver=1 + shift 1 + ;; + *) + getHelp + esac + done + + readConfig + + if [ -n "${debugEnabled}" ]; then + debug_cert="2>&1 | tee -a ${logfile}" + fi + + if [[ -n "${cadmin}" ]]; then + generateAdmincertificate + logger_cert "Admin certificates created." + fi + + if [[ -n "${ca}" ]]; then + generateRootCAcertificate + logger_cert "Authority certificates created." + fi + + if [[ -n "${cindexer}" ]]; then + generateIndexercertificates + logger_cert "Wazuh indexer certificates created." + fi + + if [[ -n "${cserver}" ]]; then + generateFilebeatcertificates + logger_cert "Wazuh server certificates created." + fi + + if [[ -n "${cdashboard}" ]]; then + generateDashboardcertificates + logger_cert "Wazuh dashboard certificates created." + fi + + else + readConfig + generateRootCAcertificate + generateAdmincertificate + generateIndexercertificates + generateFilebeatcertificates + generateDashboardcertificates + cleanFiles + fi + +} + +function parse_yaml() { + + local prefix=${2} + local s='[[:space:]]*' + local w='[a-zA-Z0-9_]*' + local fs=$(echo @|tr @ '\034') + sed -ne "s|^\($s\):|\1|" \ + -e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \ + -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" ${1} | + awk -F$fs '{ + indent = length($1)/2; + vname[indent] = $2; + for (i in vname) {if (i > indent) {delete vname[i]}} + if (length($3) > 0) { + vn=""; for (i=0; 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