-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
security entitlement support #570
Conversation
//cc @AkihiroSuda @tonistiigi |
774f7b1
to
560cf5c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reason for copying code from libentitlement
. It will be impossible to maintain it like this. It is unclear to me if there are any changes in that code. We should either use it directly(at least a fork if there are changes) or implement the unconfined
mode manually without the help of these packages.
fyi @justincormack
client/llb/state.go
Outdated
@@ -257,6 +258,13 @@ func (s State) Network(n pb.NetMode) State { | |||
func (s State) GetNetwork() pb.NetMode { | |||
return getNetwork(s) | |||
} | |||
func (s State) Security(n pb.SecMode) State { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add RunOption
version as well.
frontend/dockerfile/builder/build.go
Outdated
@@ -40,6 +40,7 @@ const ( | |||
keyImageResolveMode = "image-resolve-mode" | |||
keyGlobalAddHosts = "add-hosts" | |||
keyForceNetwork = "force-network-mode" | |||
keyForceSecurity = "force-security-mode" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets not add this yet. Can be a follow-up.
solver/llbsolver/solver.go
Outdated
@@ -269,13 +269,17 @@ func notifyCompleted(ctx context.Context, v *client.Vertex, err error, cached bo | |||
pw.Write(v.Digest.String(), *v) | |||
} | |||
|
|||
var AllowNetworkHostUnstable = false // TODO: enable in constructor | |||
var AllowNetworkHostUnstable = false // TODO: enable in constructor | |||
var AllowSecurityUnconfinedUnstable = true // TODO: enable in constructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave this to false or add the constructor initialization in this PR.
solver/llbsolver/solver.go
Outdated
|
||
func supportedEntitlements() []entitlements.Entitlement { | ||
out := []entitlements.Entitlement{} // nil means no filter | ||
if AllowNetworkHostUnstable { | ||
out = append(out, entitlements.EntitlementNetworkHost) | ||
} | ||
if AllowSecurityUnconfinedUnstable { | ||
out = append(out, entitlements.EntitlementSecurityUnconfined) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this validated? I think it is missing the condition in ValidateEntitlements()
executor/oci/spec_unix.go
Outdated
|
||
s.Mounts = GetMounts(ctx, | ||
ociProfile := entitlements.NewOCIProfile(s, meta.SecMode.String()) | ||
ociProfile, err = ociProfile.SecurityUnconfined() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be always called (and why the double call) atm.
560cf5c
to
19a2961
Compare
other simple alternative could be, build But at some point if more entitlements are required a sub library to define all entitlements will be easy to manage. |
9f12f29
to
fb002f5
Compare
The entitlements package from libentitlement is removed and replaced by a simple function based on This function is required to reviewed, if its fit for |
dee930c
to
e08ef67
Compare
executor/oci/spec_unix.go
Outdated
opts = append(opts, seccomp.WithDefaultProfile()) | ||
} | ||
if meta.SecMode == pb.SecMode_UNCONFINED { | ||
opts = append(opts, entitlements.WithDefaultAdminProfile()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should add all caps, disable seccomp/apparmor completely (no seccompsupported check), remove maskpaths and readonly overrides and change sys mounts to rw.
e08ef67
to
b11b78b
Compare
util/entitlements/security.go
Outdated
s.Process.Capabilities.Inheritable = append(s.Process.Capabilities.Inheritable, cap) | ||
s.Process.Capabilities.Permitted = append(s.Process.Capabilities.Permitted, cap) | ||
} | ||
s.Linux.Seccomp = DefaultAdminProfile(s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the unconfied, we can just skip it and not set seccomp at all. For security.admin
(future) we would use this profile.
solver/llbsolver/solver.go
Outdated
@@ -269,13 +269,17 @@ func notifyCompleted(ctx context.Context, v *client.Vertex, err error, cached bo | |||
pw.Write(v.Digest.String(), *v) | |||
} | |||
|
|||
var AllowNetworkHostUnstable = false // TODO: enable in constructor | |||
var AllowNetworkHostUnstable = false // TODO: enable in constructor | |||
var AllowSecurityUnconfinedUnstable = false // TODO: enable in constructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kunalkushwaha Could you implement this as well so we can have an integration test or would you prefer that to be a follow-up? Something like buildkitd --allow-insecure-entitlement=foo
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am working on this, shall update the PR on Monday.
Facing issue while buildctl build --allow=security.unconfined
is passed and security.confined
is also set by default.
f01c803
to
50c12a4
Compare
Have updated the code with test case and There is missing something for both Also, why |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kunalkushwaha The issue seems to be that you are not calling WithDefaultAdminProfile
anywhere (should be WithUnconfinedSecurityProfile
)
cmd/buildkitd/main.go
Outdated
for _, e := range ents { | ||
switch e { | ||
case "security.unconfined": | ||
llbsolver.AllowSecurityUnconfinedUnstable = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use these variables anymore. Instead, add them to a config array and pass to the solver constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -207,6 +212,18 @@ func main() { | |||
|
|||
controller.Register(server) | |||
|
|||
ents := c.GlobalStringSlice("allow-insecure-entitlement") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this to config and override with the flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
executor/executor.go
Outdated
@@ -18,6 +18,7 @@ type Meta struct { | |||
ReadonlyRootFS bool | |||
ExtraHosts []HostIP | |||
NetMode pb.NetMode | |||
SecMode pb.SecMode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SecurityMode
util/entitlements/security.go
Outdated
// Note: must follow the setting of process capabilities | ||
func WithDefaultAdminProfile() oci.SpecOpts { | ||
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error { | ||
addCaps := []string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still a limited list. For unconfined use all caps(different from security.admin).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @kunalkushwaha
And no seccomp for unconfined.
@kunalkushwaha Ping. Did my answer clear things up or did I miss anything? |
@tonistiigi Sorry for delay. PS: I will be on leave for 2 weeks from tomorrow. |
@kunalkushwaha What's current status? |
@AkihiroSuda Sorry have not been able to resume work on this.. Shall start from Monday. |
Hi, I need some help in understanding how the entitlements can passed from client ( Current approach in this PR.
so currently I want to use the The point where I am stuck is , where to set these LLBCaps, i.e. |
@kunalkushwaha Why do you need to pass them with buildkit/solver/llbsolver/solver.go Line 103 in 5b7f759
|
@tonistiigi I want to retrieve the value of If possible, please give me a overview of control flow how it goes once control comes to buildkitd for any build command. |
The value you need in exec is not entitlements that is passed with the build and enabled from daemon. What you need there is only the There are 2 sets of values here. One is entitlements that define the allowed actions a current build can perform. The other is the actual action that will be done for specific vertexes. The entitlements only affects the validation of the actual actions. Eg. if you just pass entitlements but don't change your vertexes, nothing would change in your build. |
50c12a4
to
2472d41
Compare
@kunalkushwaha Haven't reviewed yet but the CI seems to be failing on vendor check. |
client/client_test.go
Outdated
secMode := sb.Value("secmode") | ||
|
||
if secMode != securityUnconfined { | ||
t.Skip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should check that caps are properly restricted in securityConfined
mode.
1982a30
to
e9b1f19
Compare
Updated the testcase for |
@tonistiigi PTAL. Have fixed the testcase with check for |
e9b1f19
to
5d52724
Compare
} | ||
s.Linux.ReadonlyPaths = []string{} | ||
s.Linux.MaskedPaths = []string{} | ||
s.Process.ApparmorProfile = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove seccomp profile as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it was discussed here #570 (comment).
I am updating function comments too.
sorry needs rebase |
2445d51
to
d40781c
Compare
Its rebased and CI error gone. |
solver/pb/ops.pb.go
Outdated
|
||
var SecurityMode_name = map[int32]string{ | ||
0: "CONFINED", | ||
1: "UNCONFINED", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justincormack Would you be okay calling unconfined
insecure
instead? I know all security profiles call it unconfined, but the user intent feels clearer with insecure
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think that makes sense, although confined vs insecure is kind of weird, and I don't think we should call it secure vs insecure...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justincormack sandbox
/sandboxed
? I'm not too bothered by having both confined
and insecure
, because those who will see confined
will probably have read about its technical meaning, whereas insecure
should mean something strong to those who won't read much about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justincormack told me offline he prefers confined
and insecure
.
@kunalkushwaha would you mind updating UNCONFINED
to INSECURE
everywhere in this PR? We can keep the word CONFINED
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, I like sandbox/insecure pairing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok with sandbox/insecure too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tiborvass ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect let’s roll with sandbox/insecure then. Do you mind updating @kunalkushwaha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update with sandbox/insecure.
d40781c
to
0c9dd65
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Small comments
client/client_test.go
Outdated
require.NoError(t, err) | ||
|
||
_, err = c.Solve(context.TODO(), def, SolveOpt{ | ||
AllowedEntitlements: []entitlements.Entitlement{entitlement}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a case where you don't pass the entitlement and get an error on securityUnconfined
mode and where you try to pass entitlement on securityConfined
and get an error as well.
cmd/buildkitd/main.go
Outdated
@@ -159,6 +159,10 @@ func main() { | |||
Usage: "ca certificate to verify clients", | |||
Value: defaultConf.GRPC.TLS.CA, | |||
}, | |||
cli.StringSliceFlag{ | |||
Name: "allow-insecure-entitlement", | |||
Usage: "allows insecure entitlements like network.host & security.unconfined", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like network.host & security.unconfined
-> (eg. network.host, security.unconfined)
util/entitlements/security_linux.go
Outdated
|
||
for _, m := range s.Mounts { | ||
if m.Type == "sysfs" { | ||
m.Options = []string{"nosuid", "noexec", "nodev", "rw"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is being reset by the oci.GetMounts
call. Probably move it to that function instead for a fix.
Now that I think of it, I think it was a mistake to add "default entitlements"
EntitlementSecurityConfined cause defining that doesn't make sense in any case. You still need Security(SecurityModeConfined) though, just allowing the entitlement is pointless because it is allowed always anyway. All the functionality remains, just remove the constant. Same goes for network-none but if you want I can clean that up myself after this PR is merged.
edit: I guess I took it from https://github.com/moby/libentitlement but doesn't really fit the design. These should more be like the configuration templates for the executor, not capabilities user needs to give access to. |
0c9dd65
to
4fd84a6
Compare
Signed-off-by: Kunal Kushwaha <[email protected]>
8fc7880
to
01a8de7
Compare
Signed-off-by: Kunal Kushwaha <[email protected]>
Signed-off-by: Tonis Tiigi <[email protected]> Signed-off-by: Kunal Kushwaha <[email protected]>
Updated the PR with changes including.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kunalkushwaha , LGTM
PTAL @AkihiroSuda
This is just a rough draft for review of approach.
[edit] rebased with #560
What this PR includes:
entitlements
based on PR solver: net host with basic entitlements support #560