diff --git a/wazuh/Dockerfile b/wazuh/Dockerfile index 04b05d90..92dad7c0 100644 --- a/wazuh/Dockerfile +++ b/wazuh/Dockerfile @@ -41,20 +41,19 @@ COPY config/filebeat.yml /etc/filebeat/ RUN chmod go-w /etc/filebeat/filebeat.yml +ADD https://raw.githubusercontent.com/wazuh/wazuh/$TEMPLATE_VERSION/extensions/elasticsearch/7.x/wazuh-template.json /etc/filebeat +RUN chmod go-w /etc/filebeat/wazuh-template.json + COPY config/etc/ /etc/ -COPY config/data_dirs.env / - -# Setting volumes -VOLUME ["/var/ossec/data"] -VOLUME ["/etc/filebeat"] -VOLUME ["/var/lib/filebeat"] +# Prepare permanent data +# Sync calls are due to https://github.com/docker/docker/issues/9547 +COPY config/permanent_data.env config/permanent_data.sh / +RUN chmod 755 /permanent_data.sh && \ + sync && /permanent_data.sh && \ + sync && rm /permanent_data.sh # Services ports EXPOSE 55000/tcp 1514/udp 1515/tcp 514/udp 1516/tcp - -ADD https://raw.githubusercontent.com/wazuh/wazuh/$TEMPLATE_VERSION/extensions/elasticsearch/7.x/wazuh-template.json /etc/filebeat -RUN chmod go-w /etc/filebeat/wazuh-template.json - ENTRYPOINT [ "/init" ] diff --git a/wazuh/config/etc/cont-init.d/0-wazuh-init b/wazuh/config/etc/cont-init.d/0-wazuh-init index 10796414..2fb840dd 100644 --- a/wazuh/config/etc/cont-init.d/0-wazuh-init +++ b/wazuh/config/etc/cont-init.d/0-wazuh-init @@ -4,14 +4,18 @@ # Wazuh container bootstrap. See the README for information of the environment # variables expected by this script. -# Startup the services - -FIRST_TIME_INSTALLATION=true +# Variables +source /permanent_data.env WAZUH_INSTALL_PATH=/var/ossec -DATA_PATH=${WAZUH_INSTALL_PATH}/data - WAZUH_CONFIG_MOUNT=/wazuh-config-mount +AUTO_ENROLLMENT_ENABLED=${AUTO_ENROLLMENT_ENABLED:-true} +API_GENERATE_CERTS=${API_GENERATE_CERTS:-true} + + +############################################################################## +# Aux functions +############################################################################## print() { echo -e $1 @@ -31,72 +35,219 @@ exec_cmd_stdout() { eval $1 2>&1 || error_and_exit "$1" } +############################################################################## +# Edit configuration +############################################################################## + edit_configuration() { # $1 -> setting, $2 -> value sed -i "s/^config.$1\s=.*/config.$1 = \"$2\";/g" "${DATA_PATH}/api/configuration/config.js" || error_and_exit "sed (editing configuration)" } -if [ -e ${WAZUH_INSTALL_PATH}/etc-template ] -then - cp -p /var/ossec/etc-template/internal_options.conf /var/ossec/etc/internal_options.conf -fi -rm /var/ossec/queue/db/.template.db +############################################################################## +# This function will attempt to mount every directory in PERMANENT_DATA +# into the respective path. +# If the path is empty means permanent data volume is also empty, so a backup +# will be copied into it. Otherwise it will not be copied because there is +# already data inside the volume for the specified path. +############################################################################## -touch ${DATA_PATH}/process_list -chgrp ossec ${DATA_PATH}/process_list -chmod g+rw ${DATA_PATH}/process_list - -AUTO_ENROLLMENT_ENABLED=${AUTO_ENROLLMENT_ENABLED:-true} -API_GENERATE_CERTS=${API_GENERATE_CERTS:-true} +mount_permanent_data() { + for permanent_dir in "${PERMANENT_DATA[@]}"; do + # Check if the path is not empty + if find ${permanent_dir} -mindepth 1 | read; then + print "The path ${permanent_dir} is already mounted" + else + print "Installing ${permanent_dir}" + exec_cmd "cp -a ${WAZUH_INSTALL_PATH}/data_tmp/permanent${permanent_dir}/. ${permanent_dir}" + fi + done +} ############################################################################## -# Copy all files from $WAZUH_CONFIG_MOUNT to $DATA_PATH and respect +# This function will replace from the permanent data volume every file +# contained in PERMANENT_DATA_EXCP +# Some files as 'internal_options.conf' are saved as permanent data, but +# they must be updated to work properly if wazuh version is changed. +############################################################################## + +apply_exclusion_data() { + for exclusion_file in "${PERMANENT_DATA_EXCP[@]}"; do + if [ -e ${WAZUH_INSTALL_PATH}/data_tmp/exclusion/${exclusion_file} ] + then + DIR=$(dirname "${exclusion_file}") + if [ ! -e ${DIR} ] + then + mkdir -p ${DIR} + fi + + print "Updating ${exclusion_file}" + exec_cmd "cp -p ${WAZUH_INSTALL_PATH}/data_tmp/exclusion/${exclusion_file} ${exclusion_file}" + fi + done +} + +############################################################################## +# This function will delete from the permanent data volume every file +# contained in PERMANENT_DATA_DEL +############################################################################## + +remove_data_files() { + for del_file in "${PERMANENT_DATA_DEL[@]}"; do + if [ -e ${del_file} ] + then + print "Removing ${del_file}" + exec_cmd "rm ${del_file}" + fi + done +} + +############################################################################## +# Create certificates: Manager +############################################################################## + +create_ossec_key_cert() { + print "Creating ossec-authd key and cert" + exec_cmd "openssl genrsa -out ${WAZUH_INSTALL_PATH}/etc/sslmanager.key 4096" + exec_cmd "openssl req -new -x509 -key ${WAZUH_INSTALL_PATH}/etc/sslmanager.key -out ${WAZUH_INSTALL_PATH}/etc/sslmanager.cert -days 3650 -subj /CN=${HOSTNAME}/" +} + +############################################################################## +# Create certificates: API +############################################################################## + +create_api_key_cert() { + print "Enabling Wazuh API HTTPS" + edit_configuration "https" "yes" + print "Create Wazuh API key and cert" + exec_cmd "openssl genrsa -out ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.key 4096" + exec_cmd "openssl req -new -x509 -key ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.key -out ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.crt -days 3650 -subj /CN=${HOSTNAME}/" + + # Granting proper permissions + chmod 400 ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.key + chmod 400 ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.crt +} + +############################################################################## +# Copy all files from $WAZUH_CONFIG_MOUNT to $WAZUH_INSTALL_PATH and respect # destination files permissions # # For example, to mount the file /var/ossec/data/etc/ossec.conf, mount it at # $WAZUH_CONFIG_MOUNT/etc/ossec.conf in your container and this code will # replace the ossec.conf file in /var/ossec/data/etc with yours. ############################################################################## -if [ -e "$WAZUH_CONFIG_MOUNT" ] -then - print "Identified Wazuh configuration files to mount..." - exec_cmd_stdout "cp --verbose -r $WAZUH_CONFIG_MOUNT/* $DATA_PATH" -else - print "No Wazuh configuration files to mount..." -fi +mount_files() { + if [ -e "$WAZUH_CONFIG_MOUNT" ] + then + print "Identified Wazuh configuration files to mount..." + exec_cmd_stdout "cp --verbose -r $WAZUH_CONFIG_MOUNT/* $WAZUH_INSTALL_PATH" + else + print "No Wazuh configuration files to mount..." + fi +} + + +############################################################################## +# Stop OSSEC +############################################################################## function ossec_shutdown(){ ${WAZUH_INSTALL_PATH}/bin/ossec-control stop; } -# Trap exit signals and do a proper shutdown -trap "ossec_shutdown; exit" SIGINT SIGTERM - -chmod -R g+rw ${DATA_PATH} - ############################################################################## # Interpret any passed arguments (via docker command to this entrypoint) as -# paths or commands, and execute them. +# paths or commands, and execute them. # # This can be useful for actions that need to be run before the services are # started, such as "/var/ossec/bin/ossec-control enable agentless". ############################################################################## -for CUSTOM_COMMAND in "$@" -do - echo "Executing command \`${CUSTOM_COMMAND}\`" - exec_cmd_stdout "${CUSTOM_COMMAND}" -done + +docker_custom_args() { + for CUSTOM_COMMAND in "$@" + do + echo "Executing command \`${CUSTOM_COMMAND}\`" + exec_cmd_stdout "${CUSTOM_COMMAND}" + done +} ############################################################################## # Change Wazuh API user credentials. ############################################################################## -pushd /var/ossec/api/configuration/auth/ +change_api_user_credentials() { + pushd /var/ossec/api/configuration/auth/ + if [[ "x${SECURITY_CREDENTIALS_FILE}" == "x" ]]; then + WAZUH_API_USER=${API_USER} + WAZUH_API_PASS=${API_PASS} + else + input=${SECURITY_CREDENTIALS_FILE} + while IFS= read -r line + do + if [[ $line == *"WAZUH_API_USER"* ]]; then + arrIN=(${line//:/ }) + WAZUH_API_USER=${arrIN[1]} + elif [[ $line == *"WAZUH_API_PASS"* ]]; then + arrIN=(${line//:/ }) + WAZUH_API_PASS=${arrIN[1]} + fi + done < "$input" + fi -env + echo "Change Wazuh API user credentials" + change_user="node htpasswd -b -c user $WAZUH_API_USER $WAZUH_API_PASS" + eval $change_user + popd +} -echo "Change Wazuh API user credentials" -change_user="node htpasswd -b -c user $API_USER $API_PASS" -eval $change_user -popd +############################################################################## +# Main function +############################################################################## + +main() { + # Mount permanent data (i.e. ossec.conf) + mount_permanent_data + + # Restore files stored in permanent data that are not permanent (i.e. internal_options.conf) + apply_exclusion_data + + # Remove some files in permanent_data (i.e. .template.db) + remove_data_files + + # Generate ossec-authd certs if AUTO_ENROLLMENT_ENABLED is true and does not exist + if [ $AUTO_ENROLLMENT_ENABLED == true ] + then + if [ ! -e ${WAZUH_INSTALL_PATH}/etc/sslmanager.key ] + then + create_ossec_key_cert + fi + fi + + # Generate API certs if API_GENERATE_CERTS is true and does not exist + if [ $API_GENERATE_CERTS == true ] + then + if [ ! -e ${WAZUH_INSTALL_PATH}/api/configuration/ssl/server.crt ] + then + create_api_key_cert + fi + fi + + # Mount selected files (WAZUH_CONFIG_MOUNT) to container + mount_files + + # Trap exit signals and do a proper shutdown + trap "ossec_shutdown; exit" SIGINT SIGTERM + + # Execute custom args + docker_custom_args + + # Change API user credentials + change_api_user_credentials + + # Delete temporary data folder + rm -rf ${WAZUH_INSTALL_PATH}/data_tmp + +} + +main diff --git a/wazuh/config/init.bash b/wazuh/config/init.bash deleted file mode 100644 index e40fab94..00000000 --- a/wazuh/config/init.bash +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# Wazuh Docker Copyright (C) 2019 Wazuh Inc. (License GPLv2) - -# Initialize the custom data directory layout -source /data_dirs.env - -cd /var/ossec -for ossecdir in "${DATA_DIRS[@]}"; do - mv ${ossecdir} ${ossecdir}-template - ln -s $(realpath --relative-to=$(dirname ${ossecdir}) data)/${ossecdir} ${ossecdir} -done diff --git a/wazuh/config/permanent_data.env b/wazuh/config/permanent_data.env new file mode 100644 index 00000000..b19409ac --- /dev/null +++ b/wazuh/config/permanent_data.env @@ -0,0 +1,61 @@ +# Permanent data mounted in volumes +i=0 +PERMANENT_DATA[((i++))]="/var/ossec/api/configuration" +PERMANENT_DATA[((i++))]="/var/ossec/etc" +PERMANENT_DATA[((i++))]="/var/ossec/logs" +PERMANENT_DATA[((i++))]="/var/ossec/queue" +PERMANENT_DATA[((i++))]="/var/ossec/var/multigroups" +PERMANENT_DATA[((i++))]="/var/ossec/integrations" +PERMANENT_DATA[((i++))]="/var/ossec/active-response/bin" +PERMANENT_DATA[((i++))]="/var/ossec/wodles" +PERMANENT_DATA[((i++))]="/etc/filebeat" +export PERMANENT_DATA + +# Files mounted in a volume that should not be permanent +i=0 +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/etc/internal_options.conf" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/pagerduty" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/slack" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/slack.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/virustotal" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/integrations/virustotal.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/default-firewall-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/disable-account.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/firewalld-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/firewall-drop.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/host-deny.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ip-customblock.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ipfw_mac.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ipfw.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/kaspersky.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/kaspersky.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/npf.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ossec-slack.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/ossec-tweeter.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/pf.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/restart-ossec.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/restart.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/active-response/bin/route-null.sh" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/aws/aws-s3" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/aws/aws-s3.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/azure/azure-logs" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/azure/azure-logs.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/docker/DockerListener" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/docker/DockerListener.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/oscap" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/oscap.py" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/template_oval.xsl" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/template_xccdf.xsl" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/cve-redhat-6-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/cve-redhat-7-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/ssg-centos-6-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/ssg-centos-7-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/ssg-fedora-24-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/ssg-rhel-6-ds.xml" +PERMANENT_DATA_EXCP[((i++))]="/var/ossec/wodles/oscap/content/ssg-rhel-7-ds.xml" +export PERMANENT_DATA_EXCP + +# Files mounted in a volume that should be deleted +i=0 +PERMANENT_DATA_DEL[((i++))]="/var/ossec/queue/db/.template.db" +export PERMANENT_DATA_DEL diff --git a/wazuh/config/permanent_data.sh b/wazuh/config/permanent_data.sh new file mode 100644 index 00000000..7a9d55b4 --- /dev/null +++ b/wazuh/config/permanent_data.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# Wazuh App Copyright (C) 2019 Wazuh Inc. (License GPLv2) + +# Variables +source /permanent_data.env + +WAZUH_INSTALL_PATH=/var/ossec +DATA_TMP_PATH=${WAZUH_INSTALL_PATH}/data_tmp +mkdir ${DATA_TMP_PATH} + +# Move exclusion files to EXCLUSION_PATH +EXCLUSION_PATH=${DATA_TMP_PATH}/exclusion +mkdir ${EXCLUSION_PATH} + +for exclusion_file in "${PERMANENT_DATA_EXCP[@]}"; do + # Create the directory for the exclusion file if it does not exist + DIR=$(dirname "${exclusion_file}") + if [ ! -e ${EXCLUSION_PATH}/${DIR} ] + then + mkdir -p ${EXCLUSION_PATH}/${DIR} + fi + + mv ${exclusion_file} ${EXCLUSION_PATH}/${exclusion_file} +done + +# Move permanent files to PERMANENT_PATH +PERMANENT_PATH=${DATA_TMP_PATH}/permanent +mkdir ${PERMANENT_PATH} + +for permanent_dir in "${PERMANENT_DATA[@]}"; do + # Create the directory for the permanent file if it does not exist + DIR=$(dirname "${permanent_dir}") + if [ ! -e ${PERMANENT_PATH}${DIR} ] + then + mkdir -p ${PERMANENT_PATH}${DIR} + fi + + mv ${permanent_dir} ${PERMANENT_PATH}${permanent_dir} + +done \ No newline at end of file