MQ

MQ

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only

.NET app hosted inside the container(Redhat - Linux) connecting to MQ with TLS

By Shivaprasad D N posted yesterday

  

Pre-Requisites
1. Docker runtime
2. .NET runtime
3. Two set of certs/keys(ex : CA-Cert.crt, Client-key.p12)

MQ Server Setup : 
create a directory "keys", navigate to "keys" directory in terminal/command-prompt and run the commands listed below.

    Creating CA Certificates

        Create a Key Repository for the CA 
        runmqakm -keydb -create -db myCA.kdb -type cms

        Create your self-signed CA Certificate
        runmqakm -cert -create -db myCA.kdb -type cms -label "myCAcertificate" -dn "CN=MyCA,O=myOrganisation,OU=myDepartment,L=myLocation,C=IN" -expire 1000 -size 4096 -sig_alg SHA256WithRSA -ca true

        Extract the CA Certificate  
        runmqakm -cert -extract -db myCA.kdb -type cms -label "myCAcertificate" -target myCAcertfile.crt -format ascii


    Creating Queue Manager Certificates

        Create a Key Repository for the Queue Manager Certificate 
        runmqakm -keydb -create -db qm.kdb -type cms -stash

        Generate a certificate request file for the queue manager,along with a private key 
        runmqakm -certreq -create -db qm.kdb -type cms -dn "CN=QM,O=myOrganisation,OU=myDepartment,L=myLocation,C=IN" -label "ibmwebspheremqqm" -file qm.req -sig_alg SHA256WithRSA -size 4096

        -label : should be "ibmwebspheremq<qmgrname>"
        -size : should be 4096KB

        Sign the Queue Manager certificate with CA 
        runmqakm -cert -sign -db myCA.kdb -label "myCAcertificate" -expire 365 -format ascii -file qm.req -target qm.crt

        Add the public certificate of the CA to the key repository of the queue manager 
        runmqakm -cert -add -db qm.kdb -type cms -file myCAcertfile.crt -label "theCAcert"

        Receive the certificate (now signed by the CA) into the queue manager’s key repository: 
        runmqakm -cert -receive -db qm.kdb -type cms -file qm.crt

    Note : Set the path name for Queue Manager's key repository. We will be using a Queue Manager by name 'qm'. The &KDB_PATH& refers to the path where the qm.kdb has been created.


    Create and configure a Queue Manager for the SSL connectivity

    crtmqm <QueueManager>
    strmqm <QueueManager>
    runmqsc <QueueManager>
    ALTER QMGR SSLKEYR('&KDB_PATH&\qm')
    DEFINE CHANNEL(<ChannelName>) CHLTYPE(SVRCONN) TRPTYPE(TCP)
    SSLCAUTH(REQUIRED) SSLCIPH('ANY_TLS12_OR_HIGHER')
    DEFINE QLOCAL(<QueueName>)
    DEFINE LISTENER(<ListenerName>) TRPTYPE(TCP) PORT(1414)
    START LISTENER(<ListenerName>)
    REFRESH SECURITY(*)

    Create Client Certificates

        Creating a Key Repository for the Client Application 
        runmqakm -keydb -create -db myapp.p12 -type pkcs12 -stash -pw "password"

        Create a Certificate Request 
        runmqakm -certreq -create -db myapp.p12 -type pkcs12 -label "ibmwebspheremqroot" -dn "CN=myApp,O=myOrganisation,OU=myDepartment,L=myLocation,C=IN" -file myapp.req -size 4096 -sig_alg SHA256WithRSA

        -label : Should be "ibmwebspheremq<active-user-name>"

        Sign the application cert with the CA 
        runmqakm -cert -sign -db myCA.kdb -label "myCAcertificate" -expire 365 -format ascii -file myapp.req -target myapp.crt

        Add the CA certificate to the key repository of the application 
        runmqakm -cert -add -db myapp.p12 -type pkcs12 -file myCAcertfile.crt -label "theCAcert"

        Receive the certificate (now signed by the CA) into the application’s key repository 
        runmqakm -cert -receive -db myapp.p12 -type pkcs12 -file myapp.crt


