Using Fortanix Confidential Computing Manager to Build an Enclave OS Nginx Application

1.0 Introduction

This guide will walk you through creating an Enclave OS Nginx application that will use the HTTPS protocol for communication. The application will use a certificate issued by the Fortanix Confidential Computing Manager (CCM) to establish the HTTPS protocol and the application will be deployed on a Virtual Machine in Azure.

2.0 Prerequisites

  • A Fortanix CCM account.

  • A Microsoft Azure account.

  • Deploy Fortanix Node Agent from the Azure marketplace as described in Step 6 of the Quickstart Guide – Fortanix.

  • On the virtual machine, install docker using the following command:

    sudo apt install docker.io

3.0 Using CLI

3.1 Authenticate with Fortanix CCM

Before you can issue any requests, you first need to authenticate to Fortanix CCM using the following commands:

NOTE

Session tokens are short-lived and you will occasionally have to issue a refresh API request whenever you get {"message": "Forbidden", "code": "FORBIDDEN"}.

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/refresh
cpath=$(mktemp -p "/tmp" -t "fortanix_ccm_cookie.XXXXX")

TIP

For security reasons, it is best not to type in your credentials in the terminal windows. Instead, create a file to hold the credentials and pass the file to curl as shown below.

machine ccm.fortanix.com login <username> password <password>

where,<username> and <password> need to be replaced with the email address and password of your Fortanix CCM account.

curl --netrc-file access-file -c $cpath -X POST https://ccm.fortanix.com/v1/sys/auth

3.2 Get all Accounts

Use the GET command shown below to get all the accounts and select the account using the account_id.

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/accounts

3.3 Select the Account

NOTE

if you have multiple accounts with CCM you may see a large response for the previous request. Each account starts with the name of the account, followed by the acct_id, as shown below. Make sure to select the acct_id, which belongs to the account you want to deploy your application with. {"name":"fortanix-test","acct_id":"e5fd5441-4ffc-4a4c-af63-bddb488524c2","created_at":1609863607000,"roles":["MANAGER"],"status":"ACTIVE","features":["workflows"],"approval_state":"APPROVED"}

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X POST https://ccm.fortanix.com/v1/sys/session/select_account/<acct_id>

To create an Nginx application, you must first create a docker image with SSL enabled and deploy it to a public registry.

3.4.1 Nginx Configuration File to Enable SSL to Listen on Port 443

Create a default.conf file which is used by Nginx as shown below:

server {
    listen 443;
    ssl on;
    ssl_certificate /etc/ssl/nginx.crt;
    ssl_certificate_key /etc/ssl/nginx.key;
    server_name localhost;
    server_tokens off;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}
#redirect server error pages to the static page /50x.html

3.4.2 Dockerfile for Creating an Nginx Docker Container

The docker file fetches the latest Nginx container from dociker.io and updates the container with the new configuration created above.

FROM nginx:latest

COPY default.conf /etc/nginx/conf.d/

Build the docker on your local system and push it to your desired registry.

docker build -t /nginx-ssl-nocert:latest .

docker push /nginx-ssl-nocert

NOTE

Replace <repository-prefix> with your public or private repository prefix

3.4.3 Create the app.json file

Create the app.json config file that contains the application details.

{
    "name":"nginx-ssl-fortanix-cert",
    "description":"nginx web server app with SSL enabled.",
    "input_image_name":"<registry>/nginx-ssl-nocert",
    "output_image_name":"<registry>/nginx-ssl-fortanix-cert-eos",
    "default_build_settings": {
        "sgx": {},
        "nitro_enclaves": {
            "cpu_count": 2,
            "mem_size": 1024,
            "enable_overlay_filesystem_persistence": true
        }
    },
    "group_id": "a8e8395e-096d-4eb8-9017-2098f2ab8327",
    "allowed_domains":["fortanix-nginx.canadacentral.cloudapp.azure.com"],
    "advanced_settings":
       {
               "entrypoint": [],
               "manifestEnv": [],
               "encryptedDirs": []
               "rw_dirs": ["/var/cache/nginx", "/etc/ssl"],
               "certificate":
               {
                       "issuer":"MANAGER_CA",
                       "subject":"fortanix-nginx.canadacentral.cloudapp.azure.com",
                       "keyType":"RSA",
                       "keyParam":{"size":2048},
                       "keyPath":"/etc/ssl/nginx.key",
                       "certPath":"/etc/ssl/nginx.crt"
               }
       },
    "custom_metadata": {
        "app_type": "ENCLAVE_OS"
    }
}

