Security Problems
End-user authentication fails
With Istio, you can enable authentication for end users through request authentication policies. Follow these steps to troubleshoot the policy specification.
If
jwksUri
isn’t set, make sure the JWT issuer is of url format andurl + /.well-known/openid-configuration
can be opened in browser; for example, if the JWT issuer ishttps://accounts.google.com
, make surehttps://accounts.google.com/.well-known/openid-configuration
is a valid url and can be opened in a browser.If the JWT token is placed in the Authorization header in http requests, make sure the JWT token is valid (not expired, etc). The fields in a JWT token can be decoded by using online JWT parsing tools, e.g., jwt.io4.
Verify the Envoy proxy configuration of the target workload using
istioctl proxy-config
command.With the example policy above applied, use the following command to check the
listener
configuration on the inbound port80
. You should seeenvoy.filters.http.jwt_authn
filter with settings matching the issuer and JWKS as specified in the policy.
Authorization is too restrictive or permissive
Make sure there are no typos in the policy YAML file
One common mistake is specifying multiple items unintentionally in the YAML. Take the following policy as an example:
You may expect the policy to allow requests if the path is /foo
and the source namespace is foo
.
However, the policy actually allows requests if the path is /foo
or the source namespace is foo
, which is
more permissive.
In the YAML syntax, the -
in front of the from:
means it’s a new element in the list. This creates 2 rules in the
policy instead of 1. In authorization policy, multiple rules have the semantics of OR
.
To fix the problem, just remove the extra -
to make the policy have only 1 rule that allows requests if the
path is /foo
and the source namespace is foo
, which is more restrictive.
Make sure you are NOT using HTTP-only fields on TCP ports
The authorization policy will be more restrictive because HTTP-only fields (e.g. host
, path
, headers
, JWT, etc.)
do not exist in the raw TCP connections.
In the case of ALLOW
policy, these fields are never matched. In the case of DENY
and CUSTOM
action, these fields
are considered always matched. The final effect is a more restrictive policy that could cause unexpected denies.
Check the Kubernetes service definition to verify that the port is named with the correct protocol properly.
If you are using HTTP-only fields on the port, make sure the port name has the http-
prefix.
Make sure the policy is applied to the correct target
Check the workload selector and namespace to confirm it’s applied to the correct targets. You can determine the
authorization policy in effect by running istioctl x authz check POD-NAME.POD-NAMESPACE
.
Pay attention to the action specified in the policy
If not specified, the policy defaults to use action
ALLOW
.When a workload has multiple actions (
CUSTOM
,ALLOW
andDENY
) applied at the same time, all actions must be satisfied to allow a request. In other words, a request is denied if any of the action denies and is allowed only if all actions allow.The
AUDIT
action does not enforce access control and will not deny the request at any cases.
Read authorization implicit enablement for more details of the evaluation order.
Ensure Istiod accepts the policies
Istiod converts and distributes your authorization policies to the proxies. The following steps help you ensure Istiod is working as expected:
Run the following command to enable the debug logging in istiod:
Get the Istiod log with the following command:
Check the output and verify there are no errors. For example, you might see something similar to the following:
This shows that Istiod generated:
An HTTP filter config with policy
ns[foo]-policy[deny-path-headers]-rule[0]
for workloadhttpbin-74fb669cc6-lpscm.foo
.A TCP filter config with policy
ns[foo]-policy[deny-path-headers]-rule[0]
for workloadhttpbin-74fb669cc6-lpscm.foo
.
Ensure Istiod distributes policies to proxies correctly
Istiod distributes the authorization policies to proxies. The following steps help you ensure istiod is working as expected:
Run the following command to get the proxy configuration dump for the
httpbin
workload:Check the log and verify:
- The log includes an
envoy.filters.http.rbac
filter to enforce the authorization policy on each incoming request. - Istio updates the filter accordingly after you update your authorization policy.
- The log includes an
The following output means the proxy of
httpbin
has enabled theenvoy.filters.http.rbac
filter with rules that rejects anyone to access path/headers
.
Ensure proxies enforce policies correctly
Proxies eventually enforce the authorization policies. The following steps help you ensure the proxy is working as expected:
Turn on the authorization debug logging in proxy with the following command:
Verify you see the following output:
Send some requests to the
httpbin
workload to generate some logs.Print the proxy logs with the following command:
Check the output and verify:
The output log shows either
enforced allowed
orenforced denied
depending on whether the request was allowed or denied respectively.Your authorization policy expects the data extracted from the request.
The following is an example output for a request at path
/httpbin
:The log
enforced denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
means the request is rejected by the policyns[foo]-policy[deny-path-headers]-rule[0]
.The following is an example output for authorization policy in the dry-run mode5:
The log
shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
means the request would be rejected by the dry-run policyns[foo]-policy[deny-path-headers]-rule[0]
.The log
no engine, allowed by default
means the request is actually allowed because the dry-run policy is the only policy on the workload.
Keys and certificates errors
If you suspect that some of the keys and/or certificates used by Istio aren’t correct, you can inspect the contents from any pod:
By passing the -o json
flag, you can pass the full certificate content to openssl
to analyze its contents:
Make sure the displayed certificate contains valid information. In particular, the Subject Alternative Name
field should be URI:spiffe://cluster.local/ns/my-ns/sa/my-sa
.
Mutual TLS errors
If you suspect problems with mutual TLS, first ensure that Citadel is healthy, and second ensure that keys and certificates are being delivered to sidecars properly.
If everything appears to be working so far, the next step is to verify that the right authentication policy6 is applied and the right destination rules are in place.
If you suspect the client side sidecar may send mutual TLS or plaintext traffic incorrectly, check the Grafana Workload dashboard7. The outbound requests are annotated whether mTLS is used or not. After checking this if you believe the client sidecars are misbehaved, report an issue on GitHub.