Add initial template support for iid provisisioners.
This commit is contained in:
parent
8e7bf96769
commit
6c36ceb158
3 changed files with 111 additions and 78 deletions
|
@ -17,6 +17,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
|
"github.com/smallstep/certificates/sshutil"
|
||||||
"github.com/smallstep/certificates/x509util"
|
"github.com/smallstep/certificates/x509util"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
)
|
)
|
||||||
|
@ -126,14 +127,15 @@ type awsInstanceIdentityDocument struct {
|
||||||
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
||||||
type AWS struct {
|
type AWS struct {
|
||||||
*base
|
*base
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Accounts []string `json:"accounts"`
|
Accounts []string `json:"accounts"`
|
||||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||||
Claims *Claims `json:"claims,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
Options *Options `json:"options,omitempty"`
|
Options *Options `json:"options,omitempty"`
|
||||||
|
SSHOptions *SSHOptions `json:"sshOptions,omitempty"`
|
||||||
claimer *Claimer
|
claimer *Claimer
|
||||||
config *awsConfig
|
config *awsConfig
|
||||||
audiences Audiences
|
audiences Audiences
|
||||||
|
@ -468,34 +470,42 @@ func (p *AWS) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
|
|
||||||
doc := claims.document
|
doc := claims.document
|
||||||
|
|
||||||
signOptions := []SignOption{
|
// Validated principals.
|
||||||
// set the key id to the instance id
|
principals := []string{
|
||||||
sshCertKeyIDModifier(doc.InstanceID),
|
doc.PrivateIP,
|
||||||
}
|
fmt.Sprintf("ip-%s.%s.compute.internal", strings.Replace(doc.PrivateIP, ".", "-", -1), doc.Region),
|
||||||
|
|
||||||
// Only enforce known principals if disable custom sans is true.
|
|
||||||
var principals []string
|
|
||||||
if p.DisableCustomSANs {
|
|
||||||
principals = []string{
|
|
||||||
doc.PrivateIP,
|
|
||||||
fmt.Sprintf("ip-%s.%s.compute.internal", strings.Replace(doc.PrivateIP, ".", "-", -1), doc.Region),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default to cert type to host
|
// Default to cert type to host
|
||||||
defaults := SignSSHOptions{
|
defaults := SignSSHOptions{
|
||||||
CertType: SSHHostCert,
|
CertType: SSHHostCert,
|
||||||
Principals: principals,
|
}
|
||||||
|
defaultTemplate := sshutil.DefaultIIDCertificate
|
||||||
|
|
||||||
|
// Only enforce known principals if disable custom sans is true.
|
||||||
|
if p.DisableCustomSANs {
|
||||||
|
defaults.Principals = principals
|
||||||
|
defaultTemplate = sshutil.DefaultCertificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate user options
|
// Validate user options
|
||||||
signOptions = append(signOptions, sshCertOptionsValidator(defaults))
|
signOptions := []SignOption{
|
||||||
// Set defaults if not given as user options
|
sshCertOptionsValidator(defaults),
|
||||||
signOptions = append(signOptions, sshCertDefaultsModifier(defaults))
|
}
|
||||||
|
|
||||||
|
// Certificate templates.
|
||||||
|
data := sshutil.CreateTemplateData(sshutil.HostCert, doc.InstanceID, principals)
|
||||||
|
if v, err := unsafeParseSigned(token); err == nil {
|
||||||
|
data.SetToken(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
templateOptions, err := CustomSSHTemplateOptions(p.SSHOptions, data, defaultTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "aws.AuthorizeSSHSign")
|
||||||
|
}
|
||||||
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
// Set the default extensions.
|
|
||||||
&sshDefaultExtensionModifier{},
|
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
&sshDefaultDuration{p.claimer},
|
&sshDefaultDuration{p.claimer},
|
||||||
// Validate public key
|
// Validate public key
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
|
"github.com/smallstep/certificates/sshutil"
|
||||||
"github.com/smallstep/certificates/x509util"
|
"github.com/smallstep/certificates/x509util"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
)
|
)
|
||||||
|
@ -83,15 +84,16 @@ type azurePayload struct {
|
||||||
// and https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
|
// and https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service
|
||||||
type Azure struct {
|
type Azure struct {
|
||||||
*base
|
*base
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
TenantID string `json:"tenantID"`
|
TenantID string `json:"tenantID"`
|
||||||
ResourceGroups []string `json:"resourceGroups"`
|
ResourceGroups []string `json:"resourceGroups"`
|
||||||
Audience string `json:"audience,omitempty"`
|
Audience string `json:"audience,omitempty"`
|
||||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||||
Claims *Claims `json:"claims,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
Options *Options `json:"options,omitempty"`
|
Options *Options `json:"options,omitempty"`
|
||||||
|
SSHOptions *SSHOptions `json:"sshOptions,omitempty"`
|
||||||
claimer *Claimer
|
claimer *Claimer
|
||||||
config *azureConfig
|
config *azureConfig
|
||||||
oidcConfig openIDConfiguration
|
oidcConfig openIDConfiguration
|
||||||
|
@ -338,30 +340,40 @@ func (p *Azure) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOptio
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "azure.AuthorizeSSHSign")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "azure.AuthorizeSSHSign")
|
||||||
}
|
}
|
||||||
signOptions := []SignOption{
|
|
||||||
// set the key id to the instance name
|
// Validated principals
|
||||||
sshCertKeyIDModifier(name),
|
principals := []string{name}
|
||||||
|
|
||||||
|
// Default options and template
|
||||||
|
defaults := SignSSHOptions{
|
||||||
|
CertType: SSHHostCert,
|
||||||
}
|
}
|
||||||
|
defaultTemplate := sshutil.DefaultIIDCertificate
|
||||||
|
|
||||||
// Only enforce known principals if disable custom sans is true.
|
// Only enforce known principals if disable custom sans is true.
|
||||||
var principals []string
|
|
||||||
if p.DisableCustomSANs {
|
if p.DisableCustomSANs {
|
||||||
principals = []string{name}
|
defaults.Principals = principals
|
||||||
|
defaultTemplate = sshutil.DefaultCertificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default to host + known hostnames
|
|
||||||
defaults := SignSSHOptions{
|
|
||||||
CertType: SSHHostCert,
|
|
||||||
Principals: principals,
|
|
||||||
}
|
|
||||||
// Validate user options
|
// Validate user options
|
||||||
signOptions = append(signOptions, sshCertOptionsValidator(defaults))
|
signOptions := []SignOption{
|
||||||
// Set defaults if not given as user options
|
sshCertOptionsValidator(defaults),
|
||||||
signOptions = append(signOptions, sshCertDefaultsModifier(defaults))
|
}
|
||||||
|
|
||||||
|
// Certificate templates.
|
||||||
|
data := sshutil.CreateTemplateData(sshutil.HostCert, name, principals)
|
||||||
|
if v, err := unsafeParseSigned(token); err == nil {
|
||||||
|
data.SetToken(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
templateOptions, err := CustomSSHTemplateOptions(p.SSHOptions, data, defaultTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "azure.AuthorizeSSHSign")
|
||||||
|
}
|
||||||
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
// Set the default extensions.
|
|
||||||
&sshDefaultExtensionModifier{},
|
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
&sshDefaultDuration{p.claimer},
|
&sshDefaultDuration{p.claimer},
|
||||||
// Validate public key
|
// Validate public key
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
|
"github.com/smallstep/certificates/sshutil"
|
||||||
"github.com/smallstep/certificates/x509util"
|
"github.com/smallstep/certificates/x509util"
|
||||||
"github.com/smallstep/cli/jose"
|
"github.com/smallstep/cli/jose"
|
||||||
)
|
)
|
||||||
|
@ -77,15 +78,16 @@ func newGCPConfig() *gcpConfig {
|
||||||
// https://cloud.google.com/compute/docs/instances/verifying-instance-identity
|
// https://cloud.google.com/compute/docs/instances/verifying-instance-identity
|
||||||
type GCP struct {
|
type GCP struct {
|
||||||
*base
|
*base
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ServiceAccounts []string `json:"serviceAccounts"`
|
ServiceAccounts []string `json:"serviceAccounts"`
|
||||||
ProjectIDs []string `json:"projectIDs"`
|
ProjectIDs []string `json:"projectIDs"`
|
||||||
DisableCustomSANs bool `json:"disableCustomSANs"`
|
DisableCustomSANs bool `json:"disableCustomSANs"`
|
||||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||||
Claims *Claims `json:"claims,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
Options *Options `json:"options,omitempty"`
|
Options *Options `json:"options,omitempty"`
|
||||||
|
SSHOptions *SSHOptions `json:"sshOptions,omitempty"`
|
||||||
claimer *Claimer
|
claimer *Claimer
|
||||||
config *gcpConfig
|
config *gcpConfig
|
||||||
keyStore *keyStore
|
keyStore *keyStore
|
||||||
|
@ -379,33 +381,42 @@ func (p *GCP) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption,
|
||||||
|
|
||||||
ce := claims.Google.ComputeEngine
|
ce := claims.Google.ComputeEngine
|
||||||
|
|
||||||
signOptions := []SignOption{
|
// Validated principals
|
||||||
// set the key id to the instance name
|
principals := []string{
|
||||||
sshCertKeyIDModifier(ce.InstanceName),
|
fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
|
||||||
|
fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default options and template
|
||||||
|
defaults := SignSSHOptions{
|
||||||
|
CertType: SSHHostCert,
|
||||||
|
}
|
||||||
|
defaultTemplate := sshutil.DefaultIIDCertificate
|
||||||
|
|
||||||
// Only enforce known principals if disable custom sans is true.
|
// Only enforce known principals if disable custom sans is true.
|
||||||
var principals []string
|
|
||||||
if p.DisableCustomSANs {
|
if p.DisableCustomSANs {
|
||||||
principals = []string{
|
defaults.Principals = principals
|
||||||
fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
|
defaultTemplate = sshutil.DefaultCertificate
|
||||||
fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default to host + known hostnames
|
|
||||||
defaults := SignSSHOptions{
|
|
||||||
CertType: SSHHostCert,
|
|
||||||
Principals: principals,
|
|
||||||
}
|
|
||||||
// Validate user options
|
// Validate user options
|
||||||
signOptions = append(signOptions, sshCertOptionsValidator(defaults))
|
signOptions := []SignOption{
|
||||||
// Set defaults if not given as user options
|
sshCertOptionsValidator(defaults),
|
||||||
signOptions = append(signOptions, sshCertDefaultsModifier(defaults))
|
}
|
||||||
|
|
||||||
|
// Certificate templates.
|
||||||
|
data := sshutil.CreateTemplateData(sshutil.HostCert, ce.InstanceName, principals)
|
||||||
|
if v, err := unsafeParseSigned(token); err == nil {
|
||||||
|
data.SetToken(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
templateOptions, err := CustomSSHTemplateOptions(p.SSHOptions, data, defaultTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "gcp.AuthorizeSSHSign")
|
||||||
|
}
|
||||||
|
signOptions = append(signOptions, templateOptions)
|
||||||
|
|
||||||
return append(signOptions,
|
return append(signOptions,
|
||||||
// Set the default extensions
|
|
||||||
&sshDefaultExtensionModifier{},
|
|
||||||
// Set the validity bounds if not set.
|
// Set the validity bounds if not set.
|
||||||
&sshDefaultDuration{p.claimer},
|
&sshDefaultDuration{p.claimer},
|
||||||
// Validate public key
|
// Validate public key
|
||||||
|
|
Loading…
Add table
Reference in a new issue