-
Notifications
You must be signed in to change notification settings - Fork 256
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GMSA support for V2 process isolated containers
* Add generated V2 schema files for Container Credential Guard * Add new hcs calls that are necessary to setup container credential guard instances. * Add new resource type CCGInstance that implements ResourceCloser so a containers ccg instance will be cleaned up on container close. * Add tests to validate gmsa * Remove logging from resource Release methods and just return an error. Forego returning immediately on an error in ReleaseResources and return afterwards if any of the releases failed. Signed-off-by: Daniel Canter <dcanter@microsoft.com>
- Loading branch information
Showing
28 changed files
with
610 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package hcs | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
|
||
hcsschema "github.com/Microsoft/hcsshim/internal/schema2" | ||
"github.com/Microsoft/hcsshim/internal/vmcompute" | ||
) | ||
|
||
// GetServiceProperties returns properties of the host compute service. | ||
func GetServiceProperties(ctx context.Context, q hcsschema.PropertyQuery) (*hcsschema.ServiceProperties, error) { | ||
operation := "hcsshim::GetServiceProperties" | ||
|
||
queryb, err := json.Marshal(q) | ||
if err != nil { | ||
return nil, err | ||
} | ||
propertiesJSON, resultJSON, err := vmcompute.HcsGetServiceProperties(ctx, string(queryb)) | ||
events := processHcsResult(ctx, resultJSON) | ||
if err != nil { | ||
return nil, &HcsError{Op: operation, Err: err, Events: events} | ||
} | ||
|
||
if propertiesJSON == "" { | ||
return nil, ErrUnexpectedValue | ||
} | ||
properties := &hcsschema.ServiceProperties{} | ||
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil { | ||
return nil, err | ||
} | ||
return properties, nil | ||
} | ||
|
||
// ModifyServiceSettings modifies settings of the host compute service. | ||
func ModifyServiceSettings(ctx context.Context, settings hcsschema.ModificationRequest) error { | ||
operation := "hcsshim::ModifyServiceSettings" | ||
|
||
settingsJSON, err := json.Marshal(settings) | ||
if err != nil { | ||
return err | ||
} | ||
resultJSON, err := vmcompute.HcsModifyServiceSettings(ctx, string(settingsJSON)) | ||
events := processHcsResult(ctx, resultJSON) | ||
if err != nil { | ||
return &HcsError{Op: operation, Err: err, Events: events} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// +build windows | ||
|
||
package hcsoci | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/Microsoft/hcsshim/internal/hcs" | ||
"github.com/Microsoft/hcsshim/internal/log" | ||
hcsschema "github.com/Microsoft/hcsshim/internal/schema2" | ||
) | ||
|
||
// This file holds the necessary structs and functions for adding and removing Container | ||
// Credential Guard instances (shortened to CCG normally) for V2 HCS schema | ||
// containers. Container Credential Guard is in HCS's own words "The solution to | ||
// allowing windows containers to have access to domain credentials for the | ||
// applications running in their corresponding guest." It essentially acts as | ||
// a way to temporarily Active Directory join a given container with a Group | ||
// Managed Service Account (GMSA for short) credential specification. | ||
// CCG will launch a process in the host that will act as a middleman for the | ||
// credential passthrough logic. The guest is then configured through registry | ||
// keys to have access to the process in the host. | ||
// A CCG instance needs to be created through various HCS calls and then added to | ||
// the V2 schema container document before being sent to HCS. For V1 HCS schema containers | ||
// setting up instances manually is not needed, the GMSA credential specification | ||
// simply needs to be present in the V1 container document. | ||
|
||
// CCGInstance stores the id used when creating a ccg instance. Used when | ||
// closing a container to be able to release the instance. | ||
type CCGInstance struct { | ||
// ID of container that instance belongs to. | ||
id string | ||
} | ||
|
||
// Release calls into hcs to remove the ccg instance. These do not get cleaned up automatically | ||
// they MUST be explicitly removed with a call to ModifyServiceSettings. The instances will persist | ||
// unless vmcompute.exe exits or they are removed manually as done here. | ||
func (instance *CCGInstance) Release(ctx context.Context) error { | ||
if err := removeCredentialGuard(ctx, instance.id); err != nil { | ||
return fmt.Errorf("failed to remove container credential guard instance: %s", err) | ||
} | ||
return nil | ||
} | ||
|
||
// CreateCredentialGuard creates a container credential guard instance and | ||
// returns the state object to be placed in a v2 container doc. | ||
func CreateCredentialGuard(ctx context.Context, id, credSpec string, hypervisorIsolated bool) (*hcsschema.ContainerCredentialGuardState, *CCGInstance, error) { | ||
log.G(ctx).WithField("containerID", id).Debug("creating container credential guard instance") | ||
// V2 schema ccg setup a little different as its expected to be passed | ||
// through all the way to the gcs. Can no longer be enabled just through | ||
// a single property. The flow is as follows | ||
// ------------------------------------------------------------------------ | ||
// 1. Call HcsModifyServiceSettings with a ModificationRequest set with a | ||
// ContainerCredentialGuardAddInstanceRequest. This is where the cred spec | ||
// gets passed in. Transport either "LRPC" (Argon) or "HvSocket" (Xenon). | ||
// 2. Query the instance with a call to HcsGetServiceProperties with the | ||
// PropertyType "ContainerCredentialGuard". This will return all instances | ||
// 3. Parse for the id of our container to find which one correlates to the | ||
// container we're building the doc for, then add to the V2 doc. | ||
// 4. If xenon container the hvsocketconfig will need to be in the UVMs V2 | ||
// schema HcsComputeSystem document before being created/sent to HCS. It must | ||
// be in the doc at creation time as we do not support hot adding hvsocket | ||
// service table entries. | ||
// This is currently a blocker for adding support for hyper-v gmsa. | ||
transport := "LRPC" | ||
if hypervisorIsolated { | ||
// TODO(Dcantah) Set transport to HvSocket here when this is supported | ||
return nil, nil, errors.New("hypervisor isolated containers with v2 HCS schema do not support GMSA") | ||
} | ||
req := hcsschema.ModificationRequest{ | ||
PropertyType: hcsschema.PTContainerCredentialGuard, | ||
Settings: &hcsschema.ContainerCredentialGuardOperationRequest{ | ||
Operation: hcsschema.AddInstance, | ||
OperationDetails: &hcsschema.ContainerCredentialGuardAddInstanceRequest{ | ||
Id: id, | ||
CredentialSpec: credSpec, | ||
Transport: transport, | ||
}, | ||
}, | ||
} | ||
if err := hcs.ModifyServiceSettings(ctx, req); err != nil { | ||
return nil, nil, fmt.Errorf("failed to generate container credential guard instance: %s", err) | ||
} | ||
|
||
q := hcsschema.PropertyQuery{ | ||
PropertyTypes: []hcsschema.PropertyType{hcsschema.PTContainerCredentialGuard}, | ||
} | ||
serviceProps, err := hcs.GetServiceProperties(ctx, q) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("failed to retrieve container credential guard instances: %s", err) | ||
} | ||
if len(serviceProps.Properties) != 1 { | ||
return nil, nil, errors.New("wrong number of service properties present") | ||
} | ||
|
||
ccgSysInfo := &hcsschema.ContainerCredentialGuardSystemInfo{} | ||
if err := json.Unmarshal(serviceProps.Properties[0], ccgSysInfo); err != nil { | ||
return nil, nil, fmt.Errorf("failed to unmarshal container credential guard instances: %s", err) | ||
} | ||
for _, ccgInstance := range ccgSysInfo.Instances { | ||
if ccgInstance.Id == id { | ||
instance := &CCGInstance{ | ||
id, | ||
} | ||
return ccgInstance.CredentialGuard, instance, nil | ||
} | ||
} | ||
return nil, nil, fmt.Errorf("failed to find credential guard instance with container ID %s", id) | ||
} | ||
|
||
// Removes a ContainerCredentialGuard instance by container ID. | ||
func removeCredentialGuard(ctx context.Context, id string) error { | ||
log.G(ctx).WithField("containerID", id).Debug("removing container credential guard") | ||
|
||
req := hcsschema.ModificationRequest{ | ||
PropertyType: hcsschema.PTContainerCredentialGuard, | ||
Settings: &hcsschema.ContainerCredentialGuardOperationRequest{ | ||
Operation: hcsschema.RemoveInstance, | ||
OperationDetails: &hcsschema.ContainerCredentialGuardRemoveInstanceRequest{ | ||
Id: id, | ||
}, | ||
}, | ||
} | ||
if err := hcs.ModifyServiceSettings(ctx, req); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
internal/schema2/container_credential_guard_add_instance_request.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardAddInstanceRequest struct { | ||
Id string `json:"Id,omitempty"` | ||
CredentialSpec string `json:"CredentialSpec,omitempty"` | ||
Transport string `json:"Transport,omitempty"` | ||
} |
15 changes: 15 additions & 0 deletions
15
internal/schema2/container_credential_guard_hv_socket_service_config.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardHvSocketServiceConfig struct { | ||
ServiceId string `json:"ServiceId,omitempty"` | ||
ServiceConfig *HvSocketServiceConfig `json:"ServiceConfig,omitempty"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardInstance struct { | ||
Id string `json:"Id,omitempty"` | ||
CredentialGuard *ContainerCredentialGuardState `json:"CredentialGuard,omitempty"` | ||
HvSocketConfig *ContainerCredentialGuardHvSocketServiceConfig `json:"HvSocketConfig,omitempty"` | ||
} |
17 changes: 17 additions & 0 deletions
17
internal/schema2/container_credential_guard_modify_operation.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardModifyOperation string | ||
|
||
const ( | ||
AddInstance ContainerCredentialGuardModifyOperation = "AddInstance" | ||
RemoveInstance ContainerCredentialGuardModifyOperation = "RemoveInstance" | ||
) |
15 changes: 15 additions & 0 deletions
15
internal/schema2/container_credential_guard_operation_request.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardOperationRequest struct { | ||
Operation ContainerCredentialGuardModifyOperation `json:"Operation,omitempty"` | ||
OperationDetails interface{} `json:"OperationDetails,omitempty"` | ||
} |
14 changes: 14 additions & 0 deletions
14
internal/schema2/container_credential_guard_remove_instance_request.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* HCS API | ||
* | ||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) | ||
* | ||
* API version: 2.4 | ||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) | ||
*/ | ||
|
||
package hcsschema | ||
|
||
type ContainerCredentialGuardRemoveInstanceRequest struct { | ||
Id string `json:"Id,omitempty"` | ||
} |
Oops, something went wrong.