-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support _FILE
suffixed env vars in Docker entrypoint
#47573
Support _FILE
suffixed env vars in Docker entrypoint
#47573
Conversation
Closes elastic#43603. Allow a password to be specifed in an ES Docker container by specifying a file path in the ELASTIC_PASSWORD_FILE environment variable.
Expand support for populating environment variables from file via vars with a _FILE suffix.
Pinging @elastic/es-core-infra (:Core/Infra/Packaging) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add some tests to verify this behavior.
fi | ||
|
||
if [[ ! -e "${!VAR_NAME_FILE}" ]]; then | ||
echo "ERROR: File ${!VAR_NAME_FILE} does not exist" >&2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be worth extending the message to also include the variable name pointing to that file
fi | ||
|
||
echo "Setting $VAR_NAME from ${!VAR_NAME_FILE}" >&2 | ||
export "$VAR_NAME"="$(cat ${!VAR_NAME_FILE})" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be stripping a possible newline at the end of the file here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The newline is already stripped thanks to bash
. An earlier implementation read the file without using cat
, but didn't strip the newline.
In the Docker entrypoint, when using _FILE-suffixed env vars to populate environment variables, include the _FILE var name for context.
…ypoint-file-suffix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks this LGTM now.
I'm wondering if we should enforce safe permissions on these files.
If i'm reading this right, the env vars and thus the contents of the file,
could be used to perform command injection in the container.
Files make this worse, because all it takes is for the file to be writable by someone else
and it could trick the administrator into running those commands, granted in the container but that might still be bad enough as one could access the data directory.
_FILE
suffixed env vars in Docker entrypoint_FILE
suffixed env vars in Docker entrypoint
Where do you see the potential command injection? |
Suppose a file
So this will eventually run something like :
|
@elasticmachine run elasticsearch-ci/packaging |
I'm waiting to merge #47640 before finishing this off. |
…ypoint-file-suffix
Require files that are being used to populate env vars to have restricted file permissions. This is to attempt to limit the possibility of crafting a malicious command line for ES.
GitHub seems to have forgotten that this PR needs CI. I'll try closing and reopening. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nicely done! I left a minor comment up for discussion.
Ensure that regular environment variables are not even set at the same time as their _FILE equivalents. Previously they could be set so long as they were empty.
@@ -312,7 +312,16 @@ over the configuration files in the image. | |||
|
|||
You can set individual {es} configuration parameters using Docker environment variables. | |||
The <<docker-compose-file, sample compose file>> and the | |||
<<docker-cli-run-dev-mode, single-node example>> use this method. | |||
<<docker-cli-run-dev-mode, single-node example>> use this method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<<docker-cli-run-dev-mode, single-node example>> use this method. | |
<<docker-cli-run-dev-mode, single-node example>> use this method. |
<<docker-cli-run-dev-mode, single-node example>> use this method. | ||
<<docker-cli-run-dev-mode, single-node example>> use this method. | ||
|
||
If you are providing secrets e.g. passwords to {es} and you do not want to pass them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are providing secrets e.g. passwords to {es} and you do not want to pass them | |
If you are providing secrets, such as passwords, to {es} and do not want to pass them |
<<docker-cli-run-dev-mode, single-node example>> use this method. | ||
|
||
If you are providing secrets e.g. passwords to {es} and you do not want to pass them | ||
directly via environment variables, you can instead supply environment variables suffixed with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
directly via environment variables, you can instead supply environment variables suffixed with | |
directly via environment variables, you can supply environment variables suffixed with |
|
||
If you are providing secrets e.g. passwords to {es} and you do not want to pass them | ||
directly via environment variables, you can instead supply environment variables suffixed with | ||
"_FILE". The variable value specifies a file, whose contents are used for the secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"_FILE". The variable value specifies a file, whose contents are used for the secret. | |
"_FILE". The variable value specifies a file whose contents are used for the secret. |
"_FILE". The variable value specifies a file, whose contents are used for the secret. | ||
|
||
For example, if you specified the environment variable "ELASTIC_PASSWORD_FILE" with value | ||
"/run/secrets/password.txt", and bind-mounted a file at this location in the container with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"/run/secrets/password.txt", and bind-mounted a file at this location in the container with | |
"/run/secrets/password.txt" and bind-mounted a file at this location in the container with |
|
||
For example, if you specified the environment variable "ELASTIC_PASSWORD_FILE" with value | ||
"/run/secrets/password.txt", and bind-mounted a file at this location in the container with | ||
the contents "PleaseChangeMe", then this would be equivalent to specifying the environment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the contents "PleaseChangeMe", then this would be equivalent to specifying the environment | |
the contents "PleaseChangeMe", this would be equivalent to specifying the environment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple editorial comments, but LGTM.
|
||
If you are providing secrets, such as passwords, to {es} and do not want to pass them | ||
directly via environment variables, you can supply environment variables suffixed with | ||
"_FILE". The variable value specifies a file whose contents are used for the secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd flip this around and lead with the fact that you can set env vars with a file. Something like:
To use the contents of a file to set an environment variable, suffix the environment variable name with
_FILE
. This is useful for passing secrets such as passwords to {es} without specifying them directly.
For example, if you specified the environment variable "ELASTIC_PASSWORD_FILE" with value | ||
"/run/secrets/password.txt" and bind-mounted a file at this location in the container with | ||
the contents "PleaseChangeMe", this would be equivalent to specifying the environment | ||
variable "ELASTIC_PASSWORD" with the value "PleaseChangeMe". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I'd recommend sticking to present tense for examples. In this case, I'd go with something like:
For example, to set the {es} bootstrap password from a file, you can bind mount the file and set the
ELASTIC_PASSWORD_FILE
environment variable to the mount location. If you mount the password file to/run/secrets/password.txt
, specify:
-e ELASTIC_PASSWORD_FILE=/run/secrets/bootstrapPassword.txt \
Also note that the quotes should be backticks to render the env var and path in code font.
Thanks @debadair, I've incorporated your feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks
…ypoint-file-suffix
@elasticmachine run elasticsearch-ci/packaging-matrix |
Backport of elastic#47573. Closes elastic#43603. Allow environment variables to be passed to ES in a Docker container via a file, by setting an environment variable with the `_FILE` suffix that points to the file with the intended value of the env var.
Closes #43603. Allow environment variables to be passed to ES in a Docker container via a file, by setting an environment variable with the
_FILE
suffix that points to the file with the intended value of the env var.For example, the following command runs an ES container and sets the bootstrap password via the
/run/secrets/bootstrapPassword.txt
file, by bind-mounting a directory as/run/secrets/
.