Beveiligde toegangsgateway voor invoegtoepassing voor Istio-service-mesh voor Azure Kubernetes Service
In het artikel Externe of interne Istio Inkomend verkeer implementeren wordt beschreven hoe u een toegangsgateway configureert om een HTTP-service beschikbaar te maken voor extern/intern verkeer. In dit artikel wordt beschreven hoe u een beveiligde HTTPS-service beschikbaar maakt met behulp van eenvoudige of wederzijdse TLS.
Vereisten
Schakel de Istio-invoegtoepassing in op het cluster volgens de documentatie
Een externe Istio-ingangsgateway implementeren volgens de documentatie
Notitie
Dit artikel verwijst naar de externe ingangsgateway voor demonstratie. Dezelfde stappen zijn van toepassing op het configureren van wederzijdse TLS voor interne toegangsgateway.
Vereiste client-/servercertificaten en -sleutels
Voor dit artikel zijn verschillende certificaten en sleutels vereist. U kunt uw favoriete hulpprogramma gebruiken om ze te maken of u kunt de volgende openssl-opdrachten gebruiken.
Maak een basiscertificaat en een persoonlijke sleutel voor het ondertekenen van de certificaten voor voorbeeldservices:
mkdir bookinfo_certs openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=bookinfo Inc./CN=bookinfo.com' -keyout bookinfo_certs/bookinfo.com.key -out bookinfo_certs/bookinfo.com.crt
Genereer een certificaat en een persoonlijke sleutel voor
productpage.bookinfo.com
:openssl req -out bookinfo_certs/productpage.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/productpage.bookinfo.com.key -subj "/CN=productpage.bookinfo.com/O=product organization" openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 0 -in bookinfo_certs/productpage.bookinfo.com.csr -out bookinfo_certs/productpage.bookinfo.com.crt
Genereer een clientcertificaat en een persoonlijke sleutel:
openssl req -out bookinfo_certs/client.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/client.bookinfo.com.key -subj "/CN=client.bookinfo.com/O=client organization" openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 1 -in bookinfo_certs/client.bookinfo.com.csr -out bookinfo_certs/client.bookinfo.com.crt
Een TLS-ingangsgateway configureren
Maak een Kubernetes TLS-geheim voor de toegangsbeheergateway; Gebruik Azure Key Vault om certificaten/sleutels en azure Key Vault Secrets Provider-invoegtoepassing te hosten om geheimen te synchroniseren met het cluster.
Azure Key Vault instellen en geheimen synchroniseren met het cluster
Azure Key Vault maken
U hebt een Azure Key Vault-resource nodig om het certificaat en de sleutelinvoer op te geven aan de Istio-invoegtoepassing.
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
Schakel de Azure Key Vault-provider in voor de invoegtoepassing CSI-stuurprogramma secret store in uw cluster.
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
Autoriseren van de door de gebruiker toegewezen beheerde identiteit van de invoegtoepassing voor toegang tot Azure Key Vault-resource met behulp van toegangsbeleid. Als uw Key Vault Azure RBAC gebruikt voor het machtigingsmodel, volgt u de instructies hier om een Azure-rol van Key Vault toe te wijzen voor de door de gebruiker toegewezen beheerde identiteit van de invoegtoepassing.
OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId') az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
Geheimen maken in Azure Key Vault met behulp van de certificaten en sleutels.
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
Gebruik het volgende manifest om SecretProviderClass te implementeren om azure Key Vault-specifieke parameters op te geven voor het CSI-stuurprogramma.
cat <<EOF | kubectl apply -f - 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: $CLIENT_ID keyvaultName: $AKV_NAME 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: $TENANT_ID EOF
Gebruik het volgende manifest om een voorbeeldpod te implementeren. Het CSI-stuurprogramma voor het geheimarchief vereist een pod om te verwijzen naar de SecretProviderClass-resource om ervoor te zorgen dat geheimen worden gesynchroniseerd van Azure Key Vault naar het cluster.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-productpage namespace: aks-istio-ingress spec: containers: - name: busybox image: mcr.microsoft.com/oss/busybox/busybox:1.33.1 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "productpage-credential-spc" EOF
Controleer of
productpage-credential
het geheim dat is gemaakt in de clusternaamruimteaks-istio-ingress
, zoals gedefinieerd in de SecretProviderClass-resource.kubectl describe secret/productpage-credential -n aks-istio-ingress
Voorbeelduitvoer:
Name: productpage-credential Namespace: aks-istio-ingress Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: tls Data ==== cert: 1066 bytes key: 1704 bytes
Toegangsbeheerobjectgateway en virtuele service configureren
Routeer HTTPS-verkeer via de Ingress-gateway van Istio naar de voorbeeldtoepassingen. Gebruik het volgende manifest om gateway- en virtuele-servicebronnen te implementeren.
cat <<EOF | kubectl apply -f -
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
EOF
Notitie
In de gatewaydefinitie credentialName
moet deze overeenkomen met de secretName
in SecretProviderClass-resource en selector
moet deze verwijzen naar de externe ingangsgateway op basis van het label, waarin de sleutel van het label is istio
en de waarde is aks-istio-ingressgateway-external
. Voor intern inkomend gatewaylabel is istio
en de waarde is aks-istio-ingressgateway-internal
.
Omgevingsvariabelen instellen voor externe ingangshost en poorten:
export INGRESS_HOST_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export SECURE_INGRESS_PORT_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
export SECURE_GATEWAY_URL_EXTERNAL=$INGRESS_HOST_EXTERNAL:$SECURE_INGRESS_PORT_EXTERNAL
echo "https://$SECURE_GATEWAY_URL_EXTERNAL/productpage"
Verificatie
Een HTTPS-aanvraag verzenden voor toegang tot de productpaginaservice via HTTPS:
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>"
Controleer of de productpagina van de voorbeeldtoepassing toegankelijk is. De verwachte uitvoer is:
<title>Simple Bookstore App</title>
Notitie
Als u toegang voor inkomend HTTPS-verkeer tot een HTTPS-service wilt configureren, configureert u een gateway voor inkomend verkeer om SNI-passthrough uit te voeren in plaats van TLS-beëindiging voor binnenkomende aanvragen, werkt u de TLS-modus in de gatewaydefinitie bij naar PASSTHROUGH
. Hiermee wordt de gateway geïnstrueerd om het inkomend verkeer 'zoals is' door te geven zonder TLS te beëindigen.
Een wederzijdse TLS-ingangsgateway configureren
Breid uw gatewaydefinitie uit om wederzijdse TLS te ondersteunen.
Werk de referentie voor de toegangsbeheergateway bij door het huidige geheim te verwijderen en een nieuw geheim te maken. De server gebruikt het CA-certificaat om de clients te verifiëren en we moeten de sleutel ca.crt gebruiken om het CA-certificaat te bewaren.
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
Gebruik het volgende manifest om SecretProviderClass opnieuw te maken met een CA-certificaat.
cat <<EOF | kubectl apply -f - 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: $CLIENT_ID keyvaultName: $AKV_NAME 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: $TENANT_ID EOF
Gebruik het volgende manifest om een voorbeeldpod opnieuw te implementeren om geheimen van Azure Key Vault naar het cluster te synchroniseren.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-productpage namespace: aks-istio-ingress spec: containers: - name: busybox image: registry.k8s.io/e2e-test-images/busybox:1.29-4 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "productpage-credential-spc" EOF
Controleer het
productpage-credential
geheim dat is gemaakt in de clusternaamruimteaks-istio-ingress
.kubectl describe secret/productpage-credential -n aks-istio-ingress
Voorbeelduitvoer:
Name: productpage-credential Namespace: aks-istio-ingress Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: opaque Data ==== ca.crt: 1188 bytes tls.crt: 1066 bytes tls.key: 1704 bytes
Gebruik het volgende manifest om de gatewaydefinitie bij te werken om de TLS-modus in te stellen op MUTUAL.
cat <<EOF | kubectl apply -f - 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 EOF
Verificatie
Probeer een HTTPS-aanvraag te verzenden met behulp van de voorgaande methode, zonder het clientcertificaat door te geven, en zie dat deze mislukt.
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"
Voorbeelduitvoer:
...
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS alert, unknown (628):
* OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
* Failed receiving HTTP2 data
* OpenSSL SSL_write: SSL_ERROR_ZERO_RETURN, errno 0
* Failed sending HTTP2 data
* Connection #0 to host productpage.bookinfo.com left intact
curl: (56) OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
Geef het certificaat van uw client door met de --cert
vlag en de persoonlijke sleutel met de --key
vlag aan curl.
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>"
Controleer of de productpagina van de voorbeeldtoepassing toegankelijk is. De verwachte uitvoer is:
<title>Simple Bookstore App</title>
Resources verwijderen
Als u de Istio-service-mesh en de ingresses (achter het cluster) wilt opschonen, voert u de volgende opdracht uit:
az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}
Als u alle resources wilt opschonen die zijn gemaakt op basis van de Istio instructiedocumenten, voert u de volgende opdracht uit:
az group delete --name ${RESOURCE_GROUP} --yes --no-wait
Azure Kubernetes Service