feat: use process wrapper for dropping capabilities
Use process wrapper introduced in #6814 to drop capabilities. This change also means the capabilities are dropped per process level and not for PID 1 (machined), which allows us to drop capabilities per process. Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
parent
0c6c888745
commit
cc6e37a47f
@ -81,7 +81,6 @@ func (*Sequencer) Initialize(r runtime.Runtime) []runtime.Phase {
|
||||
MountCgroups,
|
||||
MountPseudoFilesystems,
|
||||
SetRLimit,
|
||||
DropCapabilities,
|
||||
).Append(
|
||||
"integrity",
|
||||
WriteIMAPolicy,
|
||||
|
@ -42,7 +42,6 @@ import (
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"golang.org/x/sys/unix"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
|
||||
"kernel.org/pub/linux/libs/security/libcap/cap"
|
||||
|
||||
installer "github.com/siderolabs/talos/cmd/installer/pkg/install"
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
|
||||
@ -295,39 +294,6 @@ func SetRLimit(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFun
|
||||
}, "setRLimit"
|
||||
}
|
||||
|
||||
// DropCapabilities drops some capabilities so that they can't be restored by child processes.
|
||||
func DropCapabilities(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
|
||||
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) error {
|
||||
prop, err := krnl.ReadParam(&kernel.Param{Key: "proc.sys.kernel.kexec_load_disabled"})
|
||||
if v := strings.TrimSpace(string(prop)); err == nil && v != "0" {
|
||||
logger.Printf("kernel.kexec_load_disabled is %v, skipping dropping capabilities", v)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Drop capabilities from the bounding set effectively disabling it for all forked processes,
|
||||
// but keep them for PID 1.
|
||||
droppedCapabilities := []cap.Value{
|
||||
cap.SYS_BOOT,
|
||||
cap.SYS_MODULE,
|
||||
}
|
||||
|
||||
iab := cap.IABGetProc()
|
||||
|
||||
for _, val := range droppedCapabilities {
|
||||
if err := iab.SetVector(cap.Bound, true, val); err != nil {
|
||||
return fmt.Errorf("error removing %s from the bounding set: %w", val, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := iab.SetProc(); err != nil {
|
||||
return fmt.Errorf("error applying caps: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}, "dropCapabilities"
|
||||
}
|
||||
|
||||
// See https://www.kernel.org/doc/Documentation/ABI/testing/ima_policy
|
||||
var rules = []string{
|
||||
"dont_measure fsmagic=0x9fa0", // PROC_SUPER_MAGIC
|
||||
@ -1270,20 +1236,6 @@ func injectCRIConfigPatch(ctx context.Context, st state.State, content []byte) e
|
||||
return err
|
||||
}
|
||||
|
||||
//nolint:deadcode,unused
|
||||
func doesNotExists(p string) (err error) {
|
||||
_, err = os.Stat(p)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("file exists")
|
||||
}
|
||||
|
||||
func existsAndIsFile(p string) (err error) {
|
||||
var info os.FileInfo
|
||||
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/siderolabs/gen/maps"
|
||||
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
|
||||
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/logging"
|
||||
@ -167,9 +168,9 @@ func WithCustomSeccompProfile(override func(*specs.LinuxSeccomp)) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithBoundedCapabilities sets the list of capabilities to drop.
|
||||
func WithBoundedCapabilities(caps []string) Option {
|
||||
// WithDroppedCapabilities sets the list of capabilities to drop.
|
||||
func WithDroppedCapabilities(caps map[string]struct{}) Option {
|
||||
return func(args *Options) {
|
||||
args.DroppedCapabilities = caps
|
||||
args.DroppedCapabilities = maps.Keys(caps)
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ func (c *Containerd) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
runner.WithEnv(env),
|
||||
runner.WithOOMScoreAdj(-999),
|
||||
runner.WithCgroupPath(constants.CgroupSystemRuntime),
|
||||
runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities),
|
||||
),
|
||||
restart.WithType(restart.Forever),
|
||||
), nil
|
||||
|
@ -105,6 +105,7 @@ func (c *CRI) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
runner.WithEnv(env),
|
||||
runner.WithOOMScoreAdj(-500),
|
||||
runner.WithCgroupPath(constants.CgroupPodRuntime),
|
||||
runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities),
|
||||
),
|
||||
restart.WithType(restart.Forever),
|
||||
), nil
|
||||
|
@ -84,6 +84,7 @@ func (c *Udevd) Runner(r runtime.Runtime) (runner.Runner, error) {
|
||||
runner.WithLoggingManager(r.Logging()),
|
||||
runner.WithEnv(env),
|
||||
runner.WithCgroupPath(constants.CgroupSystemRuntime),
|
||||
runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities),
|
||||
),
|
||||
restart.WithType(restart.Forever),
|
||||
), nil
|
||||
|
@ -18,7 +18,9 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
"kernel.org/pub/linux/libs/security/libcap/cap"
|
||||
|
||||
krnl "github.com/siderolabs/talos/pkg/kernel"
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
"github.com/siderolabs/talos/pkg/machinery/kernel"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -70,7 +72,10 @@ func Main() {
|
||||
}
|
||||
}
|
||||
|
||||
if droppedCaps != "" {
|
||||
prop, err := krnl.ReadParam(&kernel.Param{Key: "proc.sys.kernel.kexec_load_disabled"})
|
||||
if v := strings.TrimSpace(string(prop)); err == nil && v != "0" {
|
||||
log.Printf("kernel.kexec_load_disabled is %v, skipping dropping capabilities", v)
|
||||
} else if droppedCaps != "" {
|
||||
caps := strings.Split(droppedCaps, ",")
|
||||
dropCaps := slices.Map(caps, func(c string) cap.Value {
|
||||
capability, err := cap.FromName(c)
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"kernel.org/pub/linux/libs/security/libcap/cap"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
)
|
||||
|
||||
// AllGrantableCapabilities returns list of capabilities that can be granted to the container based on
|
||||
@ -18,6 +20,10 @@ func AllGrantableCapabilities() []string {
|
||||
|
||||
for v := cap.Value(0); v < cap.MaxBits(); v++ {
|
||||
if set, _ := cap.GetBound(v); set { //nolint:errcheck
|
||||
if _, ok := constants.DefaultDroppedCapabilities[v.String()]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
capabilities = append(capabilities, strings.ToUpper(v.String()))
|
||||
}
|
||||
}
|
||||
|
@ -817,3 +817,9 @@ var Overlays = []string{
|
||||
"/usr/etc/udev",
|
||||
"/opt",
|
||||
}
|
||||
|
||||
// DefaultDroppedCapabilities is the default set of capabilities to drop.
|
||||
var DefaultDroppedCapabilities = map[string]struct{}{
|
||||
"cap_sys_boot": {},
|
||||
"cap_sys_module": {},
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user