Enable secret provider class if you haven't done so.
export RESOURCE_GROUP=istio-rg
export AKV_NAME=istio-kv-dev
export LOCATION=australiaeast
export CLUSTER=my-istio-cluster
az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
Grant all the role assignment to the user you're using so we can store the following into our keyvault.
Once you have enable it, please deploy the book sample application:
kubectl label namespace default istio.io/rev=asm-1-22
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.18/samples/bookinfo/platform/kube/bookinfo.yaml
Next create the relevant secret for your keyvault
az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-key --file bookinfo_certs/productpage.bookinfo.com.key
az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-crt --file bookinfo_certs/productpage.bookinfo.com.crt
az keyvault secret set --vault-name $AKV_NAME --name test-bookinfo-crt --file bookinfo_certs/bookinfo.com.crt
My secret provider class to extract certificate details looks like this (please provide your tenant id below). We are creating a tls secret and that is what istio expects to find when we configure its gateway below.
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: productpage-credential-spc
namespace: aks-istio-ingress
spec:
provider: azure
secretObjects:
- secretName: productpage-credential
type: tls
data:
- objectName: test-productpage-bookinfo-key
key: key
- objectName: test-productpage-bookinfo-crt
key: cert
parameters:
useVMManagedIdentity: "true"
userAssignedIdentityID: c113f45a-4300-451e-ba7b-d772ac16a988
keyvaultName: istio-kv-dev
cloudName: ""
objects: |
array:
- |
objectName: test-productpage-bookinfo-key
objectType: secret
objectAlias: "test-productpage-bookinfo-key"
- |
objectName: test-productpage-bookinfo-crt
objectType: secret
objectAlias: "test-productpage-bookinfo-crt"
tenantId: provide-your-tenant-id
And after that we can see the secrets being created -
Proceed to apply the following yaml to configure tls to your istio gateway.
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: aks-istio-ingressgateway-external
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: productpage-credential
hosts:
- productpage.bookinfo.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: productpage-vs
spec:
hosts:
- productpage.bookinfo.com
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
port:
number: 9080
host: productpage
Then look at the output here:-
To validate run the following command
curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"
And you will get the following outputs
Configuring mutual TLS.
Run the following command to remove secret and resources earlier
kubectl delete secretproviderclass productpage-credential-spc -n aks-istio-ingress
kubectl delete secret/productpage-credential -n aks-istio-ingress
kubectl delete pod/secrets-store-sync-productpage -n aks-istio-ingress
Then reconfigure using the following yamls
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: productpage-credential-spc
namespace: aks-istio-ingress
spec:
provider: azure
secretObjects:
- secretName: productpage-credential
type: opaque
data:
- objectName: test-productpage-bookinfo-key
key: tls.key
- objectName: test-productpage-bookinfo-crt
key: tls.crt
- objectName: test-bookinfo-crt
key: ca.crt
parameters:
useVMManagedIdentity: "true"
userAssignedIdentityID: c113f45a-4300-451e-ba7b-d772ac16a988
keyvaultName: istio-kv-dev
cloudName: ""
objects: |
array:
- |
objectName: test-productpage-bookinfo-key
objectType: secret
objectAlias: "test-productpage-bookinfo-key"
- |
objectName: test-productpage-bookinfo-crt
objectType: secret
objectAlias: "test-productpage-bookinfo-crt"
- |
objectName: test-bookinfo-crt
objectType: secret
objectAlias: "test-bookinfo-crt"
tenantId: your-tenant-id
Notice that we're passing test-bookinfo-crt
- objectName: test-bookinfo-crt
key: ca.crt
Let's check out our secrets by running the following command:
kubectl describe secret/productpage-credential -n aks-istio-ingress
Let's update our gateway to include support mutual tls.
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: aks-istio-ingressgateway-external # use istio default ingress gateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: MUTUAL
credentialName: productpage-credential # must be the same as secret
hosts:
- productpage.bookinfo.com
And if we were to hit its endpoint without providing client certificate, then it will fail
curl -v -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage"
If we pass in client certificate like so,
curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt --cert bookinfo_certs/client.bookinfo.com.crt --key bookinfo_certs/client.bookinfo.com.key "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"
Then it will pass
Can we have more than one client certificate configure for your gateway?
https://medium.com/microsoftazure/certificate-pinning-for-mtls-authentication-at-the-istio-ingress-gateway-978ed31699ab#:~:text=Conclusion,level%20of%20trust%20as%20needed.
Comments