Skip to content

Commit

Permalink
provide configuration options for auto_encrypt dnssan and ipsan
Browse files Browse the repository at this point in the history
  • Loading branch information
hanshasselberg committed Jan 16, 2020
1 parent f14e0cf commit 6e2f4f9
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 2 deletions.
2 changes: 2 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ func (a *Agent) setupClientAutoEncryptCache(reply *structs.SignedResponse) (*str
Datacenter: a.config.Datacenter,
Token: a.tokens.AgentToken(),
Agent: a.config.NodeName,
DNSSAN: a.config.AutoEncryptDNSSAN,
IPSAN: a.config.AutoEncryptIPSAN,
}

// prepolutate leaf cache
Expand Down
6 changes: 4 additions & 2 deletions agent/cache-types/connect_ca_leaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,8 @@ func (c *ConnectCALeaf) generateNewLeaf(req *ConnectCALeafRequest,
Agent: req.Agent,
}
commonName = connect.ServiceCN(req.Agent, roots.TrustDomain)
dnsNames = []string{"localhost"}
ipAddresses = []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::")}
dnsNames = append([]string{"localhost"}, req.DNSSAN...)
ipAddresses = append([]net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::")}, req.IPSAN...)
} else {
return result, errors.New("URI must be either service or agent")
}
Expand Down Expand Up @@ -641,6 +641,8 @@ type ConnectCALeafRequest struct {
Datacenter string
Service string // Service name, not ID
Agent string // Agent name, not ID
DNSSAN []string
IPSAN []net.IP
MinQueryIndex uint64
MaxQueryTime time.Duration
}
Expand Down
16 changes: 16 additions & 0 deletions agent/config/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,20 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
}

autoEncryptTLS := b.boolVal(c.AutoEncrypt.TLS)
autoEncryptDNSSAN := []string{}
for _, d := range c.AutoEncrypt.DNSSAN {
autoEncryptDNSSAN = append(autoEncryptDNSSAN, d)
}
autoEncryptIPSAN := []net.IP{}
for _, i := range c.AutoEncrypt.IPSAN {
ip := net.ParseIP(i)
if ip == nil {
b.warn(fmt.Sprintf("Cannot parse ip %q from AutoEncrypt.IPSAN", i))
continue
}
autoEncryptIPSAN = append(autoEncryptIPSAN, ip)

}
autoEncryptAllowTLS := b.boolVal(c.AutoEncrypt.AllowTLS)

