Generate the nonce by default
This commit is contained in:
parent
eece4e047b
commit
53c919b1d0
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/ec2"
|
"github.com/aws/aws-sdk-go/service/ec2"
|
||||||
"github.com/fullsailor/pkcs7"
|
"github.com/fullsailor/pkcs7"
|
||||||
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/vault/helper/jsonutil"
|
"github.com/hashicorp/vault/helper/jsonutil"
|
||||||
"github.com/hashicorp/vault/helper/strutil"
|
"github.com/hashicorp/vault/helper/strutil"
|
||||||
"github.com/hashicorp/vault/logical"
|
"github.com/hashicorp/vault/logical"
|
||||||
|
@ -110,6 +111,12 @@ func validateMetadata(clientNonce, pendingTime string, storedIdentity *whitelist
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For sanity
|
||||||
|
if !storedIdentity.DisallowReauthentication &&
|
||||||
|
storedIdentity.ClientNonce == "" {
|
||||||
|
return fmt.Errorf("client nonce missing in stored identity")
|
||||||
|
}
|
||||||
|
|
||||||
// When the presented client nonce does not match the cached entry, it is
|
// When the presented client nonce does not match the cached entry, it is
|
||||||
// either that a rogue client is trying to login or that a valid client
|
// either that a rogue client is trying to login or that a valid client
|
||||||
// suffered a migration. The migration is detected via pendingTime in the
|
// suffered a migration. The migration is detected via pendingTime in the
|
||||||
|
@ -289,6 +296,15 @@ func (b *backend) pathLoginUpdate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the clientNonce is empty at this point, it means that its a first
|
||||||
|
// time login and that a nonce is not supplied. Create a random nonce
|
||||||
|
// to be associated for the instance ID.
|
||||||
|
if clientNonce == "" {
|
||||||
|
if clientNonce, err = uuid.GenerateUUID(); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate random nonce")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load the current values for max TTL and policies from the role entry,
|
// Load the current values for max TTL and policies from the role entry,
|
||||||
// before checking for overriding max TTL in the role tag. The shortest
|
// before checking for overriding max TTL in the role tag. The shortest
|
||||||
// max TTL is used to cap the token TTL; the longest max TTL is used to
|
// max TTL is used to cap the token TTL; the longest max TTL is used to
|
||||||
|
@ -367,19 +383,26 @@ func (b *backend) pathLoginUpdate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisallowReauthentication, PendingTime, LastUpdatedTime and ExpirationTime may change.
|
// DisallowReauthentication, PendingTime, LastUpdatedTime and
|
||||||
|
// ExpirationTime may change.
|
||||||
storedIdentity.LastUpdatedTime = currentTime
|
storedIdentity.LastUpdatedTime = currentTime
|
||||||
storedIdentity.ExpirationTime = currentTime.Add(longestMaxTTL)
|
storedIdentity.ExpirationTime = currentTime.Add(longestMaxTTL)
|
||||||
storedIdentity.PendingTime = identityDoc.PendingTime
|
storedIdentity.PendingTime = identityDoc.PendingTime
|
||||||
storedIdentity.DisallowReauthentication = disallowReauthentication
|
storedIdentity.DisallowReauthentication = disallowReauthentication
|
||||||
|
|
||||||
// Performing the clientNonce empty check after determining the DisallowReauthentication
|
// Performing the clientNonce empty check after determining the
|
||||||
// option. This is to make clientNonce optional when DisallowReauthentication is set.
|
// DisallowReauthentication option. This is to make clientNonce
|
||||||
|
// optional when DisallowReauthentication is set.
|
||||||
if clientNonce == "" && !storedIdentity.DisallowReauthentication {
|
if clientNonce == "" && !storedIdentity.DisallowReauthentication {
|
||||||
return logical.ErrorResponse("missing nonce"), nil
|
return logical.ErrorResponse("missing nonce"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit the nonce to a reasonable length.
|
// Don't cache the nonce if DisallowReauthentication is set
|
||||||
|
if storedIdentity.DisallowReauthentication {
|
||||||
|
storedIdentity.ClientNonce = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanitize the nonce to a reasonable length
|
||||||
if len(clientNonce) > 128 && !storedIdentity.DisallowReauthentication {
|
if len(clientNonce) > 128 && !storedIdentity.DisallowReauthentication {
|
||||||
return logical.ErrorResponse("client nonce exceeding the limit of 128 characters"), nil
|
return logical.ErrorResponse("client nonce exceeding the limit of 128 characters"), nil
|
||||||
}
|
}
|
||||||
|
@ -397,6 +420,11 @@ func (b *backend) pathLoginUpdate(
|
||||||
"role_tag_max_ttl": rTagMaxTTL.String(),
|
"role_tag_max_ttl": rTagMaxTTL.String(),
|
||||||
"role": roleName,
|
"role": roleName,
|
||||||
"ami_id": identityDoc.AmiID,
|
"ami_id": identityDoc.AmiID,
|
||||||
|
// Echo the client nonce back. If nonce was not
|
||||||
|
// supplied to the endpoint, callers should
|
||||||
|
// extract out the nonce from this field for
|
||||||
|
// reauthentication requests.
|
||||||
|
"nonce": clientNonce,
|
||||||
},
|
},
|
||||||
LeaseOptions: logical.LeaseOptions{
|
LeaseOptions: logical.LeaseOptions{
|
||||||
Renewable: true,
|
Renewable: true,
|
||||||
|
|
|
@ -85,14 +85,17 @@ as it means that once a token has expired, subsequent authentication attempts
|
||||||
would fail. By default, reauthentication is enabled in this backend, and can be
|
would fail. By default, reauthentication is enabled in this backend, and can be
|
||||||
turned off using 'disallow_reauthentication' parameter on the registered role.
|
turned off using 'disallow_reauthentication' parameter on the registered role.
|
||||||
|
|
||||||
In the default method of operation, the client supplies a unique nonce during
|
In the default method of operation, the backend will return a unique nonce
|
||||||
the first authentication attempt, storing this nonce in the client's memory for
|
during the first authentication attempt, as part of auth `metadata`. Clients
|
||||||
future use. This nonce is stored in the whitelist, tied to the instance ID.
|
should present this `nonce` for subsequent login attempts and it should match
|
||||||
Subsequent authentication attempts by the client require the nonce to match;
|
the `nonce` cached at the identity-whitelist entry at the backend. Since only
|
||||||
since only the original client knows the nonce, only the original client is
|
the original client knows the `nonce`, only the original client is allowed to
|
||||||
allowed to reauthenticate. (This is the reason that this is a whitelist rather
|
reauthenticate. (This is the reason that this is a whitelist rather than a
|
||||||
than a blacklist; by default, it's keeping track of clients allowed to
|
blacklist; by default, it's keeping track of clients allowed to reauthenticate,
|
||||||
reauthenticate, rather than those that are not.)
|
rather than those that are not.). Clients can choose to provide a `nonce` even
|
||||||
|
for the first login attempt, in which case the provided `nonce` will be tied to
|
||||||
|
the cached identity-whitelist entry. It is recommended to use a strong `nonce`
|
||||||
|
value in this case.
|
||||||
|
|
||||||
It is up to the client to behave correctly with respect to the nonce; if the
|
It is up to the client to behave correctly with respect to the nonce; if the
|
||||||
client stores the nonce on disk it can survive reboots, but could also give
|
client stores the nonce on disk it can survive reboots, but could also give
|
||||||
|
@ -287,7 +290,8 @@ $ vault write auth/aws-ec2/role/dev-role bound_ami_id=ami-fce3c696 policies=prod
|
||||||
#### Perform the login operation
|
#### Perform the login operation
|
||||||
|
|
||||||
```
|
```
|
||||||
$ vault write auth/aws-ec2/login role=dev-role pkcs7=MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggGmewogICJkZXZwYXlQcm9kdWN0Q29kZXMiIDogbnVsbCwKICAicHJpdmF0ZUlwIiA6ICIxNzIuMzEuNjMuNjAiLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1cy1lYXN0LTFjIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3RhbmNlSWQiIDogImktZGUwZjEzNDQiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVsbCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIgOiAiMjQxNjU2NjE1ODU5IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwKICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDVUMTY6MjY6NTVaIiwKICAiYXJjaGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJyYW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAAAAAxggEXMIIBEwIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDUxNjI3MDBaMCMGCSqGSIb3DQEJBDEWBBRtiynzMTNfTw1TV/d8NvfgVw+XfTAJBgcqhkjOOAQDBC4wLAIUVfpVcNYoOKzN1c+h1Vsm/c5U0tQCFAK/K72idWrONIqMOVJ8Uen0wYg4AAAAAAAA nonce=vault-client-nonce
|
$ vault write auth/aws-ec2/login role=dev-role
|
||||||
|
pkcs7=MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggGmewogICJkZXZwYXlQcm9kdWN0Q29kZXMiIDogbnVsbCwKICAicHJpdmF0ZUlwIiA6ICIxNzIuMzEuNjMuNjAiLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1cy1lYXN0LTFjIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3RhbmNlSWQiIDogImktZGUwZjEzNDQiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVsbCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIgOiAiMjQxNjU2NjE1ODU5IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwKICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDVUMTY6MjY6NTVaIiwKICAiYXJjaGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJyYW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAAAAAxggEXMIIBEwIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDUxNjI3MDBaMCMGCSqGSIb3DQEJBDEWBBRtiynzMTNfTw1TV/d8NvfgVw+XfTAJBgcqhkjOOAQDBC4wLAIUVfpVcNYoOKzN1c+h1Vsm/c5U0tQCFAK/K72idWrONIqMOVJ8Uen0wYg4AAAAAAAA nonce=5defbf9e-a8f9-3063-bdfc-54b7a42a1f95
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +318,9 @@ curl -X POST -H "x-vault-token:123" "http://127.0.0.1:8200/v1/auth/aws-ec2/role/
|
||||||
#### Perform the login operation
|
#### Perform the login operation
|
||||||
|
|
||||||
```
|
```
|
||||||
curl -X POST "http://127.0.0.1:8200/v1/auth/aws-ec2/login" -d '{"role":"dev-role","pkcs7":"$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 | tr -d '\n')","nonce":"vault-client-nonce"}'
|
curl -X POST "http://127.0.0.1:8200/v1/auth/aws-ec2/login" -d
|
||||||
|
'{"role":"dev-role","pkcs7":"$(curl -s
|
||||||
|
http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 | tr -d '\n')","nonce":"5defbf9e-a8f9-3063-bdfc-54b7a42a1f95"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,26 +330,30 @@ The response will be in JSON. For example:
|
||||||
{
|
{
|
||||||
"auth": {
|
"auth": {
|
||||||
"renewable": true,
|
"renewable": true,
|
||||||
"lease_duration": 1800000,
|
"lease_duration": 72000,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"role_tag_max_ttl": "0",
|
"role_tag_max_ttl": "0s",
|
||||||
"instance_id": "i-de0f1344"
|
"role": "ami-f083709d",
|
||||||
"ami_id": "ami-fce3c696"
|
"region": "us-east-1",
|
||||||
"role": "dev-prod"
|
"nonce": "5defbf9e-a8f9-3063-bdfc-54b7a42a1f95",
|
||||||
|
"instance_id": "i-a832f734",
|
||||||
|
"ami_id": "ami-f083709d"
|
||||||
},
|
},
|
||||||
"policies": [
|
"policies": [
|
||||||
"default",
|
"default",
|
||||||
"dev",
|
"dev",
|
||||||
"prod"
|
"prod"
|
||||||
],
|
],
|
||||||
"accessor": "20b89871-e6f2-1160-fb29-31c2f6d4645e",
|
"accessor": "5cd96cd1-58b7-2904-5519-75ddf957ec06",
|
||||||
"client_token": "c9368254-3f21-aded-8a6f-7c818e81b17a"
|
"client_token": "150fc858-2402-49c9-56a5-f4b57f2c8ff1"
|
||||||
},
|
},
|
||||||
"warnings": null,
|
"warnings": null,
|
||||||
|
"wrap_info": null,
|
||||||
"data": null,
|
"data": null,
|
||||||
"lease_duration": 0,
|
"lease_duration": 0,
|
||||||
"renewable": false,
|
"renewable": false,
|
||||||
"lease_id": ""
|
"lease_id": "",
|
||||||
|
"request_id": "d7d50c06-56b8-37f4-606c-ccdc87a1ee4c"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1122,10 +1132,13 @@ in its identity document to match the one specified by this parameter.
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<span class="param">nonce</span>
|
<span class="param">nonce</span>
|
||||||
<span class="param-flags">required/optional, depends</span>
|
<span class="param-flags">optional</span>
|
||||||
The `nonce` created by a client of this backend. When `disallow_reauthentication`
|
The `nonce` to be used for reauthentication requests. By default, the backend
|
||||||
option is enabled on either the role or the role tag, then `nonce` parameter is
|
generates a `nonce` if it is not supplied and returns it as part of auth `metadata`.
|
||||||
optional. It is a required parameter otherwise.
|
If a custom nonce is desired, this field can be supplied during the first login
|
||||||
|
attempt. Usage of strong `nonce` value is recommended. Note that, when
|
||||||
|
`disallow_reauthentication` option is enabled on either the role or the role
|
||||||
|
tag, the `nonce` holds no significance.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -1370,7 +1383,7 @@ in its identity document to match the one specified by this parameter.
|
||||||
"pending_time": "2016-04-14T01:01:41Z",
|
"pending_time": "2016-04-14T01:01:41Z",
|
||||||
"expiration_time": "2016-05-05 10:09:16.67077232 +0000 UTC",
|
"expiration_time": "2016-05-05 10:09:16.67077232 +0000 UTC",
|
||||||
"creation_time": "2016-04-14 14:09:16.67077232 +0000 UTC",
|
"creation_time": "2016-04-14 14:09:16.67077232 +0000 UTC",
|
||||||
"client_nonce": "vault-client-nonce",
|
"client_nonce": "5defbf9e-a8f9-3063-bdfc-54b7a42a1f95",
|
||||||
"role": "dev-role"
|
"role": "dev-role"
|
||||||
},
|
},
|
||||||
"lease_duration": 0,
|
"lease_duration": 0,
|
||||||
|
|
Loading…
Reference in New Issue