From 6a66860d58061c0c1867ec3fa52e52f96776a3ee Mon Sep 17 00:00:00 2001 From: Neal Timpe Date: Mon, 12 Oct 2020 13:07:35 -0400 Subject: [PATCH] PR to merge #26354 into 4.7 branch. --- _topic_map.yml | 2 + modules/ossm-cr-pilot.adoc | 39 +- modules/ossm-security-cert-manage-1x.adoc | 169 ++++++++ modules/ossm-security-cert-manage.adoc | 36 +- modules/ossm-security-mtls-1x.adoc | 105 +++++ modules/ossm-security-mtls.adoc | 40 +- ossm-threescale-authentication.adoc | 162 ++++++++ service_mesh/v1x/ossm-security.adoc | 2 +- service_mesh/v2x/upgrading-ossm.adoc | 469 ++++++++++++++++++++++ 9 files changed, 975 insertions(+), 49 deletions(-) create mode 100644 modules/ossm-security-cert-manage-1x.adoc create mode 100644 modules/ossm-security-mtls-1x.adoc create mode 100644 ossm-threescale-authentication.adoc create mode 100644 service_mesh/v2x/upgrading-ossm.adoc diff --git a/_topic_map.yml b/_topic_map.yml index d777aa7cadb5..1e850a5b2aef 100644 --- a/_topic_map.yml +++ b/_topic_map.yml @@ -2166,6 +2166,8 @@ Topics: # File: preparing-ossm-installation # - Name: Installing Service Mesh # File: installing-ossm +# - Name: Upgrading from 1.1 to 2.0 +# File: upgrading-ossm # - Name: Customizing the installation # File: customizing-installation-ossm # - Name: Deploying applications on Service Mesh diff --git a/modules/ossm-cr-pilot.adoc b/modules/ossm-cr-pilot.adoc index 3615d3f1f340..ac23e87ea981 100644 --- a/modules/ossm-cr-pilot.adoc +++ b/modules/ossm-cr-pilot.adoc @@ -5,18 +5,41 @@ [id="ossm-cr-pilot_{context}"] = Istio Pilot configuration -Here is an example that illustrates the Istio Pilot parameters for the `ServiceMeshControlPlane` and a description of the available parameters with appropriate values. +You can configure Pilot to schedule or set limits on resource allocation. +The following example illustrates the Pilot parameters for the `ServiceMeshControlPlane` and a description of the available parameters with appropriate values. .Example pilot parameters [source,yaml] ---- - pilot: - resources: - requests: - cpu: 100m - memory: 128Mi - autoscaleEnabled: false - traceSampling: 100 +spec: + runtime: + components: + pilot: + deployment: + autoScaling: + enabled: true + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 85 + pod: + tolerations: + - key: node.kubernetes.io/unreachable + operator: Exists + effect: NoExecute + tolerationSeconds: 60 + affinity: + podAntiAffinity: + requiredDuringScheduling: + - key: istio + topologyKey: kubernetes.io/hostname + operator: In + values: + - pilot + container: + resources: + limits: + cpu: 100m + memory: 128M ---- .Istio Pilot parameters diff --git a/modules/ossm-security-cert-manage-1x.adoc b/modules/ossm-security-cert-manage-1x.adoc new file mode 100644 index 000000000000..83bfa495cb34 --- /dev/null +++ b/modules/ossm-security-cert-manage-1x.adoc @@ -0,0 +1,169 @@ +// Module included in the following assemblies: +// +// * service_mesh/v1x/ossm-security.adoc + + +[id="ossm-cert-manage_{context}"] += Adding an external certificate authority key and certificate + +By default, {ProductName} generates self-signed root certificate and key, and uses them to sign the workload certificates. You can also use the user-defined certificate and key to sign workload certificates, with user-defined root certificate. This task demonstrates an example to plug certificates and key into {ProductShortName}. + +.Prerequisites + +* You must have installed {ProductName} with mutual TLS enabled to configure certificates. +* This example uses the certificates from the link:https://github.com/maistra/istio/tree/maistra-2.0/samples/certs[Maistra repository]. For production, use your own certificates from your certificate authority. +* You must deploy the Bookinfo sample application to verify the results with these instructions. + +[id="ossm-cert-manage-add-cert-key_{context}"] +== Adding an existing certificate and key + +To use an existing signing (CA) certificate and key, you must create a chain of trust file that includes the CA certificate, key, and root certificate. You must use the following exact file names for each of the corresponding certificates. The CA certificate is called `ca-cert.pem`, the key is `ca-key.pem`, and the root certificate, which signs `ca-cert.pem`, is called `root-cert.pem`. If your workload uses intermediate certificates, you must specify them in a `cert-chain.pem` file. + +Add the certificates to {ProductShortName} by following these steps. Save the example certificates from the link:https://github.com/maistra/istio/tree/maistra-1.1/samples/certs[Maistra repo] locally and replace `` with the path to your certificates. + +1. Create a secret `cacert` that includes the input files `ca-cert.pem`, `ca-key.pem`, `root-cert.pem` and `cert-chain.pem`. ++ +[source,terminal] +---- +$ oc create secret generic cacerts -n istio-system --from-file=/ca-cert.pem \ + --from-file=/ca-key.pem --from-file=/root-cert.pem \ + --from-file=/cert-chain.pem +---- ++ +2. In the `ServiceMeshControlPlane` resource set `global.mtls.enabled` to `true` and `security.selfSigned` set to `false`. {ProductShortName} reads the certificates and key from the secret-mount files. ++ +[source,yaml] +---- +apiVersion: maistra.io/v1 +kind: ServiceMeshControlPlane +spec: + istio: + global: + mtls: + enabled: true + security: + selfSigned: false +---- ++ +3. To make sure the workloads add the new certificates promptly, delete the secrets generated by {ProductShortName}, named `istio.*`. In this example, `istio.default`. {ProductShortName} issues new certificates for the workloads. ++ +[source,terminal] +---- +$ oc delete secret istio.default +---- + +[id="ossm-cert-manage-verify-cert_{context}"] +== Verifying your certificates + +Use the Bookinfo sample application to verify your certificates are mounted correctly. First, retrieve the mounted certificates. Then, verify the certificates mounted on the pod. + +1. Store the pod name in the variable `RATINGSPOD`. ++ +[source,terminal] +---- +$ RATINGSPOD=`oc get pods -l app=ratings -o jsonpath='{.items[0].metadata.name}'` +---- ++ +Run the following commands to retrieve the certificates mounted on the proxy. ++ +[source,terminal] +---- +$ oc exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/root-cert.pem > /tmp/pod-root-cert.pem +---- ++ +The file `/tmp/pod-root-cert.pem` contains the root certificate propagated to the pod. ++ +[source,terminal] +---- +$ oc exec -it $RATINGSPOD -c istio-proxy -- /bin/cat /etc/certs/cert-chain.pem > /tmp/pod-cert-chain.pem +---- ++ +The file `/tmp/pod-cert-chain.pem` contains the workload certificate and the CA certificate propagated to the pod. ++ +3. Verify the root certificate is the same as the one specified by the Operator. Replace `` with the path to your certificates. ++ +[source,terminal] +---- +$ openssl x509 -in /root-cert.pem -text -noout > /tmp/root-cert.crt.txt +---- ++ +[source,terminal] +---- +$ openssl x509 -in /tmp/pod-root-cert.pem -text -noout > /tmp/pod-root-cert.crt.txt +---- ++ +[source,terminal] +---- +$ diff /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt +---- ++ +Expect the output to be empty. ++ +4. Verify the CA certificate is the same as the one specified by Operator. Replace `` with the path to your certificates. ++ +[source,terminal] +---- +$ sed '0,/^-----END CERTIFICATE-----/d' /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-ca.pem +---- ++ +[source,terminal] +---- +$ openssl x509 -in /ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt +---- ++ +[source,terminal] +---- +$ openssl x509 -in /tmp/pod-cert-chain-ca.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt +---- ++ +[source,terminal] +---- +$ diff /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt +---- ++ +Expect the output to be empty. ++ +5. Verify the certificate chain from the root certificate to the workload certificate. Replace `` with the path to your certificates. ++ +[source,terminal] +---- +$ head -n 21 /tmp/pod-cert-chain.pem > /tmp/pod-cert-chain-workload.pem +---- ++ +[source,terminal] +---- +$ openssl verify -CAfile <(cat /ca-cert.pem /root-cert.pem) /tmp/pod-cert-chain-workload.pem +---- ++ +.Example output +[source,terminal] +---- +/tmp/pod-cert-chain-workload.pem: OK +---- + +[id="ossm-cert-cleanup_{context}"] +== Removing the certificates + +To remove the certificates you added, follow these steps. + +1. Remove the secret `cacerts`. ++ +[source,terminal] +---- +$ oc delete secret cacerts -n istio-system +---- ++ +2. Redeploy {ProductShortName} with a self-signed root certificate in the `ServiceMeshControlPlane` resource. ++ +[source,yaml] +---- +apiVersion: maistra.io/v1 +kind: ServiceMeshControlPlane +spec: + istio: + global: + mtls: + enabled: true + security: + selfSigned: true +---- diff --git a/modules/ossm-security-cert-manage.adoc b/modules/ossm-security-cert-manage.adoc index 89e64b1cf452..a1be267979f5 100644 --- a/modules/ossm-security-cert-manage.adoc +++ b/modules/ossm-security-cert-manage.adoc @@ -1,17 +1,16 @@ // Module included in the following assemblies: // -// * service_mesh/v1x/ossm-security.adoc // * service_mesh/v2x/ossm-security.adoc [id="ossm-cert-manage_{context}"] = Adding an external certificate authority key and certificate -By default, {ProductName} generates self-signed root certificate and key, and uses them to sign the workload certificates. You can also use the Operator-specified certificate and key to sign workload certificates, with Operator-specified root certificate. This task demonstrates an example to plug certificates and key into {ProductShortName}. +By default, {ProductName} generates self-signed root certificate and key, and uses them to sign the workload certificates. You can also use the user-defined certificate and key to sign workload certificates, with user-defined root certificate. This task demonstrates an example to plug certificates and key into {ProductShortName}. .Prerequisites * You must have installed {ProductName} with mutual TLS enabled to configure certificates. -* This example uses the certificates from link:https://github.com/maistra/istio/tree/maistra-2.0/samples/certs[Maistra repo]. For production, use your own certificates from your certificate authority. +* This example uses the certificates from the link:https://github.com/maistra/istio/tree/maistra-2.0/samples/certs[Maistra repository]. For production, use your own certificates from your certificate authority. * You must deploy the Bookinfo sample application to verify the results with these instructions. [id="ossm-cert-manage-add-cert-key_{context}"] @@ -19,7 +18,7 @@ By default, {ProductName} generates self-signed root certificate and key, and us To use an existing signing (CA) certificate and key, you must create a chain of trust file that includes the CA certificate, key, and root certificate. You must use the following exact file names for each of the corresponding certificates. The CA certificate is called `ca-cert.pem`, the key is `ca-key.pem`, and the root certificate, which signs `ca-cert.pem`, is called `root-cert.pem`. If your workload uses intermediate certificates, you must specify them in a `cert-chain.pem` file. -Add the certificates to {ProductShortName} by following these steps. Save the certificates from the link:https://github.com/maistra/istio/tree/maistra-2.0/samples/certs[Maistra repo] locally and replace `` with the path to your certificates. +Add the certificates to {ProductShortName} by following these steps. Save the example certificates from the link:https://github.com/maistra/istio/tree/maistra-2.0/samples/certs[Maistra repo] locally and replace `` with the path to your certificates. 1. Create a secret `cacert` that includes the input files `ca-cert.pem`, `ca-key.pem`, `root-cert.pem` and `cert-chain.pem`. + @@ -30,19 +29,22 @@ $ oc create secret generic cacerts -n istio-system --from-file=/ca-cert.pe --from-file=/cert-chain.pem ---- + -2. In the `ServiceMeshControlPlane` resource set `global.mtls.enabled` to `true` and `security.selfSigned` set to `false`. {ProductShortName} reads the certificates and key from the secret-mount files. +2. In the `ServiceMeshControlPlane` resource set `spec.security.dataPlane.mtls: true` to `true` and configure your certificateAuthority like the following example. The default `rootCADir` is `/etc/cacerts`. You do not need to set the `privateKey` if the key and certs are mounted in the default location. {ProductShortName} reads the certificates and key from the secret-mount files. + [source,yaml] ---- -apiVersion: maistra.io/v1 +apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: - istio: - global: - mtls: - enabled: true - security: - selfSigned: false + security: + dataPlane: + mtls: true + certificateAuthority: + type: Istiod + istiod: + type: PrivateKey + privateKey: + rootCADir: /etc/cacerts ---- + 3. To make sure the workloads add the new certificates promptly, delete the secrets generated by {ProductShortName}, named `istio.*`. In this example, `istio.default`. {ProductShortName} issues new certificates for the workloads. @@ -157,13 +159,9 @@ $ oc delete secret cacerts -n istio-system + [source,yaml] ---- -apiVersion: maistra.io/v1 +apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: - istio: - global: - mtls: - enabled: true - security: - selfSigned: true + dataPlane: + mtls: true ---- diff --git a/modules/ossm-security-mtls-1x.adoc b/modules/ossm-security-mtls-1x.adoc new file mode 100644 index 000000000000..51c710288aba --- /dev/null +++ b/modules/ossm-security-mtls-1x.adoc @@ -0,0 +1,105 @@ +// Module included in the following assemblies: +// +// * service_mesh/v1x/ossm-security.adoc + +[id="ossm-security-mtls_{context}"] += Enabling mutual Transport Layer Security (mTLS) + +Mutual Transport Layer Security (mTLS) is a protocol where two parties authenticate each other. It is the default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS). + +MTLS can be used without changes to the application or service code. The TLS is handled entirely by the service mesh infrastructure and between the two sidecar proxies. + +By default, {ProductName} is set to permissive mode, where the sidecars in {ProductShortName} accept both plain-text traffic and connections that are encrypted using mTLS. If a service in your mesh is communicating with a service outside the mesh, strict mTLS could break communication between those services. Use permissive mode while you migrate your workloads to {ProductShortName}. + +[id="ossm-security-enabling-strict-mtls_{context}"] +== Enabling strict mTLS across the mesh + +If your workloads do not communicate with services outside your mesh and communication will not be interrupted by only accepting encrypted connections, you can enable mTLS across your mesh quickly. Set `spec.security.controlPlane.mtls` to `true` in your `ServiceMeshControlPlane` resource. The operator creates the required resources. + +[source,yaml] +---- +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +spec: + security: + controlPlane: + mtls: true +---- + +[id="ossm-security-mtls-sidecars-incoming-services_{context}"] +=== Configuring sidecars for incoming connections for specific services + +You can also configure mTLS for individual services or namespaces by creating a policy. + +[source,yaml] +---- +apiVersion: "authentication.istio.io/v1alpha1" +kind: "Policy" +metadata: + name: default + namespace: +spec: + peers: + - mtls: {} +---- + +[id="ossm-security-mtls-sidecars-outgoing_{context}"] +== Configuring sidecars for outgoing connections + +Create a destination rule to configure {ProductShortName} to use mTLS when sending requests to other services in the mesh. + +[source,yaml] +---- +apiVersion: "networking.istio.io/v1alpha3" +kind: "DestinationRule" +metadata: + name: "default" + namespace: > +spec: + host: "*.local" + trafficPolicy: + tls: + mode: ISTIO_MUTUAL +---- + +[id="ossm-security-min-max-tls_{context}"] +== Setting the minimum and maximum protocol versions + +If your environment has specific requirements for encrypted traffic in your service mesh, you can control the cryptographic functions that are allowed by setting the `spec.security.controlPlane.tls.minProtocolVersion` or `spec.security.controlPlane.tls.maxProtocolVersion` in your `ServiceMeshControlPlane` resource. Those values, configured in your control plane resource, define the minimum and maximum TLS version used by mesh components when communicating securely over TLS. + +[source,yaml] +---- +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +metadata: + name: basic-install + namespace: istio-system +spec: + security: + controlPlane: + tls: + minProtocolVersion: TLSv1_2 + maxProtocolVersion: TLSv1_3 +---- + +The default is `TLS_AUTO` and does not specify a version of TLS. + +.Valid values +|=== +|Value|Description + +|`TLS_AUTO` +| default + +|`TLSv1_0` +|TLS version 1.0 + +|`TLSv1_1` +|TLS version 1.1 + +|`TLSv1_2` +|TLS version 1.2 + +|`TLSv1_3` +|TLS version 1.3 +|=== diff --git a/modules/ossm-security-mtls.adoc b/modules/ossm-security-mtls.adoc index c6ed39d0dc47..3257a2fdf591 100644 --- a/modules/ossm-security-mtls.adoc +++ b/modules/ossm-security-mtls.adoc @@ -1,12 +1,11 @@ // Module included in the following assemblies: // -// * service_mesh/v1x/ossm-security.adoc // * service_mesh/v2x/ossm-security.adoc [id="ossm-security-mtls_{context}"] = Enabling mutual Transport Layer Security (mTLS) -Mutual Transport Layer Security (mTLS) is a protocol where two parties authenticate each other at the same time. It is the default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS). +Mutual Transport Layer Security (mTLS) is a protocol where two parties authenticate each other. It is the default mode of authentication in some protocols (IKE, SSH) and optional in others (TLS). MTLS can be used without changes to the application or service code. The TLS is handled entirely by the service mesh infrastructure and between the two sidecar proxies. @@ -15,17 +14,16 @@ By default, {ProductName} is set to permissive mode, where the sidecars in {Prod [id="ossm-security-enabling-strict-mtls_{context}"] == Enabling strict mTLS across the mesh -If your workloads do not communicate with services outside your mesh and communication will not be interrupted by only accepting encrypted connections, you can enable mTLS across your mesh quickly. Set `spec.istio.global.mtls.enabled` to `true` in your `ServiceMeshControlPlane` resource. The operator creates the required resources. +If your workloads do not communicate with services outside your mesh and communication will not be interrupted by only accepting encrypted connections, you can enable mTLS across your mesh quickly. Set `spec.security.dataPlane.mtls` to `true` in your `ServiceMeshControlPlane` resource. The operator creates the required resources. [source,yaml] ---- -apiVersion: maistra.io/v1 +apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: - istio: - global: - mtls: - enabled: true + security: + dataPlane: + mtls: true ---- [id="ossm-security-mtls-sidecars-incoming-services_{context}"] @@ -35,14 +33,14 @@ You can also configure mTLS for individual services or namespaces by creating a [source,yaml] ---- -apiVersion: "authentication.istio.io/v1alpha1" -kind: "Policy" +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication metadata: - name: "default" - namespace: + name: default + namespace: spec: - peers: - - mtls: {} + mtls: + mode: STRICT ---- [id="ossm-security-mtls-sidecars-outgoing_{context}"] @@ -52,16 +50,16 @@ Create a destination rule to configure {ProductShortName} to use mTLS when sendi [source,yaml] ---- -apiVersion: "networking.istio.io/v1alpha3" -kind: "DestinationRule" +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule metadata: - name: "default" - namespace: + name: default + namespace: spec: - host: "*.local" + host: "*..svc.cluster.local" trafficPolicy: - tls: - mode: ISTIO_MUTUAL + tls: + mode: ISTIO_MUTUAL ---- [id="ossm-security-min-max-tls_{context}"] diff --git a/ossm-threescale-authentication.adoc b/ossm-threescale-authentication.adoc new file mode 100644 index 000000000000..dc192c100b60 --- /dev/null +++ b/ossm-threescale-authentication.adoc @@ -0,0 +1,162 @@ +// Module included in the following assemblies: +// +// * service_mesh/v1x/threescale_adapter/threescale-adapter.adoc +// * service_mesh/v2x/threescale_adapter/threescale-adapter.adoc + +[id="ossm-threescale-authentication_{context}"] += Authenticating requests +This release supports the following authentication methods: + +* *Standard API Keys*: single randomized strings or hashes acting as an identifier and a secret token. +* *Application identifier and key pairs*: immutable identifier and mutable secret key strings. +* *OpenID authentication method*: client ID string parsed from the JSON Web Token. + + +[id="ossm-threescale-authentication-patterns_{context}"] +== Applying authentication patterns +Modify the `instance` custom resource, as illustrated in the following authentication method examples, to configure authentication behavior. You can accept the authentication credentials from: + +* Request headers +* Request parameters +* Both request headers and query parameters + +[NOTE] +==== +When specifying values from headers, they must be lower case. For example, if you want to send a header as `User-Key`, this must be referenced in the configuration as `request.headers["user-key"]`. +==== + +[id="ossm-threescale-apikey-authentication_{context}"] +=== API key authentication method +{ProductShortName} looks for the API key in query parameters and request headers as specified in the `user` option in the `subject` custom resource parameter. It checks the values in the order given in the custom resource file. You can restrict the search for the API key to either query parameters or request headers by omitting the unwanted option. + +In this example, {ProductShortName} looks for the API key in the `user_key` query parameter. If the API key is not in the query parameter, {ProductShortName} then checks the `user-key` header. + +.API key authentication method example + +[source,yaml] +---- +apiVersion: "config.istio.io/v1alpha2" +kind: instance +metadata: + name: threescale-authorization + namespace: istio-system +spec: + template: authorization + params: + subject: + user: request.query_params["user_key"] | request.headers["user-key"] | "" + action: + path: request.url_path + method: request.method | "get" +---- + +If you want the adapter to examine a different query parameter or request header, change the name as appropriate. For example, to check for the API key in a query parameter named “key”, change `request.query_params["user_key"]` to `request.query_params["key"]`. + +[id="ossm-threescale-appidapikey-authentication_{context}"] +=== Application ID and application key pair authentication method +{ProductShortName} looks for the application ID and application key in query parameters and request headers, as specified in the `properties` option in the `subject` custom resource parameter. The application key is optional. It checks the values in the order given in the custom resource file. You can restrict the search for the credentials to either query parameters or request headers by not including the unwanted option. + +In this example, {ProductShortName} looks for the application ID and application key in the query parameters first, moving on to the request headers if needed. + +.Application ID and application key pair authentication method example + +[source,yaml] +---- +apiVersion: "config.istio.io/v1alpha2" +kind: instance +metadata: + name: threescale-authorization + namespace: istio-system +spec: + template: authorization + params: + subject: + app_id: request.query_params["app_id"] | request.headers["app-id"] | "" + app_key: request.query_params["app_key"] | request.headers["app-key"] | "" + action: + path: request.url_path + method: request.method | "get" +---- + +If you want the adapter to examine a different query parameter or request header, change the name as appropriate. For example, to check for the application ID in a query parameter named `identification`, change `request.query_params["app_id"]` to `request.query_params["identification"]`. + +[id="ossm-threescale-openid-authentication_{context}"] +=== OpenID authentication method +To use the _OpenID Connect (OIDC) authentication method_, use the `properties` value on the `subject` field to set `client_id`, and optionally `app_key`. + +You can manipulate this object using the methods described previously. In the example configuration shown below, the client identifier (application ID) is parsed from the JSON Web Token (JWT) under the label _azp_. You can modify this as needed. + +.OpenID authentication method example + +[source,yaml] +---- + apiVersion: "config.istio.io/v1alpha2" + kind: instance + metadata: + name: threescale-authorization + spec: + template: threescale-authorization + params: + Subject: + properties: + app_key: request.query_params["app_key"] | request.headers["app-key"] | "" + client_id: request.auth.claims["azp"] | "" + action: + path: request.url_path + method: request.method | "get" + service: destination.labels["service-mesh.3scale.net/service-id"] | "" +---- + +For this integration to work correctly, OIDC must still be done in 3scale for the client to be created in the identity provider (IdP). You should create link:https://istio.io/docs/ops/security/end-user-auth/[end-user authentication] for the service you want to protect in the same namespace as that service. The JWT is passed in the `Authorization` header of the request. + +In the sample `Policy` defined below, replace `issuer` and `jwksUri` as appropriate. + +.OpenID Policy example + +[source,yaml] +---- + apiVersion: authentication.istio.io/v1alpha1 + kind: Policy + metadata: + name: jwt-example + namespace: bookinfo + spec: + origins: + - jwt: + issuer: >- + http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak + jwksUri: >- + http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak/protocol/openid-connect/certs + principalBinding: USE_ORIGIN + targets: + - name: productpage +---- + +[id="ossm-threescale-hybrid-authentication_{context}"] +=== Hybrid authentication method +You can choose to not enforce a particular authentication method and accept any valid credentials for either method. If both an API key and an application ID/application key pair are provided, {ProductShortName} uses the API key. + +In this example, {ProductShortName} checks for an API key in the query parameters, then the request headers. If there is no API key, it then checks for an application ID and key in the query parameters, then the request headers. + +.Hybrid authentication method example + +[source,yaml] +---- +apiVersion: "config.istio.io/v1alpha2" +kind: instance +metadata: + name: threescale-authorization +spec: + template: authorization + params: + subject: + user: request.query_params["user_key"] | request.headers["user-key"] | + properties: + app_id: request.query_params["app_id"] | request.headers["app-id"] | "" + app_key: request.query_params["app_key"] | request.headers["app-key"] | "" + client_id: request.auth.claims["azp"] | "" + action: + path: request.url_path + method: request.method | "get" + service: destination.labels["service-mesh.3scale.net/service-id"] | "" +---- diff --git a/service_mesh/v1x/ossm-security.adoc b/service_mesh/v1x/ossm-security.adoc index 69324db33ddb..b7fa001bfded 100644 --- a/service_mesh/v1x/ossm-security.adoc +++ b/service_mesh/v1x/ossm-security.adoc @@ -7,7 +7,7 @@ toc::[] If your service mesh application is constructed with a complex array of microservices, you can use {ProductName} to customize the security of the communication between those services. The infrastructure of {product-title} along with the traffic management features of {ProductShortName} can help you manage the complexity of your applications and provide service and identity security for microservices. -include::modules/ossm-security-mtls.adoc[leveloffset=+1] +include::modules/ossm-security-mtls-1x.adoc[leveloffset=+1] include::modules/ossm-security-cipher.adoc[leveloffset=+1] diff --git a/service_mesh/v2x/upgrading-ossm.adoc b/service_mesh/v2x/upgrading-ossm.adoc new file mode 100644 index 000000000000..01253b998d54 --- /dev/null +++ b/service_mesh/v2x/upgrading-ossm.adoc @@ -0,0 +1,469 @@ +[id="upgrading-ossm"] += Upgrading {ProductName} from version 1.1 to version 2.0 +include::modules/ossm-document-attributes.adoc[] +:context: upgrading-ossm +toc::[] + +To access the most current features of {ProductName}, upgrade to the most current version, 2.0. Upgrading from version 1.1 to 2.0 requires manual steps that migrate your workloads and apps to a new instance of {ProductName} running the new version. + +.Prerequisites + +* You must upgrade to {product-title} 4.6. before you upgrade to {ProductName} 2.0. +* You must have an updated {ProductName} operator. If you selected the *automatic* upgrade path, the operator automatically downloads the latest information. However, there are steps you must take to use the features in {ProductName} version 2.0. + +[id="ossm-upgrading-upgrade_{context}"] +== Upgrading {ProductName} + +To upgrade {ProductName}, you must create an instance of {ProductName} 2.0 in a new namespace. Then, once it's configured, move your microservice applications and workloads from your old mesh to the new service mesh. + +.Procedure + +. Back up your control plane configuration. Switch to the project that contains your `ServiceMeshControlPlane` resource. ++ +[source,terminal] +---- +oc project istio-system +---- ++ +. Enter the following command to retrieve the current configuration. Your is specified in the metadata of your `ServiceMeshControlPlane` resource, for example `basic-install` or `full-install`. ++ +[source,terminal] +---- +$ oc get servicemeshcontrolplanes.v1.maistra.io -o yaml > .v1.yaml +---- ++ +. Convert your `ServiceMeshControlPlane` to a v2 control plane version that contains information about your configuration as a starting point. ++ +[source,terminal] +---- +$ oc get smcp -o yaml > .v2.yaml +---- ++ +. Create a project. In the {product-title} console Project menu, click `New Project` and enter a name for your project, `istio-system-upgrade`, for example. Or, you can run this command from the CLI. ++ +[source,terminal] +---- +$ oc new-project istio-system-upgrade +---- ++ +. Create a `ServiceMeshControlPlane` in the new namespace. On the command line, run the following command to deploy the control plane with the v2 version of the `ServiceMeshControlPlane` that you retrieved. In this example, replace ` `with the path to your file. ++ +[source,terminal] +---- +$ oc create -n istio-system-update -f .yaml +---- ++ +Alternatively, you can use the console to create the control plane. In the {product-title} web console, click *Project*. Then, select the project name you just entered. ++ +.. Click *Operators* -> *Installed Operators*. +.. Click *Create ServiceMeshControlPlane*. +.. Select *YAML view* and paste text of the YAML file you retrieved into the field. Check that the `apiVersion` field is set to `maistra.io/v2` and modify the `metadata.namespace` field to use the new namespace, for example `istio-system-upgrade`. +.. Click *Create*. + +[id="ossm-upgrading-differences_{context}"] +== Configuring the 2.0 `ServiceMeshControlPlane` + +The `ServiceMeshControlPlane` resource has been updated for {ProductName} version 2.0. After you created a v2 version of the `ServiceMeshControlPlane` resource, modify it to take advantage of the new features and to fit your deployment. Consider the following changes to the specification and behavior of {ProductName} 2.0 as you're modifying your `ServiceMeshControlPlane` resource. You can also refer to the {ProductName} 2.0 product documentation for updates to features you use. The v2 resource must be used for {ProductName} 2.0 installations. + +[id="ossm-upgrading-differences-arch_{context}"] +=== Architecture changes + +The architectural units used by previous versions have been replaced by istiod. In 2.0 the control plane components Mixer, Pilot, Citadel, Galley and the sidecar injector functionality have been combined into a single component, istiod. + +Although Mixer is no longer supported as a control plane component, Mixer policy and telemetry plugins are now supported through WASM extensions in istiod. Mixer can be enabled for policy and telemetry if you need to integrate legacy Mixer plugins. + +Security Discovery Service (SDS) is used to distribute certificates and keys to sidecars directly from istiod. In {ProductName} version 1.1, secrets were generated by Citadel, which were used by the proxies to retrieve their client certificates and keys. + +[id="ossm-upgrading-differences-annotation_{context}"] +=== Annotation changes + +The following annotations are no longer supported in v2.0. If you are using one of these annotations, you must update your workload before moving it to a v2.0 control plane. + +* `sidecar.maistra.io/proxyCPULimit` has been replaced with `sidecar.istio.io/proxyCPULimit`. If you were using `sidecar.maistra.io` annotations on your workloads, you must modify those workloads to use `sidecar.istio.io` equivalents instead. +* `sidecar.maistra.io/proxyMemoryLimit` has been replaced with `sidecar.istio.io/proxyMemoryLimit` +* `sidecar.istio.io/discoveryAddress` is no longer supported. Also, the default discovery address has moved from `pilot..svc:15010` (or port 15011, if mtls is enabled) to `istiod-..svc:15012`. +* The health status port is no longer configurable and is hard-coded to 15021. * If you were defining a custom status port, for example, `status.sidecar.istio.io/port`, you must remove the override before moving the workload to a v2.0 control plane. Readiness checks can still be disabled by setting the status port to `0`. +* Kubernetes Secret resources are no longer used to distribute client certificates for sidecars. Certificates are now distributed through istiod’s SDS service. If you were relying on mounted secrets, they are longer available for workloads in v2.0 control planes. + +[id="ossm-upgrading-differences-behavior_{context}"] +=== Behavioral changes + +Some features in {ProductName} 2.0 work differently than they did in previous versions. + +* The readiness port on gateways has moved from `15020` to `15021`. +* The target host visibility includes VirtualService, as well as ServiceEntry resources. It includes any restrictions applied through Sidecar resources. +* Automatic mutual TLS is enabled by default. Proxy to proxy communication is automatically configured to use mTLS, regardless of global PeerAuthentication policies in place. +* Secure connections are always used when proxies communicate with the control plane regardless of `spec.security.controlPlane.mtls` setting. The `spec.security.controlPlane.mtls` setting is only used when configuring connections for Mixer telemetry or policy. + +[id="ossm-upgrading-mig-unsupp_{context}"] +=== Migration details for unsupported resources + +.Policy (authentication.istio.io/v1alpha1) + +Policy resources must be migrated to new resource types for use with v2.0 control planes, PeerAuthentication and RequestAuthentication. Depending on the specific configuration in your Policy resource, you may have to configure multiple resources to achieve the same effect. + +.Mutual TLS + +Mutual TLS enforcement is accomplished using the `security.istio.io/v1beta1` PeerAuthentication resource. The legacy `spec.peers.mtls.mode` field maps directly to the new resource’s `spec.mtls.mode` field. Selection criteria has changed from specifying a service name in `spec.targets[x].name` to a label selector in `spec.selector.matchLabels`. In PeerAuthentication, the labels must match the selector on the services named in the targets list. Any port-specific settings will need to be mapped into `spec.portLevelMtls`. + +.Authentication + +Additional authentication methods specified in `spec.origins`, must be mapped into a `security.istio.io/v1beta1` RequestAuthentication resource. `spec.selector.matchLabels` must be configured similarly to the same field on PeerAuthentication. Configuration specific to JWT principals from `spec.origins.jwt` items map to similar fields in `spec.rules` items. + +* `spec.origins[x].jwt.triggerRules` specified in the Policy must be mapped into one or more `security.istio.io/v1beta1` AuthorizationPolicy resources. Any `spec.selector.labels` must be configured similarly to the same field on RequestAuthentication. +* `spec.origins[x].jwt.triggerRules.excludedPaths` must be mapped into an AuthorizationPolicy whose spec.action is set to ALLOW, with `spec.rules[x].to.operation.path` entries matching the excluded paths. +* `spec.origins[x].jwt.triggerRules.includedPaths` must be mapped into a separate AuthorizationPolicy whose `spec.action` is set to `ALLOW`, with `spec.rules[x].to.operation.path` entries matching the included paths, and `spec.rules.[x].from.source.requestPrincipals` entries that align with the `specified spec.origins[x].jwt.issuer` in the Policy resource. + +.ServiceMeshPolicy (maistra.io/v1) + +ServiceMeshPolicy was configured automatically for the control plane through the `spec.istio.global.mtls.enabled` in the v1 resource or `spec.security.dataPlane.mtls` in the v2 resource setting. For v2 control planes, a functionally equivalent PeerAuthentication resource is created during installation. This feature is deprecated in {ProductName} version 2.0 + +.RbacConfig, ServiceRole, ServiceRoleBinding (rbac.istio.io/v1alpha1) + +These resources were replaced by the `security.istio.io/v1beta1` AuthorizationPolicy resource. + +Mimicking RbacConfig behavior requires writing a default AuthorizationPolicy whose settings depend on the spec.mode specified in the RbacConfig. + +* When `spec.mode` is set to `OFF`, no resource is required as the default policy is ALLOW, unless an AuthorizationPolicy applies to the request. +* When `spec.mode` is set to ON, set `spec: {}`. You must create AuthorizationPolicy policies for all services in the mesh. +* `spec.mode` is set to `ON_WITH_INCLUSION`, must create an AuthorizationPolicy with `spec: {}` in each included namespace. Inclusion of individual services is not supported by AuthorizationPolicy. However, as soon as any AuthorizationPolicy is created that applies to the workloads for the service, all other requests not explicitly allowed will be denied. +* When `spec.mode` is set to `ON_WITH_EXCLUSION`, it is not supported by AuthorizationPolicy. A global DENY policy can be created, but an AuthorizationPolicy must be created for every workload in the mesh because there is no allow-all policy that can be applied to either a namespace or a workload. + +AuthorizationPolicy includes configuration for both the selector to which the configuration applies, which is similar to the function ServiceRoleBinding provides and the rules which should be applied, which is similar to the function ServiceRole provides. + +.ServiceMeshRbacConfig (maistra.io/v1) + +This resource is replaced by using a `security.istio.io/v1beta1` AuthorizationPolicy resource with an empty spec.selector in the control plane’s namespace. This policy will be the default authorization policy applied to all workloads in the mesh. For specific migration details, see RbacConfig above. + +[id="ossm-upgrading-mig-mixer_{context}"] +=== Mixer plugins + +Mixer components are disabled by default in version 2.0. If you rely on Mixer plugins for your workload, you must configure your version 2.0 `ServiceMeshControlPlane` to include the Mixer components. + +To enable the Mixer policy components, add the following snippet to your `ServiceMeshControlPlane`. + +[source,yaml] +---- +spec: + policy: + type: Mixer +---- + +To enable the Mixer telemetry components, add the following snippet to your `ServiceMeshControlPlane`. + +[source,yaml] +---- +spec: + telemetry: + type: Mixer +---- + +Legacy mixer plugins can also be migrated to WASM and integrated using the new ServiceMeshExtension (maistra.io/v1alpha1) custom resource. + +Built-in WASM filters included in the upstream Istio distribution are not available in {ProductName} 2.0. + +[id="ossm-upgrading-mig-mtls_{context}"] +=== Mutual TLS changes + +The mTLS feature only considers PeerAuthentication policies that affect an entire namespace or the entire mesh. There is no selector. When using mTLS with workload specific PeerAuthentication policies, a corresponding DestinationRule is required to allow traffic if the workload policy differs from the namespace/global policy. + +Auto mTLS is enabled by default, but can be disabled by setting `spec.security.dataPlane.automtls` to false in the `ServiceMeshControlPlane` resource. When disabling auto mTLS, DestinationRules may be required for proper communication between services. For example, setting PeerAuthentication to `STRICT` for one namespace may prevent services in other namespaces from accessing them, unless a DestinationRule configures TLS mode for the services in the namespace. + +For information about mTLS, see xref:../../service_mesh/v2x/ossm-security.adoc#ossm-security-mtls_ossm-security[Enabling mutual Transport Layer Security (mTLS)] + +==== Other mTLS Examples + +To disable mTLS For productpage service in the bookinfo sample application, your Policy resource was configured the following way for {ProductName} v1.1. + +.Example Policy resource +[source,yaml] +---- +apiVersion: authentication.istio.io/v1alpha1 +kind: Policy +metadata: + name: productpage-mTLS-disable + namespace: +spec: + targets: + - name: productpage +---- + +To disable mTLS For productpage service in the bookinfo sample application, use the following example to configure your PeerAuthentication resource for {ProductName} v2.0. + +.Example PeerAuthentication resource +[source,yaml] +---- +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: productpage-mTLS-disable + namespace: +spec: + mtls: + mode: DISABLE + selector: + matchLabels: + # this should match the selector for the "productpage" service + app: productpage +---- + +To enable mTLS With JWT authentication for the `productpage` service in the bookinfo sample application, your Policy resource was configured the following way for {ProductName} v1.1. + +.Example Policy resource +[source,yaml] +---- +apiVersion: authentication.istio.io/v1alpha1 +kind: Policy +metadata: + name: productpage-mTLS-with-JWT + namespace: +spec: + targets: + - name: productpage + ports: + - number: 9000 + peers: + - mtls: + origins: + - jwt: + issuer: "https://securetoken.google.com" + audiences: + - "productpage" + jwksUri: "https://www.googleapis.com/oauth2/v1/certs" + jwtHeaders: + - "x-goog-iap-jwt-assertion" + triggerRules: + - excludedPaths: + - exact: /health_check + principalBinding: USE_ORIGIN +---- + +To enable mTLS With JWT authentication for the productpage service in the bookinfo sample application, use the following example to configure your PeerAuthentication resource for {ProductName} v2.0. + +.Example PeerAuthentication resource +[source,yaml] +---- +#require mtls for productpage:9000 +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: productpage-mTLS-with-JWT + namespace: +spec: + selector: + matchLabels: + # this should match the selector for the "productpage" service + app: productpage + portLevelMtls: + 9000: + mode: STRICT +... +#JWT authentication for productpage +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: productpage-mTLS-with-JWT + namespace: +spec: + selector: + matchLabels: + # this should match the selector for the "productpage" service + app: productpage + jwtRules: + - issuer: "https://securetoken.google.com" + audiences: + - "productpage" + jwksUri: "https://www.googleapis.com/oauth2/v1/certs" + fromHeaders: + - name: "x-goog-iap-jwt-assertion" +... +#Require JWT token to access product page service from +#any client to all paths except /health_check +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: productpage-mTLS-with-JWT + namespace: +spec: + action: ALLOW + selector: + matchLabels: + # this should match the selector for the "productpage" service + app: productpage + rules: + - to: # require JWT token to access all other paths + - operation: + notPaths: + - /health_check + from: + - source: + # if using principalBinding: USE_PEER in the Policy, + # then use principals, e.g. + # principals: + # - “*” + requestPrincipals: + - “*” + - to: # no JWT token required to access health_check + - operation: + paths: + - /health_check +---- + +[id="ossm-upgrading-config-recipes_{context}"] +== Configuration recipes + +You can configure the following items with these configuration recipes. + +[id="ossm-upgrading-config-mtls_{context}"] +=== Mutual TLS in a data plane + +Mutual TLS for data plane communication is configured through `spec.security.dataPlane.mtls` in the `ServiceMeshControlPlane` resource, which is `false` by default. + +[id="ossm-upgrading-config-sign-key_{context}"] +=== Custom signing key + +Istiod manages client certificates and private keys used by service proxies. By default, istiod uses a self-signed certificate for signing, but you can configure a custom certificate and private key. For more information about how to configure signing keys, see xref:../../service_mesh/v2x/ossm-security.html#ossm-cert-manage_ossm-security[Adding an external certificate authority key and certificate] + +[id="ossm-upgrading-config-tracing_{context}"] +=== Tracing + +Tracing is configured under `spec.tracing`. Currently, the only type of tracer that is supported is `Jaeger`. Sampling is a scaled integer representing 0.01% increments, e.g. 1 is 0.01% and 10000 is 100%. The tracing implementation and sampling rate can be specified: + +[source,yaml] +---- +spec: + tracing: + sampling: 100 # 1% + type: Jaeger +---- + +Jaeger is configured under the addons section of the SMCP spec. + +[source,yaml] +---- +spec: + addons: + jaeger: + name: jaeger + install: + storage: Memory # or Elasticsearch + memory: {} # details specific to memory storage + elasticsearch: {} # details specific to elasticsearch storage + runtime: + components: + tracing.jaeger: {} # general jaeger specific runtime configuration + tracing.jaeger.elasticsearch: {} # runtime configuration for jaeger elasticsearch deployment +---- + +The Jaeger installation can be customized with the `install` field. Container configuration, such as resource limits is configured in `spec.runtime.components.jaeger` related fields. If a Jaeger resource matching the value of name exists, the control plane will be configured to use the existing installation. Use an existing Jaeger resource to fully customize your Jaeger installation. + +[id="ossm-upgrading-config-vis_{context}"] +=== Visualization + +Kiali and Grafana are configured under the addons section of the `ServiceMeshControlPlane` resource. + +[source,yaml] +---- +spec: + addons: + grafana: + enabled: true + install: {} # customize install + kiali: + enabled: true + name: kiali + install: {} # customize install +---- + +The Grafana and Kiali installations can be somewhat customized through their respective `install` fields. Container customization, such as resource limits, is configured in `spec.runtime.components.kiali` and `spec.runtime.components.grafana`. If an existing Kiali resource matching the value of name exists, the control plane configures the Kiali resource for use with the control plane. Some fields in the Kiali resource are overridden, such as the `accessible_namespaces` list, as well as the endpoints for Grafana, Prometheus, and tracing. Use an existing resource to fully customize your Kiali installation. + +=== Resource utilization and scheduling + +Resources are configured under `spec.runtime.`. The following component names are supported. + +|=== +|Component |Description |Versions supported + +|security +|Citadel container +|v1.0/1.1 + +|galley +|Galley container +|v1.0/1.1 + +|pilot +|Pilot/istiod container +|v1.0/1.1/2.0 + +|mixer +|istio-telemetry and istio-policy containers +|v1.0/1.1 + +|`mixer.policy` +|istio-policy container +|v2.0 + +|`mixer.telemetry` +|istio-telemetry container +|v2.0 + +|`global.ouathproxy` +|oauth-proxy container used with various addons +|v1.0/1.1/2.0 + +|`sidecarInjectorWebhook` +|sidecar injector webhook container +|v1.0/1.1 + +|`tracing.jaeger` +|general Jaeger container - not all settings may be applied. Complete customization of Jaeger installation is supported by specifying an existing Jaeger resource in the control plane configuration. +|v1.0/1.1/2.0 + +|`tracing.jaeger.agent` +|settings specific to Jaeger agent +|v1.0/1.1/2.0 + +|`tracing.jaeger.allInOne` +|settings specific to Jaeger allInOne +|v1.0/1.1/2.0 + +|`tracing.jaeger.collector` +|settings specific to Jaeger collector +|v1.0/1.1/2.0 + +|`tracing.jaeger.elasticsearch` +|settings specific to Jaeger elasticsearch deployment +|v1.0/1.1/2.0 + +|`tracing.jaeger.query` +|settings specific to Jaeger query +|v1.0/1.1/2.0 + +|prometheus +|prometheus container +|v1.0/1.1/2.0 + +|kiali +|Kiali container - complete customization of Kiali installation is supported by specifying an existing Kiali resource in the control plane configuration. +|v1.0/1.1/2.0 + +|grafana +|Grafana container +|v1.0/1.1/2.0 + +|3scale +|3scale container +|v1.0/1.1/2.0 + +|`wasmExtensions.cacher` +|WASM extensions cacher container +|v2.0 - tech preview +|=== + +For an example, of how to configure Pilot resource scheduling see xref:../../service_mesh/v2x/customizing-installation-ossm.adoc#ossm-cr-pilot_customizing-installation-ossm[Istio Pilot configuration] + +[id="ossm-upgrading-mig-apps_{context}"] +== Next steps for migrating your applications and workflows + +Move the application workload to the new mesh and remove the old instances to complete your upgrade. \ No newline at end of file