if autoEncryptAllowTLS {
Expand Down Expand Up @@ -809,6 +823,8 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
ClientAddrs: clientAddrs,
ConfigEntryBootstrap: configEntries,
AutoEncryptTLS: autoEncryptTLS,
AutoEncryptDNSSAN: autoEncryptDNSSAN,
AutoEncryptIPSAN: autoEncryptIPSAN,
AutoEncryptAllowTLS: autoEncryptAllowTLS,
ConnectEnabled: connectEnabled,
ConnectCAProvider: connectCAProvider,
Expand Down
6 changes: 6 additions & 0 deletions agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,12 @@ type AutoEncrypt struct {
// TLS enables receiving certificates for clients from servers
TLS *bool `json:"tls,omitempty" hcl:"tls" mapstructure:"tls"`

// Additional DNS SAN entries that clients request for their certificates.
DNSSAN []string `json:"dns_san,omitempty" hcl:"dns_san" mapstructure:"dns_san"`

// Additional IP SAN entries that clients request for their certificates.
IPSAN []string `json:"ip_san,omitempty" hcl:"ip_san" mapstructure:"ip_san"`

// AllowTLS enables the RPC endpoint on the server to answer
// AutoEncrypt.Sign requests.
AllowTLS *bool `json:"allow_tls,omitempty" hcl:"allow_tls" mapstructure:"allow_tls"`
Expand Down
8 changes: 8 additions & 0 deletions agent/config/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,14 @@ type RuntimeConfig struct {
// servers.
AutoEncryptTLS bool

// Additional DNS SAN entries that clients request during auto_encrypt
// flow for their certificates.
AutoEncryptDNSSAN []string

// Additional IP SAN entries that clients request during auto_encrypt
// flow for their certificates.
AutoEncryptIPSAN []net.IP

// AutoEncryptAllowTLS enables the server to respond to
// AutoEncrypt.Sign requests.
AutoEncryptAllowTLS bool
Expand Down
8 changes: 8 additions & 0 deletions agent/config/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3727,6 +3727,8 @@ func TestFullConfig(t *testing.T) {
},
"auto_encrypt": {
"tls": true,
"dns_san": ["a.com", "b.com"],
"ip_san": ["192.168.4.139", "192.168.4.140"],
"allow_tls": true
},
"connect": {
Expand Down Expand Up @@ -4324,6 +4326,8 @@ func TestFullConfig(t *testing.T) {
}
auto_encrypt = {
tls = true
dns_san = ["a.com", "b.com"]
ip_san = ["192.168.4.139", "192.168.4.140"]
allow_tls = true
}
connect {
Expand Down Expand Up @@ -5030,6 +5034,8 @@ func TestFullConfig(t *testing.T) {
},
},
AutoEncryptTLS: true,
AutoEncryptDNSSAN: []string{"a.com", "b.com"},
AutoEncryptIPSAN: []net.IP{net.ParseIP("192.168.4.139"), net.ParseIP("192.168.4.140")},
AutoEncryptAllowTLS: true,
ConnectEnabled: true,
ConnectSidecarMinPort: 8888,
Expand Down Expand Up @@ -5868,6 +5874,8 @@ func TestSanitize(t *testing.T) {
"ClientAddrs": [],
"ConfigEntryBootstrap": [],
"AutoEncryptTLS": false,
"AutoEncryptDNSSAN": [],
"AutoEncryptIPSAN": [],
"AutoEncryptAllowTLS": false,
"ConnectCAConfig": {},
"ConnectCAProvider": "",
Expand Down
4 changes: 4 additions & 0 deletions website/source/docs/agent/options.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,10 @@ default will automatically work with some tooling.
* <a name="tls"></a><a href="#tls">`tls`</a> (Defaults to `false`) Allows the client to request the Connect CA and certificates from the servers, for encrypting RPC communication. The client will make the request to any servers listed in the `-join` or `-retry-join` option. This requires that every server to have `auto_encrypt.allow_tls` enabled. When both `auto_encrypt` options are used, it allows clients to receive certificates that are generated on the servers. If the `-server-port` is not the default one, it has to be provided to the client as well. Usually this is discovered through LAN gossip, but `auto_encrypt` provision happens before the information can be distributed through gossip. The most secure `auto_encrypt` setup is when the client is provided with the built-in CA, `verify_server_hostname` is turned on, and when an ACL token with `node.write` permissions is setup. It is also possible to use `auto_encrypt` with a CA and ACL, but without `verify_server_hostname`, or only with a ACL enabled, or only with CA and `verify_server_hostname`, or only with a CA, or finally without a CA and without ACL enabled. In any case, the communication to the `auto_encrypt` endpoint is always TLS encrypted.
* <a name="dns_san"></a><a href="#dns_san">`dns_san`</a> (Defaults to `[]`) When this option is being used, the certificates requested by `auto_encrypt` from the server have these `dns_san` set as DNS SAN.
* <a name="ip_san"></a><a href="#ip_san">`ip_san`</a> (Defaults to `[]`) When this option is being used, the certificates requested by `auto_encrypt` from the server have these `ip_san` set as IP SAN.
* <a name="bootstrap"></a><a href="#bootstrap">`bootstrap`</a> Equivalent to the
[`-bootstrap` command-line flag](#_bootstrap).
Expand Down

0 comments on commit 6e2f4f9

Please sign in to comment.