Use OpenSSL-based images with custom CA certificates

In OpenSSL-based container images, such as curl and nginx, you can make your custom root Certificate Authority (CA) certificates available to the image. Your application can then establish secure TLS connections to services that use certificates signed by your company’s CA.

Replace system CA certificates in OpenSSL-based images by using Podman

Use the Podman volume mount option to override the image’s Certificate Authority (CA) bundle if you require only a custom certificate bundle in an OpenSSL-based image. The application in your image then uses only the custom bundle.

Before you begin

  • The podman package is installed.
  • You have the CA certificate bundle in PEM format.

Procedure

When you start the container, use a bind mount to pass the certificate bundle to the container. For example:
$ podman run \
    --rm \
    --volume <path_to_certificate_bundle>.pem:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro,Z \
    registry.access.redhat.com/hi/<image>
Important

This approach replaces the image’s built-in CA certificate bundle. If you require that your container trusts multiple CAs, ensure that all required CA certificates are part of the file that you mount to the container.

Replace system CA certificates by injecting the cluster-wide CA bundle in OpenSSL-based images on OpenShift Container Platform

If you require only a custom certificate bundle in an OpenSSL-based image, you can use an OpenShift Container Platform ConfigMap to override the image’s Certificate Authority (CA) bundle. The application in your image then uses only the custom bundle.

Before you begin

  • You have access to OpenShift Container Platform CLI.
  • The cluster administrator added the custom CA bundle to the cluster-wide proxy.
  • You have the permissions to create ConfigMaps and modify Pod specifications in the target namespace.

Procedure

  1. Display the name of the ConfigMap that contains the cluster-wide trusted certificates:
    $ oc get proxy/cluster -o jsonpath='{.spec.trustedCA.name}'
    ca-bundle
  2. Create a YAML configuration file that both requests the cluster-wide CA bundle and defines the volume mount necessary for your application to access it:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: trusted-ca
      labels:
        config.openshift.io/inject-trusted-cabundle: "true"
    ---
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: app
        image: registry.access.redhat.com/hi/<image>:latest
        volumeMounts:
        - name: trusted-ca
          mountPath: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
          subPath: ca-bundle.crt
          readOnly: true
      volumes:
      - name: trusted-ca
        configMap:
          name: trusted-ca

    This configuration uses the config.openshift.io/inject-trusted-cabundle: "true" label to trigger the automatic injection of the cluster CA bundle into the ConfigMap. The subPath: ca-bundle.crt property mounts the certificate at the path required by OpenSSL.

  3. Apply the configuration:
    $ oc apply -f <configuration_file>.yaml

Replace system CA certificates by injecting a custom CA bundle in OpenSSL-based images on OpenShift Container Platform

If you require only a custom certificate bundle in an OpenSSL-based image, you can use an OpenShift Container Platform ConfigMap to override the image’s Certificate Authority (CA) bundle. The application in your image then uses only the custom bundle.

Before you begin

  • You have access to OpenShift Container Platform CLI.
  • You have the CA certificate bundle in PEM format.
  • You have the permissions to create ConfigMaps and modify Pod specifications in the target namespace.

Procedure

  1. Create a YAML configuration file that both defines the CA bundle and the volume mount necessary for your application to access it:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: custom-ca-bundle
    data:
      tls-ca-bundle.pem: |
        -----BEGIN CERTIFICATE-----
        <certificate>
        -----END CERTIFICATE-----
        <more_certificates_if_needed>
    ---
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: app
        image: registry.access.redhat.com/hi/<image>:latest
        volumeMounts:
        - name: custom-ca
          mountPath: /etc/pki/ca-trust/extracted/pem
          readOnly: true
      volumes:
      - name: custom-ca
        configMap:
          name: custom-ca-bundle
  2. Apply the configuration:
    $ oc apply -f <configuration_file>.yaml

Create a modified OpenSSL-based image to add custom root CA certificates

If you require that an OpenSSL-based image trusts both your custom Certificate Authorities (CAs) and the image’s built-in default CAs, create a modified image to add the custom certificates.

Before you begin

  • The podman package is installed.

Procedure

  1. Create a project directory. For example:
    $ mkdir ~/project/
  2. Copy the custom CA certificate to your project directory:
    $ cp <path>/custom-root-ca.pem ~/project/
  3. Create a file named ~/project/Containerfile, that references the Red Hat Hardened Images in the FROM instructions. For example:
    # Build stage:
    FROM registry.access.redhat.com/hi/curl:latest-builder AS builder
    
    # Copy the certificate to the image
    COPY custom-root-ca.pem /tmp/
    
    # Temporarily switch to root to add the CA certificate to the truststore
    USER root
    RUN trust anchor /tmp/custom-root-ca.pem
    USER ${CONTAINER_DEFAULT_USER}
    
    
    # Runtime stage:
    # Copy the truststore from the builder image to the runtime image
    FROM registry.access.redhat.com/hi/curl:latest
    COPY --from=builder /etc/pki/ca-trust/extracted /etc/pki/ca-trust/extracted
  4. Build the custom image:
    $ podman build -t <image_name> ~/project/

    The -t <image_name> option specifies the name of the image after the build process.

  5. Optional: Display the list of images:
    $ podman image list
    REPOSITORY             TAG     IMAGE ID      CREATED        SIZE
    localhost/<image_name> latest  2cd25ce7a7ef  2 minutes ago  51 MB
  6. Create a container that uses the image. For example:
    $ podman run --rm <image_name>:latest https://intranet.example.com