-
Notifications
You must be signed in to change notification settings - Fork 937
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
Container: BPF token support #15009
base: main
Are you sure you want to change the base?
Container: BPF token support #15009
Conversation
fadb3b9
to
a2a0bd1
Compare
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
a2a0bd1
to
cc5f336
Compare
|
||
``` | ||
|
||
```{config:option} security.delegate_bpf.attachs instance-security |
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.
```{config:option} security.delegate_bpf.attachs instance-security | |
```{config:option} security.delegate_bpf.attaches instance-security |
Not sure about this one but I think it needs an e
in the plural form.
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.
Actually, I'm just following the naming from the kernel https://github.com/torvalds/linux/blob/2408a807bfc3f738850ef5ad5e3fd59d66168996/kernel/bpf/inode.c#L813
But I agree that attaches
looks better :) So let's decide what we want to do here.
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.
Following the kernel convention feels like less friction, thanks for sharing.
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.
or "attach_types"?
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.
attach_types seems best!
@@ -1071,6 +1071,13 @@ func (d *lxc) initLXC(config bool) (*liblxc.Container, error) { | |||
} | |||
} | |||
|
|||
if shared.IsTrue(d.expandedConfig["security.delegate_bpf"]) { | |||
err = lxcSetConfigItem(cc, "lxc.hook.start-host", fmt.Sprintf("%s callhook %s %s %s starthost", d.state.OS.ExecPath, shared.VarPath(""), strconv.Quote(d.Project().Name), strconv.Quote(d.Name()))) |
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'd like that fmt.Sprintf()
to be replaced by string concatenation but I understand you might want to leave it as-is as there are other similar line in that file ;)
// IsBpfDelegateOption validates a BPF Token delegation option. | ||
func IsBpfDelegateOption(delegateOption string) func(value string) error { | ||
return func(value string) error { | ||
cdelegateOption := C.CString(fmt.Sprintf("delegate_%s", delegateOption)) |
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.
cdelegateOption := C.CString(fmt.Sprintf("delegate_%s", delegateOption)) | |
cdelegateOption := C.CString("delegate_"+delegateOption) |
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
… options Signed-off-by: Alexander Mikhalitsyn <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
Signed-off-by: Alexander Mikhalitsyn <[email protected]>
1e28d4f
to
d495777
Compare
@@ -73,6 +73,15 @@ func HandleContainerHook(lxdPath string, projectName string, instanceRef string, | |||
u := api.NewURL().Path("internal", "containers", instanceRef, "on"+hook) | |||
u.WithQuery("target", target) | |||
|
|||
if hook == "starthost" { | |||
lxcPID := os.Getenv("LXC_PID") |
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.
Can we lose this validation and instead still call the starthost URL with a missing or blank lxc_pid query parameter, then let LXD validate that its missing, as the error will then be more accessible in the LXD logs rather than in the lxc debug log.
// mountBpfFs mounts bpffs inside the container. | ||
func (d *lxc) mountBpfFs(pid int, bpffsParams map[string]string) error { | ||
if !d.state.OS.BPFToken { | ||
return fmt.Errorf("BPF Token mechanism is not supported by kernel running.") |
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.
No full stops on log messages or errors please
bpffsParams["delegate_progs"], | ||
bpffsParams["delegate_attachs"]) | ||
if err != nil { | ||
d.logger.Error("bpffs mount helper has failed", logger.Ctx{"err": err, "stdout": stdout}) |
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.
is there potentially useful info in stdout we should be collecting and passing to the end user in err?
// onStartHost implements the LXC start-host hook. | ||
func (d *lxc) onStartHost(args map[string]string) error { | ||
if shared.IsFalseOrEmpty(d.expandedConfig["security.delegate_bpf"]) { | ||
return nil |
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 move the contents of his function from line 2580 into its own function, suggest d.onStartHostBPFDelegate()
or similar, and then reverse this if statement's logic to call that function if shared.IsTrue(d.expandedConfig["security.delegate_bpf"])
.
That way we nicely structure the general onStartHost
function with the BPF delegation logic, allowing for easier future expansion for other purposes.
@@ -866,6 +866,10 @@ func isContainerLowLevelOptionForbidden(key string) bool { | |||
return true | |||
} | |||
|
|||
if strings.HasPrefix(key, "security.delegate_bpf") { |
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.
good thinking!
) | ||
|
||
// IsBpfDelegateOption validates a BPF Token delegation option. | ||
func IsBpfDelegateOption(delegateOption string) func(value string) error { |
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.
Go's style guide recommends using upper case acronyms in exported functions, so suggest calling this IsBPFDelegationOption
- there may be other places in this PR where the same change should occur too.
// IsBpfDelegateOption validates a BPF Token delegation option. | ||
func IsBpfDelegateOption(delegateOption string) func(value string) error { | ||
return func(value string) error { | ||
return fmt.Errorf("This should never be called.") |
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.
no full stop in error
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.
LGTM, a few minor suggestions though.
Thanks!
@mihalicyn we should also expand our docs to explain this feature and give an example of how to use it. |
@@ -2618,3 +2618,7 @@ Note that the `openid` and `email` scopes are always required. | |||
## `project_default_network_and_storage` | |||
|
|||
Adds flags --network and --storage. The --network flag adds a network device connected to the specified network to the default profile. The --storage flag adds a root disk device using the specified storage pool to the default profile. | |||
|
|||
## `bpf_delegation` |
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.
As this is container specific, suggest container_bpf_delegation
, similar to container_syscall_intercept_bpf_devices
that exists today.
Good description at https://docs.ebpf.io/linux/concepts/token/
Linux kernel 6.9+ is required for testing
Manual test scenario: