How to run AWS CloudHSM workloads on Docker containers
AWS CloudHSM is a cloud-based hardware security module (HSM)
that enables you to generate and use your own encryption keys on the AWS Cloud.
With CloudHSM, you can manage your own encryption keys using FIPS 140-2 Level 3
validated HSMs. Your HSMs are part of a CloudHSM cluster. CloudHSM
automatically manages synchronization, high availability, and failover within a
cluster.
CloudHSM is part of the AWS Cryptography suite of services,
which also includes AWS Key Management Service (KMS) and AWS Certificate
Manager Private Certificate Authority (ACM PCA). KMS and ACM PCA are fully
managed services that are easy to use and integrate. You’ll generally use AWS
CloudHSM only if your workload needs a single-tenant HSM under your own
control, or if you need cryptographic algorithms that aren’t available in the
fully-managed alternatives.
CloudHSM offers several options for you to connect your
application to your HSMs, including PKCS#11, Java Cryptography Extensions
(JCE), or Microsoft CryptoNG (CNG). Regardless of which library you choose,
you’ll use the CloudHSM client to connect to all HSMs in your cluster. The
CloudHSM client runs as a daemon, locally on the same Amazon Elastic Compute
Cloud (EC2) instance or server as your applications.
The deployment process is straightforward if you’re running
your application directly on your compute resource. However, if you want to
deploy applications using the HSMs in containers, you’ll need to make some
adjustments to the installation and execution of your application and the
CloudHSM components it depends on. Docker containers don’t typically include
access to an init process like systemd or upstart. This means that you can’t
start the CloudHSM client service from within the container using the general
instructions provided by CloudHSM. You also can’t run the CloudHSM client
service remotely and connect to it from the containers, as the client daemon
listens to your application using a local Unix Domain Socket. You cannot
connect to this socket remotely from outside the EC2 instance network
namespace.
This blog post discusses the workaround that you’ll need in
order to configure your container and start the client daemon so that you can
utilize CloudHSM-based applications with containers. Specifically, in this
post, I’ll show you how to run the CloudHSM client daemon from within a Docker
container without needing to start the service. This enables you to use Docker
to develop, deploy and run applications using the CloudHSM software libraries,
and it also gives you the ability to manage and orchestrate workloads using
tools and services like Amazon Elastic Container Service (Amazon ECS), Kubernetes,
Amazon Elastic Container Service for Kubernetes (Amazon EKS), and Jenkins.
Solution overview
My solution shows you how to create a proof-of-concept
sample Docker container that is configured to run the CloudHSM client daemon.
When the daemon is up and running, it runs the AESGCMEncryptDecryptRunner Java
class, available on the AWS CloudHSM Java JCE samples repo. This class uses
CloudHSM to generate an AES key, then it uses the key to encrypt and decrypt
randomly generated data.
Note: In my example, you must manually enter the crypto user
(CU) credentials as environment variables when running the container. For any
production workload, you’ll need to carefully consider how to provide, secure,
and automate the handling and distribution of your HSM credentials. You should
work with your security or compliance officer to ensure that you’re using an
appropriate method of securing HSM login credentials for your application and
security needs.
Figure 1: Architectural diagram
Figure 1: Architectural diagram
Prerequisites
To implement my solution, I recommend that you have basic
knowledge of the below:
CloudHSM
Docker
Java
Here’s what you’ll need to follow along with my example:
An active CloudHSM cluster with at least one active HSM. You
can follow the Getting Started Guide to create and initialize a CloudHSM
cluster. (Note that for any production cluster, you should have at least two
active HSMs spread across Availability Zones.)
An Amazon Linux 2 EC2 instance in the same Amazon Virtual
Private Cloud in which you created your CloudHSM cluster. The EC2 instance must
have the CloudHSM cluster security group attached—this security group is
automatically created during the cluster initialization and is used to control
access to the HSMs. You can learn about attaching security groups to allow EC2
instances to connect to your HSMs in our online documentation.
A CloudHSM crypto user (CU) account created on your HSM. You
can create a CU by following these user guide steps.
Solution details
On your Amazon Linux EC2 instance, install Docker:
# sudo yum -y
install docker
Start the docker service:
# sudo service
docker start
Create a new directory and step into it. In my example, I
use a directory named “cloudhsm_container.” You’ll use the new directory to
configure the Docker image.
# mkdir
cloudhsm_container
# cd
cloudhsm_container
Copy the CloudHSM cluster’s CA certificate (customerCA.crt)
to the directory you just created. You can find the CA certificate on any
working CloudHSM client instance under the path
/opt/cloudhsm/etc/customerCA.crt. This certificate is created during
initialization of the CloudHSM Cluster and is needed to connect to the CloudHSM
cluster.
In your new directory, create a new file with the name
run_sample.sh that includes the contents below. The script starts the CloudHSM
client daemon, waits until the daemon process is running and ready, and then
runs the Java class that is used to generate an AES key to encrypt and decrypt
your data.
#! /bin/bash
# start
cloudhsm client
echo -n
"* Starting CloudHSM client ... "
/opt/cloudhsm/bin/cloudhsm_client /opt/cloudhsm/etc/cloudhsm_client.cfg
&> /tmp/cloudhsm_client_start.log &
# wait for
startup
while true
do
if grep
'libevmulti_init: Ready !' /tmp/cloudhsm_client_start.log &> /dev/null
then
echo
"[OK]"
break
fi
sleep 0.5
done
echo -e
"\n* CloudHSM client started successfully ... \n"
# start
application
echo -e
"\n* Running application ... \n"
java -ea
-Djava.library.path=/opt/cloudhsm/lib/ -jar target/assembly/aesgcm-runner.jar
--method environment
echo -e
"\n* Application completed successfully ... \n"
In the new directory, create another new file and name it
Dockerfile (with no extension). This file will specify that the Docker image is
built with the following components:
The AWS CloudHSM client package.
The AWS CloudHSM Java JCE package.
OpenJDK 1.8. This is needed to compile and run the Java
classes and JAR files.
Maven, a build automation tool that is needed to assist with
building the Java classes and JAR files.
The AWS CloudHSM Java JCE samples that will be downloaded
and built.
Cut and paste the contents below into Dockerfile.
Note: Make sure to replace the HSM_IP line with the IP of an
HSM in your CloudHSM cluster. You can get your HSM IPs from the CloudHSM
console, or by running the describe-clusters AWS CLI command.
# Use the
amazon linux image
FROM
amazonlinux:2
# Install
CloudHSM client
RUN yum install
-y
https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-client-latest.el7.x86_64.rpm
# Install
CloudHSM Java library
RUN yum
install -y
https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-client-jce-latest.el7.x86_64.rpm
# Install
Java, Maven, wget, unzip and ncurses-compat-libs
RUN yum
install -y java maven wget unzip ncurses-compat-libs
# Create a
work dir
WORKDIR /app
# Download
sample code
RUN wget
https://github.com/aws-samples/aws-cloudhsm-jce-examples/archive/master.zip
# unzip sample
code
RUN unzip master.zip
# Change to
the create directory
WORKDIR
aws-cloudhsm-jce-examples-master
# Build JAR
files
RUN mvn
validate && mvn clean package
# Set HSM IP
as an environmental variable
ENV HSM_IP
<insert the IP address of an active CloudHSM instance here>
# Configure
cloudhms-client
COPY
customerCA.crt /opt/cloudhsm/etc/
RUN
/opt/cloudhsm/bin/configure -a $HSM_IP
# Copy the run_sample.sh
script
COPY
run_sample.sh .
# Run the
script
CMD
["bash","run_sample.sh"]
Now you’re ready to build the Docker image. Use the
following command, with the name jce_sample_client. This command will let you
use the Dockerfile you created in step 6 to create the image.
# sudo docker
build -t jce_sample_client .
To run a Docker container from the Docker image you just
created, use the following command. Make sure to replace the user and password
with your actual CU username and password. (If you need help setting up your CU
credentials, see prerequisite 3. For more information on how to provide CU
credentials to the AWS CloudHSM Java JCE Library, refer to the steps in the
CloudHSM user guide.)
# sudo docker
run --env HSM_PARTITION=PARTITION_1 \
--env
HSM_USER=<user> \
--env
HSM_PASSWORD=<password> \
jce_sample_client
If successful, the output should look like this:
* Starting
cloudhsm-client ... [OK]
*
cloudhsm-client started successfully ...
* Running
application ...
ERROR StatusLogger No log4j2 configuration
file found. Using default configuration: logging only errors
to the
console.
70132FAC146BFA41697E164500000000
Successful
decryption
SDK
Version: 2.03
* Application
completed successfully ...
Conclusion
My solution provides an example of how to run CloudHSM
workloads on Docker containers. You can use it as a reference to implement your
cryptographic application in a way that benefits from the high availability and
load balancing built in to AWS CloudHSM without compromising on the flexibility
that Docker provides for developing, deploying, and running applications. If
you have comments about this post, submit them in the Comments section
below.[Source]-https://aws.amazon.com/blogs/security/how-to-run-aws-cloudhsm-workloads-on-docker-containers/
Beginners
& Advanced level Docker Training Course in Mumbai. Asterix Solution's 25 Hour Docker Training gives
broad hands-on practicals. For details, Visit :
Comments
Post a Comment