mirror of https://github.com/istio/istio.io.git
511 lines
14 KiB
Bash
511 lines
14 KiB
Bash
#!/bin/bash
|
|
# shellcheck disable=SC2034,SC2153,SC2155,SC2164
|
|
|
|
# Copyright Istio Authors. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
####################################################################################################
|
|
# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE:
|
|
# docs/tasks/security/authentication/authn-policy/index.md
|
|
####################################################################################################
|
|
|
|
snip_before_you_begin_1() {
|
|
istioctl install --set profile=default
|
|
}
|
|
|
|
snip_setup_1() {
|
|
kubectl create ns foo
|
|
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n foo
|
|
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
|
|
kubectl create ns bar
|
|
kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n bar
|
|
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n bar
|
|
kubectl create ns legacy
|
|
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
|
|
kubectl apply -f samples/sleep/sleep.yaml -n legacy
|
|
}
|
|
|
|
snip_setup_2() {
|
|
kubectl exec "$(kubectl get pod -l app=sleep -n bar -o jsonpath={.items..metadata.name})" -c sleep -n bar -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_setup_2_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_setup_3() {
|
|
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl -s "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
|
}
|
|
|
|
! read -r -d '' snip_setup_3_out <<\ENDSNIP
|
|
sleep.foo to httpbin.foo: 200
|
|
sleep.foo to httpbin.bar: 200
|
|
sleep.foo to httpbin.legacy: 200
|
|
sleep.bar to httpbin.foo: 200
|
|
sleep.bar to httpbin.bar: 200
|
|
sleep.bar to httpbin.legacy: 200
|
|
sleep.legacy to httpbin.foo: 200
|
|
sleep.legacy to httpbin.bar: 200
|
|
sleep.legacy to httpbin.legacy: 200
|
|
ENDSNIP
|
|
|
|
snip_setup_4() {
|
|
kubectl get peerauthentication --all-namespaces
|
|
}
|
|
|
|
! read -r -d '' snip_setup_4_out <<\ENDSNIP
|
|
No resources found
|
|
ENDSNIP
|
|
|
|
snip_setup_5() {
|
|
kubectl get destinationrules.networking.istio.io --all-namespaces -o yaml | grep "host:"
|
|
}
|
|
|
|
! read -r -d '' snip_setup_5_out <<\ENDSNIP
|
|
|
|
ENDSNIP
|
|
|
|
snip_auto_mutual_tls_1() {
|
|
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl -s http://httpbin.foo:8000/headers -s | grep X-Forwarded-Client-Cert | sed 's/Hash=[a-z0-9]*;/Hash=<redacted>;/'
|
|
}
|
|
|
|
! read -r -d '' snip_auto_mutual_tls_1_out <<\ENDSNIP
|
|
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=<redacted>;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
|
|
ENDSNIP
|
|
|
|
snip_auto_mutual_tls_2() {
|
|
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
|
|
}
|
|
|
|
! read -r -d '' snip_auto_mutual_tls_2_out <<\ENDSNIP
|
|
|
|
ENDSNIP
|
|
|
|
snip_globally_enabling_istio_mutual_tls_in_strict_mode_1() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: PeerAuthentication
|
|
metadata:
|
|
name: "default"
|
|
namespace: "istio-system"
|
|
spec:
|
|
mtls:
|
|
mode: STRICT
|
|
EOF
|
|
}
|
|
|
|
snip_globally_enabling_istio_mutual_tls_in_strict_mode_2() {
|
|
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
|
}
|
|
|
|
! read -r -d '' snip_globally_enabling_istio_mutual_tls_in_strict_mode_2_out <<\ENDSNIP
|
|
sleep.foo to httpbin.foo: 200
|
|
sleep.foo to httpbin.bar: 200
|
|
sleep.foo to httpbin.legacy: 200
|
|
sleep.bar to httpbin.foo: 200
|
|
sleep.bar to httpbin.bar: 200
|
|
sleep.bar to httpbin.legacy: 200
|
|
sleep.legacy to httpbin.foo: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.bar: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.legacy: 200
|
|
ENDSNIP
|
|
|
|
snip_cleanup_part_1_1() {
|
|
kubectl delete peerauthentication -n istio-system default
|
|
}
|
|
|
|
snip_namespacewide_policy_1() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: PeerAuthentication
|
|
metadata:
|
|
name: "default"
|
|
namespace: "foo"
|
|
spec:
|
|
mtls:
|
|
mode: STRICT
|
|
EOF
|
|
}
|
|
|
|
snip_namespacewide_policy_2() {
|
|
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
|
}
|
|
|
|
! read -r -d '' snip_namespacewide_policy_2_out <<\ENDSNIP
|
|
sleep.foo to httpbin.foo: 200
|
|
sleep.foo to httpbin.bar: 200
|
|
sleep.foo to httpbin.legacy: 200
|
|
sleep.bar to httpbin.foo: 200
|
|
sleep.bar to httpbin.bar: 200
|
|
sleep.bar to httpbin.legacy: 200
|
|
sleep.legacy to httpbin.foo: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.bar: 200
|
|
sleep.legacy to httpbin.legacy: 200
|
|
ENDSNIP
|
|
|
|
snip_enable_mutual_tls_per_workload_1() {
|
|
cat <<EOF | kubectl apply -n bar -f -
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: PeerAuthentication
|
|
metadata:
|
|
name: "httpbin"
|
|
namespace: "bar"
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: httpbin
|
|
mtls:
|
|
mode: STRICT
|
|
EOF
|
|
}
|
|
|
|
snip_enable_mutual_tls_per_workload_2() {
|
|
cat <<EOF | kubectl apply -n bar -f -
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: DestinationRule
|
|
metadata:
|
|
name: "httpbin"
|
|
spec:
|
|
host: "httpbin.bar.svc.cluster.local"
|
|
trafficPolicy:
|
|
tls:
|
|
mode: ISTIO_MUTUAL
|
|
EOF
|
|
}
|
|
|
|
snip_enable_mutual_tls_per_workload_3() {
|
|
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
|
}
|
|
|
|
! read -r -d '' snip_enable_mutual_tls_per_workload_3_out <<\ENDSNIP
|
|
sleep.foo to httpbin.foo: 200
|
|
sleep.foo to httpbin.bar: 200
|
|
sleep.foo to httpbin.legacy: 200
|
|
sleep.bar to httpbin.foo: 200
|
|
sleep.bar to httpbin.bar: 200
|
|
sleep.bar to httpbin.legacy: 200
|
|
sleep.legacy to httpbin.foo: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.bar: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.legacy: 200
|
|
ENDSNIP
|
|
|
|
! read -r -d '' snip_enable_mutual_tls_per_workload_4 <<\ENDSNIP
|
|
...
|
|
sleep.legacy to httpbin.bar: 000
|
|
command terminated with exit code 56
|
|
ENDSNIP
|
|
|
|
snip_enable_mutual_tls_per_workload_5() {
|
|
cat <<EOF | kubectl apply -n bar -f -
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: PeerAuthentication
|
|
metadata:
|
|
name: "httpbin"
|
|
namespace: "bar"
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: httpbin
|
|
mtls:
|
|
mode: STRICT
|
|
portLevelMtls:
|
|
80:
|
|
mode: DISABLE
|
|
EOF
|
|
}
|
|
|
|
snip_enable_mutual_tls_per_workload_6() {
|
|
cat <<EOF | kubectl apply -n bar -f -
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: DestinationRule
|
|
metadata:
|
|
name: "httpbin"
|
|
spec:
|
|
host: httpbin.bar.svc.cluster.local
|
|
trafficPolicy:
|
|
tls:
|
|
mode: ISTIO_MUTUAL
|
|
portLevelSettings:
|
|
- port:
|
|
number: 8000
|
|
tls:
|
|
mode: DISABLE
|
|
EOF
|
|
}
|
|
|
|
snip_enable_mutual_tls_per_workload_7() {
|
|
for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/ip" -s -o /dev/null -w "sleep.${from} to httpbin.${to}: %{http_code}\n"; done; done
|
|
}
|
|
|
|
! read -r -d '' snip_enable_mutual_tls_per_workload_7_out <<\ENDSNIP
|
|
sleep.foo to httpbin.foo: 200
|
|
sleep.foo to httpbin.bar: 200
|
|
sleep.foo to httpbin.legacy: 200
|
|
sleep.bar to httpbin.foo: 200
|
|
sleep.bar to httpbin.bar: 200
|
|
sleep.bar to httpbin.legacy: 200
|
|
sleep.legacy to httpbin.foo: 000
|
|
command terminated with exit code 56
|
|
sleep.legacy to httpbin.bar: 200
|
|
sleep.legacy to httpbin.legacy: 200
|
|
ENDSNIP
|
|
|
|
snip_policy_precedence_1() {
|
|
cat <<EOF | kubectl apply -n foo -f -
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: PeerAuthentication
|
|
metadata:
|
|
name: "overwrite-example"
|
|
namespace: "foo"
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: httpbin
|
|
mtls:
|
|
mode: DISABLE
|
|
EOF
|
|
}
|
|
|
|
snip_policy_precedence_2() {
|
|
cat <<EOF | kubectl apply -n foo -f -
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: DestinationRule
|
|
metadata:
|
|
name: "overwrite-example"
|
|
spec:
|
|
host: httpbin.foo.svc.cluster.local
|
|
trafficPolicy:
|
|
tls:
|
|
mode: DISABLE
|
|
EOF
|
|
}
|
|
|
|
snip_policy_precedence_3() {
|
|
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -c sleep -n legacy -- curl http://httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_policy_precedence_3_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_cleanup_part_2_1() {
|
|
kubectl delete peerauthentication default overwrite-example -n foo
|
|
kubectl delete peerauthentication httpbin -n bar
|
|
kubectl delete destinationrules overwrite-example -n foo
|
|
kubectl delete destinationrules httpbin -n bar
|
|
}
|
|
|
|
snip_enduser_authentication_1() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: Gateway
|
|
metadata:
|
|
name: httpbin-gateway
|
|
namespace: foo
|
|
spec:
|
|
selector:
|
|
istio: ingressgateway # use Istio default gateway implementation
|
|
servers:
|
|
- port:
|
|
number: 80
|
|
name: http
|
|
protocol: HTTP
|
|
hosts:
|
|
- "*"
|
|
EOF
|
|
}
|
|
|
|
snip_enduser_authentication_2() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: networking.istio.io/v1alpha3
|
|
kind: VirtualService
|
|
metadata:
|
|
name: httpbin
|
|
namespace: foo
|
|
spec:
|
|
hosts:
|
|
- "*"
|
|
gateways:
|
|
- httpbin-gateway
|
|
http:
|
|
- route:
|
|
- destination:
|
|
port:
|
|
number: 8000
|
|
host: httpbin.foo.svc.cluster.local
|
|
EOF
|
|
}
|
|
|
|
snip_enduser_authentication_3() {
|
|
curl "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_enduser_authentication_3_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_enduser_authentication_4() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: RequestAuthentication
|
|
metadata:
|
|
name: "jwt-example"
|
|
namespace: istio-system
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
istio: ingressgateway
|
|
jwtRules:
|
|
- issuer: "testing@secure.istio.io"
|
|
jwksUri: "https://raw.githubusercontent.com/istio/istio/master/security/tools/jwt/samples/jwks.json"
|
|
EOF
|
|
}
|
|
|
|
snip_enduser_authentication_5() {
|
|
curl "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_enduser_authentication_5_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_enduser_authentication_6() {
|
|
curl --header "Authorization: Bearer deadbeef" "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_enduser_authentication_6_out <<\ENDSNIP
|
|
401
|
|
ENDSNIP
|
|
|
|
snip_enduser_authentication_7() {
|
|
TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/master/security/tools/jwt/samples/demo.jwt -s)
|
|
curl --header "Authorization: Bearer $TOKEN" "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_enduser_authentication_7_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_enduser_authentication_8() {
|
|
wget --no-verbose https://raw.githubusercontent.com/istio/istio/master/security/tools/jwt/samples/gen-jwt.py
|
|
}
|
|
|
|
snip_enduser_authentication_9() {
|
|
wget --no-verbose https://raw.githubusercontent.com/istio/istio/master/security/tools/jwt/samples/key.pem
|
|
}
|
|
|
|
snip_enduser_authentication_10() {
|
|
TOKEN=$(python3 ./gen-jwt.py ./key.pem --expire 5)
|
|
for i in $(seq 1 10); do curl --header "Authorization: Bearer $TOKEN" "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"; sleep 10; done
|
|
}
|
|
|
|
! read -r -d '' snip_enduser_authentication_10_out <<\ENDSNIP
|
|
200
|
|
200
|
|
200
|
|
200
|
|
200
|
|
200
|
|
200
|
|
401
|
|
401
|
|
401
|
|
ENDSNIP
|
|
|
|
snip_require_a_valid_token_1() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: AuthorizationPolicy
|
|
metadata:
|
|
name: "frontend-ingress"
|
|
namespace: istio-system
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
istio: ingressgateway
|
|
action: DENY
|
|
rules:
|
|
- from:
|
|
- source:
|
|
notRequestPrincipals: ["*"]
|
|
EOF
|
|
}
|
|
|
|
snip_require_a_valid_token_2() {
|
|
curl "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_require_a_valid_token_2_out <<\ENDSNIP
|
|
403
|
|
ENDSNIP
|
|
|
|
snip_require_valid_tokens_perpath_1() {
|
|
kubectl apply -f - <<EOF
|
|
apiVersion: security.istio.io/v1beta1
|
|
kind: AuthorizationPolicy
|
|
metadata:
|
|
name: "frontend-ingress"
|
|
namespace: istio-system
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
istio: ingressgateway
|
|
action: DENY
|
|
rules:
|
|
- from:
|
|
- source:
|
|
notRequestPrincipals: ["*"]
|
|
to:
|
|
- operation:
|
|
paths: ["/headers"]
|
|
EOF
|
|
}
|
|
|
|
snip_require_valid_tokens_perpath_2() {
|
|
curl "$INGRESS_HOST:$INGRESS_PORT/headers" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_require_valid_tokens_perpath_2_out <<\ENDSNIP
|
|
403
|
|
ENDSNIP
|
|
|
|
snip_require_valid_tokens_perpath_3() {
|
|
curl "$INGRESS_HOST:$INGRESS_PORT/ip" -s -o /dev/null -w "%{http_code}\n"
|
|
}
|
|
|
|
! read -r -d '' snip_require_valid_tokens_perpath_3_out <<\ENDSNIP
|
|
200
|
|
ENDSNIP
|
|
|
|
snip_cleanup_part_3_1() {
|
|
kubectl -n istio-system delete requestauthentication jwt-example
|
|
}
|
|
|
|
snip_cleanup_part_3_2() {
|
|
kubectl -n istio-system delete authorizationpolicy frontend-ingress
|
|
}
|
|
|
|
snip_cleanup_part_3_3() {
|
|
rm -f ./gen-jwt.py ./key.pem
|
|
}
|
|
|
|
snip_cleanup_part_3_4() {
|
|
kubectl delete ns foo bar legacy
|
|
}
|