セキュリティの問題
エンドユーザー認証が失敗する
Istioを使用すると、リクエスト認証ポリシーを通じてエンドユーザーの認証を有効にできます。ポリシーの仕様のトラブルシューティングを行うには、次の手順に従ってください。
jwksUri
が設定されていない場合は、JWT発行者がURL形式であり、url + /.well-known/openid-configuration
をブラウザで開くことができることを確認してください。たとえば、JWT発行者がhttps://#
の場合、https://#/.well-known/openid-configuration
が有効なURLであり、ブラウザで開くことができることを確認してください。apiVersion: security.istio.io/v1 kind: RequestAuthentication metadata: name: "example-3" spec: selector: matchLabels: app: httpbin jwtRules: - issuer: "testing@secure.istio.io" jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.24/security/tools/jwt/samples/jwks.json"
JWTトークンがHTTPリクエストのAuthorizationヘッダーに配置されている場合は、JWTトークンが有効であることを確認してください(期限切れなど)。JWTトークンのフィールドは、jwt.ioなどのオンラインJWT解析ツールを使用してデコードできます。jwt.io
istioctl proxy-config
コマンドを使用して、ターゲットワークロードのEnvoyプロキシ設定を確認してください。上記の例に従ってポリシーを適用した後、次のコマンドを使用して、インバウンドポート80の
listener
設定を確認します。ポリシーで指定された発行者とJWKSと一致する設定を持つenvoy.filters.http.jwt_authn
フィルターが表示されるはずです。$ POD=$(kubectl get pod -l app=httpbin -n foo -o jsonpath={.items..metadata.name}) $ istioctl proxy-config listener ${POD} -n foo --port 80 --type HTTP -o json <redacted> { "name": "envoy.filters.http.jwt_authn", "typedConfig": { "@type": "type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication", "providers": { "origins-0": { "issuer": "testing@secure.istio.io", "localJwks": { "inlineString": "*redacted*" }, "payloadInMetadata": "testing@secure.istio.io" } }, "rules": [ { "match": { "prefix": "/" }, "requires": { "requiresAny": { "requirements": [ { "providerName": "origins-0" }, { "allowMissing": {} } ] } } } ] } }, <redacted>
認可が厳しすぎるか、緩すぎる
ポリシーYAMLファイルにタイプミスがないことを確認してください
よくある間違いの1つは、YAMLで意図せずに複数の項目を指定することです。次のポリシーを例として示します
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: example
namespace: foo
spec:
action: ALLOW
rules:
- to:
- operation:
paths:
- /foo
- from:
- source:
namespaces:
- foo
パスが/foo
**かつ**ソース名前空間がfoo
の場合、ポリシーによってリクエストが許可されると予想されるかもしれません。しかし、実際には、パスが/foo
**または**ソース名前空間がfoo
の場合にリクエストが許可されます。これはより緩やかな条件です。
YAML構文では、from:
の前にある-
は、リスト内の新しい要素であることを意味します。これにより、ポリシーに1つのルールではなく2つのルールが作成されます。認可ポリシーでは、複数のルールはOR
のセマンティクスを持ちます。
この問題を解決するには、余分な-
を削除して、パスが/foo
**かつ**ソース名前空間がfoo
の場合にリクエストを許可するルールが1つだけになるようにポリシーを変更します。これはより厳しい条件です。
TCPポートでHTTP専用フィールドを使用していないことを確認してください
HTTP専用フィールド(例:host
、path
、headers
、JWTなど)は生のTCP接続には存在しないため、認可ポリシーはより厳しくなります。
ALLOW
ポリシーの場合、これらのフィールドは一致しません。DENY
とCUSTOM
アクションの場合、これらのフィールドは常に一致すると見なされます。最終的な効果は、予期しない拒否を引き起こす可能性のある、より厳格なポリシーになります。
ポートが正しいプロトコルで適切に名前付けされていることを確認するために、Kubernetesサービス定義を確認してください。HTTP専用フィールドをポートで使用している場合は、ポート名にhttp-
プレフィックスが付いていることを確認してください。
ポリシーが正しいターゲットに適用されていることを確認してください
ワークロードセレクターと名前空間を確認して、正しいターゲットに適用されていることを確認してください。有効な認可ポリシーを確認するには、istioctl x authz check POD-NAME.POD-NAMESPACE
を実行します。
ポリシーで指定されたアクションに注意してください
指定されていない場合、ポリシーはデフォルトで
ALLOW
アクションを使用します。ワークロードに複数のアクション(
CUSTOM
、ALLOW
、DENY
)が同時に適用されている場合、リクエストを許可するにはすべてのアクションを満たす必要があります。言い換えれば、いずれかのアクションが拒否した場合、リクエストは拒否され、すべてのアクションが許可した場合のみ許可されます。AUDIT
アクションはアクセス制御を強制せず、いずれの場合もリクエストを拒否しません。
評価順序の詳細については、認可の暗黙的な有効化を参照してください。
Istiodがポリシーを受け入れることを確認してください
Istiodは認可ポリシーを変換してプロキシに配布します。次の手順は、Istiodが期待通りに動作していることを確認するのに役立ちます。
次のコマンドを実行して、Istiodのデバッグログを有効にします。
$ istioctl admin log --level authorization:debug
次のコマンドでIstiodログを取得します。
$ kubectl logs $(kubectl -n istio-system get pods -l app=istiod -o jsonpath='{.items[0].metadata.name}') -c discovery -n istio-system
出力を確認し、エラーがないことを確認します。たとえば、次のようなものが見られる場合があります。
2021-04-23T20:53:29.507314Z info ads Push debounce stable[31] 1: 100.981865ms since last change, 100.981653ms since last push, full=true 2021-04-23T20:53:29.507641Z info ads XDS: Pushing:2021-04-23T20:53:29Z/23 Services:15 ConnectedEndpoints:2 Version:2021-04-23T20:53:29Z/23 2021-04-23T20:53:29.507911Z debug authorization Processed authorization policy for httpbin-74fb669cc6-lpscm.foo with details: * found 0 CUSTOM actions 2021-04-23T20:53:29.508077Z debug authorization Processed authorization policy for curl-557747455f-6dxbl.foo with details: * found 0 CUSTOM actions 2021-04-23T20:53:29.508128Z debug authorization Processed authorization policy for httpbin-74fb669cc6-lpscm.foo with details: * found 1 DENY actions, 0 ALLOW actions, 0 AUDIT actions * generated config from rule ns[foo]-policy[deny-path-headers]-rule[0] on HTTP filter chain successfully * built 1 HTTP filters for DENY action * added 1 HTTP filters to filter chain 0 * added 1 HTTP filters to filter chain 1 2021-04-23T20:53:29.508158Z debug authorization Processed authorization policy for curl-557747455f-6dxbl.foo with details: * found 0 DENY actions, 0 ALLOW actions, 0 AUDIT actions 2021-04-23T20:53:29.509097Z debug authorization Processed authorization policy for curl-557747455f-6dxbl.foo with details: * found 0 CUSTOM actions 2021-04-23T20:53:29.509167Z debug authorization Processed authorization policy for curl-557747455f-6dxbl.foo with details: * found 0 DENY actions, 0 ALLOW actions, 0 AUDIT actions 2021-04-23T20:53:29.509501Z debug authorization Processed authorization policy for httpbin-74fb669cc6-lpscm.foo with details: * found 0 CUSTOM actions 2021-04-23T20:53:29.509652Z debug authorization Processed authorization policy for httpbin-74fb669cc6-lpscm.foo with details: * found 1 DENY actions, 0 ALLOW actions, 0 AUDIT actions * generated config from rule ns[foo]-policy[deny-path-headers]-rule[0] on HTTP filter chain successfully * built 1 HTTP filters for DENY action * added 1 HTTP filters to filter chain 0 * added 1 HTTP filters to filter chain 1 * generated config from rule ns[foo]-policy[deny-path-headers]-rule[0] on TCP filter chain successfully * built 1 TCP filters for DENY action * added 1 TCP filters to filter chain 2 * added 1 TCP filters to filter chain 3 * added 1 TCP filters to filter chain 4 2021-04-23T20:53:29.510903Z info ads LDS: PUSH for node:curl-557747455f-6dxbl.foo resources:18 size:85.0kB 2021-04-23T20:53:29.511487Z info ads LDS: PUSH for node:httpbin-74fb669cc6-lpscm.foo resources:18 size:86.4kB
これは、Istiodが生成したことを示しています。
ワークロード
httpbin-74fb669cc6-lpscm.foo
に対するポリシーns[foo]-policy[deny-path-headers]-rule[0]
を持つHTTPフィルター構成。ワークロード
httpbin-74fb669cc6-lpscm.foo
に対するポリシーns[foo]-policy[deny-path-headers]-rule[0]
を持つTCPフィルター構成。
Istiodがプロキシにポリシーを正しく配布することを確認してください
Istiodは認可ポリシーをプロキシに配布します。次の手順は、istiodが期待通りに動作していることを確認するのに役立ちます。
次のコマンドを実行して、
httpbin
ワークロードのプロキシ構成ダンプを取得します。$ kubectl exec $(kubectl get pods -l app=httpbin -o jsonpath='{.items[0].metadata.name}') -c istio-proxy -- pilot-agent request GET config_dump
ログを確認して確認します。
- ログには、受信リクエストごとに認可ポリシーを適用する
envoy.filters.http.rbac
フィルターが含まれています。 - 認可ポリシーを更新した後、Istioはそれに応じてフィルターを更新します。
- ログには、受信リクエストごとに認可ポリシーを適用する
次の出力は、
httpbin
のプロキシが、パス/headers
へのアクセスを拒否するルールを持つenvoy.filters.http.rbac
フィルターを有効にしていることを意味します。{ "name": "envoy.filters.http.rbac", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", "rules": { "action": "DENY", "policies": { "ns[foo]-policy[deny-path-headers]-rule[0]": { "permissions": [ { "and_rules": { "rules": [ { "or_rules": { "rules": [ { "url_path": { "path": { "exact": "/headers" } } } ] } } ] } } ], "principals": [ { "and_ids": { "ids": [ { "any": true } ] } } ] } } }, "shadow_rules_stat_prefix": "istio_dry_run_allow_" } },
プロキシがポリシーを正しく適用することを確認してください
プロキシは最終的に認可ポリシーを適用します。次の手順は、プロキシが期待通りに動作していることを確認するのに役立ちます。
次のコマンドを使用して、プロキシで認可デバッグログを有効にします。
$ istioctl proxy-config log deploy/httpbin --level "rbac:debug"
次の出力があることを確認してください。
active loggers: ... ... rbac: debug ... ...
いくつかのリクエストを
httpbin
ワークロードに送信して、いくつかのログを生成します。次のコマンドでプロキシログを出力します。
$ kubectl logs $(kubectl get pods -l app=httpbin -o jsonpath='{.items[0].metadata.name}') -c istio-proxy
出力を確認して確認します。
出力ログには、リクエストが許可されたか拒否されたかによって、それぞれ
enforced allowed
またはenforced denied
が表示されます。認可ポリシーは、リクエストから抽出されたデータが必要です。
パス
/httpbin
のリクエストの出力例を次に示します。... 2021-04-23T20:43:18.552857Z debug envoy rbac checking request: requestedServerName: outbound_.8000_._.httpbin.foo.svc.cluster.local, sourceIP: 10.44.3.13:46180, directRemoteIP: 10.44.3.13:46180, remoteIP: 10.44.3.13:46180,localAddress: 10.44.1.18:80, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/foo/sa/curl, dnsSanPeerCertificate: , subjectPeerCertificate: , headers: ':authority', 'httpbin:8000' ':path', '/headers' ':method', 'GET' ':scheme', 'http' 'user-agent', 'curl/7.76.1-DEV' 'accept', '*/*' 'x-forwarded-proto', 'http' 'x-request-id', '672c9166-738c-4865-b541-128259cc65e5' 'x-envoy-attempt-count', '1' 'x-b3-traceid', '8a124905edf4291a21df326729b264e9' 'x-b3-spanid', '21df326729b264e9' 'x-b3-sampled', '0' 'x-forwarded-client-cert', 'By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=d64cd6750a3af8685defbbe4dd8c467ebe80f6be4bfe9ca718e81cd94129fc1d;Subject="";URI=spiffe://cluster.local/ns/foo/sa/curl' , dynamicMetadata: filter_metadata { key: "istio_authn" value { fields { key: "request.auth.principal" value { string_value: "cluster.local/ns/foo/sa/curl" } } fields { key: "source.namespace" value { string_value: "foo" } } fields { key: "source.principal" value { string_value: "cluster.local/ns/foo/sa/curl" } } fields { key: "source.user" value { string_value: "cluster.local/ns/foo/sa/curl" } } } } 2021-04-23T20:43:18.552910Z debug envoy rbac enforced denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0] ...
ログ
enforced denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
は、リクエストがポリシーns[foo]-policy[deny-path-headers]-rule[0]
によって拒否されたことを意味します。ドライランモードの認可ポリシーの出力例を次に示します。
... 2021-04-23T20:59:11.838468Z debug envoy rbac checking request: requestedServerName: outbound_.8000_._.httpbin.foo.svc.cluster.local, sourceIP: 10.44.3.13:49826, directRemoteIP: 10.44.3.13:49826, remoteIP: 10.44.3.13:49826,localAddress: 10.44.1.18:80, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/foo/sa/curl, dnsSanPeerCertificate: , subjectPeerCertificate: , headers: ':authority', 'httpbin:8000' ':path', '/headers' ':method', 'GET' ':scheme', 'http' 'user-agent', 'curl/7.76.1-DEV' 'accept', '*/*' 'x-forwarded-proto', 'http' 'x-request-id', 'e7b2fdb0-d2ea-4782-987c-7845939e6313' 'x-envoy-attempt-count', '1' 'x-b3-traceid', '696607fc4382b50017c1f7017054c751' 'x-b3-spanid', '17c1f7017054c751' 'x-b3-sampled', '0' 'x-forwarded-client-cert', 'By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=d64cd6750a3af8685defbbe4dd8c467ebe80f6be4bfe9ca718e81cd94129fc1d;Subject="";URI=spiffe://cluster.local/ns/foo/sa/curl' , dynamicMetadata: filter_metadata { key: "istio_authn" value { fields { key: "request.auth.principal" value { string_value: "cluster.local/ns/foo/sa/curl" } } fields { key: "source.namespace" value { string_value: "foo" } } fields { key: "source.principal" value { string_value: "cluster.local/ns/foo/sa/curl" } } fields { key: "source.user" value { string_value: "cluster.local/ns/foo/sa/curl" } } } } 2021-04-23T20:59:11.838529Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0] 2021-04-23T20:59:11.838538Z debug envoy rbac no engine, allowed by default ...
ログ
shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
は、リクエストが**ドライラン**ポリシーns[foo]-policy[deny-path-headers]-rule[0]
によって拒否されることを意味します。ログ
no engine, allowed by default
は、ドライランポリシーがワークロードの唯一のポリシーであるため、リクエストが実際に許可されていることを意味します。
キーと証明書のエラー
Istioで使用されているキーや証明書の一部が正しくないと思われる場合は、任意のpodから内容を確認できます。
$ istioctl proxy-config secret curl-8f795f47d-4s4t7
RESOURCE NAME TYPE STATUS VALID CERT SERIAL NUMBER NOT AFTER NOT BEFORE
default Cert Chain ACTIVE true 138092480869518152837211547060273851586 2020-11-11T16:39:48Z 2020-11-10T16:39:48Z
ROOTCA CA ACTIVE true 288553090258624301170355571152070165215 2030-11-08T16:34:52Z 2020-11-10T16:34:52Z
-o json
フラグを渡すことで、完全な証明書の内容をopenssl
に渡して内容を分析できます。
$ istioctl proxy-config secret curl-8f795f47d-4s4t7 -o json | jq '[.dynamicActiveSecrets[] | select(.name == "default")][0].secret.tlsCertificate.certificateChain.inlineBytes' -r | base64 -d | openssl x509 -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
99:59:6b:a2:5a:f4:20:f4:03:d7:f0:bc:59:f5:d8:40
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = k8s.cluster.local
Validity
Not Before: Jun 4 20:38:20 2018 GMT
Not After : Sep 2 20:38:20 2018 GMT
...
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
URI:spiffe://cluster.local/ns/my-ns/sa/my-sa
...
表示された証明書に有効な情報が含まれていることを確認してください。特に、Subject Alternative Name
フィールドはURI:spiffe://cluster.local/ns/my-ns/sa/my-sa
である必要があります。
相互TLSエラー
相互TLSに問題があると思われる場合は、まずIstiodが正常に動作していることを確認し、次にキーと証明書がサイドカーに正しく配信されていることを確認してください。
ここまですべて正常に動作していると思われる場合は、次に、正しい認証ポリシーが適用され、正しい宛先ルールが設定されていることを確認します。
クライアント側のサイドカーが相互TLSまたはプレーンテキストトラフィックを誤って送信する可能性があると思われる場合は、Grafanaワークロードダッシュボードを確認してください。アウトバウンドリクエストには、mTLSが使用されているかどうかが注釈付きで示されます。これを確認した後、クライアント側のサイドカーが誤動作していると判断した場合は、GitHubで問題を報告してください。