-
Notifications
You must be signed in to change notification settings - Fork 259
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
rego and hardening: add enforcement and hardening for encrypted scratch #1538
Conversation
@SeanTAllen @matajoh @helsaawy putting as draft to get early feedback. The code hasn't been tested yet, working on the unit tests. |
149326b
to
ec141d0
Compare
if err != nil { | ||
return errors.Wrapf(err, "unmounting scsi device at %s denied by policy", mvd.MountPath) | ||
} | ||
if mvd.ReadOnly { |
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.
Doesn't this logic change behavior? If ReadOnly and Encrypted is false, there is no policy enforcement.
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 think we just missed this during review, but currently we don't have any enforcement for non-readonly devices: https://github.com/microsoft/hcsshim/blob/main/internal/guest/runtime/hcsv2/uvm.go#L657-L668.
This doesnt match my understanding of what we were going to be doing. Im going to set up a meeting. |
After discussing more, we came to a conclusion that in the current implementation we're doing more of a hardening inside the policy, instead we should do the hardening in GCS. The plan is to have a policy config that'll tell us whether running with unencrypted scratch is allowed or not and GCS will make sure that the overlays are mounted under encrypted mount points. |
ec141d0
to
0ef8783
Compare
0ef8783
to
58eb832
Compare
586492b
to
776fe7a
Compare
f557838
to
23cad7b
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.
Aside from merge conflicts and comments bellow, LGTM
"testing" | ||
) | ||
|
||
func Test_Add_Remove_RWDevice(t *testing.T) { |
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.
probably should add functional or gcs tests for this as well in a future pr
dede668
to
6b8a53f
Compare
AllowPropertiesAccess bool | ||
AllowDumpStacks bool | ||
AllowRuntimeLogging bool | ||
Containers []*securityPolicyContainer |
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.
Hi Maksim, the continued addition of bools to this function signature makes a good case for refactoring. I recommend a type or similar construct to avoid unreadable code at the function invocation:
code, err = marshalRego(
securityPolicy.AllowAll,
containers,
[]ExternalProcessConfig{},
true,
true,
true,
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.
yeah, we have "post feature complete" list of improvements and this one is on it 😄
@@ -1968,6 +1968,55 @@ func Test_EnforceRuntimeLogging_Not_Allowed(t *testing.T) { | |||
} | |||
} | |||
|
|||
func Test_Rego_Scratch_Mount_Policy(t *testing.T) { |
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.
Kudos for your continued inclusion of test modules. Unit tests should be considered a requirement for all new code, and you consistently are a role model for this habit.
da50fe6
to
62b7ec2
Compare
596f978
to
3407acb
Compare
3407acb
to
e5fc898
Compare
The request to encrypt scratch comes from the host, but in confidential scenario, the host cannot be trusted and it may attempt to mount the read-write overlay of a container under an unencrypted path or omit the encryption request altogether. To address the issue, add `scratch_mount`, `scratch_unmount` enforcement points and `allow_unencrypted_scratch` policy config, which can be used to (you guessed it) allow containers to run with unencrypted scratch. Since the request to add encrypted read-write scratch disk and mounting container overlayfs come at different times, we also introduced minimal (for now) hardening around adding read-write devices to the UVM. We record the mounted read-write devices when they arrive and at the time of adding overlayfs we check if the scratch path encrypted or not and validate against the policy before enforcing overlay policy. The policy config can be set at the top level, e.g.: ``` allow_unencrypted_scratch := true containers := [...] ``` The `scratch_mount` enforcement point takes an input with the following members: ``` { "target": "<mount target>", "encrypted": [true|false], } ``` Add `/internal/guest/runtime/hcsv2/uvm_state.go`, which adds a new `hostMounts` struct which keeps track of mounted RW devices. This can be extended in the future for more GCS hardening purposes, e.g. overlay, RO layer mounts and other container lifecycle management. Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
As part of enforcing encrypted scratch policy, we need to make sure that the source matches. To figure out the source for a SCSI attachment we need to first find the actual controller number where the SCSI is presented, which can be different from what hcsshim has requested originally. Rename and export `fetchActualControllerNumber` as `ActualControllerNumber` and figure out the correct controller before calling to scsi Mount/Unmount. Remove wrappers and update unit tests. Signed-off-by: Maksim An <maksiman@microsoft.com>
Signed-off-by: Maksim An <maksiman@microsoft.com>
e5fc898
to
8b4f695
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.
lgtm
…ch (microsoft#1538) * rego and hardening: add enforcement and hardening for encrypted scratch The request to encrypt scratch comes from the host, but in confidential scenario, the host cannot be trusted and it may attempt to mount the read-write overlay of a container under an unencrypted path or omit the encryption request altogether. To address the issue, add `scratch_mount`, `scratch_unmount` enforcement points and `allow_unencrypted_scratch` policy config, which can be used to (you guessed it) allow containers to run with unencrypted scratch. Since the request to add encrypted read-write scratch disk and mounting container overlayfs come at different times, we also introduced minimal (for now) hardening around adding read-write devices to the UVM. We record the mounted read-write devices when they arrive and at the time of adding overlayfs we check if the scratch path encrypted or not and validate against the policy before enforcing overlay policy. The policy config can be set at the top level, e.g.: ``` allow_unencrypted_scratch := true containers := [...] ``` The `scratch_mount` enforcement point takes an input with the following members: ``` { "target": "<mount target>", "encrypted": [true|false], } ``` Add `/internal/guest/runtime/hcsv2/uvm_state.go`, which adds a new `hostMounts` struct which keeps track of mounted RW devices. This can be extended in the future for more GCS hardening purposes, e.g. overlay, RO layer mounts and other container lifecycle management. * crypt package refactor and adding more unit tests * tests: add e2e tests for scratch encryption policy * export and rename fetchActualControllerNumber As part of enforcing encrypted scratch policy, we need to make sure that the source matches. To figure out the source for a SCSI attachment we need to first find the actual controller number where the SCSI is presented, which can be different from what hcsshim has requested originally. Rename and export `fetchActualControllerNumber` as `ActualControllerNumber` and figure out the correct controller before calling to scsi Mount/Unmount. Remove wrappers and update unit tests. Signed-off-by: Maksim An <maksiman@microsoft.com>
rego and hardening: add enforcement and hardening for encrypted scratch
The request to encrypt scratch comes from the host, but in confidential
scenario, the host cannot be trusted and it may attempt to mount the
read-write overlay of a container under an unencrypted path or omit the
encryption request altogether.
To address the issue, add
scratch_mount
,scratch_unmount
enforcementpoints and
allow_unencrypted_scratch
policy config, which can be usedto (you guessed it) allow containers to run with unencrypted scratch.
Since the request to add encrypted read-write scratch disk and mounting
container overlayfs come at different times, we also introduced minimal
(for now) hardening around adding read-write devices to the UVM. We
record the mounted read-write devices when they arrive and at the time
of adding overlayfs we check if the scratch path encrypted or not and
validate against the policy before enforcing overlay policy.
The policy config can be set at the top level, e.g.:
The
scratch_mount
enforcement point takes an input with the followingmembers:
Add
/internal/guest/runtime/hcsv2/uvm_state.go
, which adds a newhostMounts
struct which keeps track of mounted RW devices. This canbe extended in the future for more GCS hardening purposes, e.g. overlay,
RO layer mounts and other container lifecycle management.
Signed-off-by: Maksim An maksiman@microsoft.com