You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/09/10 00:45:05 UTC
mesos git commit: Introduced linux capabilities support for mesos
containerizer.
Repository: mesos
Updated Branches:
refs/heads/master 02f13c9aa -> 8f7bd95ed
Introduced linux capabilities support for mesos containerizer.
This change introduces linux capability based security for unified
containerizer. A new agent flag `allowed_capabilities` has been
introduced to override the default capabilities of the user or the
capabilities requested by the user.
This feature is only available on linux.
Review: https://reviews.apache.org/r/50270/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8f7bd95e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8f7bd95e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8f7bd95e
Branch: refs/heads/master
Commit: 8f7bd95ed3f4111c327ff4a376388cb961f207d9
Parents: 02f13c9
Author: Benjamin Bannier <be...@mesosphere.io>
Authored: Fri Sep 9 16:38:48 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Sep 9 17:29:49 2016 -0700
----------------------------------------------------------------------
src/slave/containerizer/mesos/launch.cpp | 81 +++++++++++++++++++++++++++
src/slave/containerizer/mesos/launch.hpp | 1 +
src/slave/flags.cpp | 28 +++++++++
src/slave/flags.hpp | 1 +
4 files changed, 111 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/8f7bd95e/src/slave/containerizer/mesos/launch.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/launch.cpp b/src/slave/containerizer/mesos/launch.cpp
index 13b65d8..b8ad27e 100644
--- a/src/slave/containerizer/mesos/launch.cpp
+++ b/src/slave/containerizer/mesos/launch.cpp
@@ -30,6 +30,7 @@
#include <stout/unreachable.hpp>
#ifdef __linux__
+#include "linux/capabilities.hpp"
#include "linux/fs.hpp"
#include "linux/ns.hpp"
#endif
@@ -46,6 +47,12 @@ using std::vector;
using process::Subprocess;
+#ifdef __linux__
+using mesos::internal::capabilities::Capabilities;
+using mesos::internal::capabilities::Capability;
+using mesos::internal::capabilities::ProcessCapabilities;
+#endif // __linux__
+
namespace mesos {
namespace internal {
namespace slave {
@@ -101,6 +108,10 @@ MesosContainerizerLaunch::Flags::Flags()
"unshare_namespace_mnt",
"Whether to launch the command in a new mount namespace.",
false);
+
+ add(&capabilities,
+ "capabilities",
+ "Capabilities of the command can use.");
#endif // __linux__
}
@@ -303,6 +314,30 @@ int MesosContainerizerLaunch::execute()
}
#endif // __WINDOWS__
+#ifdef __linux__
+ // Initialize capabilities support if necessary.
+ Try<Capabilities> capabilitiesManager = Error("Not initialized");
+
+ if (flags.capabilities.isSome()) {
+ capabilitiesManager = Capabilities::create();
+ if (capabilitiesManager.isError()) {
+ cerr << "Failed to initialize capabilities support: "
+ << capabilitiesManager.error() << endl;
+ return EXIT_FAILURE;
+ }
+
+ // Prevent clearing of capabilities on `setuid`.
+ if (uid.isSome()) {
+ Try<Nothing> keepCaps = capabilitiesManager->setKeepCaps();
+ if (keepCaps.isError()) {
+ cerr << "Failed to set process control for keeping capabilities "
+ << "on potential uid change: " << keepCaps.error() << endl;
+ return EXIT_FAILURE;
+ }
+ }
+ }
+#endif // __linux__
+
#ifdef __WINDOWS__
// Not supported on Windows.
const Option<std::string> rootfs = None();
@@ -370,6 +405,52 @@ int MesosContainerizerLaunch::execute()
}
#endif // __WINDOWS__
+#ifdef __linux__
+ if (flags.capabilities.isSome()) {
+ Try<CapabilityInfo> requestedCapabilities =
+ ::protobuf::parse<CapabilityInfo>(flags.capabilities.get());
+
+ if (requestedCapabilities.isError()) {
+ cerr << "Failed to parse capabilities: "
+ << requestedCapabilities.error() << endl;
+ return EXIT_FAILURE;
+ }
+
+ Try<ProcessCapabilities> capabilities = capabilitiesManager->get();
+ if (capabilities.isError()) {
+ cerr << "Failed to get capabilities for the current process: "
+ << capabilities.error() << endl;
+ return EXIT_FAILURE;
+ }
+
+ // After 'setuid', 'effective' set is cleared. Since `SETPCAP` is
+ // required in the `effective` set of a process to change the
+ // bounding set, we need to restore it first.
+ capabilities->add(capabilities::EFFECTIVE, capabilities::SETPCAP);
+
+ Try<Nothing> setPcap = capabilitiesManager->set(capabilities.get());
+ if (setPcap.isError()) {
+ cerr << "Failed to add SETPCAP to the effective set: "
+ << setPcap.error() << endl;
+ return EXIT_FAILURE;
+ }
+
+ // Set up requested capabilities.
+ Set<Capability> target = capabilities::convert(requestedCapabilities.get());
+
+ capabilities->set(capabilities::EFFECTIVE, target);
+ capabilities->set(capabilities::PERMITTED, target);
+ capabilities->set(capabilities::INHERITABLE, target);
+ capabilities->set(capabilities::BOUNDING, target);
+
+ Try<Nothing> set = capabilitiesManager->set(capabilities.get());
+ if (set.isError()) {
+ cerr << "Failed to set process capabilities: " << set.error() << endl;
+ return EXIT_FAILURE;
+ }
+ }
+#endif // __linux__
+
if (flags.working_directory.isSome()) {
Try<Nothing> chdir = os::chdir(flags.working_directory.get());
if (chdir.isError()) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/8f7bd95e/src/slave/containerizer/mesos/launch.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/mesos/launch.hpp b/src/slave/containerizer/mesos/launch.hpp
index 0e86da9..859990c 100644
--- a/src/slave/containerizer/mesos/launch.hpp
+++ b/src/slave/containerizer/mesos/launch.hpp
@@ -45,6 +45,7 @@ public:
Option<JSON::Array> pre_exec_commands;
#ifdef __linux__
bool unshare_namespace_mnt;
+ Option<JSON::Object> capabilities;
#endif // __linux__
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/8f7bd95e/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 0f2be17..f6cd6f7 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -452,6 +452,34 @@ mesos::internal::slave::Flags::Flags()
"systemd_runtime_directory",
"The path to the systemd system run time directory\n",
"/run/systemd/system");
+
+ add(&Flags::allowed_capabilities,
+ "allowed_capabilities",
+ "JSON representation of system capabilities that the operator will\n"
+ "allow for a task that will be run in a container launched by the\n"
+ "containerizer (currently only supported in MesosContainerizer).\n"
+ "This set overrides the default capabilities for the user and the\n"
+ "capabilities requested by the framework.\n"
+ "\n"
+ "The net capability for a task running in the container would be:\n"
+ " ((F & A) & U)\n"
+ " where F = capabilities requested by the framework.\n"
+ " U = permitted capabilities for the agent process.\n"
+ " A = allowed capabilities specified by this flag.\n"
+ "\n"
+ "To set capabilities the agent should have the `SETPCAP` capability.\n"
+ "\n"
+ "This flag is effective iff `capabilities` isolation is enabled.\n"
+ "When `capabilities` isolation is enabled, the absense of this flag\n"
+ "would imply that the operator would allow ALL capabilities.\n"
+ "\n"
+ "Example:\n"
+ "{\n"
+ " \"capabilities\": [\n"
+ " \"NET_RAW\",\n"
+ " \"SYS_ADMIN\"\n"
+ " ]\n"
+ "}");
#endif
add(&Flags::firewall_rules,
http://git-wip-us.apache.org/repos/asf/mesos/blob/8f7bd95e/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index 1a00666..897f3f8 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -100,6 +100,7 @@ public:
bool revocable_cpu_low_priority;
bool systemd_enable_support;
std::string systemd_runtime_directory;
+ Option<CapabilityInfo> allowed_capabilities;
#endif
Option<Firewall> firewall_rules;
Option<Path> credential;