NOTE

Replace <repository-prefix> with the location of your registry used previously where the Nginx container was pushed.

The certificate and private key will be generated by Fortanix CCM at the time of deployment and Enclave OS will place them in the default path of Nginx when the container runs in Azure.

As part of the config, you must specify the domain URL for whitelisting by Fortanix CCM so that the Enclave OS can be accessed. The same domain URL is assigned to the certificate so that the public certificate can be generated against this domain. As an example, in this case, we created http://fortanix-nginx.canadacentral.cloudapp.azure.com, but this can be any URL of your choice. DNS record will need to be set up in your infrastructure to route to the VM for this domain.

3.4.5 Create Application

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -H "Content-Type: application/json" -d @app.json -X POST https://ccm.fortanix.com/v1/apps

Note the app_id value returned as part of the above command. It will be used later.

As an example: "app_id":"de40482c-2092-4a25-b9a2-635eb55c5d97"

3.5 Fetch the Domain Whitelisting Tasks

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/tasks?task_type=DOMAIN_WHITELIST > all_domain_tasks.json

All the tasks fetched will be stored in all_domain_tasks.json file. Select the task_id to approve the task in the next step.

3.6 Approve a Task

Among the tasks fetched in the previous step, approve the application-specific task using the task_id.

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d '{"status":"APPROVED"}' -X PATCH https://ccm.fortanix.com/v1/tasks/<task_id>

3.7 Create an Image

Creating an image of the application requires two steps:

  1. Create a build.json file with the registry credentials for the docker container created previously (only needed if it is a private registry) and the registry credentials for the docker container where CCM can push the Enclave OS container

  2. Issuing a CCM command to convert the Nginx container to an Enclave OS container

3.7.1 Create a build.json file

Create a build.json file with the following content.

{
   "app_id": "${app_id}",
   "inputAuthConfig":
     {
       "username": "<account-id>",
       "password": "<password>"
     },
   "input_docker_version": "latest",
   "outputAuthConfig":
     {
       "username": "<account-id>",
       "password": "<password>"
     }
   "output_docker_version": "nitro"
}

Replace <account-id> and <password> with the credentials for the registries which will be used for input and output.

Replace <app_id> the as per below.

First, get the list of all apps and identify the app_id for the app created in the above steps (this is only needed if you did not note the app_id previously)

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/apps

3.7.2 Convert the Image

Convert the image using the command below (which uses the build.json created above)

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d @build.json -X POST https://ccm.fortanix.com/v1/builds/convert-app

Now check that your docker registry contains the converted container.

After the image has been converted by Fortanix CCM and before it can be run in attested mode, it will require approval. This is to ensure that only approved images can run on the enrolled compute nodes with Fortanix CCM. The following section describes how to approve the image.

3.8 Fetch all the Image Whitelist Tasks

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -X GET https://ccm.fortanix.com/v1/tasks?task_type=BUILD_WHITELIST

All the image whitelist tasks will be stored in all_build_tasks.json file. Select the image whitelist task ID to approve the image in the next step.

3.9 Approve the Image Whitelist Task

curl -b $cpath -c $cpath -H "X-CSRF-Header:true" -s -H "Content-Type: application/json" -d '{"status":"APPROVED"}' -X PATCH https://ccm.fortanix.com/v1/tasks/<task_id>

The image is created and whitelisted.

Next, run the following command on a machine running the node agent to run the Nginx Enclave OS application.

3.10 Run the Application

To run the application, you must first log in to the machine on which the Node Agent was deployed. Run the application using the following command:

docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://<node-agent-ip>:9092/v1/ -p <port-mapping> <converted-image-id>

In this example use the following <port-mapping> and converted-image-id.

docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://<node-agent-ip>:9092/v1/ -p 8121:443 <registry-prefix>/nginx-ssl-fortanix-cert-eos:nitro
  • is the IP address of the compute node enrolled with Fortanix Confidential Computing Manager (CCM).

  • 9092 is the port on which Node Agent and Enclave OS communicate

4.0 Test Nginx (Enclave OS) App

