From 3ca30d04f48f8e97fe82bb76149b84fece88a0e5 Mon Sep 17 00:00:00 2001 From: Mike Dickey Date: Fri, 16 Aug 2019 16:15:31 -0700 Subject: [PATCH 1/3] This PR enables running in unpriviliged mode when run as the splunk user account. The splunk user is now part of the ansible group and able to run the ansible playbooks itself at startup, but unlike ansible, it has no sudo capabilities at startup time. Note that you currently must explicitly set SPLUNK_HOME_OWNERSHIP_ENFORCEMENT to false when running as the splunk user, otherwise it will fail due to lack of permissions. Note that there are limitations, beyond just being unable to "correct" permission for volume mounts. Any features requiring elevated permissions, such as install JDK or other packages, will not work when running as the splunk user. The defaults are left unchanged. By default, it will still run as the ansible user and the behavior should be the same as before. --- splunk/common-files/Dockerfile | 8 ++- splunk/common-files/entrypoint.sh | 96 ++++++++++++++++--------------- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/splunk/common-files/Dockerfile b/splunk/common-files/Dockerfile index 9c70e0ac..667f1ab0 100644 --- a/splunk/common-files/Dockerfile +++ b/splunk/common-files/Dockerfile @@ -101,11 +101,15 @@ RUN sed -i -e 's/%sudo\s\+ALL=(ALL\(:ALL\)\?)\s\+ALL/%sudo ALL=NOPASSWD:ALL/g' / && groupadd -r ${ANSIBLE_GROUP} \ && useradd -r -m -g ${ANSIBLE_GROUP} ${ANSIBLE_USER} \ && usermod -aG sudo ${ANSIBLE_USER} \ + && usermod -aG ${ANSIBLE_GROUP} ${SPLUNK_USER} \ # Container Artifact Directory is a place for all artifacts and logs that are generated by the provisioning process. The directory is owned by the user "ansible". && mkdir ${CONTAINER_ARTIFACT_DIR} \ - && chown -R ${ANSIBLE_USER}:${ANSIBLE_GROUP} $CONTAINER_ARTIFACT_DIR \ + && chown -R ${ANSIBLE_USER}:${ANSIBLE_GROUP} ${CONTAINER_ARTIFACT_DIR} \ + && chmod -R 775 ${CONTAINER_ARTIFACT_DIR} \ && chmod -R 555 ${SPLUNK_ANSIBLE_HOME} \ - && chmod -R 777 ${CONTAINER_ARTIFACT_DIR} \ + && chgrp ${ANSIBLE_GROUP} ${SPLUNK_ANSIBLE_HOME} ${SPLUNK_ANSIBLE_HOME}/ansible.cfg \ + && chmod 775 ${SPLUNK_ANSIBLE_HOME} \ + && chmod 664 ${SPLUNK_ANSIBLE_HOME}/ansible.cfg \ && chmod 755 /sbin/entrypoint.sh /sbin/createdefaults.py /sbin/checkstate.sh USER ${ANSIBLE_USER} diff --git a/splunk/common-files/entrypoint.sh b/splunk/common-files/entrypoint.sh index b4ce7caa..66153a8c 100755 --- a/splunk/common-files/entrypoint.sh +++ b/splunk/common-files/entrypoint.sh @@ -35,6 +35,9 @@ trap teardown SIGINT SIGTERM prep_ansible() { cd ${SPLUNK_ANSIBLE_HOME} + if [ `whoami` == "${SPLUNK_USER}" ]; then + sed -i -e "s,^become\\s*=.*,become = false," ansible.cfg + fi if [[ "$DEBUG" == "true" ]]; then ansible-playbook --version python inventory/environ.py --write-to-file @@ -54,33 +57,36 @@ watch_for_failure(){ echo user_permission_change # Any crashes/errors while Splunk is running should get logged to splunkd_stderr.log and sent to the container's stdout + if [ `whoami` != "${SPLUNK_USER}" ]; then + RUN_AS_SPLUNK="sudo -u ${SPLUNK_USER}" + fi if [ -z "$SPLUNK_TAIL_FILE" ]; then - sudo -u ${SPLUNK_USER} tail -n 0 -f ${SPLUNK_HOME}/var/log/splunk/splunkd_stderr.log & + ${RUN_AS_SPLUNK} tail -n 0 -f ${SPLUNK_HOME}/var/log/splunk/splunkd_stderr.log & else - sudo -u ${SPLUNK_USER} tail -n 0 -f ${SPLUNK_TAIL_FILE} & + ${RUN_AS_SPLUNK} tail -n 0 -f ${SPLUNK_TAIL_FILE} & fi wait } create_defaults() { - createdefaults.py + createdefaults.py } start_and_exit() { - if [ -z "$SPLUNK_PASSWORD" ] - then - echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" - fi + if [ -z "$SPLUNK_PASSWORD" ] + then + echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" + fi sh -c "echo 'starting' > ${CONTAINER_ARTIFACT_DIR}/splunk-container.state" setup - prep_ansible + prep_ansible ansible-playbook $ANSIBLE_EXTRA_FLAGS -i inventory/environ.py site.yml } start() { - trap teardown EXIT + trap teardown EXIT start_and_exit - watch_for_failure + watch_for_failure } configure_multisite() { @@ -89,58 +95,58 @@ configure_multisite() { } restart(){ - trap teardown EXIT + trap teardown EXIT sh -c "echo 'restarting' > ${CONTAINER_ARTIFACT_DIR}/splunk-container.state" - prep_ansible - ${SPLUNK_HOME}/bin/splunk stop 2>/dev/null || true + prep_ansible + ${SPLUNK_HOME}/bin/splunk stop 2>/dev/null || true ansible-playbook -i inventory/environ.py start.yml watch_for_failure } user_permission_change(){ if [[ "$STEPDOWN_ANSIBLE_USER" == "true" ]]; then - bash -c "sudo deluser -q ansible sudo" + bash -c "sudo deluser -q ansible sudo" fi } help() { cat << EOF - ____ _ _ __ + ____ _ _ __ / ___| _ __ | |_ _ _ __ | | __ \ \\ \___ \| '_ \| | | | | '_ \| |/ / \ \\ - ___) | |_) | | |_| | | | | < / / + ___) | |_) | | |_| | | | | < / / |____/| .__/|_|\__,_|_| |_|_|\_\ /_/ - |_| + |_| ======================================== Environment Variables: - * SPLUNK_USER - user under which to run Splunk (default: splunk) - * SPLUNK_GROUP - group under which to run Splunk (default: splunk) - * SPLUNK_HOME - home directory where Splunk gets installed (default: /opt/splunk) - * SPLUNK_START_ARGS - arguments to pass into the Splunk start command; you must include '--accept-license' to start Splunk (default: none) - * SPLUNK_ROLE - the role of this Splunk instance (default: splunk_standalone) - Acceptable values: - - splunk_standalone - - splunk_search_head - - splunk_indexer - - splunk_deployer - - splunk_license_master - - splunk_cluster_master - - splunk_heavy_forwarder - * SPLUNK_LICENSE_URI - URI or local file path (absolute path in the container) to a Splunk license - * SPLUNK_STANDALONE_URL, SPLUNK_INDEXER_URL, ... - comma-separated list of resolvable aliases to properly bring-up a distributed environment. - This is optional for standalones, but required for multi-node Splunk deployments. - * SPLUNK_BUILD_URL - URL to a Splunk build which will be installed (instead of the image's default build) - * SPLUNK_APPS_URL - comma-separated list of URLs to Splunk apps which will be downloaded and installed + * SPLUNK_USER - user under which to run Splunk (default: splunk) + * SPLUNK_GROUP - group under which to run Splunk (default: splunk) + * SPLUNK_HOME - home directory where Splunk gets installed (default: /opt/splunk) + * SPLUNK_START_ARGS - arguments to pass into the Splunk start command; you must include '--accept-license' to start Splunk (default: none) + * SPLUNK_ROLE - the role of this Splunk instance (default: splunk_standalone) + Acceptable values: + - splunk_standalone + - splunk_search_head + - splunk_indexer + - splunk_deployer + - splunk_license_master + - splunk_cluster_master + - splunk_heavy_forwarder + * SPLUNK_LICENSE_URI - URI or local file path (absolute path in the container) to a Splunk license + * SPLUNK_STANDALONE_URL, SPLUNK_INDEXER_URL, ... - comma-separated list of resolvable aliases to properly bring-up a distributed environment. + This is optional for standalones, but required for multi-node Splunk deployments. + * SPLUNK_BUILD_URL - URL to a Splunk build which will be installed (instead of the image's default build) + * SPLUNK_APPS_URL - comma-separated list of URLs to Splunk apps which will be downloaded and installed Examples: - * docker run -it -p 8000:8000 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -p 8000:8000 -p 8089:8089 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic -p 8000:8000 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_INDEXER_URL=idx1,idx2 -e SPLUNK_SEARCH_HEAD_URL=sh1,sh2 -e SPLUNK_ROLE=splunk_search_head --hostname sh1 --network splunknet --network-alias sh1 -e SPLUNK_PASSWORD=helloworld -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic splunk/splunk start + * docker run -it -p 8000:8000 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -p 8000:8000 -p 8089:8089 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic -p 8000:8000 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_INDEXER_URL=idx1,idx2 -e SPLUNK_SEARCH_HEAD_URL=sh1,sh2 -e SPLUNK_ROLE=splunk_search_head --hostname sh1 --network splunknet --network-alias sh1 -e SPLUNK_PASSWORD=helloworld -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic splunk/splunk start EOF - exit 1 + exit 1 } case "$1" in @@ -157,12 +163,12 @@ case "$1" in configure_multisite $0 ;; create-defaults) - create_defaults - ;; + create_defaults + ;; restart) - shift - restart $@ - ;; + shift + restart $@ + ;; no-provision) user_permission_change tail -n 0 -f /etc/hosts & From 1595f16ae7748cd67ecab60b95624685df5fd52e Mon Sep 17 00:00:00 2001 From: Mike Dickey Date: Mon, 19 Aug 2019 12:33:53 -0700 Subject: [PATCH 2/3] More whitespace changes in splunk/splunk entrypoint.sh file to fix ascii art formatting and finish indenting consistency. Merged in same changes for running as splunk user to universal forwarder Dockerfile and entrypoint.sh. Updated whitespace in universal forwarder entrypoint.sh to also use tables for consistency. --- splunk/common-files/entrypoint.sh | 58 +++++++++++++++---------------- uf/common-files/Dockerfile | 7 +++- uf/common-files/entrypoint.sh | 47 ++++++++++++++----------- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/splunk/common-files/entrypoint.sh b/splunk/common-files/entrypoint.sh index 66153a8c..238e8a70 100755 --- a/splunk/common-files/entrypoint.sh +++ b/splunk/common-files/entrypoint.sh @@ -56,10 +56,10 @@ watch_for_failure(){ echo Ansible playbook complete, will begin streaming var/log/splunk/splunkd_stderr.log echo user_permission_change - # Any crashes/errors while Splunk is running should get logged to splunkd_stderr.log and sent to the container's stdout if [ `whoami` != "${SPLUNK_USER}" ]; then RUN_AS_SPLUNK="sudo -u ${SPLUNK_USER}" fi + # Any crashes/errors while Splunk is running should get logged to splunkd_stderr.log and sent to the container's stdout if [ -z "$SPLUNK_TAIL_FILE" ]; then ${RUN_AS_SPLUNK} tail -n 0 -f ${SPLUNK_HOME}/var/log/splunk/splunkd_stderr.log & else @@ -69,13 +69,13 @@ watch_for_failure(){ } create_defaults() { - createdefaults.py + createdefaults.py } start_and_exit() { if [ -z "$SPLUNK_PASSWORD" ] then - echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" + echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" fi sh -c "echo 'starting' > ${CONTAINER_ARTIFACT_DIR}/splunk-container.state" setup @@ -111,42 +111,42 @@ user_permission_change(){ help() { cat << EOF - ____ _ _ __ + ____ _ _ __ / ___| _ __ | |_ _ _ __ | | __ \ \\ \___ \| '_ \| | | | | '_ \| |/ / \ \\ - ___) | |_) | | |_| | | | | < / / + ___) | |_) | | |_| | | | | < / / |____/| .__/|_|\__,_|_| |_|_|\_\ /_/ - |_| + |_| ======================================== Environment Variables: - * SPLUNK_USER - user under which to run Splunk (default: splunk) - * SPLUNK_GROUP - group under which to run Splunk (default: splunk) - * SPLUNK_HOME - home directory where Splunk gets installed (default: /opt/splunk) - * SPLUNK_START_ARGS - arguments to pass into the Splunk start command; you must include '--accept-license' to start Splunk (default: none) - * SPLUNK_ROLE - the role of this Splunk instance (default: splunk_standalone) - Acceptable values: - - splunk_standalone - - splunk_search_head - - splunk_indexer - - splunk_deployer - - splunk_license_master - - splunk_cluster_master - - splunk_heavy_forwarder - * SPLUNK_LICENSE_URI - URI or local file path (absolute path in the container) to a Splunk license - * SPLUNK_STANDALONE_URL, SPLUNK_INDEXER_URL, ... - comma-separated list of resolvable aliases to properly bring-up a distributed environment. - This is optional for standalones, but required for multi-node Splunk deployments. - * SPLUNK_BUILD_URL - URL to a Splunk build which will be installed (instead of the image's default build) - * SPLUNK_APPS_URL - comma-separated list of URLs to Splunk apps which will be downloaded and installed + * SPLUNK_USER - user under which to run Splunk (default: splunk) + * SPLUNK_GROUP - group under which to run Splunk (default: splunk) + * SPLUNK_HOME - home directory where Splunk gets installed (default: /opt/splunk) + * SPLUNK_START_ARGS - arguments to pass into the Splunk start command; you must include '--accept-license' to start Splunk (default: none) + * SPLUNK_ROLE - the role of this Splunk instance (default: splunk_standalone) + Acceptable values: + - splunk_standalone + - splunk_search_head + - splunk_indexer + - splunk_deployer + - splunk_license_master + - splunk_cluster_master + - splunk_heavy_forwarder + * SPLUNK_LICENSE_URI - URI or local file path (absolute path in the container) to a Splunk license + * SPLUNK_STANDALONE_URL, SPLUNK_INDEXER_URL, ... - comma-separated list of resolvable aliases to properly bring-up a distributed environment. + This is optional for standalones, but required for multi-node Splunk deployments. + * SPLUNK_BUILD_URL - URL to a Splunk build which will be installed (instead of the image's default build) + * SPLUNK_APPS_URL - comma-separated list of URLs to Splunk apps which will be downloaded and installed Examples: - * docker run -it -p 8000:8000 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -p 8000:8000 -p 8089:8089 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic -p 8000:8000 splunk/splunk start - * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_INDEXER_URL=idx1,idx2 -e SPLUNK_SEARCH_HEAD_URL=sh1,sh2 -e SPLUNK_ROLE=splunk_search_head --hostname sh1 --network splunknet --network-alias sh1 -e SPLUNK_PASSWORD=helloworld -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic splunk/splunk start + * docker run -it -p 8000:8000 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -p 8000:8000 -p 8089:8089 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic -p 8000:8000 splunk/splunk start + * docker run -it -e SPLUNK_START_ARGS=--accept-license -e SPLUNK_INDEXER_URL=idx1,idx2 -e SPLUNK_SEARCH_HEAD_URL=sh1,sh2 -e SPLUNK_ROLE=splunk_search_head --hostname sh1 --network splunknet --network-alias sh1 -e SPLUNK_PASSWORD=helloworld -e SPLUNK_LICENSE_URI=http://example.com/splunk.lic splunk/splunk start EOF - exit 1 + exit 1 } case "$1" in diff --git a/uf/common-files/Dockerfile b/uf/common-files/Dockerfile index 9ea27573..5bbab1f5 100644 --- a/uf/common-files/Dockerfile +++ b/uf/common-files/Dockerfile @@ -90,10 +90,15 @@ RUN \ && groupadd -r ${ANSIBLE_GROUP} \ && useradd -r -m -g ${ANSIBLE_GROUP} ${ANSIBLE_USER} \ && usermod -aG sudo ${ANSIBLE_USER} \ + && usermod -aG ${ANSIBLE_GROUP} ${SPLUNK_USER} \ # Container Artifact Directory is a place for all artifacts and logs that are generated by the provisioning process. The directory is owned by the user "ansible". && mkdir ${CONTAINER_ARTIFACT_DIR} \ - && chown -R ${ANSIBLE_USER}:${ANSIBLE_GROUP} $CONTAINER_ARTIFACT_DIR \ + && chown -R ${ANSIBLE_USER}:${ANSIBLE_GROUP} ${CONTAINER_ARTIFACT_DIR} \ + && chmod -R 775 ${CONTAINER_ARTIFACT_DIR} \ && chmod -R 555 ${SPLUNK_ANSIBLE_HOME} \ + && chgrp ${ANSIBLE_GROUP} ${SPLUNK_ANSIBLE_HOME} ${SPLUNK_ANSIBLE_HOME}/ansible.cfg \ + && chmod 775 ${SPLUNK_ANSIBLE_HOME} \ + && chmod 664 ${SPLUNK_ANSIBLE_HOME}/ansible.cfg \ && chmod 755 /sbin/entrypoint.sh /sbin/createdefaults.py /sbin/checkstate.sh USER ${ANSIBLE_USER} diff --git a/uf/common-files/entrypoint.sh b/uf/common-files/entrypoint.sh index 33f581fc..4bbf8ebb 100755 --- a/uf/common-files/entrypoint.sh +++ b/uf/common-files/entrypoint.sh @@ -20,8 +20,8 @@ setup() { # Check if the user accepted the license if [[ "$SPLUNK_START_ARGS" != *"--accept-license"* ]]; then printf "License not accepted, please ensure the environment variable SPLUNK_START_ARGS contains the '--accept-license' flag\n" - printf "For example: docker run -e SPLUNK_START_ARGS=--accept-license splunk/splunk\n\n" - printf "For additional information and examples, see the help: docker run -it splunk/splunk help\n" + printf "For example: docker run -e SPLUNK_START_ARGS=--accept-license splunk/universalforwarder\n\n" + printf "For additional information and examples, see the help: docker run -it splunk/universalforwarder help\n" exit 1 fi } @@ -35,6 +35,9 @@ trap teardown SIGINT SIGTERM prep_ansible() { cd ${SPLUNK_ANSIBLE_HOME} + if [ `whoami` == "${SPLUNK_USER}" ]; then + sed -i -e "s,^become\\s*=.*,become = false," ansible.cfg + fi if [[ "$DEBUG" == "true" ]]; then ansible-playbook --version python inventory/environ.py --write-to-file @@ -52,42 +55,44 @@ watch_for_failure(){ echo Ansible playbook complete, will begin streaming var/log/splunk/splunkd_stderr.log echo user_permission_change - # Any crashes/errors while Splunk is running should get logged to splunkd_stderr.log and sent to the container's stdout + if [ `whoami` != "${SPLUNK_USER}" ]; then + RUN_AS_SPLUNK="sudo -u ${SPLUNK_USER}" + fi # Any crashes/errors while Splunk is running should get logged to splunkd_stderr.log and sent to the container's stdout if [ -z "$SPLUNK_TAIL_FILE" ]; then - sudo -u ${SPLUNK_USER} tail -n 0 -f ${SPLUNK_HOME}/var/log/splunk/splunkd_stderr.log & + ${RUN_AS_SPLUNK} tail -n 0 -f ${SPLUNK_HOME}/var/log/splunk/splunkd_stderr.log & else - sudo -u ${SPLUNK_USER} tail -n 0 -f ${SPLUNK_TAIL_FILE} & + ${RUN_AS_SPLUNK} tail -n 0 -f ${SPLUNK_TAIL_FILE} & fi wait } create_defaults() { - createdefaults.py + createdefaults.py } start_and_exit() { - if [ -z "$SPLUNK_PASSWORD" ] - then - echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" - fi + if [ -z "$SPLUNK_PASSWORD" ] + then + echo "WARNING: No password ENV var. Stack may fail to provision if splunk.password is not set in ENV or a default.yml" + fi sh -c "echo 'starting' > ${CONTAINER_ARTIFACT_DIR}/splunk-container.state" setup - prep_ansible + prep_ansible ansible-playbook $ANSIBLE_EXTRA_FLAGS -i inventory/environ.py site.yml } start() { - trap teardown EXIT + trap teardown EXIT start_and_exit - watch_for_failure + watch_for_failure } restart(){ trap teardown EXIT sh -c "echo 'restarting' > ${CONTAINER_ARTIFACT_DIR}/splunk-container.state" - prep_ansible - ${SPLUNK_HOME}/bin/splunk stop 2>/dev/null || true + prep_ansible + ${SPLUNK_HOME}/bin/splunk stop 2>/dev/null || true ansible-playbook -i inventory/environ.py start.yml watch_for_failure } @@ -123,7 +128,7 @@ Environment Variables: EOF - exit 1 + exit 1 } case "$1" in @@ -136,12 +141,12 @@ case "$1" in start_and_exit $@ ;; create-defaults) - create_defaults - ;; + create_defaults + ;; restart) - shift - restart $@ - ;; + shift + restart $@ + ;; no-provision) user_permission_change tail -n 0 -f /etc/hosts & From 0450046faebd7c8b78ab4b61fe37352e706b9b3d Mon Sep 17 00:00:00 2001 From: Mike Dickey Date: Mon, 19 Aug 2019 16:20:42 -0700 Subject: [PATCH 3/3] Added SECURITY.md documentation --- docs/SECURITY.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/SECURITY.md diff --git a/docs/SECURITY.md b/docs/SECURITY.md new file mode 100644 index 00000000..6f1ae709 --- /dev/null +++ b/docs/SECURITY.md @@ -0,0 +1,87 @@ +## Security ## +This section will cover various security considerations when using the Splunk Enterprise and Universal Forwarder containers. + +### Startup Users ### + +The Splunk Enterprise and Universal Forwarder containers may be started using one of the following three user accounts: + +* `splunk` (most secure): This user has no privileged access and cannot use `sudo` to change to another user account. +It is a member of the `ansible` group, which enables it to run the embedded playbooks at startup. When using the +`splunk` user, all processes will run as this user. Note that you must set the `SPLUNK_HOME_OWNERSHIP_ENFORCEMENT` +environment variable to `false` when starting as this user. ***Recommended for production*** + +* `ansible` (middle ground): This user is a member of the `sudo` group and able to execute `sudo` commands without a +password. It uses privileged access at startup only to perform certain actions which cannot be performed by regular +users (see below). After startup, `sudo` access will automatically be removed from the `ansible` user if the +environment variable `STEPDOWN_ANSIBLE_USER` is set to `true`. ***This is the default user account*** + +* `root` (least secure): This is a privileged user running with UID of `0`. Some customers may want to use this for +forwarder processes that require access to log files which cannot be read by any other user. ***This is not recommended*** + +### After Startup ### + +By default, the primary Splunk processes will always run as the unprivileged user and group `splunk`, +irregardless of which user account the containers are started with. You can override this by changing the following: + +* User: `splunk.user` variable in your `default.yml` template, or the `SPLUNK_USER` environment variable +* Group: `splunk.group` variable in your `default.yml` template, or the `SPLUNK_GROUP` environment variable + +Note that the containers are built with the `splunk` user having UID `41812` and the `splunk` group having GID `41812`. + +You may want to override these settings to ensure that Splunk forwarder processes have access to read your log files. +For example, you can ensure that all processes run as `root` by starting as the `root` user with the environment +variable `SPLUNK_USER` also set to `root` (this is not recommended). + +### Privileged Features ### + +Certain features supported by the Splunk Enterprise and Universal Forwarder containers require that they are started +with privileged access using either the `ansible` or `root` user accounts. + +#### Splunk Home Ownership #### + +By default, at startup the containers will ensure that all files located under the `SPLUNK_HOME` directory +(`/opt/splunk`) are owned by user `splunk` and group `splunk`. This helps to ensure that the Splunk processes are +able to read and write any external volumes mounted for `/opt/splunk/etc` and `/opt/splunk/var`. While all supported +versions of the docker engine will automatically set proper ownership for these volumes, external orchestration systems +typically will require extra steps. + +If you know that this step is unnecessary, you can disable it by setting the `SPLUNK_HOME_OWNERSHIP_ENFORCEMENT` +environment variable to `false`. Note that this must be disabled when starting containers with the `splunk` user +account. + +#### Package Installation #### + +The `JAVA_VERSION` environment variable can be used to automatically install OpenJDK at startup time. This feature +requires starting as a privileged user account. + +### Kubernetes Users ### + +For Kubernetes, we recommend using the `fsGroup` [Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) +to ensure that all Pods are able to write to your Persistent Volumes. For example: + +``` +apiVersion: v1 +kind: Pod +metadata: + name: example-splunk-pod +spec: + securityContext: + runAsUser: 41812 + fsGroup: 41812 + containers: + name: example-splunk-container + image: splunk/splunk + env: + - name: SPLUNK_HOME_OWNERSHIP_ENFORCEMENT + value: "false" +... +``` + +This can be used to create a Splunk Enterprise Pod running as the unprivileged `splunk` user which is able to securely +read and write from any Persistent Volumes that are created for it. + +Red Hat OpenShift users can leverage the built-in `nonroot` [Security Context Constraint](https://docs.openshift.com/container-platform/3.9/admin_guide/manage_scc.html) +to run Pods with the above Security Context: +``` +oc adm policy add-scc-to-user nonroot default +``` \ No newline at end of file