Add the ability to customise the details of the CA (#17309)
Co-authored-by: James Rasell <jrasell@users.noreply.github.com>
This commit is contained in:
parent
2b85290d55
commit
0455389534
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
cli: Add the ability to customize the details of the CA when running `nomad tls ca create`
|
||||
```
|
|
@ -34,6 +34,27 @@ type TLSCACreateCommand struct {
|
|||
// additionalDomain provides a list of restricted domains to the CA which
|
||||
// will then reject any domains other than these.
|
||||
additionalDomain flags.StringFlag
|
||||
|
||||
// country is used to set a country code for the CA
|
||||
country string
|
||||
|
||||
// postalCode is used to set a postal code for the CA
|
||||
postalCode string
|
||||
|
||||
// province is used to set a province for the CA
|
||||
province string
|
||||
|
||||
// locality is used to set a locality for the CA
|
||||
locality string
|
||||
|
||||
// streetAddress is used to set a street address for the CA
|
||||
streetAddress string
|
||||
|
||||
// organization is used to set an organization for the CA
|
||||
organization string
|
||||
|
||||
// organizationalUnit is used to set an organizational unit for the CA
|
||||
organizationalUnit string
|
||||
}
|
||||
|
||||
func (c *TLSCACreateCommand) Help() string {
|
||||
|
@ -53,6 +74,9 @@ CA Create Options:
|
|||
-common-name
|
||||
Common Name of CA. Defaults to "Nomad Agent CA".
|
||||
|
||||
-country
|
||||
Country of the CA. Defaults to "US".
|
||||
|
||||
-days
|
||||
Provide number of days the CA is valid for from now on.
|
||||
Defaults to 5 years or 1825 days.
|
||||
|
@ -61,12 +85,31 @@ CA Create Options:
|
|||
Domain of Nomad cluster. Only used in combination with -name-constraint.
|
||||
Defaults to "nomad".
|
||||
|
||||
-locality
|
||||
Locality of the CA. Defaults to "San Francisco".
|
||||
|
||||
-name-constraint
|
||||
Enables the DNS name restriction functionality to the CA. Results in the CA
|
||||
rejecting certificates for any other DNS zone. If enabled, localhost and the
|
||||
value of -domain will be added to the allowed DNS zones field. If the UI is
|
||||
going to be served over HTTPS its hostname must be added with
|
||||
-additional-domain. Defaults to false.
|
||||
|
||||
-organization
|
||||
Organization of the CA. Defaults to "HashiCorp Inc.".
|
||||
|
||||
-organizational-unit
|
||||
Organizational Unit of the CA. Defaults to "Nomad".
|
||||
|
||||
-postal-code
|
||||
Postal Code of the CA. Defaults to "94105".
|
||||
|
||||
-province
|
||||
Province of the CA. Defaults to "CA".
|
||||
|
||||
-street-address
|
||||
Street Address of the CA. Defaults to "101 Second Street".
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
@ -74,11 +117,18 @@ CA Create Options:
|
|||
func (c *TLSCACreateCommand) AutocompleteFlags() complete.Flags {
|
||||
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
|
||||
complete.Flags{
|
||||
"-additional-domain": complete.PredictAnything,
|
||||
"-common-name": complete.PredictAnything,
|
||||
"-days": complete.PredictAnything,
|
||||
"-domain": complete.PredictAnything,
|
||||
"-name-constraint": complete.PredictAnything,
|
||||
"-additional-domain": complete.PredictAnything,
|
||||
"-common-name": complete.PredictAnything,
|
||||
"-days": complete.PredictAnything,
|
||||
"-country": complete.PredictAnything,
|
||||
"-domain": complete.PredictAnything,
|
||||
"-locality": complete.PredictAnything,
|
||||
"-name-constraint": complete.PredictAnything,
|
||||
"-organization": complete.PredictAnything,
|
||||
"-organizational-unit": complete.PredictAnything,
|
||||
"-postal-code": complete.PredictAnything,
|
||||
"-province": complete.PredictAnything,
|
||||
"-street-address": complete.PredictAnything,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -97,10 +147,17 @@ func (c *TLSCACreateCommand) Run(args []string) int {
|
|||
flagSet := c.Meta.FlagSet(c.Name(), FlagSetClient)
|
||||
flagSet.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flagSet.Var(&c.additionalDomain, "additional-domain", "")
|
||||
flagSet.IntVar(&c.days, "days", 1825, "")
|
||||
flagSet.IntVar(&c.days, "days", 0, "")
|
||||
flagSet.BoolVar(&c.constraint, "name-constraint", false, "")
|
||||
flagSet.StringVar(&c.domain, "domain", "nomad", "")
|
||||
flagSet.StringVar(&c.domain, "domain", "", "")
|
||||
flagSet.StringVar(&c.commonName, "common-name", "", "")
|
||||
flagSet.StringVar(&c.country, "country", "", "")
|
||||
flagSet.StringVar(&c.postalCode, "postal-code", "", "")
|
||||
flagSet.StringVar(&c.province, "province", "", "")
|
||||
flagSet.StringVar(&c.locality, "locality", "", "")
|
||||
flagSet.StringVar(&c.streetAddress, "street-address", "", "")
|
||||
flagSet.StringVar(&c.organization, "organization", "", "")
|
||||
flagSet.StringVar(&c.organizationalUnit, "organizational-unit", "", "")
|
||||
if err := flagSet.Parse(args); err != nil {
|
||||
return 1
|
||||
}
|
||||
|
@ -112,6 +169,32 @@ func (c *TLSCACreateCommand) Run(args []string) int {
|
|||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
if c.IsCustom() && c.days != 0 || c.IsCustom() {
|
||||
c.domain = "nomad"
|
||||
} else {
|
||||
if c.commonName == "" {
|
||||
c.Ui.Error("Please provide the -common-name flag when customizing the CA")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
if c.country == "" {
|
||||
c.Ui.Error("Please provide the -country flag when customizing the CA")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
|
||||
if c.organization == "" {
|
||||
c.Ui.Error("Please provide the -organization flag when customizing the CA")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
|
||||
if c.organizationalUnit == "" {
|
||||
c.Ui.Error("Please provide the -organizational-unit flag when customizing the CA")
|
||||
c.Ui.Error(commandErrorText(c))
|
||||
return 1
|
||||
}
|
||||
}
|
||||
if c.domain != "" && c.domain != "nomad" && !c.constraint {
|
||||
c.Ui.Error("Please provide the -name-constraint flag to use a custom domain constraint")
|
||||
return 1
|
||||
|
@ -143,7 +226,18 @@ func (c *TLSCACreateCommand) Run(args []string) int {
|
|||
constraints = append(constraints, c.additionalDomain...)
|
||||
}
|
||||
|
||||
ca, pk, err := tlsutil.GenerateCA(tlsutil.CAOpts{Name: c.commonName, Days: c.days, Domain: c.domain, PermittedDNSDomains: constraints})
|
||||
ca, pk, err := tlsutil.GenerateCA(tlsutil.CAOpts{
|
||||
Name: c.commonName,
|
||||
Days: c.days,
|
||||
PermittedDNSDomains: constraints,
|
||||
Country: c.country,
|
||||
PostalCode: c.postalCode,
|
||||
Province: c.province,
|
||||
Locality: c.locality,
|
||||
StreetAddress: c.streetAddress,
|
||||
Organization: c.organization,
|
||||
OrganizationalUnit: c.organizationalUnit,
|
||||
})
|
||||
if err != nil {
|
||||
c.Ui.Error(err.Error())
|
||||
return 1
|
||||
|
@ -163,3 +257,17 @@ func (c *TLSCACreateCommand) Run(args []string) int {
|
|||
|
||||
return 0
|
||||
}
|
||||
|
||||
// IsCustom checks whether any of TLSCACreateCommand parameters have been populated with
|
||||
// non-default values.
|
||||
func (c *TLSCACreateCommand) IsCustom() bool {
|
||||
return c.commonName == "" &&
|
||||
c.country == "" &&
|
||||
c.postalCode == "" &&
|
||||
c.province == "" &&
|
||||
c.locality == "" &&
|
||||
c.streetAddress == "" &&
|
||||
c.organization == "" &&
|
||||
c.organizationalUnit == ""
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ package command
|
|||
import (
|
||||
"crypto/x509"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -47,6 +46,10 @@ func TestCACreateCommand(t *testing.T) {
|
|||
"-name-constraint=true",
|
||||
"-domain=foo",
|
||||
"-additional-domain=bar",
|
||||
"-common-name=CustomCA",
|
||||
"-country=ZZ",
|
||||
"-organization=CustOrg",
|
||||
"-organizational-unit=CustOrgUnit",
|
||||
},
|
||||
"foo-agent-ca.pem",
|
||||
"foo-agent-ca-key.pem",
|
||||
|
@ -55,24 +58,20 @@ func TestCACreateCommand(t *testing.T) {
|
|||
require.True(t, cert.PermittedDNSDomainsCritical)
|
||||
require.Len(t, cert.PermittedDNSDomains, 4)
|
||||
require.ElementsMatch(t, cert.PermittedDNSDomains, []string{"nomad", "foo", "localhost", "bar"})
|
||||
require.Equal(t, cert.Issuer.Organization, []string{"CustOrg"})
|
||||
require.Equal(t, cert.Issuer.OrganizationalUnit, []string{"CustOrgUnit"})
|
||||
require.Equal(t, cert.Issuer.Country, []string{"ZZ"})
|
||||
require.Contains(t, cert.Issuer.CommonName, "CustomCA")
|
||||
},
|
||||
},
|
||||
{"with common-name",
|
||||
{"ca custom date",
|
||||
[]string{
|
||||
"-common-name=foo",
|
||||
"-days=365",
|
||||
},
|
||||
"nomad-agent-ca.pem",
|
||||
"nomad-agent-ca-key.pem",
|
||||
func(t *testing.T, cert *x509.Certificate) {
|
||||
require.Equal(t, cert.Subject.CommonName, "foo")
|
||||
},
|
||||
},
|
||||
{"without common-name",
|
||||
[]string{},
|
||||
"nomad-agent-ca.pem",
|
||||
"nomad-agent-ca-key.pem",
|
||||
func(t *testing.T, cert *x509.Certificate) {
|
||||
require.True(t, strings.HasPrefix(cert.Subject.CommonName, "Nomad Agent CA"))
|
||||
require.Equal(t, 365*24*time.Hour, time.Until(cert.NotAfter).Round(24*time.Hour))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -97,5 +96,4 @@ func TestCACreateCommand(t *testing.T) {
|
|||
require.NoError(t, os.Remove(tc.keyPath))
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
|
@ -66,7 +67,13 @@ type CAOpts struct {
|
|||
Serial *big.Int
|
||||
Days int
|
||||
PermittedDNSDomains []string
|
||||
Domain string
|
||||
Country string
|
||||
PostalCode string
|
||||
Province string
|
||||
Locality string
|
||||
StreetAddress string
|
||||
Organization string
|
||||
OrganizationalUnit string
|
||||
Name string
|
||||
}
|
||||
|
||||
|
@ -81,10 +88,28 @@ type CertOpts struct {
|
|||
ExtKeyUsage []x509.ExtKeyUsage
|
||||
}
|
||||
|
||||
// IsCustom checks whether any of CAOpts parameters have been populated with
|
||||
// non-default values.
|
||||
func (c *CAOpts) IsCustom() bool {
|
||||
return c.Country == "" &&
|
||||
c.PostalCode == "" &&
|
||||
c.Province == "" &&
|
||||
c.Locality == "" &&
|
||||
c.StreetAddress == "" &&
|
||||
c.Organization == "" &&
|
||||
c.OrganizationalUnit == "" &&
|
||||
c.Name == ""
|
||||
}
|
||||
|
||||
// GenerateCA generates a new CA for agent TLS (not to be confused with Connect TLS)
|
||||
func GenerateCA(opts CAOpts) (string, string, error) {
|
||||
signer := opts.Signer
|
||||
var pk string
|
||||
var (
|
||||
id []byte
|
||||
pk string
|
||||
err error
|
||||
signer = opts.Signer
|
||||
sn = opts.Serial
|
||||
)
|
||||
if signer == nil {
|
||||
var err error
|
||||
signer, pk, err = GeneratePrivateKey()
|
||||
|
@ -93,12 +118,11 @@ func GenerateCA(opts CAOpts) (string, string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
id, err := keyID(signer.Public())
|
||||
id, err = keyID(signer.Public())
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
sn := opts.Serial
|
||||
if sn == nil {
|
||||
var err error
|
||||
sn, err = GenerateSerialNumber()
|
||||
|
@ -106,32 +130,55 @@ func GenerateCA(opts CAOpts) (string, string, error) {
|
|||
return "", "", err
|
||||
}
|
||||
}
|
||||
name := opts.Name
|
||||
if name == "" {
|
||||
name = fmt.Sprintf("Nomad Agent CA %d", sn)
|
||||
}
|
||||
|
||||
days := opts.Days
|
||||
if opts.Days == 0 {
|
||||
days = 365
|
||||
if opts.IsCustom() {
|
||||
opts.Name = fmt.Sprintf("Nomad Agent CA %d", sn)
|
||||
if opts.Days == 0 {
|
||||
opts.Days = 1825
|
||||
}
|
||||
opts.Country = "US"
|
||||
opts.PostalCode = "94105"
|
||||
opts.Province = "CA"
|
||||
opts.Locality = "San Francisco"
|
||||
opts.StreetAddress = "101 Second Street"
|
||||
opts.Organization = "HashiCorp Inc."
|
||||
opts.OrganizationalUnit = "Nomad"
|
||||
} else {
|
||||
if opts.Name == "" {
|
||||
return "", "", errors.New("common name value not provided")
|
||||
} else {
|
||||
opts.Name = fmt.Sprintf("%s %d", opts.Name, sn)
|
||||
}
|
||||
if opts.Country == "" {
|
||||
return "", "", errors.New("country value not provided")
|
||||
}
|
||||
|
||||
if opts.Organization == "" {
|
||||
return "", "", errors.New("organization value not provided")
|
||||
}
|
||||
|
||||
if opts.OrganizationalUnit == "" {
|
||||
return "", "", errors.New("organizational unit value not provided")
|
||||
}
|
||||
}
|
||||
|
||||
// Create the CA cert
|
||||
template := x509.Certificate{
|
||||
SerialNumber: sn,
|
||||
Subject: pkix.Name{
|
||||
Country: []string{"US"},
|
||||
PostalCode: []string{"94105"},
|
||||
Province: []string{"CA"},
|
||||
Locality: []string{"San Francisco"},
|
||||
StreetAddress: []string{"101 Second Street"},
|
||||
Organization: []string{"HashiCorp Inc."},
|
||||
CommonName: name,
|
||||
Country: []string{opts.Country},
|
||||
PostalCode: []string{opts.PostalCode},
|
||||
Province: []string{opts.Province},
|
||||
Locality: []string{opts.Locality},
|
||||
StreetAddress: []string{opts.StreetAddress},
|
||||
Organization: []string{opts.Organization},
|
||||
OrganizationalUnit: []string{opts.OrganizationalUnit},
|
||||
CommonName: opts.Name,
|
||||
},
|
||||
BasicConstraintsValid: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign | x509.KeyUsageDigitalSignature,
|
||||
IsCA: true,
|
||||
NotAfter: time.Now().AddDate(0, 0, days),
|
||||
NotAfter: time.Now().AddDate(0, 0, opts.Days),
|
||||
NotBefore: time.Now(),
|
||||
AuthorityKeyId: id,
|
||||
SubjectKeyId: id,
|
||||
|
|
|
@ -94,7 +94,7 @@ func TestGenerateCA(t *testing.T) {
|
|||
require.Equal(t, true, cert.BasicConstraintsValid)
|
||||
|
||||
require.WithinDuration(t, cert.NotBefore, time.Now(), time.Minute)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 365), time.Minute)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 1825), time.Minute)
|
||||
|
||||
require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage)
|
||||
})
|
||||
|
@ -112,10 +112,110 @@ func TestGenerateCA(t *testing.T) {
|
|||
require.Equal(t, true, cert.BasicConstraintsValid)
|
||||
|
||||
require.WithinDuration(t, cert.NotBefore, time.Now(), time.Minute)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 365), time.Minute)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 1825), time.Minute)
|
||||
|
||||
require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage)
|
||||
})
|
||||
|
||||
t.Run("Custom CA", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 6,
|
||||
PermittedDNSDomains: []string{"domain1.com"},
|
||||
Country: "ZZ",
|
||||
PostalCode: "0000",
|
||||
Province: "CustProvince",
|
||||
Locality: "CustLocality",
|
||||
StreetAddress: "CustStreet",
|
||||
Organization: "CustOrg",
|
||||
OrganizationalUnit: "CustUnit",
|
||||
Name: "Custom CA",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, ca)
|
||||
require.NotEmpty(t, pk)
|
||||
|
||||
cert, err := parseCert(ca)
|
||||
require.NoError(t, err)
|
||||
require.True(t, strings.HasPrefix(cert.Subject.CommonName, "Custom CA"))
|
||||
require.True(t, strings.Contains(cert.PermittedDNSDomains[0], "domain1.com"))
|
||||
require.True(t, strings.Contains(cert.Subject.Country[0], "ZZ"))
|
||||
require.True(t, strings.Contains(cert.Subject.PostalCode[0], "0000"))
|
||||
require.True(t, strings.Contains(cert.Subject.Province[0], "CustProvince"))
|
||||
require.True(t, strings.Contains(cert.Subject.Locality[0], "CustLocality"))
|
||||
require.True(t, strings.Contains(cert.Subject.StreetAddress[0], "CustStreet"))
|
||||
require.True(t, strings.Contains(cert.Subject.Organization[0], "CustOrg"))
|
||||
require.True(t, strings.Contains(cert.Subject.OrganizationalUnit[0], "CustUnit"))
|
||||
require.Equal(t, true, cert.IsCA)
|
||||
require.Equal(t, true, cert.BasicConstraintsValid)
|
||||
|
||||
require.WithinDuration(t, cert.NotBefore, time.Now(), time.Minute)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 6), time.Minute)
|
||||
|
||||
require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage)
|
||||
})
|
||||
|
||||
t.Run("Custom CA Custom Date", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 365,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, ca)
|
||||
require.NotEmpty(t, pk)
|
||||
|
||||
cert, err := parseCert(ca)
|
||||
require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 365), time.Minute)
|
||||
})
|
||||
|
||||
t.Run("Custom CA No CN", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 6,
|
||||
PermittedDNSDomains: []string{"domain1.com"},
|
||||
Locality: "CustLocality",
|
||||
})
|
||||
require.ErrorContains(t, err, "common name value not provided")
|
||||
require.Empty(t, ca)
|
||||
require.Empty(t, pk)
|
||||
})
|
||||
|
||||
t.Run("Custom CA No Country", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 6,
|
||||
PermittedDNSDomains: []string{"domain1.com"},
|
||||
Name: "Custom CA",
|
||||
Locality: "CustLocality",
|
||||
})
|
||||
require.ErrorContains(t, err, "country value not provided")
|
||||
require.Empty(t, ca)
|
||||
require.Empty(t, pk)
|
||||
})
|
||||
|
||||
t.Run("Custom CA No Organization", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 6,
|
||||
PermittedDNSDomains: []string{"domain1.com"},
|
||||
Name: "Custom CA",
|
||||
Country: "ZZ",
|
||||
Locality: "CustLocality",
|
||||
})
|
||||
require.ErrorContains(t, err, "organization value not provided")
|
||||
// require.NoError(t, err)
|
||||
require.Empty(t, ca)
|
||||
require.Empty(t, pk)
|
||||
})
|
||||
|
||||
t.Run("Custom CA No Organizational Unit", func(t *testing.T) {
|
||||
ca, pk, err := GenerateCA(CAOpts{
|
||||
Days: 6,
|
||||
PermittedDNSDomains: []string{"domain1.com"},
|
||||
Name: "Custom CA",
|
||||
Country: "ZZ",
|
||||
Locality: "CustLocality",
|
||||
Organization: "CustOrg",
|
||||
})
|
||||
require.ErrorContains(t, err, "organizational unit value not provided")
|
||||
require.Empty(t, ca)
|
||||
require.Empty(t, pk)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateCert(t *testing.T) {
|
||||
|
@ -123,10 +223,16 @@ func TestGenerateCert(t *testing.T) {
|
|||
|
||||
signer, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
require.Nil(t, err)
|
||||
ca, _, err := GenerateCA(CAOpts{Signer: signer})
|
||||
ca, _, err := GenerateCA(CAOpts{
|
||||
Name: "Custom CA",
|
||||
Country: "ZZ",
|
||||
Organization: "CustOrg",
|
||||
OrganizationalUnit: "CustOrgUnit",
|
||||
Signer: signer},
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
DNSNames := []string{"server.dc1.consul"}
|
||||
DNSNames := []string{"server.dc1.nomad"}
|
||||
IPAddresses := []net.IP{net.ParseIP("123.234.243.213")}
|
||||
extKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
|
||||
name := "Cert Name"
|
||||
|
@ -150,7 +256,7 @@ func TestGenerateCert(t *testing.T) {
|
|||
caID, err := keyID(signer.Public())
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, caID, cert.AuthorityKeyId)
|
||||
require.Contains(t, cert.Issuer.CommonName, "Nomad Agent CA")
|
||||
require.Contains(t, cert.Issuer.CommonName, "Custom CA")
|
||||
require.Equal(t, false, cert.IsCA)
|
||||
|
||||
require.WithinDuration(t, cert.NotBefore, time.Now(), time.Minute)
|
||||
|
|
|
@ -1370,7 +1370,13 @@ func newTLSTestHelper(t *testing.T) tlsTestHelper {
|
|||
}
|
||||
|
||||
// Generate CA certificate and write it to disk.
|
||||
h.caPEM, h.pk, err = tlsutil.GenerateCA(tlsutil.CAOpts{Days: 5, Domain: "nomad"})
|
||||
h.caPEM, h.pk, err = tlsutil.GenerateCA(tlsutil.CAOpts{
|
||||
Name: "Nomad CA",
|
||||
Country: "ZZ",
|
||||
Days: 5,
|
||||
Organization: "CustOrgUnit",
|
||||
OrganizationalUnit: "CustOrgUnit",
|
||||
})
|
||||
must.NoError(t, err)
|
||||
|
||||
err = os.WriteFile(filepath.Join(h.dir, "ca.pem"), []byte(h.caPEM), 0600)
|
||||
|
|
|
@ -24,7 +24,9 @@ nomad tls ca create [options]
|
|||
`-additional-domain`. Can be used multiple times. This option can only used in
|
||||
combination with `-domain` and `-name-constraint`.
|
||||
|
||||
- `common-name`: Common Name of CA. Defaults to Nomad Agent CA.
|
||||
- `-common-name`: Common Name of CA. Defaults to Nomad Agent CA.
|
||||
|
||||
- `-country`: Country of the CA. Defaults to "US".
|
||||
|
||||
- `-days=<int>`: Provide number of days the CA is valid for from now on,
|
||||
defaults to 5 years.
|
||||
|
@ -32,6 +34,8 @@ nomad tls ca create [options]
|
|||
- `-domain=<string>`: Domain of nomad cluster. Only used in combination with
|
||||
`-name-constraint`. Defaults to `nomad`.
|
||||
|
||||
- `-locality`: Locality of the CA. Defaults to "San Francisco".
|
||||
|
||||
- `-name-constraint`: Add name constraints for the CA. Results in rejecting
|
||||
certificates for other DNS than specified. If set to true, "localhost" and
|
||||
`-domain` will be added to the allowed DNS. Defaults to false.
|
||||
|
@ -40,6 +44,16 @@ nomad tls ca create [options]
|
|||
Nomad web UI over HTTPS its DNS must be added with `additional-domain`. It is
|
||||
not possible to add that after the fact.
|
||||
|
||||
- `-organization`: Organization of the CA. Defaults to "HashiCorp Inc.".
|
||||
|
||||
- `-organizational-unit`: Organizational Unit of the CA. Defaults to "Nomad".
|
||||
|
||||
- `-postal-code`: Postal Code of the CA. Defaults to "94105".
|
||||
|
||||
- `-province`: Province of the CA. Defaults to "CA".
|
||||
|
||||
- `-street-address`: Street Address of the CA. Defaults to "101 Second Street".
|
||||
|
||||
## Example
|
||||
|
||||
Create CA:
|
||||
|
|
Loading…
Reference in New Issue