Follow below steps in the Client machine(RHEL) :

First, We will install the certificates and add the CA to the trusted store on the local Linux machine, then use the same certs within the container.

Local Linux Machine Steps :
    In Linux, certificates are managed by OpenSSL. There are two types of certificates that need to be installed/added to the personal/trusted store :
        1. Private Key of the Client. 
        2. CA certificate which is used to sign both Queue-Manager and Client’s certificates.

    1. Installing the Private key of the client : On Linux, you can install the client’s private key through a piece of code, similar to the approach you have already followed.
        The private key is typically stored in a .pfx (PKCS#12) format during installation.

        The below piece of code will install the cert. The program has to be updated with appropriate keystore and password values. The sample code below uses the keystore "myapp.p12" and password used to create that keystore. Make sure you provide the correct path to the client key(myapp.p12). 

for ex., X509Certificate2 certificate1 = new X509Certificate2("/path/to/the/key/myapp.p12", "*****");

        Note : The *.pfx files will be installed into this directory "/root/.dotnet/corefx/cryptography/x509stores/my/".

                        try
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadWrite);
                X509Certificate2 certificate1 = new X509Certificate2("myapp.p12", "*****");

                //Create a collection and add two of the certificates.
                X509Certificate2Collection collection = new X509Certificate2Collection();
                collection.Add(certificate1);
                
                //Add certificates to the store.
                store.Add(certificate1);
                store.AddRange(collection);
                X509Certificate2Collection collection2 = new X509Certificate2Collection();
                collection2.Import("myapp.p12", "*****", X509KeyStorageFlags.PersistKeySet);

                foreach (X509Certificate2 cert in collection2)
                {
                    store.Add(cert);
                    Console.WriteLine("Certificate installed successfully");
                }
            }
            catch (Exception e)
            {
                throw e;
            }

    2. Adding the CA into trusted Store : The CA we used to sign the client and Queue-Manager certificate need to be added to the trusted store.
        Navigate to "/etc/pki/ca-trust/source/anchors/" directory, place a copy of the CA certificate in this folder. ex., "CA.crt"
        run the "update-ca-trust"
        To verify the CA is added to trusted store, run the "opnessl verify CA.crt", it will log OK if the cert is added.

        Note : It adds the CA into following trusted store "ca-bundle.crt and ca-bundle.trust.crt". Path to ca-bundle.crt and ca-bundle.trust.crt is "/etc/ssl/certs/"

Inside the Container :

    The certs we just installed/added are in the Local linux machine, the application inside the container cannot access private-key or ca-bundle to verify the server certificate.
    So, we need to add the installed *.pfx, ca-bundle.crt and ca-bundle.trust.crt into container as well.

    Let's start by creating a directory which conatins all the pre-requisites.
    1. Create a new directory "SimplePut"
    2. Copy SimplePut.cs and SimplePut.csproj files to the SimplePut folder created in Step 1 from the following location:
        Windows : MQ_INST_PATH\tools\dotnet\samples\cs\core\base\SimplePut
        Linux : MQ_INST_PATH/samp/dotnet/samples/cs/core/base/SimplePut
    3. Remove the following line from SimplePut.csproj file
        <HintPath>..\bin\amqmxmsstd.dll</HintPath>
    4. Copy amqmxmsstd.dll file to the SimplePut folder created in Step 1 from the following location:
        Windows : MQ_INST_PATH\bin
        Linux : MQ_INST_PATH/lib64
    5. Get a copy of the *.pfx files from the "/root/.dotnet/corefx/cryptography/x509stores/my/"(Local Machine directory). 
        Create a directory with "certificates", place the copied *.pfx files inside this directory.
        The .NET runtime expects the client's private key to be available in the following default location: /root/.dotnet/corefx/cryptography/x509stores/my/
        We will copy these certifiactes into "/root/.dotnet/corefx/cryptography/x509stores/my/" this location inside the conatiner.
    6. Get a copy of the ca-bundle.crt and ca-bundle.trust.crt from the "/etc/ssl/certs/" (alternate location of ca-bundles "/etc/pki/tls/certs")
        Create a directory with "cabundle", Place both ca-bundle.crt and ca-bundle.trust.crt files inside this directory.
        This is needed to verify whether the certificate sent by the QM(MQServer) is signed by a trusted CA.