There are two ways to verify that the Enclave OS application is successfully running and using the Fortanix CCM-issued certificate.

  1. Log into the compute node where the Node Agent and the Nginx applications are deployed. Run the following command to view the Nginx response and associated certificate.

    curl --verbose -k https://fortanix-nginx.canadacentral.cloudapp.azure.com:8121

    It is possible to use localhost as shown below, but this will show a certificate error since the certificate was created for a specific domain.

    curl -verbose -k https://localhost:8121

    The response will include the CCM-issued certificate information as well as the Nginx HTML page (same tests shown in the image below). Also, ensure that it’s a 200 OK response.

  2. Go to a browser and open the following URL: https://fortanix-nginx.canadacentral.cloudapp.azure.com:8121

    Nginx_App13.png

    Figure 1: Test Nginx

    NOTE

    The browser will show a certificate warning as the root CA is unrecognized by the browser. Proceed to advance and continue to the site.

5.0 Using Fortanix Confidential Computing Manager UI

5.1 Log in to Fortanix CCM

5.2 Get all Accounts

To get the accounts using Fortanix CCM UI, log in to Fortanix CCM to see the available accounts.

Nginx_App4.png

Figure 3: Get the accounts

5.3 Select the Account

To select an account using Fortanix CCM UI, click the SELECT ACCOUNT button, and then click the GO TO ACCOUNT button to enter the account.

Select_Account1.png

Figure 4: Select accounts

5.4 Create a Group

Create a group to manage the Nginx application.

Click the Groups menu item in the CCM UI left navigation bar, and click +ADD GROUP to create a new group.

CreateGroup-Doc27.png

Figure 5: Create a group

5.5 Create an Application

Create an Nginx application using the configuration provided in the app.json file above.

  1. To create an application using Fortanix CCM UI, go to the detailed view of the group created previously and click the plus icon  Plus-CCMDoc27.png on the Application tile to create an application.  

    AddApp-Doc27.png

    Figure 6: Create an Application

    You can also create an application by navigating to the Applications page and clicking the + APPLICATION button to add an application.

  2. In the ADD APPLICATION window, click ADD on the Enclave OS Application tile.  

    all-app-pop-up-screen - Copy.png

    Figure 7: Create Enclave OS Application

  3. In the Application form, add the details of the application.

  4. The Add Labels section allows a user to add labels.  

    Figure 10: Configure an application

  5. Click CREATE at the bottom of the page to create the application.

5.6 Create an Image

After you create the "nginx-fortanix-cert-eos" application, click the application to go to its detailed view. Click +IMAGE to configure the tags for the input/output image and credentials for the registry where the container will be fetched from and the converted container pushed to.

AddImage-Doc27.png

Figure 11: Create an Image of an Application

In the Image form, add the details of the image. Select Image Type as AWS Nitro Enclaves.

Figure 12: Create an image of an application

After the credentials and the tags have been set up, Click SAVE at the bottom of the page.

5.7 View the Domain and Image Whitelist Tasks

To view the domain and image whitelisting tasks using Fortanix CCM UI, click the Tasks menu item.

ApproveTasks-Doc27.png

Figure 13: View and Approve Image Whitelisting Task

5.8 Approve the Domain and Image Whitelist Tasks

To approve the domain and image whitelisting task for the "nginx-ssl-fortanix-cert-eos" application using Fortanix CCM UI, click the request, and then click the APPROVE button.

ApproveDomainTasks-Doc27.png

Figure 14: Approve tasks

Next, run the following command on a machine running the node agent to run the application.

5.9 Run the Application

For the node attestation type Enhanced Privacy ID (EPID)/Data Center Attestation Primitives (DCAP), use the command:

docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://172.31.8.234:9092/v1/ -p <port-mapping> <registry-prefix>/<converted-image-id>

In our case, we will use the following <port-mapping> and <converted-image-id> .

docker run -it --privileged -v /run/nitro_enclaves:/run/nitro_enclaves -e NODE_AGENT=http://172.31.8.234:9092/v1/ -p 8121:443 <registry-prefix>/nginx-ssl-fortanix-cert-eos:nitro

Where,

  • <node-agent-ip>is the IP address of the compute node registered on Fortanix CCM.

  • 9092 is the port on which Node Agent listens up

  • converted-image-id is the converted app that can be found on the Images page under the Image Name column in the Images table.

NOTE

  • Use your own inputs for Node IP, Port, and Converted Image in the above format. The information in the example above is just a sample.

  • Add the following flag along with the command to get more details:

    • -e ENCLAVEOS_LOG_LEVEL=debug - to get the debug log

    • -p 7622:80 -p 8038:443 - to map the application's custom port to 80 or 443

To verify and monitor the application, click the Applications menu item, and verify that there is a running application image associated with it and displayed with the application in the detailed view of the application.

Fig-15-AppRunning-Doc27.png

Figure 15: Deployed Application