Installing Crypto Express Network API for Secure Execution Enclaves
Before you install Crypto Express Network API for Secure Execution Enclaves, ensure that you complete the prerequisites and download the image.
Installing Crypto Express Network API for Secure Execution Enclaves image
For detailed installation instructions, see "Chapter 13 - Installing a new software appliance in a Secure Service Container partition" in the Secure Service Container User's Guide, SC28-6978-02a.
Switching to the Installer
After you complete installing the Crypto Express Network API for Secure Execution Enclaves image, access to the console UI is disabled. Before you reinstall the image, you must switch the system to the installer mode. You can perform one of the following two methods to switch to the installer.
1. Switch to the Installer on the Hardware Management Console (HMC)
Select Secure Service Container Installer as the boot option after you log in to the HMC. For more information, see "Chapter 4. Starting a Secure Service Container partition on a standard mode system" from the Secure Service Container User's Guide, SC28-6978-02a.
2. Using REST API to switch to the installer
The REST API can be used to switch to the installer under the following conditions:
-
The caller must provide an API token.
-
The user represented by the API token must have an "administrator" role.
POST /api/com.ibm.zaci.system/maintenance-actions/switch-to-installer
You can use the following sample shell script as a reference for using the Rest API
- Appliance IP, administrator's user and password are required
- jq json parsing tool is required to installed
#!/bin/bash -e
appliance_ip=""
admin_user=""
admin_pass=""
get_access_token() {
echo "Get access token"
echo "---> request: /api/com.ibm.zaci.system/api-tokens"
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"user":"${admin_user}",
"password":"${admin_pass}"
}
}
EOF
)
auth_token=$(curl -k -X POST https://${appliance_ip}/api/com.ibm.zaci.system/api-tokens -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -d "${req_json}" | jq -r .parameters.token)
echo "---> auth_token: [${auth_token}]"
}
switch_to_installer(){
echo "switch to installer mode"
echo "---> request: /api/com.ibm.zaci.system/maintenance-actions/switch-to-installer"
response=$(curl -k -X POST https://${appliance_ip}/api/com.ibm.zaci.system/maintenance-actions/switch-to-installer -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json; charset=UTF-8;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}")
echo "---> response: [${response}]"
}
force_appliance_to_installer(){
echo "Force appliance to installer mode"
echo "---> request: /api/com.ibm.zaci.system/appliance"
response=$(curl -k -X GET https://${appliance_ip}/api/com.ibm.zaci.system/appliance -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" | jq -r .properties.name)
echo "---> response: [${response}]"
if [ "${response}" = "Secure Service Container Installer" ]; then
echo "Appliance is already in installer mode"
else
echo "Appliance is not in installer mode"
switch_to_installer
fi
}
get_access_token
force_appliance_to_installer
3. Sample installation script
The following shell script can be used as a sample script to install the appliance. Before you run the installation script, the parameters listed at the beginning of the script must be defined as shown in the sample:
#!/bin/bash
# the ip-address of the appliance
appliance_ip="1.1.2.1"
# the user of the appliance
admin_user="root"
# the password of the appliance
admin_pass="password"
# the disktype (DASD or FCP), default is DASD
appliance_disktype="DASD"
# the path of the crypto-appliance image
apppliance_image="./crypto-appliance-rel.img.gz"
echo "appliance_ip: ${appliance_ip}"
echo "appliance_disktype: ${appliance_disktype}"
echo "apppliance_image: ${apppliance_image}"
wait_for_lpar() {
echo "wait for lpar ready..."
max_tries=81
index=1 ; while [[ $index -le $max_tries ]] ; do
((index = index + 1)) ;
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"user":"${admin_user}",
"password":"${admin_pass}"
}
}
EOF
)
response=$(curl -k -X POST https://${appliance_ip}/api/com.ibm.zaci.system/api-tokens -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -d "${req_json}")
if [[ $? -eq 0 ]]; then
if jq -e . >/dev/null 2>&1 <<<"$response"; then
kind=$(echo "$response" | jq -r .kind)
auth_token=$(echo "$response" | jq -r .parameters.token)
if [ "${kind}" = "response" ]; then
echo "---> auth_token: [${auth_token}]"
echo "lpar is ready."
return 0
fi;
fi
fi
echo "response:$response"
echo "lpar is not ready, continue try [$index]..."
sleep 10s
done
echo "waiting for lpar ready timeout."
exit 1
}
force_to_accept_license(){
echo "Get current license status"
echo "---> request: /api/com.ibm.zaci.system/software-license"
response=$(curl -k -X GET "https://${appliance_ip}/api/com.ibm.zaci.system/software-license" -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json;version=1.0' -H "Authorization: Bearer ${auth_token}")
echo "---> response: [${response}]"
license_status=$(echo "${response}" | jq .properties.accepted)
if [ "${license_status}" = "false" ]; then
echo "Force to accept license status"
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"accept": true
}
}
EOF
)
response=$(curl -k -X PUT https://${appliance_ip}/api/com.ibm.zaci.system/software-license -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" -d "${req_json}" | jq -r .)
echo "---> response: [${response}]"
else
echo "License is already accept"
fi;
}
switch_to_installer(){
echo "switch to installer mode"
echo "---> request: /api/com.ibm.zaci.system/maintenance-actions/switch-to-installer"
response=$(curl -k -X POST https://${appliance_ip}/api/com.ibm.zaci.system/maintenance-actions/switch-to-installer -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json; charset=UTF-8;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}")
echo "---> response: [${response}]"
}
force_appliance_to_installer(){
echo "Force appliance to installer mode"
echo "---> request: /api/com.ibm.zaci.system/appliance"
response=$(curl -k -X GET https://${appliance_ip}/api/com.ibm.zaci.system/appliance -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" | jq -r .properties.name)
echo "---> response: [${response}]"
if [ "${response}" = "Secure Service Container Installer" ]; then
echo "Appliance is already in installer mode"
else
echo "Appliance is not in installer mode"
force_to_accept_license
switch_to_installer
wait_for_lpar
fi
}
get_free_storage_dasd(){
echo "---> request: /api/com.ibm.zaci.system/storage-devices?type=ECKD&status=free"
response=$(curl -k -X GET "https://${appliance_ip}/api/com.ibm.zaci.system/storage-devices?type=ECKD&status=free" -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json;version=1.0' -H "Authorization: Bearer ${auth_token}" | jq .)
DASD_ID=`echo $response | jq -r '.instances|.[0].id'`
echo "DASD_ID=$DASD_ID"
}
get_free_storage_fcp(){
echo "---> request:https://${appliance_ip}/api/com.ibm.zaci.system/fcp-disks?type=FCP&status=free"
response=$(curl -k -X GET "https://${appliance_ip}/api/com.ibm.zaci.system/fcp-disks?type=FCP&status=free" -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json;version=1.0' -H "Authorization: Bearer ${auth_token}" | jq .)
FCP_DEVICE=`echo $response | jq -r '.instances|.[0].paths|.[0]."fcp-device"'`
FCP_WWPN=`echo $response | jq -r '.instances|.[0].paths|.[0]."target"'`
FCP_LUN=`echo $response | jq -r '.instances|.[0].paths|.[0]."lun"'`
echo "FCP_DEVICE=$FCP_DEVICE"
echo "FCP_WWPN=$FCP_WWPN"
echo "FCP_LUN=$FCP_LUN"
echo "id=${FCP_DEVICE} wwpn=${FCP_WWPN} lun=${FCP_LUN}"
}
reboot_dasd(){
DASD_ID=$1
echo "reboot dasd"
echo "---> request: /api/com.ibm.zaci.system/sw-appliances/select:"
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"disk": {
"id": "$DASD_ID"
},
"reboot-after": true
}
}
EOF
)
response=$(curl -k -X PUT https://${appliance_ip}/api/com.ibm.zaci.system/sw-appliances/select -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" -d "${req_json}")
echo "---> response: [${response}]"
}
reboot_fcp(){
FCP_DEVICE=$1
FCP_WWPN=$2
FCP_LUN=$3
echo "reboot fcp"
echo "---> request: /api/com.ibm.zaci.system/sw-appliances/select:"
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"disk": {
"id": "$FCP_DEVICE",
"wwpn": "$FCP_WWPN",
"lun": "$FCP_LUN"
},
"reboot-after": true
}
}
EOF
)
response=$(curl -k -X PUT https://${appliance_ip}/api/com.ibm.zaci.system/sw-appliances/select -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" -d "${req_json}")
echo "---> response: [${response}]"
}
upload_image_dasd(){
DASD_ID=$1
echo "upload image with storage type: dasd"
echo "---> request: /api/com.ibm.zaci.system/sw-appliances/install?id=${DASD_ID}"
echo "DASD_ID=$DASD_ID"
echo "auth_token=${auth_token}"
FILE_SIZE=$(ls -l "${apppliance_image}" | awk '{print $5}')
echo "file size=$FILE_SIZE"
response=$(curl -k -X POST "https://${appliance_ip}/api/com.ibm.zaci.system/sw-appliances/install?id=${DASD_ID}" -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/octet-stream' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Content-length: $FILE_SIZE" -H "Authorization: Bearer ${auth_token}" -T "${apppliance_image}")
echo "---> response: [${response}]"
}
upload_image_fcp(){
FCP_DEVICE=$1
FCP_WWPN=$2
FCP_LUN=$3
echo "upload image with storage type: fcp"
echo "---> request: /api/com.ibm.zaci.system/sw-appliances/install?id=${FCP_DEVICE}&wwpn=${FCP_WWPN}&lun=${FCP_LUN}"
FILE_SIZE=$(ls -l "${apppliance_image}" | awk '{print $5}')
echo "file size=$FILE_SIZE"
response=$(curl -k -X POST "https://${appliance_ip}/api/com.ibm.zaci.system/sw-appliances/install?id=${FCP_DEVICE}&wwpn=${FCP_WWPN}&lun=${FCP_LUN}" -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/octet-stream' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Content-length: $FILE_SIZE" -H "Authorization: Bearer ${auth_token}" -T "${apppliance_image}")
echo "---> response: [${response}]"
}
upload_image(){
if [ "$appliance_disktype" = "FCP" ]; then
get_free_storage_fcp
upload_image_fcp $FCP_DEVICE $FCP_WWPN $FCP_LUN
reboot_fcp $FCP_DEVICE $FCP_WWPN $FCP_LUN
else
get_free_storage_dasd
upload_image_dasd $DASD_ID
reboot_dasd $DASD_ID
fi
}
wait_for_lpar
force_appliance_to_installer
upload_image
wait_for_lpar
Note: If you already installed Crypto Express Network API for Secure Execution Enclaves version 1.1.0, you can reinstall with version 1.1.1 following the same installation instructions.
Checking the installation status
As the console UI of the installed appliance is disabled, you can use one of the following methods to check the installation status:
1. Check the status on the Hardware Management Console (HMC)
After logon the HMC, you can found the specific LPAR, related to which a new installed version can be viewed in the table
2. Using REST API to check the status
To execute below sample shell script, if the responded "properties.name"
is "IBM Hyper Protect Crypto Appliance"
and there is the expected version in "properties.version"
,
the appliance is installed successfully
#!/bin/bash -e
appliance_ip=""
admin_user=""
admin_pass=""
get_access_token() {
echo "Get access token"
req_json=$(cat << EOF
{
"kind": "request",
"parameters":{
"user":"${admin_user}",
"password":"${admin_pass}"
}
}
EOF
)
auth_token=$(curl -k -X POST https://${appliance_ip}/api/com.ibm.zaci.system/api-tokens -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -d "${req_json}" | jq -r .parameters.token)
}
get_appliance_status(){
echo "---> request: /api/com.ibm.zaci.system/appliance"
response=$(curl -k -X GET https://${appliance_ip}/api/com.ibm.zaci.system/appliance -H 'zACI-API: com.ibm.zaci.system/1.0' -H 'Content-type: application/vnd.ibm.zaci.payload+json;version=1.0' -H 'Accept: application/vnd.ibm.zaci.payload+json' -H "Authorization: Bearer ${auth_token}" | jq -r .)
echo "---> appliance: [${response}]"
}
get_access_token
get_appliance_status
The sample json response:
{
"kind": "instance",
"self": "/api/com.ibm.zaci.system/appliance",
"resource-name": "appliance",
"resource-version": "1.0",
"properties": {
"self": "/api/com.ibm.zaci.system/appliance",
"name": "IBM Hyper Protect Crypto Appliance",
"description": "IBM Hyper Protect Crypto Appliance",
"version": "23.3.2",
"boot-time": 1678437000,
"hostname": "hursscc.hursley.ibm.com",
"physical-server-name": "IYACPCTX",
"virtual-server-name": "HURSSCC"
}
}
Preparing Rsyslog server for log collection
Rsyslog is a log processing system that can be configured to receive logs from the c16 server and output the logs for your review. It is installed by default on Ubuntu.
-
Install
rsyslog-gnutls
to enable TLS log transaction. For example, for Ubuntu:apt-get install -y rsyslog-gnutls
-
Prepare a TLS keypair for the Rsyslog central server by completing the following steps:
-
The following certificates must be prepared in this section:
Filename Description rsyslog-ca.pem
ROOT certificate of Rsyslog server rsyslog-cert.pem
Rsyslog central server certificate rsyslog-server.key
Rsyslog central server key rsyslog-client.pem
Rsyslog client certificate which is configured into crypto appliance by API rsyslog-client.key
Rsyslog client key which is configured into crypto appliance by API Follow Creating OpenSSL certificates for Crypto Express Network API for Secure Execution Enclaves, to prepare the required TLS certificate by using OpenSSL(self-signed certificates):
-
Replace
%prefix%
withrsyslog
Note: If you want to use other methods of preparing Rsyslog certificates, follow these instructions.
-
-
Follow the instructions in Encrypting Syslog Traffic with TLS (SSL). Ensure that you read the documentation that matches the version of your Rsyslog server. Choose one of the following methods for configuring the
rsyslog.conf
file:-
An example of settings in the Rsyslog configuration file
rsyslog.conf
, which is usually located under/etc/
:global( DefaultNetstreamDriver="gtls" DefaultNetstreamDriverCAFile="/root/rsyslog-ca.pem" DefaultNetstreamDriverCertFile="/root/rsyslog-cert.pem" DefaultNetstreamDriverKeyFile="/root/rsyslog-server.key" ) module(load="imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" gnutlsprioritystring="SECURE128:-VERS-TLS-ALL:+VERS-TLS1.3" StreamDriver.Authmode="x509/certvalid") input(type="imtcp" port="6514" ruleset="to_local") module(load="builtin:omfile") ruleset(name="to_local"){ action(type="omfile" dirCreateMode="0766" FileCreateMode="0644" File="/root/c16server.log") }
-
If you want to use the same Rsyslog server that you have set up to use with the Hyper Protect Container Runtime instance, use the following example of the configuration of a Rsyslog server:
# make gtls driver the default and set certificate files $DefaultNetstreamDriver "gtls" $DefaultNetstreamDriverCAFile /root/rsyslog-ca.pem $DefaultNetstreamDriverCertFile /root/rsyslog-cert.pem $DefaultNetstreamDriverKeyFile /root/rsyslog-server.key # provides TCP syslog reception module(load="imtcp" StreamDriver.Name="gtls" StreamDriver.Mode= "1" StreamDriver.Authmode="x509/certvalid" ) input(type="imtcp" port="6514") # Template for incoming logs $template incoming-remote-logs,"/var/log/remotelogs/%FROMHOST-IP%/%PROGRAMNAME%.log" *.* ?incoming-remote-logs
Ensure that you create the root path to store the received traces from clients by using the
mkdir -p /var/log/remotelogs
command. Traces that are received from each client can be found in the specific%FROMHOST-IP%
folder under the path"/var/log/remotelogs"
.
-
-
After you finish the configurations, restart the Rsyslog server.
systemctl restart rsyslog.service
Now you are ready to configure the Crypto Express Network API for Secure Execution Enclaves and collect and send logs to the Rsyslog central server.
Notes:
- It is recommended to use the same Rsyslog version (current version is
8.2001.0-1ubuntu1.3
). If you choose to use a different version, confirm the steps on the Rsyslog server official website. - During log server downtime, the first log message is lost due to plain TCP connection.
- By default, the 'authmode' of Rsyslog peer (listener) is 'x509/certvalid' in Crypto Express Network API for Secure Execution Enclaves appliance, and identity authentication is required.