Skip to content

Commit 63f6a77

Browse files
committed
Limit _FILE env var support to specific vars
Backport of elastic#52525. Closes elastic#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 c5d7d0b commit 63f6a77

File tree

2 files changed

+23
-50
lines changed

2 files changed

+23
-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: 17 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,42 @@ 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.writeString(tempDir.resolve(passwordFilename), "other_hunter2\n");
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.writeString(tempDir.resolve(passwordFilename), "hunter2\n");
417386

418-
Map<String, String> envVars = singletonMap("ES_JAVA_OPTS_FILE", "/run/secrets/" + optionsFilename);
387+
Map<String, String> envVars = Map.of("ELASTIC_PASSWORD_FILE", "/run/secrets/" + passwordFilename);
419388

420389
// Set invalid file permissions
421-
Files.setPosixFilePermissions(tempDir.resolve(optionsFilename), p660);
390+
Files.setPosixFilePermissions(tempDir.resolve(passwordFilename), p660);
422391

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

@@ -428,7 +397,7 @@ public void test084EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws
428397
assertThat(
429398
dockerLogs.stderr,
430399
containsString(
431-
"ERROR: File /run/secrets/" + optionsFilename + " from ES_JAVA_OPTS_FILE must have " + "file permissions 400 or 600"
400+
"ERROR: File /run/secrets/" + passwordFilename + " from ELASTIC_PASSWORD_FILE must have file permissions 400 or 600"
432401
)
433402
);
434403
}
@@ -437,7 +406,7 @@ public void test084EnvironmentVariablesUsingFilesHaveCorrectPermissions() throws
437406
* Check that when verifying the file permissions of _FILE environment variables, symlinks
438407
* are followed, and that invalid target permissions are detected.
439408
*/
440-
public void test085SymlinkToFileWithInvalidPermissionsIsRejected() throws Exception {
409+
public void test084SymlinkToFileWithInvalidPermissionsIsRejected() throws Exception {
441410
// Test relies on configuring security
442411
assumeTrue(distribution.isDefault());
443412
// Test relies on symlinks
@@ -483,7 +452,7 @@ public void test085SymlinkToFileWithInvalidPermissionsIsRejected() throws Except
483452
* Check that environment variables are translated to -E options even for commands invoked under
484453
* `docker exec`, where the Docker image's entrypoint is not executed.
485454
*/
486-
public void test086EnvironmentVariablesAreRespectedUnderDockerExec() {
455+
public void test085EnvironmentVariablesAreRespectedUnderDockerExec() {
487456
// This test relies on a CLI tool attempting to connect to Elasticsearch, and the
488457
// tool in question is only in the default distribution.
489458
assumeTrue(distribution.isDefault());

0 commit comments

Comments
 (0)