Skip to content

Commit 0206b7c

Browse files
authored
Limit _FILE env var support to specific vars (#52647)
Backport of #52525. Closes #52503. Implement a list of `_FILE` env vars that will be used to populate env vars with file content, instead of processing all `_FILE` vars in the environment.
1 parent 09b8a1f commit 0206b7c

File tree

2 files changed

+24
-50
lines changed

2 files changed

+24
-50
lines changed

distribution/src/bin/elasticsearch-env-from-file

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ set -e -o pipefail
77
# point to it. This can be used to provide secrets to a container, without
88
# the values being specified explicitly when running the container.
99
#
10+
# Note that only supported environment variables are processed, in order
11+
# to avoid unexpected failures when an environment sets a "*_FILE" variable
12+
# that doesn't contain a filename.
13+
#
1014
# This script is intended to be sourced, not executed, and modifies the
1115
# environment.
1216

13-
for VAR_NAME_FILE in $(env | cut -f1 -d= | grep '_FILE$'); do
14-
if [[ -n "$VAR_NAME_FILE" ]]; then
17+
for VAR_NAME_FILE in ELASTIC_PASSWORD_FILE KEYSTORE_PASSWORD_FILE ; do
18+
if [[ -n "${!VAR_NAME_FILE}" ]]; then
1519
VAR_NAME="${VAR_NAME_FILE%_FILE}"
1620

1721
if env | grep "^${VAR_NAME}="; then

qa/os/src/test/java/org/elasticsearch/packaging/test/DockerTests.java

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import static org.elasticsearch.packaging.util.FileUtils.append;
4343
import static org.elasticsearch.packaging.util.FileUtils.getTempDir;
4444
import static org.elasticsearch.packaging.util.FileUtils.rm;
45-
import static org.elasticsearch.packaging.util.ServerUtils.makeRequest;
4645
import static org.hamcrest.Matchers.arrayWithSize;
4746
import static org.hamcrest.Matchers.containsString;
4847
import static org.hamcrest.Matchers.emptyString;
@@ -270,38 +269,10 @@ public void test071BindMountCustomPathWithDifferentUID() throws Exception {
270269
});
271270
}
272271

