😽
【Istio】TLS / Authentication / Authorizationまとめ
TLS設定
TLS Secretを用いたHTTPS設定
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
selector:
istio: ingressgateway # default istio gateway proxy
servers:
- port:
number: 80 # HTTP用
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com # DNSホスト(HTTP用)
- port:
number: 443 # HTTPS用
name: https
protocol: HTTPS
hosts:
- "bookinfo-namespace/*.bookinfo.com" # HTTPS ポート443用DNS
tls:
mode: SIMPLE # SIMPLE or MUTUAL
credentialName: bookinfo-secret # TLS証明書
SNI(複数ホストへのTLS)設定
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
selector:
istio: ingressgateway # default istio gateway proxy
servers:
- port:
number: 80 # HTTP用
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com # DNSホスト(HTTP用)
- port:
number: 443 # HTTPS用
name: https
protocol: HTTPS
hosts:
- "bookinfo-namespace/*.bookinfo.com" # HTTPS ポート443用DNS
tls:
mode: SIMPLE # SIMPLE or MUTUAL
credentialName: bookinfo-secret # TLS証明書
- port:
number: 443 # SNI用HTTPSポート443
name: https-sni
protocol: HTTPS
hosts:
- "bookinfo-namespace/*.bookinfo-to-sni.com" # DNS(SNI用)
tls:
mode: SIMPLE # SIMPLE or MUTUAL
credentialName: bookinfo-secret-to-sni # TLS証明書(SNI用)
SNI用ホストをVirtualServiceに追加
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-rule
namespace: default
spec:
hosts:
- "bookinfo-namespace/*.bookinfo.com" # HTTPS(メイン用)
- "bookinfo-namespace/*.bookinfo-to-sni.com" # HTTPS(SNI用)
gateways:
- default/my-gateway
http:
- match:
- uri:
prefix: /reviews/
route:
- destination:
port:
number: 80 # serviceポート
host: reviews.prod.svc.cluster.local
PeerAuthentication(Namespace限定)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: default # 相互TLSトラフィックのみ許容 相互TLSのためdefaultはブロック
spec:
mtls:
mode: STRICT
PeerAuthentication(Workload限定)
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: default # 相互TLSトラフィックのみ許容
spec:
selector:
matchLabels:
run: httpbin # ラベル(httpbin)がついているpodに限定される
mtls:
mode: STRICT
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin.default # ホスト
trafficPolicy:
tls:
mode: ISTIO_MUTUAL # 相互TLSのみ許可する
HTTPからHTTPSへのリダイレクト
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com # HTTPホスト
tls:
httpsRedirect: true # HTTPからHTTPSへリダイレクト
curl pod作成
$ kubectl run curl \
--restart Never \
--image curlimages/curl \
-n <namespace名> \
--dry-run -o yaml \
-- /bin/sh -c "sleep infinity" > curl_pod.yaml
httpbin pod作成
$ kubectl run httpbin \
--restart Never \
-n <namespace名> \
--image docker.io/kennethreitz/httpbin
httpbin pod公開
kubectl expose pod httpbin --port 80 -n <namespace名>
curl実行
$ kubectl exec -it curl -n <curl podのnamespace名> sh
$ curl httpbin.<httpbinのnamespace名>/headers -v
JWT認証
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: "jwt-example"
namespace: istio-system # Istioのroot namespaceに適用する
spec:
selector:
matchLabels:
app: ingressgateway # IngressGatewayに適用
jwtRules: # JWT必須化
- issuer: "testing@secure.istio.io"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.10/security/tools/jwt/samples/jwks.json"
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-jwt
namespace: istio-system # Istioのroot namespaceに適用する
spec:
selector:
matchLabels:
app: ingressgateway # IngressGatewayに適用
action: ALLOW
rules:
- from:
- source: # principalsがある場合、JWT有効(valid)
requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
JWT認証(HTTP PATH限定)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: jwt_path
namespace: istio-system # Istioのroot namespaceに適用する
spec:
selector:
matchLabels:
app: ingressgateway # IngressGatewayに適用
action: ALLOW
rules:
- from:
- source: # principalsがある場合、JWT有効(valid)
requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
to:
- operation:
paths: ["/headers"] # headersへのアクセスは、JWT認証必須
hosts: ["test.sni.com"] # test.sni.com/headersへのアクセスはJWT認証必須
HTTP header Attributeを用いたJWT認証
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: jwt_path
namespace: istio-system # Istioのroot namespaceに適用する
spec:
selector:
matchLabels:
app: ingressgateway # IngressGatewayに適用
action: ALLOW
rules:
- from:
- source: # principalsがある場合、JWT有効(valid)
requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
to:
- operation:
paths: ["/headers"] # headersへのアクセスは、JWT認証必須
hosts: ["test.sni.com"] # test.sni.com/headersへのアクセスはJWT認証必須
when:
- key: request.headers[x-token]
values: ["admin"] # headerのX-tokenがadminである必要あり
特定のIPアドレスに対して、JWT認証を有効化する
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: jwt_path
namespace: istio-system # Istioのroot namespaceに適用する
spec:
selector:
matchLabels:
app: ingressgateway # IngressGatewayに適用
action: ALLOW
rules:
- from:
- source:
ipBlocks: ["XX.XXX.X.XX"] # 指定したIPアドレスのみ、アクセス許可
ServiceEntry
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- api.dropboxapi.com # ServiceEntryに関連付けられているホスト
location: MESH_EXTERNAL # サービスを「メッシュの外部と見なす」か、「メッシュの一部と見なす」か
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS # 必須項目
タイムアウト設定
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local # k8sのService名(virtualservice.ymlと同じ)
- mesh # Gatewayに限らず、それぞれのEnvoy Proxyにもルールを適用する
http:
- timeout: 1s # 1秒以内にreturnしない場合、HTTPエラーコードが表示される
- route:
- destination:
host: reviews.prod.svc.cluster.local # k8sのService名(virtualservice.ymlと同じ)
subset: v1 # podにつけたlabel(負荷分散用)
weight: 25
- destination:
host: reviews.prod.svc.cluster.local # k8sのService名(virtualservice.ymlと同じ)
subset: v2
weight: 75
ServiceEntry HTTPS有効化
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- www.google.com # ServiceEntryに関連付けられているホスト
location: MESH_EXTERNAL # サービスを「メッシュの外部と見なす」か、「メッシュの一部と見なす」か
ports:
- number: 80
name: http-port
protocol: HTTP
- number: 443
name: https-port-for-tls-origination
protocol: HTTPS
resolution: DNS # 必須項目
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: google-com
spec:
host: www.google.com
subsets:
- name: tls-origination
trafficPolicy:
loadBalancer: # round robin / random / least connectionの3択
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE # SIMPLE or MUTUAL
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: google.com
spec:
hosts:
- "*.google.com"
http:
- match:
- port: 80
- route:
- destination:
host: www.google.com # ServiceEntryとDestinationRuleと関連付け
subset: tls-origination # DestinationRuleで定義
port:
number: 443
Discussion