From d7d25fe6b595422c38426ed1b39ab8f93f5b5919 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 5 Aug 2015 06:45:52 -0400 Subject: [PATCH] Add path.scripts directory Today this is "unofficial" as conf/scripts, but some people want to share scripts across different nodes and so on. Because they cannot configure it, they are forced to use dirty hacks like symbolic links, which isnt going to work: we aren't going to recursively scan conf/ and add permissions to all link targets underneath it, thats crazy. I really hate adding yet another configuration knob here, but users resorting to using symlinks are going to be frustrated, and do things in a more insecure way. --- .../org/elasticsearch/bootstrap/Security.java | 1 + .../java/org/elasticsearch/env/Environment.java | 15 +++++++++++++++ .../org/elasticsearch/script/ScriptService.java | 2 +- .../elasticsearch/bootstrap/SecurityTests.java | 3 +++ docs/reference/modules/scripting.asciidoc | 10 ++++++---- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Security.java b/core/src/main/java/org/elasticsearch/bootstrap/Security.java index ca6fb9f0eb0..7bd25ce2fc8 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/Security.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/Security.java @@ -122,6 +122,7 @@ final class Security { addPath(policy, environment.libFile(), "read,readlink"); addPath(policy, environment.pluginsFile(), "read,readlink"); addPath(policy, environment.configFile(), "read,readlink"); + addPath(policy, environment.scriptsFile(), "read,readlink"); // read-write dirs addPath(policy, environment.tmpFile(), "read,readlink,write,delete"); addPath(policy, environment.logsFile(), "read,readlink,write,delete"); diff --git a/core/src/main/java/org/elasticsearch/env/Environment.java b/core/src/main/java/org/elasticsearch/env/Environment.java index 113caa0003a..fccf767ea71 100644 --- a/core/src/main/java/org/elasticsearch/env/Environment.java +++ b/core/src/main/java/org/elasticsearch/env/Environment.java @@ -53,6 +53,8 @@ public class Environment { private final Path configFile; + private final Path scriptsFile; + private final Path pluginsFile; /** location of bin/, used by plugin manager */ @@ -100,6 +102,12 @@ public class Environment { configFile = homeFile.resolve("config"); } + if (settings.get("path.scripts") != null) { + scriptsFile = PathUtils.get(cleanPath(settings.get("path.scripts"))); + } else { + scriptsFile = configFile.resolve("scripts"); + } + if (settings.get("path.plugins") != null) { pluginsFile = PathUtils.get(cleanPath(settings.get("path.plugins"))); } else { @@ -233,6 +241,13 @@ public class Environment { return configFile; } + /** + * Location of on-disk scripts + */ + public Path scriptsFile() { + return scriptsFile; + } + public Path pluginsFile() { return pluginsFile; } diff --git a/core/src/main/java/org/elasticsearch/script/ScriptService.java b/core/src/main/java/org/elasticsearch/script/ScriptService.java index e683e5d66fd..f6d8132d6c6 100644 --- a/core/src/main/java/org/elasticsearch/script/ScriptService.java +++ b/core/src/main/java/org/elasticsearch/script/ScriptService.java @@ -171,7 +171,7 @@ public class ScriptService extends AbstractComponent implements Closeable { this.scriptModes = new ScriptModes(this.scriptEnginesByLang, scriptContextRegistry, settings); // add file watcher for static scripts - scriptsDirectory = env.configFile().resolve("scripts"); + scriptsDirectory = env.scriptsFile(); if (logger.isTraceEnabled()) { logger.trace("Using scripts directory [{}] ", scriptsDirectory); } diff --git a/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java b/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java index 664b677fe7f..17b74404528 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java @@ -74,6 +74,7 @@ public class SecurityTests extends ESTestCase { Settings.Builder settingsBuilder = Settings.builder(); settingsBuilder.put("path.home", esHome.resolve("home").toString()); settingsBuilder.put("path.conf", esHome.resolve("conf").toString()); + settingsBuilder.put("path.scripts", esHome.resolve("scripts").toString()); settingsBuilder.put("path.plugins", esHome.resolve("plugins").toString()); settingsBuilder.putArray("path.data", esHome.resolve("data1").toString(), esHome.resolve("data2").toString()); settingsBuilder.put("path.logs", esHome.resolve("logs").toString()); @@ -109,6 +110,8 @@ public class SecurityTests extends ESTestCase { assertExactPermissions(new FilePermission(environment.libFile().toString(), "read,readlink"), permissions); // config file: ro assertExactPermissions(new FilePermission(environment.configFile().toString(), "read,readlink"), permissions); + // scripts file: ro + assertExactPermissions(new FilePermission(environment.scriptsFile().toString(), "read,readlink"), permissions); // plugins: ro assertExactPermissions(new FilePermission(environment.pluginsFile().toString(), "read,readlink"), permissions); diff --git a/docs/reference/modules/scripting.asciidoc b/docs/reference/modules/scripting.asciidoc index 69748f09ed1..ea31b2d010c 100644 --- a/docs/reference/modules/scripting.asciidoc +++ b/docs/reference/modules/scripting.asciidoc @@ -85,10 +85,12 @@ supported scripting languages: To increase security, Elasticsearch does not allow you to specify scripts for non-sandboxed languages with a request. Instead, scripts must be placed in the `scripts` directory inside the configuration directory (the directory where -elasticsearch.yml is). Scripts placed into this directory will automatically be -picked up and be available to be used. Once a script has been placed in this -directory, it can be referenced by name. For example, a script called -`calculate-score.groovy` can be referenced in a request like this: +elasticsearch.yml is). The default location of this `scripts` directory can be +changed by setting `path.scripts` in elasticsearch.yml. Scripts placed into +this directory will automatically be picked up and be available to be used. +Once a script has been placed in this directory, it can be referenced by name. +For example, a script called `calculate-score.groovy` can be referenced in a +request like this: [source,sh] --------------------------------------------------