Skip to content

Commit

Permalink
Build Docker images (#194)
Browse files Browse the repository at this point in the history
* Assemble tar packages

* Add files to generate Docker images

First working version

* Fix certs path

* clean up

* Working indexer in Docker

* Add documentation to build Docker images

Simplify names of Docker build args

* Remove unused Docker dependencies

---------

Signed-off-by: Álex Ruiz <[email protected]>
  • Loading branch information
AlexRuiz7 committed Sep 9, 2024
1 parent b6c98d6 commit 43cc0d7
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,17 @@ Refer to [scripts/README.md](../scripts/README.md) for details about how to buil
[docker-variant]: https://docs.docker.com/desktop/install/linux-install/#differences-between-docker-desktop-for-linux-and-docker-engine
[docker-context]: https://docs.docker.com/desktop/install/linux-install/#context
[wi-repo]: https://github.com/wazuh/wazuh-indexer

## Building Docker images

The [prod](./prod) folder contains the code to build Docker images. A tarball of `wazuh-indexer` needs to be located at the same level that the Dockerfile. Below there is example of the command needed to build the image. Set the build arguments and the image tag accordingly.

```console
docker build --build-arg="VERSION=4.9.0" --build-arg="INDEXER_TAR_NAME=wazuh-indexer-4.9.0-1_linux-x64_cfca84f.tar.gz" --tag=wazuh-indexer:4.9.0 --progress=plain --no-cache .
```

Then, start a container with:

```console
docker run -it --rm wazuh-indexer:4.9.0
```
78 changes: 78 additions & 0 deletions docker/prod/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Wazuh Docker Copyright (C) 2017, Wazuh Inc. (License GPLv2)
FROM amazonlinux:2023.3.20240219.0 AS builder

ARG VERSION
ARG INDEXER_TAR_NAME

RUN yum install openssl tar findutils shadow-utils -y

COPY ${INDEXER_TAR_NAME} /

COPY config/opensearch.yml /

COPY config/config.yml /

COPY config/config.sh /

RUN bash config.sh

################################################################################
# Build stage 1 (the actual Wazuh indexer image):
#
# Copy wazuh-indexer from stage 0
# Add entrypoint

################################################################################
FROM amazonlinux:2023.3.20240219.0

ENV USER="wazuh-indexer" \
GROUP="wazuh-indexer" \
NAME="wazuh-indexer" \
INSTALL_DIR="/usr/share/wazuh-indexer"

RUN yum install curl-minimal shadow-utils findutils hostname -y

RUN getent group $GROUP || groupadd -r -g 1000 $GROUP

RUN useradd --system \
--uid 1000 \
--no-create-home \
--home-dir $INSTALL_DIR \
--gid $GROUP \
--shell /sbin/nologin \
--comment "$USER user" \
$USER

WORKDIR $INSTALL_DIR

COPY entrypoint.sh /

COPY config/securityadmin.sh /

RUN chmod 700 /entrypoint.sh && chmod 700 /securityadmin.sh

RUN chown 1000:1000 /*.sh

COPY --from=builder --chown=1000:1000 /debian/wazuh-indexer/usr/share/wazuh-indexer /usr/share/wazuh-indexer
COPY --from=builder --chown=0:0 /debian/wazuh-indexer/usr/lib/systemd /usr/lib/systemd
COPY --from=builder --chown=0:0 /debian/wazuh-indexer/usr/lib/sysctl.d /usr/lib/sysctl.d
COPY --from=builder --chown=0:0 /debian/wazuh-indexer/usr/lib/tmpfiles.d /usr/lib/tmpfiles.d

RUN chown -R 1000:1000 /usr/share/wazuh-indexer

RUN mkdir -p /var/lib/wazuh-indexer && chown 1000:1000 /var/lib/wazuh-indexer && \
mkdir -p /usr/share/wazuh-indexer/logs && chown 1000:1000 /usr/share/wazuh-indexer/logs && \
mkdir -p /run/wazuh-indexer && chown 1000:1000 /run/wazuh-indexer && \
mkdir -p /var/log/wazuh-indexer && chown 1000:1000 /var/log/wazuh-indexer && \
chmod 700 /usr/share/wazuh-indexer && \
chmod 600 /usr/share/wazuh-indexer/config/jvm.options && \
chmod 600 /usr/share/wazuh-indexer/config/opensearch.yml

USER wazuh-indexer

# Services ports
EXPOSE 9200

ENTRYPOINT ["/entrypoint.sh"]
# Dummy overridable parameter parsed by entrypoint
CMD ["opensearchwrapper"]
64 changes: 64 additions & 0 deletions docker/prod/config/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash

# Wazuh Docker Copyright (C) 2017, Wazuh Inc. (License GPLv2)
# This has to be exported to make some magic below work.
export DH_OPTIONS

export NAME=wazuh-indexer
export TARGET_DIR=${CURDIR}/debian/${NAME}

# Package build options
export LOG_DIR=/var/log/${NAME}
export LIB_DIR=/var/lib/${NAME}
export PID_DIR=/run/${NAME}
export INDEXER_HOME=/usr/share/${NAME}
export CONFIG_DIR=${INDEXER_HOME}/config
export BASE_DIR=${NAME}-*

rm -rf ${INDEXER_HOME:?}/
tar -xf "${INDEXER_TAR_NAME}"

## TOOLS

## Variables
TOOLS_PATH=${NAME}-${VERSION}/plugins/opensearch-security/tools
CERT_TOOL=${TOOLS_PATH}/wazuh-certs-tool.sh

# generate certificates
cp $CERT_TOOL .
chmod 755 wazuh-certs-tool.sh && bash wazuh-certs-tool.sh -A

# copy to target
mkdir -p ${TARGET_DIR}${INDEXER_HOME}
# mkdir -p ${TARGET_DIR}${INDEXER_HOME}/opensearch-security/ <-- empty dir
mkdir -p ${TARGET_DIR}${CONFIG_DIR}
mkdir -p ${TARGET_DIR}${LIB_DIR}
mkdir -p ${TARGET_DIR}${LOG_DIR}
mkdir -p ${TARGET_DIR}/etc/init.d
mkdir -p ${TARGET_DIR}/etc/default
mkdir -p ${TARGET_DIR}/usr/lib/tmpfiles.d
mkdir -p ${TARGET_DIR}/usr/lib/sysctl.d
mkdir -p ${TARGET_DIR}/usr/lib/systemd/system
mkdir -p ${TARGET_DIR}${CONFIG_DIR}/certs
# Copy installation files to final location
cp -pr ${BASE_DIR}/* ${TARGET_DIR}${INDEXER_HOME}
cp -pr /opensearch.yml ${TARGET_DIR}${CONFIG_DIR}
# Copy Wazuh indexer's certificates
cp -pr /wazuh-certificates/demo.indexer.pem ${TARGET_DIR}${CONFIG_DIR}/certs/indexer.pem
cp -pr /wazuh-certificates/demo.indexer-key.pem ${TARGET_DIR}${CONFIG_DIR}/certs/indexer-key.pem
cp -pr /wazuh-certificates/root-ca.key ${TARGET_DIR}${CONFIG_DIR}/certs/root-ca.key
cp -pr /wazuh-certificates/root-ca.pem ${TARGET_DIR}${CONFIG_DIR}/certs/root-ca.pem
cp -pr /wazuh-certificates/admin.pem ${TARGET_DIR}${CONFIG_DIR}/certs/admin.pem
cp -pr /wazuh-certificates/admin-key.pem ${TARGET_DIR}${CONFIG_DIR}/certs/admin-key.pem

# Set path to indexer home directory
sed -i 's/-Djava.security.policy=file:\/\/\/etc\/wazuh-indexer\/opensearch-performance-analyzer\/opensearch_security.policy/-Djava.security.policy=file:\/\/\/usr\/share\/wazuh-indexer\/opensearch-performance-analyzer\/opensearch_security.policy/g' ${TARGET_DIR}${CONFIG_DIR}/jvm.options

chmod -R 500 ${TARGET_DIR}${CONFIG_DIR}/certs
chmod -R 400 ${TARGET_DIR}${CONFIG_DIR}/certs/*

find ${TARGET_DIR} -type d -exec chmod 750 {} \;
find ${TARGET_DIR} -type f -perm 644 -exec chmod 640 {} \;
find ${TARGET_DIR} -type f -perm 664 -exec chmod 660 {} \;
find ${TARGET_DIR} -type f -perm 755 -exec chmod 750 {} \;
find ${TARGET_DIR} -type f -perm 744 -exec chmod 740 {} \;
5 changes: 5 additions & 0 deletions docker/prod/config/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
nodes:
# Wazuh indexer server nodes
indexer:
- name: demo.indexer
ip: demo.indexer
26 changes: 26 additions & 0 deletions docker/prod/config/opensearch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
network.host: "0.0.0.0"
node.name: "wazuh.indexer"
path.data: /var/lib/wazuh-indexer
path.logs: /var/log/wazuh-indexer
discovery.type: single-node
compatibility.override_main_response_version: true
plugins.security.ssl.http.pemcert_filepath: /usr/share/wazuh-indexer/config/certs/indexer.pem
plugins.security.ssl.http.pemkey_filepath: /usr/share/wazuh-indexer/config/certs/indexer-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: /usr/share/wazuh-indexer/config/certs/root-ca.pem
plugins.security.ssl.transport.pemcert_filepath: /usr/share/wazuh-indexer/config/certs/indexer.pem
plugins.security.ssl.transport.pemkey_filepath: /usr/share/wazuh-indexer/config/certs/indexer-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: /usr/share/wazuh-indexer/config/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.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=demo.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"]
11 changes: 11 additions & 0 deletions docker/prod/config/securityadmin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

# Initialize the `.opendistro_security` index.
sleep 30
bash "$INDEXER_HOME"/plugins/opensearch-security/tools/securityadmin.sh \
-cacert "$INDEXER_HOME"/config/certs/root-ca.pem \
-cert "$INDEXER_HOME"/config/certs/admin.pem \
-key "$INDEXER_HOME"/config/certs/admin-key.pem \
-cd "$INDEXER_HOME"/config/opensearch-security/ \
-nhnv \
-icl
98 changes: 98 additions & 0 deletions docker/prod/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Wazuh Docker Copyright (C) 2017, Wazuh Inc. (License GPLv2)
set -e

umask 0002

# Constants
INDEXER_HOME=/usr/share/wazuh-indexer
OPENSEARCH_PATH_CONF=${INDEXER_HOME}/config
JAVA_HOME=${INDEXER_HOME}/jdk

# DISCOVERY=$(grep -oP "(?<=discovery.type: ).*" ${OPENSEARCH_PATH_CONF}/opensearch.yml)

# Export variables to environment
export INDEXER_HOME
export OPENSEARCH_PATH_CONF
export JAVA_HOME

run_as_other_user_if_needed() {
if [[ "$(id -u)" == "0" ]]; then
# If running as root, drop to specified UID and run command
exec chroot --userspec=1000:0 / "${@}"
else
# Either we are running in Openshift with random uid and are a member of the root group
# or with a custom --user
exec "${@}"
fi
}

# Allow user specify custom CMD, maybe bin/opensearch itself
# for example to directly specify `-E` style parameters for opensearch on k8s
# or simply to run /bin/bash to check the image
if [[ "$1" != "opensearchwrapper" ]]; then
if [[ "$(id -u)" == "0" && $(basename "$1") == "opensearch" ]]; then
# Rewrite CMD args to replace $1 with `opensearch` explicitly,
# Without this, user could specify `opensearch -E x.y=z` but
# `bin/opensearch -E x.y=z` would not work.
set -- "opensearch" "${@:2}"
# Use chroot to switch to UID 1000 / GID 0
exec chroot --userspec=1000:0 / "$@"
else
# User probably wants to run something else, like /bin/bash, with another uid forced (Openshift?)
exec "$@"
fi
fi

# Allow environment variables to be set by creating a file with the
# contents, and setting an environment variable with the suffix _FILE to
# point to it. This can be used to provide secrets to a container, without
# the values being specified explicitly when running the container.
#
# This is also sourced in opensearch-env, and is only needed here
# as well because we use INDEXER_PASSWORD below. Sourcing this script
# is idempotent.
source /usr/share/wazuh-indexer/bin/opensearch-env-from-file

if [[ -f bin/opensearch-users ]]; then
# Check for the INDEXER_PASSWORD environment variable to set the
# bootstrap password for Security.
#
# This is only required for the first node in a cluster with Security
# enabled, but we have no way of knowing which node we are yet. We'll just
# honor the variable if it's present.
if [[ -n "$INDEXER_PASSWORD" ]]; then
[[ -f /usr/share/wazuh-indexer/opensearch.keystore ]] || (run_as_other_user_if_needed opensearch-keystore create)
if ! (run_as_other_user_if_needed opensearch-keystore has-passwd --silent); then
# keystore is unencrypted
if ! (run_as_other_user_if_needed opensearch-keystore list | grep -q '^bootstrap.password$'); then
(run_as_other_user_if_needed echo "$INDEXER_PASSWORD" | opensearch-keystore add -x 'bootstrap.password')
fi
else
# keystore requires password
if ! (run_as_other_user_if_needed echo "$KEYSTORE_PASSWORD" |
opensearch-keystore list | grep -q '^bootstrap.password$'); then
COMMANDS="$(printf "%s\n%s" "$KEYSTORE_PASSWORD" "$INDEXER_PASSWORD")"
(run_as_other_user_if_needed echo "$COMMANDS" | opensearch-keystore add -x 'bootstrap.password')
fi
fi
fi
fi

if [[ "$(id -u)" == "0" ]]; then
# If requested and running as root, mutate the ownership of bind-mounts
if [[ -n "$TAKE_FILE_OWNERSHIP" ]]; then
chown -R 1000:0 /usr/share/wazuh-indexer/{data,logs}
fi
fi

# Initialize security
nohup /securityadmin.sh &

#if [[ "$DISCOVERY" == "single-node" ]] && [[ ! -f "/var/lib/wazuh-indexer/.flag" ]]; then
# run securityadmin.sh for single node with CACERT, CERT and KEY parameter
# nohup /securityadmin.sh &
# touch "/var/lib/wazuh-indexer/.flag"
#fi

run_as_other_user_if_needed /usr/share/wazuh-indexer/bin/opensearch <<<"$KEYSTORE_PASSWORD"

0 comments on commit 43cc0d7

Please sign in to comment.