Configure OPC UA certificates infrastructure for the connector for OPC UA

Important

Azure IoT Operations Preview – enabled by Azure Arc is currently in preview. You shouldn't use this preview software in production environments.

You'll need to deploy a new Azure IoT Operations installation when a generally available release is made available. You won't be able to upgrade a preview installation.

See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.

In this article, you learn how to configure the OPC UA certificates infrastructure for the connector for OPC UA. This configuration lets you determine which OPC UA servers you trust to securely establish a session with.

Based on the OPC UA specification, the connector for OPC UA acts as a single OPC UA application when it establishes secure communications with OPC UA servers. The connector for OPC UA uses the same application instance certificate for all secure channels it opens to your OPC UA servers.

To learn more, see OPC UA certificates infrastructure for the connector for OPC UA.

Prerequisites

A deployed instance of Azure IoT Operations Preview. To deploy Azure IoT Operations for demonstration and exploration purposes, see Quickstart: Run Azure IoT Operations Preview in GitHub Codespaces with K3s.

Configure a self-signed application instance certificate

The default deployment of the connector for OPC UA installs all the resources needed by cert-manager to create an OPC UA compliant self-signed certificate. This certificate is stored in the aio-opc-opcuabroker-default-application-cert secret. This secret is mapped into all the connector for OPC UA pods and acts as the OPC UA client application instance certificate. cert-manager handles the automatic renewal of this application instance certificate.

This configuration is typically sufficient for compliant and secure communication between your OPC UA servers and the connector for OPC UA in a demonstration or exploration environment. For a production environment, use enterprise grade application instance certificates in your deployment.

Configure the trusted certificates list

To connect to an asset, first you need to establish the application authentication mutual trust. For the connector for OPC UA, complete the following steps:

  1. Get the OPC UA server application's instance certificate as a file. These files typically have a .der or .crt extension. This is the public key only.

    Tip

    Typically, an OPC UA server has an interface that lets you export its application instance certificate. This interface isn't standardized. For servers such as KEPServerEx, there's a Windows-based configuration UI for certificates management. Other servers might have a web interface or use operating system folders to store the certificates. Refer to the user manual of your server to find out how to export the application instance certificate. After you have the certificate, make sure it's either DER or PEM encoded. Typically stored in files with either the .der or .crt extension. If the certificate isn't in one of those file formats, use a tool such as openssl to transform the certificate into the required format.

  2. Add the OPC UA server's application instance certificate to the trusted certificates list. This list is implemented as a Kubernetes native secret named aio-opc-ua-broker-trust-list that's created when you deploy Azure IoT Operations.

    For a DER encoded certificate in a file such as ./my-server.der, run the following command:

    # Append my-server.der OPC UA server certificate to the trusted certificate list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=my-server.der=./my-server.der --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{\"data\": $data}"
    

    For a PEM encoded certificate in a file such as ./my-server.crt, run the following command:

    # Append my-server.crt OPC UA server certificate to the trusted certificate list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=my-server.crt=./my-server.crt --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{\"data\": $data}"
    

If your OPC UA server uses a certificate issued by a certificate authority (CA), you can trust the CA by adding its public key certificate to the connector for OPC UA trusted certificates list. The connector for OPC UA now automatically trusts all the servers that use a valid certificate issued by the CA. Therefore, you don't need to explicitly add the OPC UA server's certificate to the connector for OPC UA trusted certificates list.

