diff --git a/modules/installation-guide/examples/snip_importing-untrusted-tls-certificates_1.adoc b/modules/installation-guide/examples/snip_importing-untrusted-tls-certificates_1.adoc new file mode 100644 index 0000000000..83d2c735d4 --- /dev/null +++ b/modules/installation-guide/examples/snip_importing-untrusted-tls-certificates_1.adoc @@ -0,0 +1,9 @@ +. Save the certificates you need to import, to a local file system. ++ +[CAUTION] +==== +* Certificate files are typically stored as Base64 ASCII files, such as `.pem`, `.crt`, `.ca-bundle`. But, they can also be binary-encoded, for example, as `.cer` files. All Secrets that hold certificate files should use the Base64 ASCII certificate rather than the binary-encoded certificate. +* {prod-short} already uses some reserved file names to automatically inject certificates into the ConfigMap, so you should avoid using the following reserved file names to save your certificates: + ** `ca-bundle.crt` + ** `ca.crt` +==== \ No newline at end of file diff --git a/modules/installation-guide/nav.adoc b/modules/installation-guide/nav.adoc index 66387b1f53..84c248a480 100644 --- a/modules/installation-guide/nav.adoc +++ b/modules/installation-guide/nav.adoc @@ -41,7 +41,7 @@ ** xref:deploying-che-with-support-for-git-repositories-with-self-signed-certificates.adoc[] ** xref:installing-che-using-storage-classes.adoc[] ** xref:configuring-storage-types.adoc[] -** xref:importing-tls-certificates-to-che-server-java-truststore.adoc[] +** xref:importing-untrusted-tls-certificates.adoc[] ** xref:switching-between-external-and-internal-communication.adoc[] * xref:upgrading-che.adoc[] diff --git a/modules/installation-guide/pages/importing-tls-certificates-to-che-server-java-truststore.adoc b/modules/installation-guide/pages/importing-tls-certificates-to-che-server-java-truststore.adoc deleted file mode 100644 index 103bdfc34d..0000000000 --- a/modules/installation-guide/pages/importing-tls-certificates-to-che-server-java-truststore.adoc +++ /dev/null @@ -1,7 +0,0 @@ -[id="importing-tls-certificates-to-che-server-java-truststore"] -// = Importing TLS certificates to Che server Java truststore -:navtitle: Importing TLS certificates to Che server Java truststore -:keywords: installation-guide, importing-tls-certificates-to-che-server-java-truststore -:page-aliases: .:importing-tls-certificates-to-che-server-java-truststore - -include::partial$proc_importing-tls-certificates-to-che-server-java-truststore.adoc[] diff --git a/modules/installation-guide/pages/importing-untrusted-tls-certificates.adoc b/modules/installation-guide/pages/importing-untrusted-tls-certificates.adoc new file mode 100644 index 0000000000..28ee867bad --- /dev/null +++ b/modules/installation-guide/pages/importing-untrusted-tls-certificates.adoc @@ -0,0 +1,7 @@ +[id="importing-untrusted-tls-certificates"] +// = Importing untrusted TLS certificates +:navtitle: Importing untrusted TLS certificates to {prod-short} +:keywords: installation-guide, tls, certificate +:page-aliases: .:importing-untrusted-tls-certificates + +include::partial$proc_importing-untrusted-tls-certificates.adoc[] diff --git a/modules/installation-guide/partials/assembly_advanced-configuration.adoc b/modules/installation-guide/partials/assembly_advanced-configuration.adoc index 322b1679d3..25b108f653 100644 --- a/modules/installation-guide/partials/assembly_advanced-configuration.adoc +++ b/modules/installation-guide/partials/assembly_advanced-configuration.adoc @@ -32,7 +32,7 @@ The next sections describe some specific user stories. * xref:configuring-storage-types.adoc[] -* xref:importing-tls-certificates-to-che-server-java-truststore.adoc[] +* xref:importing-untrusted-tls-certificates.adoc[] * xref:switching-between-external-and-internal-communication.adoc[] diff --git a/modules/installation-guide/partials/proc_importing-tls-certificates-to-che-server-java-truststore.adoc b/modules/installation-guide/partials/proc_importing-tls-certificates-to-che-server-java-truststore.adoc deleted file mode 100644 index 99b2d3dd82..0000000000 --- a/modules/installation-guide/partials/proc_importing-tls-certificates-to-che-server-java-truststore.adoc +++ /dev/null @@ -1,111 +0,0 @@ - - -[id="importing-tls-certificates-to-{prod-id-short}-server-java-trustore_{context}"] -= Importing TLS certificates to {prod-short} server Java truststore - -When {prod-short} server attempts to send an HTTPS request to an external service as {identity-provider}, a proxy or a git server, the connection fails if {prod-short} does not trust the TLS certificate used by the external service. - -To fix this problem, configure {prod-short} to authorize HTTPS communication with external services, such as identity and Git servers, by adding information about the TLS certificates to the {prod-short} configuration. - -.Prerequisites - -* The `{orch-cli}` tool is available. - -.Procedure - -. Save the external services certificates to a local file system. - -. Create a new configMap with the required TLS certificates: -+ -[subs="+attributes,+quotes"] ----- -$ {orch-cli} create configmap ____ --from-file=____ -n=__<{project-context}-namespace-name>__ ----- -+ -To apply more than one certificate, add another `--from-file=__` option to the above command. - -. Update the existing {prod-short} server configuration -+ -NOTE: Use these steps with existing instances of {prod-short}. To install a new instance of {prod-short} with self-signed TLS certificates, create a new `CheCluster` Custom Resource or Helm Chart property, based on the installation method selected, instead of updating the existing configuration. -+ -==== -** For a {prod-short} link:https://docs.openshift.com/container-platform/latest/operators/olm-what-operators-are.html[Operators] deployment: - -* Define a name for the newly created configMap by editing the `spec.server.ServerTrustStoreConfigMapName` `CheCluster` Custom Resource property to match the previously created configMap: -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} patch checluster {prod-checluster} -n che --type=json -p '[{"op": "replace", "path": "/spec/server/serverTrustStoreConfigMapName", "value": "____"}]' ----- -==== -+ -ifeval::["{project-context}" == "che"] -==== -** For a {prod-short} link:https://helm.sh/[Helm Chart] deployment: -+ -. Clone the https://github.com/eclipse/che[che] project. -. Go to the `deploy/kubernetes/helm/che` directory. -. Define a name for the newly created configMap by editing the `global.tls.serverTrustStoreConfigMapName` Helm Chart property to match the previously created configMap: -+ -[subs="+quotes",options="nowrap",role=white-space-pre] ----- -$ helm upgrade che -n che --set global.tls.serverTrustStoreConfigMapName=____ \ - --set global.ingressDomain=____ . ----- -+ -When using Minikube to run {prod-short}, substitute __ with `$(minikube ip).nip.io`. -==== -endif::[] - -.Verification - -If the certificates have been added correctly, the {prod-short} server starts and obtains {identity-provider} configuration over HTTPS. Otherwise here is a list of things to verify: - -- CheCluster attribute `serverTrustStoreConfigMapName` value matches the name of the ConfigMap. Get the value using the following command : -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} get -o json checluster/{prod-checluster} -n {prod-namespace} | jq .spec.server.serverTrustStoreConfigMapName ----- -+ -- {prod-short} Pod Volumes list contains one Volume that uses the ConfigMap as data-source. To get the list of Volumes of the {prod-short} Pod: -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} get po -o json __<{prod-id-short}-pod-name>__ -n {prod-namespace} | jq .spec.volumes ----- -+ -- Certificates are mounted in folder `/public-certs/` of the {prod-short} server container. This command returns the list of files in that folder: -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} exec -t __<{prod-id-short}-pod-name>__ -n {prod-namespace} -- ls /public-certs/ ----- -+ -- In the {prod-short} server logs there is a line for every certificate added to the Java truststore, including {prod-short} self signed certificate. -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} logs __<{prod-id-short}-pod-name>__ -n {prod-namespace} -(...) -Found a custom cert. Adding it to java trust store based on /usr/lib/jvm/java-1.8.0/jre/lib/security/cacerts -(...) ----- -+ -- ${prod-short} server Java trustore contains the certificates. The certificates SHA1 fingerpints are among the list of the SHA1 of the certificates included in the trustore returned by the following command: -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ {orch-cli} exec -t __<{prod-id-short}-pod-name>__ -n {prod-namespace} -- keytool -list -keystore /home/che/cacerts -Your keystore contains 141 entries - -(...) ----- -+ -To get the SHA1 hash of a certificate on the local filesystem: -+ -[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] ----- -$ openssl x509 -in ____ -fingerprint -noout -SHA1 Fingerprint=3F:DA:BF:E7:A7:A7:90:62:CA:CF:C7:55:0E:1D:7D:05:16:7D:45:60 ----- diff --git a/modules/installation-guide/partials/proc_importing-untrusted-tls-certificates.adoc b/modules/installation-guide/partials/proc_importing-untrusted-tls-certificates.adoc new file mode 100644 index 0000000000..7a8703ca15 --- /dev/null +++ b/modules/installation-guide/partials/proc_importing-untrusted-tls-certificates.adoc @@ -0,0 +1,300 @@ + + +[id="importing-untrusted-tls-certificates_{context}"] += Importing untrusted TLS certificates to {prod-short} + +Internal communications between {prod-short} components are, by default, encrypted with TLS. Communications of {prod-short} components with external services such as proxies, source code repositories, identity providers may require TLS tool. Those communications require the use of SSL certificates signed by trusted Certificate Authorities. + +When the certificates used by {prod-short} components or by an external service are signed by an untrusted CA it can be necessary to import the CA certificate in the {prod-short} installation, so that every {prod-short} component will consider them as signed by a trusted CA. + +Typical cases that may require this addition are: + +* when the underlying Kubernetes cluster uses TLS certificates signed by a CA that is not trusted, +* when {prod-short} server or workspace components connect to external services such as {identity-provider} or a Git server that use TLS certificates signed by an untrusted CA. + +To store those certificates, {prod-short} uses a dedicated ConfigMap. Its default name is `ca-certs` but {prod-short} allows configuring its name. + +[NOTE] +==== +ifeval::["{project-context}" == "che"] +On OpenShift, when +endif::[] +ifeval::["{project-context}" != "che"] +When +endif::[] +the cluster contains cluster-wide trusted CA certificates added through the link:https://docs.openshift.com/container-platform/4.4/networking/configuring-a-custom-pki.html#nw-proxy-configure-object_configuring-a-custom-pki[cluster-wide-proxy configuration], {prod-short} Operator detects them and automatically injects them into this ConfigMap: + +- {prod-short} automatically labels the ConfigMap with the `config.openshift.io/inject-trusted-cabundle="true"` label. +- Based on this annotation, OpenShift automatically injects the cluster-wide trusted CA certificates inside the `ca-bundle.crt` key of ConfigMap +==== + +== At {prod-short} installation time + +.Prerequisites + +* The `{orch-cli}` tool is available. +* You are ready to create `CheCluster` custom resource. + +.Procedure + +include::example$snip_importing-untrusted-tls-certificates_1.adoc[] + +. Create a new ConfigMap with the required TLS certificates: ++ +[subs="+attributes,+quotes"] +---- +$ {orch-cli} create configmap ca-certs --from-file=____ -n=__<{project-context}-namespace-name>__ +---- ++ +To apply more than one certificate, add another `--from-file=__` option to the above command. + +. During the installation process, when creating the `CheCluster` custom resource, take care of configuring the right name for the created ConfigMap. ++ +==== +For a {prod-short} link:https://docs.openshift.com/container-platform/latest/operators/olm-what-operators-are.html[Operator] deployment, +ensure you add the `spec.server.ServerTrustStoreConfigMapName` field with the name of the ConfigMap, to the `CheCluster` Custom Resource you will create during the installation: + +[source,yaml,subs="+quotes",options="nowrap",role=white-space-pre] +---- +spec: + server: + ... + spec.server.ServerTrustStoreConfigMapName: ca-certs +---- +==== +ifeval::["{project-context}" == "che"] ++ +==== +For a {prod-short} link:https://helm.sh/[Helm Chart] deployment, ensure you override the `global.tls.serverTrustStoreConfigMapName` Helm Chart property with the name of the ConfigMap when installing the {prod-short} Helm Chart. For this you should add the following arguments to the Helm command line: +[subs="+quotes",options="nowrap",role=white-space-pre] +---- +--set global.tls.serverTrustStoreConfigMapName=ca-certs +---- +==== +endif::[] + +== On already-running {prod-short} installations + +.Prerequisites + +* The `{orch-cli}` tool is available. + +* You should first gather the name of the ConfigMap used to import certificates: ++ +==== +On instances of {prod-short} deployed with the {prod-short} link:https://docs.openshift.com/container-platform/latest/operators/olm-what-operators-are.html[Operator], +retrieve the name of the ConfigMap by reading the `spec.server.ServerTrustStoreConfigMapName` `CheCluster` Custom Resource property: + +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get checluster {prod-checluster} -n __<{project-context}-namespace-name>__ -o jsonpath={.spec.server.serverTrustStoreConfigMapName} +---- +==== +ifeval::["{project-context}" == "che"] ++ +==== +On instances of {prod-short} deployed with the {prod-short} link:https://helm.sh/[Helm Chart] deployment, retrieve the name of the ConfigMap by reading the `global.tls.serverTrustStoreConfigMapName` property from the Helm Chart: + +[subs="+quotes",options="nowrap",role=white-space-pre] +---- +$ helm get values che --all --output json | jq -r '.global.tls.serverTrustStoreConfigMapName' +---- +==== +endif::[] ++ +[NOTE] +==== +If the existing installation did not define any name for the ConfigMap, just use `ca-certs`. +==== + +.Procedure + +include::example$snip_importing-untrusted-tls-certificates_1.adoc[] + +. Add the required TLS certificates in the ConfigMap: ++ +[subs="+attributes,+quotes"] +---- +$ {orch-cli} create configmap ____ --from-file=____ -n=__<{project-context}-namespace-name>__ -o yaml --dry-run | {orch-cli} apply -f - +---- ++ +To apply more than one certificate, add another `--from-file=__` option to the above command. + +. Configure the {prod-short} installation to use the ConfigMap: ++ +==== +For a {prod-short} link:https://docs.openshift.com/container-platform/latest/operators/olm-what-operators-are.html[Operators] deployment: + +. Edit the `spec.server.ServerTrustStoreConfigMapName` `CheCluster` Custom Resource property to match the name of the ConfigMap: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} patch checluster {prod-checluster} -n __<{project-context}-namespace-name>__ --type=json -p '[{"op": "replace", "path": "/spec/server/serverTrustStoreConfigMapName", "value": ""}]' +---- ++ +==== +ifeval::["{project-context}" == "che"] ++ +==== +For a {prod-short} link:https://helm.sh/[Helm Chart] deployment: + +. Clone the https://github.com/eclipse/che[che] project. +. Go to the `deploy/kubernetes/helm/che` directory. +. Update the name of the configMap {prod-short} will use, by editing the `global.tls.serverTrustStoreConfigMapName` Helm Chart property to match the created or updated ConfigMap: ++ +[subs="+quotes",options="nowrap",role=white-space-pre] +---- +$ helm upgrade che -n che --set global.tls.serverTrustStoreConfigMapName= \ + --set global.ingressDomain=____ . +---- ++ +When using Minikube to run {prod-short}, substitute __ with `$(minikube ip).nip.io`. +==== +endif::[] + +. Restart the {prod-short} Operator, the {prod-short} server and {identity-provider} to load the new certificates: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ kubectl rollout restart -n __<{project-context}-namespace-name>__ deployment/{prod-id-short}-operator +$ kubectl rollout restart -n __<{project-context}-namespace-name>__ deployment/{prod-id-short}/keycloak +$ kubectl rollout restart -n __<{project-context}-namespace-name>__ deployment/{prod-id-short} +---- ++ +[NOTE] +==== +Restarting the {prod-short} components is not required anymore on {prod-short} +ifeval::["{project-context}" == "che"] +v7.20.0 +endif::[] +ifeval::["{project-context}" != "che"] +2.5.0 +endif::[] +and higher. +==== + +== Verification at the {prod-short} installation level + +If you added the certificates without error, the {prod-short} server starts and obtains {identity-provider} configuration over https. Otherwise here is a list of things to verify: + +- In case of a {prod-short} link:https://docs.openshift.com/container-platform/latest/operators/olm-what-operators-are.html[Operator] deployment, the `CheCluster` attribute `serverTrustStoreConfigMapName` value matches the name of the ConfigMap. Get the value using the following command : ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get -o json checluster/{prod-checluster} -n __<{project-context}-namespace-name>__ | jq .spec.server.serverTrustStoreConfigMapName +---- ++ +- {prod-short} Pod Volumes list contains one Volume that uses the ConfigMap as data-source. To get the list of Volumes of the {prod-short} Pod: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get pod -o json __<{prod-id-short}-pod-name>__ -n __<{project-context}-namespace-name>__ | jq .spec.volumes +---- ++ +- {prod-short} mounts certificates in folder `/public-certs/` of the {prod-short} server container. This command returns the list of files in that folder: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} exec -t __<{prod-id-short}-pod-name>__ -n __<{project-context}-namespace-name>__ -- ls /public-certs/ +---- ++ +- In the {prod-short} server logs there is a line for every certificate added to the Java truststore, including configured {prod-short} certificates. ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} logs __<{prod-id-short}-pod-name>__ -n __<{project-context}-namespace-name>__ +(...) +Found a custom cert. Adding it to java trust store based on /usr/lib/jvm/java-1.8.0/jre/lib/security/cacerts +(...) +---- ++ +- ${prod-short} server Java truststore contains the certificates. The certificates SHA1 fingerprints are among the list of the SHA1 of the certificates included in the truststore returned by the following command: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} exec -t __<{prod-id-short}-pod-name>__ -n {prod-namespace} -- keytool -list -keystore {prod-home}/cacerts +Your keystore contains 141 entries + +(...) +---- ++ +To get the SHA1 hash of a certificate on the local filesystem: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ openssl x509 -in ____ -fingerprint -noout +SHA1 Fingerprint=3F:DA:BF:E7:A7:A7:90:62:CA:CF:C7:55:0E:1D:7D:05:16:7D:45:60 +---- + +== Verification at the workspace level + +- Start a workspace, get the Kubernetes namespace in which it has been created, and wait for it to be started + +- Get the name of the workspace Pod with the following command: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get pods -o=jsonpath='{.items[0].metadata.name}' -n ____ | grep '^workspace.*' +---- + +- Get the name of the theia IDE container in the workspace POD with the following command: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get -o json pod ____ -n ____ | \ + jq -r '.spec.containers[] | select(.name | startswith("theia-ide")).name' +---- + +- Look for a `ca-certs` ConfigMap that should have been created inside the workspace namespace: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get cm ca-certs ____ +---- + +- Check that the entries in the `ca-certs` config map contain all the additional entries you added in the certificate ConfigMap at the {prod-short} installation level, in addition to the the `ca-bundl.crt` entry which is a reserved one: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get cm ca-certs -n ____ -o json | jq -r '.data | keys[]' +ca-bundle.crt +manually-added-certificate.crt +---- + +- Make sure that the `ca-certs` ConfigMap has been added as a volume in the workspace Pod: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get -o json pod ____ -n ____ | \ + jq '.spec.volumes[] | select(.configMap.name == "ca-certs")' +{ + "configMap": { + "defaultMode": 420, + "name": "ca-certs" + }, + "name": "che-self-signed-certs" +} +---- + +- Confirm that the volume has been mounted into containers, especially in the Theia IDE container: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} get -o json pod ____ -n ____ | \ + jq '.spec.containers[] | select(.name == "____").volumeMounts[] | select(.name == "che-self-signed-certs")' +{ + "mountPath": "/public-certs", + "name": "che-self-signed-certs", + "readOnly": true +} +---- + +- Inspect `/public-certs` folder on the Theia IDE container and check that its contents match the list of entries in the `ca-certs` ConfigMap: ++ +[subs="+attributes,+quotes",options="nowrap",role=white-space-pre] +---- +$ {orch-cli} exec ____ -c ____ -n ____ -- ls /public-certs +ca-bundle.crt +manually-added-certificate.crt +---- ++