-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: Support reviewing audiences of token #56
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,18 +28,22 @@ All command line flags: | |
```txt | ||
$ kube-rbac-proxy -h | ||
Usage of _output/linux/amd64/kube-rbac-proxy: | ||
--add_dir_header If true, adds the file directory to the header | ||
--alsologtostderr log to standard error as well as files | ||
--auth-header-fields-enabled When set to true, kube-rbac-proxy adds auth-related fields to the headers of http requests sent to the upstream | ||
--auth-header-groups-field-name string The name of the field inside a http(2) request header to tell the upstream server about the user's groups (default "x-remote-groups") | ||
--auth-header-groups-field-separator string The separator string used for concatenating multiple group names in a groups header field's value (default "|") | ||
--auth-header-user-field-name string The name of the field inside a http(2) request header to tell the upstream server about the user's name (default "x-remote-user") | ||
--auth-token-audiences strings Comma-separated list of token audiences to accept. By default a token does not have to have any specific audience. It is recommended to set a specific audience. | ||
--client-ca-file string If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file is authenticated with an identity corresponding to the CommonName of the client certificate. | ||
--config-file string Configuration file to configure kube-rbac-proxy. | ||
--insecure-listen-address string The address the kube-rbac-proxy HTTP server should listen on. | ||
--kubeconfig string Path to a kubeconfig file, specifying how to connect to the API server. If unset, in-cluster configuration will be used | ||
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) | ||
--log_dir string If non-empty, write log files in this directory | ||
--logtostderr log to standard error instead of files | ||
--log_file string If non-empty, use this log file | ||
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) | ||
--logtostderr log to standard error instead of files (default true) | ||
--oidc-ca-file string If set, the OpenID server's certificate will be verified by one of the authorities in the oidc-ca-file, otherwise the host's root CA set will be used. | ||
--oidc-clientID string The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set. | ||
--oidc-groups-claim string Identifier of groups in JWT claim, by default set to 'groups' (default "groups") | ||
|
@@ -48,15 +52,18 @@ Usage of _output/linux/amd64/kube-rbac-proxy: | |
--oidc-sign-alg stringArray Supported signing algorithms, default RS256 (default [RS256]) | ||
--oidc-username-claim string Identifier of the user in JWT claim, by default set to 'email' (default "email") | ||
--secure-listen-address string The address the kube-rbac-proxy HTTPs server should listen on. | ||
--skip_headers If true, avoid header prefixes in the log messages | ||
--skip_log_headers If true, avoid headers when opening log files | ||
--stderrthreshold severity logs at or above this threshold go to stderr (default 2) | ||
--tls-cert-file string File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert) | ||
--tls-cipher-suites strings Comma-separated list of cipher suites for the server. Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). If omitted, the default Go cipher suites will be used | ||
--tls-min-version string Minimum TLS version supported. Value must match version names from https://golang.org/pkg/crypto/tls/#pkg-constants. (default "VersionTLS12") | ||
--tls-private-key-file string File containing the default x509 private key matching --tls-cert-file. | ||
--tls-reload-interval duration The interval at which to watch for TLS certificate changes, by default set to 1 minute. (default 1m0s) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This actually came in as I regenerated the help text |
||
--upstream string The upstream URL to proxy to once requests have successfully been authenticated and authorized. | ||
--upstream-ca-file string The CA the upstream uses for TLS connection. This is required when the upstream uses TLS and its own CA certificate | ||
--upstream-force-h2c Force h2c to communiate with the upstream. This is required when the upstream speaks h2c(http/2 cleartext - insecure variant of http/2) only. For example, go-grpc server in the insecure mode, such as helm's tiller w/o TLS, speaks h2c only | ||
-v, --v Level log level for V logs | ||
-v, --v Level number for the log level verbosity | ||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,292 @@ | ||
# non-resource-url-token-request example | ||
|
||
> Token audience reviews can be combined with any of the other features of kube-rbac-proxy, such as reviewing permission for specific resources, this example merely chooses to show the functionality using a non-resource-url permission. | ||
|
||
This examples is in essence similar to the [non-resource-url](../non-resource-url/) example, with the key difference, that this example requires the ServiceAccount token sent by a client must be scoped to the `kube-rbac-proxy.default.svc` audience. In this example the scoped ServiceAccount token is obtained via a projected volume and mounted into the client container from where it can be consumed. The reasoning here is that scoped tokens cannot be used to impersonate an entity by re-using the token to perform a request against the Kubernetes API itself. | ||
|
||
The audience a token must be scoped to is configured within the kube-rbac-proxy using the `--auth-token-audiences` flag. | ||
```bash | ||
$ kubectl create -f deployment.yaml | ||
``` | ||
|
||
The content of this manifest is: | ||
|
||
[embedmd]:# (./deployment.yaml) | ||
```yaml | ||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: kube-rbac-proxy | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: kube-rbac-proxy | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: kube-rbac-proxy | ||
subjects: | ||
- kind: ServiceAccount | ||
name: kube-rbac-proxy | ||
namespace: default | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1 | ||
kind: ClusterRole | ||
metadata: | ||
name: kube-rbac-proxy | ||
rules: | ||
- apiGroups: ["authentication.k8s.io"] | ||
resources: | ||
- tokenreviews | ||
verbs: ["create"] | ||
- apiGroups: ["authorization.k8s.io"] | ||
resources: | ||
- subjectaccessreviews | ||
verbs: ["create"] | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
labels: | ||
app: kube-rbac-proxy | ||
name: kube-rbac-proxy | ||
spec: | ||
ports: | ||
- name: https | ||
port: 8443 | ||
targetPort: https | ||
selector: | ||
app: kube-rbac-proxy | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: kube-rbac-proxy | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: kube-rbac-proxy | ||
template: | ||
metadata: | ||
labels: | ||
app: kube-rbac-proxy | ||
spec: | ||
serviceAccountName: kube-rbac-proxy | ||
containers: | ||
- name: kube-rbac-proxy | ||
image: quay.io/brancz/kube-rbac-proxy:v0.4.1 | ||
args: | ||
- "--secure-listen-address=0.0.0.0:8443" | ||
- "--upstream=http://127.0.0.1:8081/" | ||
- "--auth-token-audiences=kube-rbac-proxy.default.svc" | ||
- "--logtostderr=true" | ||
- "--v=10" | ||
ports: | ||
- containerPort: 8443 | ||
name: https | ||
- name: prometheus-example-app | ||
image: quay.io/brancz/prometheus-example-app:v0.1.0 | ||
args: | ||
- "--bind=127.0.0.1:8081" | ||
``` | ||
|
||
Once the prometheus-example-app is up and running, we can test it. In order to test it, we deploy a Job, that performs a `curl` against the above deployment. Because it has the `/metrics` path in its `nonResourceURLs` it is allowed to access the endpoint. | ||
|
||
The Dockerfile of this container can be found [here](../example-client/Dockerfile). | ||
|
||
```bash | ||
$ kubectl create -f client-rbac.yaml client.yaml | ||
``` | ||
|
||
The content of this manifest is: | ||
|
||
[embedmd]:# (./client-rbac.yaml) | ||
```yaml | ||
apiVersion: rbac.authorization.k8s.io/v1beta1 | ||
kind: ClusterRole | ||
metadata: | ||
name: metrics | ||
rules: | ||
- nonResourceURLs: ["/metrics"] | ||
verbs: ["get"] | ||
--- | ||
apiVersion: rbac.authorization.k8s.io/v1beta1 | ||
kind: ClusterRoleBinding | ||
metadata: | ||
name: metrics | ||
roleRef: | ||
apiGroup: rbac.authorization.k8s.io | ||
kind: ClusterRole | ||
name: metrics | ||
subjects: | ||
- kind: ServiceAccount | ||
name: default | ||
namespace: default | ||
``` | ||
|
||
[embedmd]:# (./client.yaml) | ||
```yaml | ||
apiVersion: batch/v1 | ||
kind: Job | ||
metadata: | ||
name: krp-curl | ||
spec: | ||
template: | ||
metadata: | ||
name: krp-curl | ||
spec: | ||
restartPolicy: Never | ||
containers: | ||
- name: krp-curl | ||
image: quay.io/brancz/krp-curl:v0.0.1 | ||
command: | ||
- /bin/sh | ||
- -c | ||
- 'curl -v -s -k -H "Authorization: Bearer `cat /service-account/token`" https://kube-rbac-proxy.default.svc:8443/metrics' | ||
volumeMounts: | ||
- name: token-vol | ||
mountPath: "/service-account" | ||
readOnly: true | ||
volumes: | ||
- name: token-vol | ||
projected: | ||
sources: | ||
- serviceAccountToken: | ||
audience: kube-rbac-proxy.default.svc | ||
expirationSeconds: 3600 | ||
path: token | ||
backoffLimit: 4 | ||
``` | ||
|
||
We can look at the logs and we should get something similar to: | ||
|
||
``` | ||
* Trying 10.106.147.107... | ||
* TCP_NODELAY set | ||
* Connected to kube-rbac-proxy.default.svc (10.106.147.107) port 8443 (#0) | ||
* ALPN, offering http/1.1 | ||
* successfully set certificate verify locations: | ||
* CAfile: /etc/ssl/certs/ca-certificates.crt | ||
CApath: none | ||
* TLSv1.2 (OUT), TLS handshake, Client hello (1): | ||
} [242 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server hello (2): | ||
{ [49 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Certificate (11): | ||
{ [1649 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server key exchange (12): | ||
{ [300 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server finished (14): | ||
{ [4 bytes data] | ||
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16): | ||
} [37 bytes data] | ||
* TLSv1.2 (OUT), TLS change cipher, Client hello (1): | ||
} [1 bytes data] | ||
* TLSv1.2 (OUT), TLS handshake, Finished (20): | ||
} [16 bytes data] | ||
* TLSv1.2 (IN), TLS change cipher, Client hello (1): | ||
{ [1 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Finished (20): | ||
{ [16 bytes data] | ||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 | ||
* ALPN, server did not agree to a protocol | ||
* Server certificate: | ||
* subject: CN=kube-rbac-proxy-695b54f7ff-z54b7@1579943520 | ||
* start date: Jan 25 08:12:00 2020 GMT | ||
* expire date: Jan 24 08:12:00 2021 GMT | ||
* issuer: CN=kube-rbac-proxy-695b54f7ff-z54b7-ca@1579943520 | ||
* SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway. | ||
> GET /metrics HTTP/1.1 | ||
> Host: kube-rbac-proxy.default.svc:8443 | ||
> User-Agent: curl/7.61.0 | ||
> Accept: */* | ||
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InBtUmFFQnJIUzJXS1RuR3FmcmRkRDd3TEM2NUx3STZmb29DczRNRGwzLXcifQ.eyJhdWQiOlsia3ViZS1yYmFjLXByb3h5LmRlZmF1bHQuc3ZjIl0sImV4cCI6MTU3OTk0NzYxMiwiaWF0IjoxNTc5OTQ0MDEyLCJpc3MiOiJrdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJrcnAtY3VybC1nMjVweCIsInVpZCI6IjA3MWYxYzM1LWNmZWYtNGRhNy05ZjMxLWJiMmJkNmJmY2VmNyJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjRlYzFiOWU4LTdkZmItNDhiNi1hMjU0LWFiYTg4MGJhZGY5ZiJ9fSwibmJmIjoxNTc5OTQ0MDEyLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWZhdWx0In0.fM05SSlLzb5zMpTjYhn_H8Y0KFwX000VYqE8CMA3sP5lMAbXBInGSudbm_r_ppAMUYar6cmyAiSmIAD1bOR-DlzmJdX-LA5kgA3J9GAsrWBxXMlmASo1OfTjtOuQ98Y8tM6P-BCCe5rOAcx-ppmbPE_8Pu_7IkHjABURtClr6VUspsLfqsZ9GcN5pDBSR9iFt2Cl6m8YsbBXIDJ1kp9CknFt36s5Dg7OcTQR-WWkA21iZiOqayWGphW-DqpjEdm16XpjOqqDOf2qyFisjPhxNN-rivPJaCeoRb3GUIQVbvVShEgygzdM_8OqmZT3THeHBCdC_685Ffv3hFC4G6ijAQ | ||
> | ||
< HTTP/1.1 200 OK | ||
< Content-Type: text/plain; version=0.0.4 | ||
< Date: Sat, 25 Jan 2020 09:20:12 GMT | ||
< Content-Length: 102 | ||
< | ||
{ [102 bytes data] | ||
* Connection #0 to host kube-rbac-proxy.default.svc left intact | ||
# HELP version Version information about this binary | ||
# TYPE version gauge | ||
version{version="v0.1.0"} 0 | ||
``` | ||
|
||
Whereas if we didn't use a token that was created for the correct audience, for example the default ServiceAccount token mounted into containers, then we should not be able to authenticate with that token. This can be verified with: | ||
|
||
|
||
[embedmd]:# (./wrong-client.yaml) | ||
```yaml | ||
apiVersion: batch/v1 | ||
kind: Job | ||
metadata: | ||
name: krp-wrong-token-curl | ||
spec: | ||
template: | ||
metadata: | ||
name: krp-wrong-token-curl | ||
spec: | ||
restartPolicy: Never | ||
containers: | ||
- name: krp-curl | ||
image: quay.io/brancz/krp-curl:v0.0.1 | ||
``` | ||
|
||
Then the log output should look something along the lines of: | ||
|
||
``` | ||
* Trying 10.106.147.107... | ||
* TCP_NODELAY set | ||
* Connected to kube-rbac-proxy.default.svc (10.106.147.107) port 8443 (#0) | ||
* ALPN, offering http/1.1 | ||
* successfully set certificate verify locations: | ||
* CAfile: /etc/ssl/certs/ca-certificates.crt | ||
CApath: none | ||
* TLSv1.2 (OUT), TLS handshake, Client hello (1): | ||
} [242 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server hello (2): | ||
{ [49 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Certificate (11): | ||
{ [1649 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server key exchange (12): | ||
{ [300 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Server finished (14): | ||
{ [4 bytes data] | ||
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16): | ||
} [37 bytes data] | ||
* TLSv1.2 (OUT), TLS change cipher, Client hello (1): | ||
} [1 bytes data] | ||
* TLSv1.2 (OUT), TLS handshake, Finished (20): | ||
} [16 bytes data] | ||
* TLSv1.2 (IN), TLS change cipher, Client hello (1): | ||
{ [1 bytes data] | ||
* TLSv1.2 (IN), TLS handshake, Finished (20): | ||
{ [16 bytes data] | ||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 | ||
* ALPN, server did not agree to a protocol | ||
* Server certificate: | ||
* subject: CN=kube-rbac-proxy-695b54f7ff-z54b7@1579943520 | ||
* start date: Jan 25 08:12:00 2020 GMT | ||
* expire date: Jan 24 08:12:00 2021 GMT | ||
* issuer: CN=kube-rbac-proxy-695b54f7ff-z54b7-ca@1579943520 | ||
* SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway. | ||
> GET /metrics HTTP/1.1 | ||
> Host: kube-rbac-proxy.default.svc:8443 | ||
> User-Agent: curl/7.61.0 | ||
> Accept: */* | ||
> Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InBtUmFFQnJIUzJXS1RuR3FmcmRkRDd3TEM2NUx3STZmb29DczRNRGwzLXcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbWtienYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRlYzFiOWU4LTdkZmItNDhiNi1hMjU0LWFiYTg4MGJhZGY5ZiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.dWmmPOUTpIXve3svadwPd3a1PswkL8YC5JnPvul4EqQjcf-SLNSgp-TT4I2SqUTiNqwrehmdjjZdD925Erpdb8ZnrTTcaicmO6G95IvpwfMz3EvJY7A0anjjS_IOJpwoBN3RpgftGQcuFIaOc10xa5DC9TcS1-HouoyR-FdciqEOr3ZaOhr_em3W3MLqr6IMBTALz__rObKrb7kAUPNiBfy5fUhznbp2VgQeJYQRIxGQDOnn-_5bfFjsWjQAz098SknNAwOKtdy9BpRPwyrVybQ17i15DJcAP92aSIMP7dhYvDpuSvHBg5GhHNT3y5abd_o4ZXpWpSwqSpxAHqGE5g | ||
> | ||
< HTTP/1.1 401 Unauthorized | ||
< Content-Type: text/plain; charset=utf-8 | ||
< X-Content-Type-Options: nosniff | ||
< Date: Sat, 25 Jan 2020 09:21:16 GMT | ||
< Content-Length: 13 | ||
< | ||
{ [13 bytes data] | ||
* Connection #0 to host kube-rbac-proxy.default.svc left intact | ||
Unauthorized | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if this is used at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s from klog