To trust a CA, complete the following steps:

  1. Get the CA certificate public key encode in DER or PEM format. These certificates are typically stored in files with either the .der or .crt extension. Get the CA's CRL. This list is typically in a file with the .crl. Check the documentation for your OPC UA server for details.

  2. Save the CA certificate and the CRL in the aio-opc-ua-broker-trust-list Kubernetes native secret.

    For a DER encoded CA certificate in a file such as ./my-server-ca.der, run the following commands:

    # Append CA certificate to the trusted certificate list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=my-server-ca.der=./my-server-ca.der --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{`"data`": $data}"
    
    # Append the CRL to the trusted certificate list secret as a new entry
    data=$(kubectl create secret generic temp --from-file= my-server-ca.crl=./ my-server-ca.crl --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{`"data`": $data}"
    

    For a PEM encoded CA certificate in a file such as ./my-server-ca.crt, run the following commands:

    # Append CA certificate to the trusted certificate list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=my-server-ca.crt=./my-server-ca.crt --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{`"data`": $data}"
    
    # Append the CRL to the trusted certificates list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=my-server-ca.crl=./my-server-ca.crl --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-trust-list -n azure-iot-operations -p "{`"data`": $data}"
    

Configure the issuer certificates list

If your OPC UA server uses a certificate issued by a CA, but you don't want to trust all certificates issued by the CA, complete the following steps:

  1. Trust the OPC UA server's application instance certificate by following the first three steps in the previous section.

  2. Besides the certificate itself, the connector for OPC UA needs the CA certificate to properly validate the issuer chain of the OPC UA server's certificate. Add the CA certificate and its certificate revocation list (CRL) to a separate list called aio-opc-ua-broker-issuer-list that's implemented as a Kubernetes secret.

    1. Save the CA certificate and the CRL in the aio-opc-ua-broker-issuer-list secret.

      For a DER encoded certificate in a file such as ./my-server-ca.der, run the following commands:

      # Append CA certificate to the issuer list secret as a new entry
      data=$(kubectl create secret generic temp --from-file=my-server-ca.der=./my-server-ca.der --dry-run=client -o jsonpath='{.data}')
      kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
      
      # Append the CRL to the issuer list secret as a new entry
      data=$(kubectl create secret generic temp --from-file=my-server-ca.crl=./my-server-ca.crl --dry-run=client -o jsonpath='{.data}')
      kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
      

      For a PEM encoded certificate in a file such as ./my-server-ca.crt, run the following commands:

      # Append CA certificate to the issuer list secret as a new entry
      data=$(kubectl create secret generic temp --from-file=my-server-ca.crt=./my-server-ca.crt --dry-run=client -o jsonpath='{.data}')
      kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
      
      # Append the CRL to the issuer list secret as a new entry
      data=$(kubectl create secret generic temp --from-file=my-server-ca.crl=./my-server-ca.crl --dry-run=client -o jsonpath='{.data}')
      kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
      

Configure your OPC UA server

To complete the configuration of the application authentication mutual trust, you need to configure your OPC UA server to trust the connector for OPC UA application instance certificate:

  1. To extract the connector for OPC UA certificate into a opcuabroker.crt file, run the following command:

    kubectl -n azure-iot-operations get secret aio-opc-opcuabroker-default-application-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > opcuabroker.crt
    
  2. Many OPC UA servers only support certificates in the DER format. If necessary, use the following command to convert the opcuabroker.crt certificate to opcuabroker.der:

    openssl x509 -outform der -in opcuabroker.crt -out opcuabroker.der
    
  3. Consult the documentation of your OPC UA server to learn how to add the opcuabroker.crt or opcuabroker.der certificate file to the server's trusted certificates list.

Configure an enterprise grade application instance certificate

For production environments, you can configure the connector for OPC UA to use an enterprise grade application instance certificate. Typically, an enterprise CA issues this certificate and you need the CA certificate to your configuration. Often, there's a hierarchy of CAs and you need to add the complete validation chain of CAs to your configuration.

The following example references the following items:

Item Description
opcuabroker-certificate.der File that contains the enterprise grade application instance certificate public key.
opcuabroker-certificate.pem File that contains the enterprise grade application instance certificate private key.
subjectName The subject name string embedded in the application instance certificate.
applicationUri The application instance URI embedded in the application instance.
enterprise-grade-ca-1.der File that contains the enterprise grade CA certificate public key.
enterprise-grade-ca-1.crl The CA's CRL file.

Like the previous examples, you use a dedicated Kubernetes secret to store the certificates and CRLs. To configure the enterprise grade application instance certificate, complete the following steps:

  1. Save the certificates and the CRL in the aio-opc-ua-broker-client-certificate secret by using the following command:

    # Create aio-opc-ua-broker-client-certificate secret
    # Upload OPC UA public key certificate as an entry to the secret
    # Upload OPC UA private key certificate as an entry to the secret
    kubectl create secret generic aio-opc-ua-broker-client-certificate -n azure-iot-operations  \
      --from-file=opcuabroker-certificate.der=./opcuabroker-certificate.der \
      --from-file=opcuabroker-certificate.pem=./opcuabroker-certificate.pem
    
  2. If you use the CA to issue certificates for your OPC UA broker, configure the aio-opc-ua-broker-issuer-list secret. Use a Kubernetes client such as kubectl to configure the secrets enterprise-grade-ca-1.der and enterprise-grade-ca-1.crl:

    # Append CA certificate to the issuer list secret as a new entry
    data=$(kubectl create secret generic temp --from-file=enterprise-grade-ca-1.der=./enterprise-grade-ca-1.der --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
    
    # Append the CRL to the issuer list secret as a new entry
    data=$(kubectl create secret generic temp --from-file= enterprise-grade-ca-1.crl=./enterprise-grade-ca-1.crl --dry-run=client -o jsonpath='{.data}')
    kubectl patch secret aio-opc-ua-broker-issuer-list -n azure-iot-operations -p "{`"data`": $data}"
    
  3. Update the connector for OPC UA deployment to use the new secret source for application instance certificates by using the following command:

    az k8s-extension update \
        --version 0.7.0-preview \
        --name azure-iot-operations-qlll2 \
        --release-train preview \
        --cluster-name <cluster-name> \
        --resource-group <azure-resource-group> \
        --cluster-type connectedClusters \
        --auto-upgrade-minor-version false \
        --config connectors.values.securityPki.applicationCert=aio-opc-ua-broker-client-certificate \
        --config connectors.values.securityPki.subjectName=<subjectName> \
        --config connectors.values.securityPki.applicationUri=<applicationUri>
    

Now that the connector for OPC UA uses the enterprise certificate, don't forget to add the new certificate's public key to the trusted certificate lists of all OPC UA servers it needs to connect to.