273-
/**
274-
* Check that environment variables can be populated by setting variables with the suffix "_FILE",
275-
* which point to files that hold the required values.
276-
*/
277-
public void test080SetEnvironmentVariablesUsingFiles() throws Exception {
278-
final String optionsFilename = "esJavaOpts.txt";
279-
280-
// ES_JAVA_OPTS_FILE
281-
append(tempDir.resolve(optionsFilename), "-XX:-UseCompressedOops\n");
282-
283-
Map<String, String> envVars = singletonMap("ES_JAVA_OPTS_FILE", "/run/secrets/" + optionsFilename);
284-
285-
// File permissions need to be secured in order for the ES wrapper to accept
286-
// them for populating env var values
287-
Files.setPosixFilePermissions(tempDir.resolve(optionsFilename), p600);
288-
289-
final Map<Path, Path> volumes = singletonMap(tempDir, Paths.get("/run/secrets"));
290-
291-
// Restart the container
292-
runContainer(distribution(), volumes, envVars);
293-
294-
waitForElasticsearch(installation);
295-
296-
final String nodesResponse = makeRequest(Request.Get("http://localhost:9200/_nodes"));
297-
298-
assertThat(nodesResponse, containsString("\"using_compressed_ordinary_object_pointers\":\"false\""));
299-
}
300-
301272
/**
302273
* Check that the elastic user's password can be configured via a file and the ELASTIC_PASSWORD_FILE environment variable.
303274
*/
304-
public void test081ConfigurePasswordThroughEnvironmentVariableFile() throws Exception {
275+
public void test080ConfigurePasswordThroughEnvironmentVariableFile() throws Exception {
305276
// Test relies on configuring security
306277
assumeTrue(distribution.isDefault());
307278

@@ -344,7 +315,7 @@ public void test081ConfigurePasswordThroughEnvironmentVariableFile() throws Exce
344315
* Check that when verifying the file permissions of _FILE environment variables, symlinks
345316
* are followed.
346317
*/
347-
public void test082SymlinksAreFollowedWithEnvironmentVariableFiles() throws Exception {
318+
public void test081SymlinksAreFollowedWithEnvironmentVariableFiles() throws Exception {
348319
// Test relies on configuring security
349320
assumeTrue(distribution.isDefault());
350321
// Test relies on symlinks
@@ -381,44 +352,43 @@ public void test082SymlinksAreFollowedWithEnvironmentVariableFiles() throws Exce
381352
/**
382353
* Check that environment variables cannot be used with _FILE environment variables.
383354
*/
384-
public void test083CannotUseEnvVarsAndFiles() throws Exception {
385-
final String optionsFilename = "esJavaOpts.txt";
355+
public void test082CannotUseEnvVarsAndFiles() throws Exception {
356+
final String passwordFilename = "password.txt";
386357

387-
// ES_JAVA_OPTS_FILE
388-
append(tempDir.resolve(optionsFilename), "-XX:-UseCompressedOops\n");
358+
Files.write(tempDir.resolve(passwordFilename), "other_hunter2\n".getBytes(StandardCharsets.UTF_8));
389359

390360
Map<String, String> envVars = new HashMap<>();
391-
envVars.put("ES_JAVA_OPTS", "-XX:+UseCompressedOops");
392-
envVars.put("ES_JAVA_OPTS_FILE", "/run/secrets/" + optionsFilename);
361+
envVars.put("ELASTIC_PASSWORD", "hunter2");
362+
envVars.put("ELASTIC_PASSWORD_FILE", "/run/secrets/" + passwordFilename);
393363

394364
// File permissions need to be secured in order for the ES wrapper to accept
395365
// them for populating env var values
396-
Files.setPosixFilePermissions(tempDir.resolve(optionsFilename), p600);
366+
Files.setPosixFilePermissions(tempDir.resolve(passwordFilename), p600);
397367

398368
final Map<Path, Path> volumes = singletonMap(tempDir, Paths.get("/run/secrets"));
399369

400370
final Result dockerLogs = runContainerExpectingFailure(distribution, volumes, envVars);
401371

402372
assertThat(
403373
dockerLogs.stderr,
404-
containsString("ERROR: Both ES_JAVA_OPTS_FILE and ES_JAVA_OPTS are set. These are mutually " + "exclusive.")
374+
containsString("ERROR: Both ELASTIC_PASSWORD_FILE and ELASTIC_PASSWORD are set. These are mutually exclusive.")
405375
);
406376
}
407377

408378
/**
409379
* Check that when populating environment variables by setting variables with the suffix "_FILE",
410380
* the files' permissions are checked.
411381
*/
412-
public void test084EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws Exception {
413-
final String optionsFilename = "esJavaOpts.txt";
382+
public void test083EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws Exception {
383+
final String passwordFilename = "password.txt";
414384

415-
// ES_JAVA_OPTS_FILE
416-
append(tempDir.resolve(optionsFilename), "-XX:-UseCompressedOops\n");
385+
Files.write(tempDir.resolve(passwordFilename), "hunter2\n".getBytes(StandardCharsets.UTF_8));
417386

418-
Map<String, String> envVars = singletonMap("ES_JAVA_OPTS_FILE", "/run/secrets/" + optionsFilename);
387+
Map<String, String> envVars = new HashMap<>();
388+
envVars.put("ELASTIC_PASSWORD_FILE", "/run/secrets/" + passwordFilename);
419389

420390
// Set invalid file permissions
421-
Files.setPosixFilePermissions(tempDir.resolve(optionsFilename), p660);
391+
Files.setPosixFilePermissions(tempDir.resolve(passwordFilename), p660);
422392

423393
final Map<Path, Path> volumes = singletonMap(tempDir, Paths.get("/run/secrets"));
424394

@@ -428,7 +398,7 @@ public void test084EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws
428398
assertThat(
429399
dockerLogs.stderr,
430400
containsString(
431-
"ERROR: File /run/secrets/" + optionsFilename + " from ES_JAVA_OPTS_FILE must have " + "file permissions 400 or 600"
401+
"ERROR: File /run/secrets/" + passwordFilename + " from ELASTIC_PASSWORD_FILE must have file permissions 400 or 600"
432402
)
433403
);
434404
}
@@ -437,7 +407,7 @@ public void test084EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws
437407
* Check that when verifying the file permissions of _FILE environment variables, symlinks
438408
* are followed, and that invalid target permissions are detected.
439409
*/
440-
public void test085SymlinkToFileWithInvalidPermissionsIsRejected() throws Exception {
410+
public void test084SymlinkToFileWithInvalidPermissionsIsRejected() throws Exception {
441411
// Test relies on configuring security
442412
assumeTrue(distribution.isDefault());
443413
// Test relies on symlinks
@@ -483,7 +453,7 @@ public void test085SymlinkToFileWithInvalidPermissionsIsRejected() throws Except
483453
* Check that environment variables are translated to -E options even for commands invoked under
484454
* `docker exec`, where the Docker image's entrypoint is not executed.
485455
*/
486-
public void test086EnvironmentVariablesAreRespectedUnderDockerExec() {
456+
public void test085EnvironmentVariablesAreRespectedUnderDockerExec() {
487457
// This test relies on a CLI tool attempting to connect to Elasticsearch, and the
488458
// tool in question is only in the default distribution.
489459
assumeTrue(distribution.isDefault());

0 commit comments

Comments
 (0)