bootstrap-tokens: clean up and separate signing and authentication (#6471)
This PR attempts to: * Generally clean up the bootstrapping token doc. * Separate the authentication and signing features. Help users that only want to enable the authenticator without the signer. * Adds a warning about ConfigMap signing being susceptible to MITM if the same token is reused.
This commit is contained in:
@@ -36,74 +36,86 @@ information. It is used when referring to a token without leaking the secret
|
|||||||
part used for authentication. The second part is the "Token Secret" and should
|
part used for authentication. The second part is the "Token Secret" and should
|
||||||
only be shared with trusted parties.
|
only be shared with trusted parties.
|
||||||
|
|
||||||
## Enabling Bootstrap Tokens
|
## Enabling Bootstrap Token Authentication
|
||||||
|
|
||||||
All features for Bootstrap Tokens are disabled by default in Kubernetes v1.8.
|
The Bootstrap Token authenticator can be enabled using the following flag on the
|
||||||
|
API server:
|
||||||
|
|
||||||
You can enable the Bootstrap Token authenticator with the
|
```
|
||||||
`--enable-bootstrap-token-auth` flag on the API server. You can enable
|
--enable-bootstrap-token-auth
|
||||||
the Bootstrap controllers by specifying them with the `--controllers` flag on the
|
```
|
||||||
controller manager with something like
|
|
||||||
`--controllers=*,tokencleaner,bootstrapsigner`. This is done automatically when
|
|
||||||
using `kubeadm`.
|
|
||||||
|
|
||||||
Tokens are used in an HTTPS call as follows:
|
When enabled, bootstrapping tokens can be used as bearer token credentials to
|
||||||
|
authenticate requests against the API server.
|
||||||
|
|
||||||
```http
|
```http
|
||||||
Authorization: Bearer 07401b.f395accd246ae52d
|
Authorization: Bearer 07401b.f395accd246ae52d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Tokens authenticate as the username `system:bootstrap:<token id>` and are members
|
||||||
|
of the group `system:bootstrappers`. Additional groups may be specified in the
|
||||||
|
token's Secret.
|
||||||
|
|
||||||
|
Expired tokens can be deleted automatically by enabling the `tokencleaner`
|
||||||
|
controller on the controller manager.
|
||||||
|
|
||||||
|
```
|
||||||
|
--controllers=*,tokencleaner
|
||||||
|
```
|
||||||
|
|
||||||
## Bootstrap Token Secret Format
|
## Bootstrap Token Secret Format
|
||||||
|
|
||||||
Each valid token is backed by a secret in the `kube-system` namespace. You can
|
Each valid token is backed by a secret in the `kube-system` namespace. You can
|
||||||
find the full design doc
|
find the full design doc
|
||||||
[here](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md).
|
[here](https://github.com/kubernetes/community/blob/{{page.githubbranch}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md).
|
||||||
|
|
||||||
Here is what the secret looks like. Note that `base64(string)` indicates the
|
Here is what the secret looks like.
|
||||||
value should be base64 encoded. The undecoded version is provided here for
|
|
||||||
readability.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
|
# Name MUST be of form "bootstrap-token-<token id>"
|
||||||
name: bootstrap-token-07401b
|
name: bootstrap-token-07401b
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
|
|
||||||
|
# Type MUST be 'bootstrap.kubernetes.io/token'
|
||||||
type: bootstrap.kubernetes.io/token
|
type: bootstrap.kubernetes.io/token
|
||||||
data:
|
stringData:
|
||||||
description: base64(The default bootstrap token generated by 'kubeadm init'.)
|
# Human readable description. Optional.
|
||||||
token-id: base64(07401b)
|
description: "The default bootstrap token generated by 'kubeadm init'."
|
||||||
token-secret: base64(f395accd246ae52d)
|
|
||||||
expiration: base64(2017-03-10T03:22:11Z)
|
# Token ID and secret. Required.
|
||||||
usage-bootstrap-authentication: base64(true)
|
token-id: 07401b
|
||||||
usage-bootstrap-signing: base64(true)
|
token-secret: f395accd246ae52d
|
||||||
auth-extra-groups: base64(system:bootstrappers:group1,system:bootstrappers:group2)
|
|
||||||
|
# Expiration. Optional.
|
||||||
|
expiration: 2017-03-10T03:22:11Z
|
||||||
|
|
||||||
|
# Allowed usages.
|
||||||
|
usage-bootstrap-authentication: true
|
||||||
|
usage-bootstrap-signing: true
|
||||||
|
|
||||||
|
# Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
|
||||||
|
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
|
||||||
```
|
```
|
||||||
|
|
||||||
The type of the secret must be `bootstrap.kubernetes.io/token` and the name must
|
The type of the secret must be `bootstrap.kubernetes.io/token` and the name must
|
||||||
be `bootstrap-token-<token id>`. It must also exist in the `kube-system`
|
be `bootstrap-token-<token id>`. It must also exist in the `kube-system`
|
||||||
namespace. `description` is a human readable description that should not be
|
namespace.
|
||||||
used for machine readable information. The Token ID and Secret are included in
|
|
||||||
the data dictionary.
|
|
||||||
|
|
||||||
The `usage-bootstrap-*` members indicate what this secret is intended to be used
|
The `usage-bootstrap-*` members indicate what this secret is intended to be used
|
||||||
for. A value must be set to `true` to be enabled.
|
for. A value must be set to `true` to be enabled.
|
||||||
|
|
||||||
`usage-bootstrap-authentication` indicates that the token can be used to
|
* `usage-bootstrap-authentication` indicates that the token can be used to
|
||||||
authenticate to the API server. The authenticator authenticates as
|
authenticate to the API server as a bearer token.
|
||||||
`system:bootstrap:<Token ID>`. It is included in the `system:bootstrappers`
|
* `usage-bootstrap-signing` indicates that the token may be used to sign the
|
||||||
group. `auth-extra-groups` indicates that it will also be included in the
|
|
||||||
`system:bootstrappers:group1`, and `system:bootstrappers:group2` groups. The
|
|
||||||
naming and groups are intentionally limited to discourage users from using these
|
|
||||||
tokens past bootstrapping. Extra bootstrap token groups must start with
|
|
||||||
`system:bootstrappers:`.
|
|
||||||
|
|
||||||
`usage-bootstrap-signing` indicates that the token should be used to sign the
|
|
||||||
`cluster-info` ConfigMap as described below.
|
`cluster-info` ConfigMap as described below.
|
||||||
|
|
||||||
The `expiration` data member lists a time after which the token is no longer
|
The `expiration` field controls the expiry of the token. Expired tokens are
|
||||||
valid. This is encoded as an absolute UTC time using RFC3339. The TokenCleaner
|
rejected when used for authentication and ignored during ConfigMap signing.
|
||||||
controller will delete expired tokens.
|
The expiry value is encoded as an absolute UTC time using RFC3339. Enable the
|
||||||
|
`tokencleaner` controller to automatically delete expired tokens.
|
||||||
|
|
||||||
## Token Management with `kubeadm`
|
## Token Management with `kubeadm`
|
||||||
|
|
||||||
@@ -116,6 +128,13 @@ In addition to authentication, the tokens can be used to sign a ConfigMap. This
|
|||||||
is used early in a cluster bootstrap process before the client trusts the API
|
is used early in a cluster bootstrap process before the client trusts the API
|
||||||
server. The signed ConfigMap can be authenticated by the shared token.
|
server. The signed ConfigMap can be authenticated by the shared token.
|
||||||
|
|
||||||
|
Enable ConfigMap signing by enabling the `bootstrapsigner` controller on the
|
||||||
|
Controller Manager.
|
||||||
|
|
||||||
|
```
|
||||||
|
--controllers=*,bootstrapsigner
|
||||||
|
```
|
||||||
|
|
||||||
The ConfigMap that is signed is `cluster-info` in the `kube-public` namespace.
|
The ConfigMap that is signed is `cluster-info` in the `kube-public` namespace.
|
||||||
The typical flow is that a client reads this ConfigMap while unauthenticated and
|
The typical flow is that a client reads this ConfigMap while unauthenticated and
|
||||||
ignoring TLS errors. It then validates the payload of the ConfigMap by looking
|
ignoring TLS errors. It then validates the payload of the ConfigMap by looking
|
||||||
@@ -156,3 +175,11 @@ is then used to form a whole JWS by inserting it between the 2 dots. You can
|
|||||||
verify the JWS using the `HS256` scheme (HMAC-SHA256) with the full token (e.g.
|
verify the JWS using the `HS256` scheme (HMAC-SHA256) with the full token (e.g.
|
||||||
`07401b.f395accd246ae52d`) as the shared secret. Users _must_ verify that HS256
|
`07401b.f395accd246ae52d`) as the shared secret. Users _must_ verify that HS256
|
||||||
is used.
|
is used.
|
||||||
|
|
||||||
|
WARNING: Any party with a bootstrapping token can create a valid signature for that
|
||||||
|
token. When using ConfigMap signing it's discouraged to share the same token with
|
||||||
|
many clients, since a compromised client can potentially man-in-the middle another
|
||||||
|
client relying on the signature to bootstrap TLS trust.
|
||||||
|
|
||||||
|
Consult the [kubeadm security model](/docs/reference/generated/kubeadm/#security-model)
|
||||||
|
section for more information.
|
||||||
|
|||||||
Reference in New Issue
Block a user