Writing the dockerfile :

    1. Create a "dockerfile" inside the SimplePut directory.
    2. copy the below content inside the dockerfile
        # ---- Build Stage ----
    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /app

    # Copy project files and restore dependencies
    COPY *.csproj ./
    RUN dotnet restore

    # Copy the entire source code and build the application
    COPY . ./
    RUN dotnet publish -c Release -o out

    # ---- Runtime Stage ----
    FROM mcr.microsoft.com/dotnet/aspnet:8.0
    WORKDIR /app

    # Copy required certificates
    COPY certificates /root/.dotnet/corefx/cryptography/x509stores/my/
    # copy the installed private key into the default location where the .NET runtime expects it

    COPY cabundle /etc/ssl/certs/
    # copy the CA bundle into the default location where the .NET runtime expects it

    ### RUN grep -i "CN-Name" /etc/ssl/certs/ca-bundle.trust.crt
    ## Uncomment the above line to verify that the CA cert is included in the system CA bundle
    # replace "CN-Name" with the actual common name of your CA cert

    # Copy the published output from the build stage
    COPY --from=build /app/out .

    # Set the entry point
    ENTRYPOINT ["dotnet", "SimplePut.dll"]


Running the dockerfile :

    1. Open command prompt to build the docker image.
    2. To verify whether docker is installed or not, issue the following command on command line as follows:
    docker -v
    Output (latest version): Docker version 28.0.4, build b8034c0
    If not, please install Docker for Linux/windows containers from Docker website.

    3. Navigate to your project folder and use the below command to build your Docker image.
        "docker build -t simpleput ."
        Note: Image_name should be lowercase alphabets.
    4. Docker image with simpleput will be successfully created. Output as follows:
    Building 9.3s (20/20) FINISHED
    ------------------ Output of other commands ----------------
    => exporting to image                                                                                                                                 0.4s 
    => => exporting layers                                                                                                                                0.3s 
    => => writing image sha256:13d6a5964a5852d9419e650b56ff87532e0fc19cf6a42eba0da7447c83dcf567                                                           0.0s 
    => => naming to docker.io/library/simpleput 

    5. Running the Docker Image :
    Issue "docker run simpleput -q queue-name -h host-name -l channel-name -p port-num -k *SYSTEM/*USER -s cipher-spec"
    e.x. docker run simpleput -q LQ -h localhost -l CHL -p 1414 -k *SYSTEM -s TLS_RSA_WITH_AES_128_CBC_SHA256

    Output : 
    Start of SimplePut Application
    MQ Parameters
    1) queueName = queue-name
    2) keyRepository = *SYSTEM/*USER
    3) cipherSpec = cipher-spec
    4) host = host-name
    5) port = port-num
    6) channel = channel-name
    7) numberOfMsgs = 1
    8) sslPeerName = 
    9) keyResetCount = 0
    10) sslCertRevocationCheck = False

    Connecting to queue manager..
    done
    Accessing queue queue-name.. done
    Message 1 <test message>.. put successfully onto the queue
    Closing queue.. done
    Disconnecting queue manager.. done
    End of SimplePut Application

Note : 
1. Keep only one *.pfx certificate in the "certifiactes" directory and try to connect. There will be two *.pfx files present, please place one cert at a time and try out independently for each cert.
2. Verify the key-size for 4096KB, CA-cert and Queue Manager set-up.

0 comments
12 views

Permalink