mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
This PR enables setting allow_caps on the exec driver plugin configuration, as well as cap_add and cap_drop in exec task configuration. These options replicate the functionality already present in the docker task driver. Important: this change also reduces the default set of capabilities enabled by the exec driver to match the default set enabled by the docker driver. Until v1.0.5 the exec task driver would enable all capabilities supported by the operating system. v1.0.5 removed NET_RAW from that list of default capabilities, but left may others which could potentially also be leveraged by compromised tasks. Important: the "root" user is still special cased when used with the exec driver. Older versions of Nomad enabled enabled all capabilities supported by the operating system for tasks set with the root user. To maintain compatibility with existing clusters we continue supporting this "feature", however we maintain support for the legacy set of capabilities rather than enabling all capabilities now supported on modern operating systems.
111 lines
2.6 KiB
Go
111 lines
2.6 KiB
Go
// Package capabilities is used for managing sets of linux capabilities.
|
|
package capabilities
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type nothing struct{}
|
|
|
|
var null = nothing{}
|
|
|
|
// Set represents a group linux capabilities, implementing some useful set
|
|
// operations, taking care of name normalization, and sentinel value expansions.
|
|
//
|
|
// Linux capabilities can be expressed in multiple ways when working with docker
|
|
// and/or libcontainer, along with Nomad.
|
|
//
|
|
// Capability names may be upper or lower case, and may or may not be prefixed
|
|
// with "CAP_" or "cap_". On top of that, Nomad interprets the special name "all"
|
|
// and "ALL" to mean "all capabilities supported by the operating system".
|
|
type Set struct {
|
|
data map[string]nothing
|
|
}
|
|
|
|
func New(caps []string) *Set {
|
|
m := make(map[string]nothing, len(caps))
|
|
for _, c := range caps {
|
|
insert(m, c)
|
|
}
|
|
return &Set{data: m}
|
|
}
|
|
|
|
// Add cap into s.
|
|
func (s *Set) Add(cap string) {
|
|
insert(s.data, cap)
|
|
}
|
|
|
|
func insert(data map[string]nothing, cap string) {
|
|
switch name := normalize(cap); name {
|
|
case "":
|
|
case "all":
|
|
for k, v := range Supported().data {
|
|
data[k] = v
|
|
}
|
|
return
|
|
default:
|
|
data[name] = null
|
|
}
|
|
}
|
|
|
|
// Remove caps from s.
|
|
func (s *Set) Remove(caps []string) {
|
|
for _, c := range caps {
|
|
name := normalize(c)
|
|
if name == "all" {
|
|
s.data = make(map[string]nothing)
|
|
return
|
|
}
|
|
delete(s.data, name)
|
|
}
|
|
}
|
|
|
|
// Difference returns the Set of elements of b not in s.
|
|
func (s *Set) Difference(b *Set) *Set {
|
|
data := make(map[string]nothing)
|
|
for c := range b.data {
|
|
if _, exists := s.data[c]; !exists {
|
|
data[c] = null
|
|
}
|
|
}
|
|
return &Set{data: data}
|
|
}
|
|
|
|
// Empty return true if no capabilities exist in s.
|
|
func (s *Set) Empty() bool {
|
|
return len(s.data) == 0
|
|
}
|
|
|
|
// String returns the normalized and sorted string representation of s.
|
|
func (s *Set) String() string {
|
|
return strings.Join(s.Slice(false), ", ")
|
|
}
|
|
|
|
// Slice returns a sorted slice of capabilities in s.
|
|
//
|
|
// big - indicates whether to uppercase and prefix capabilities with CAP_
|
|
func (s *Set) Slice(upper bool) []string {
|
|
caps := make([]string, 0, len(s.data))
|
|
for c := range s.data {
|
|
if upper {
|
|
c = "CAP_" + strings.ToUpper(c)
|
|
}
|
|
caps = append(caps, c)
|
|
}
|
|
sort.Strings(caps)
|
|
return caps
|
|
}
|
|
|
|
// linux capabilities are often named in 4 possible ways - upper or lower case,
|
|
// and with or without a CAP_ prefix
|
|
//
|
|
// since we must do comparisons on cap names, always normalize the names before
|
|
// letting them into the Set data-structure
|
|
func normalize(name string) string {
|
|
spaces := strings.TrimSpace(name)
|
|
lower := strings.ToLower(spaces)
|
|
trim := strings.TrimPrefix(lower, "cap_")
|
|
return trim
|
|
}
|