Run a Minecraft server on IBM Cloud Hyper Protect Virtual Servers

In this tutorial, you will learn how to protect your application by leveraging the Bring your own Image (BYOI) feature of the IBM Cloud® Hyper Protect Virtual Servers service using the example of a Minecraft server. I show you how to build your own Minecraft server image and create a new Hyper Protect Virtual Server with it. By deploying the application on this service, you can run it on IBM LinuxONE on the secured software stack of the IBM Secure Service Container technology which provides protection from internal and outsider threats. To achieve even more confidentiality for the Minecraft server, the image that will be built will only include the Minecraft application and the necessary runtime. There will be no interactive shell available to interact with the server to protect it from attacks. After you have completed this tutorial, you will be able to play Minecraft on your Hyper Protect Minecraft server.

Learning objectives

When you’ve completed this tutorial, you will understand how to:

  • Build an OCI image for a Minecraft server
  • Deploy a Hyper Protect Virtual Server using your own Image
  • Connect to the Hyper Protect Virtual Server instance

Prerequisites

To complete this tutorial, you’ll need:

Estimated time

It should take you about 1 – 2 hours to complete this tutorial.

Steps

The following steps will show you how to:

  1. Create an Ubuntu Hyper Protect Virtual Server with the name Minecraft Build Server that you will use for the preparation of the image
  2. Use the Minecraft Build Server to build the Minecraft Server into an OCI image which can be consumed by Hyper Protect Virtual Servers
  3. Push this image to IBM Cloud Container Registry and sign it
  4. Create the registration definition file that is required for the deployment
  5. Deploy a new Hyper Protect Virtual Server using your Minecraft OCI image, and then connect to the deployed Minecraft Server using your Minecraft Launcher

Tutorial components overview

1

Create the Minecraft Build Server

In this step, I show you how to install the Hyper Protect Virtual Servers plugin for the IBM Cloud CLI, and how to use it to order a Virtual Server.

Go to the terminal where you can run ibmcloud commands and login:

ibmcloud login

Install the Hyper Protect Virtual Servers plugin for the IBM Cloud CLI:

ibmcloud plugin install hpvs

Run the following command to create the Minecraft Build Server instance. Possible values for the <location> are: dal10, dal12, dal13, fra02, fra04, fra05, syd01, syd04, syd05, wdc04, wdc06, and wdc07.

ibmcloud hpvs instance-create "Minecraft Build Server" free <location> --ssh-path <path-to-ssh-public-key>

Check the provisioning status regularly with the command you get as a response and wait until the instance becomes available.

2

Build the image

In this section, I show you how to build the Minecraft Server image, so that it can be consumed by Hyper Protect Virtual Servers. This service runs on IBM LinuxONE hardware, therefore the image needs to be built for the s390x architecture. You will use the Minecraft Build Server instance for that.

Login to your Minecraft Build Server via SSH:

ssh root@<minecraft_build_server_public_ip>

Then install the necessary tools to build and push the image:

apt update && apt install -y docker.io gpg jq

Create a Dockerfile with the following content. This build script will install the needed tools, download the minecraft_server.1.16.1.jar, and configure the start command for the image.

FROM ubuntu
RUN apt-get update && apt-get upgrade -y && apt-get install -y default-jdk curl
RUN mkdir minecraft
RUN curl https://launcher.mojang.com/v1/objects/a412fd69db1f81db3f511c1463fd304675244077/server.jar --output  minecraft/minecraft_server.jar
RUN echo "eula=true" > eula.txt
CMD java -Xms1024m -Xmx1024m -jar minecraft/minecraft_server.jar --nogui

Replace the region and the icr_namespace in the following command with the details from your IBM Cloud Container Registry instance and run it to build the image:

docker build -t <region>.icr.io/<icr_namespace>/minecraft:latest .
3

Push the image to IBM Cloud Container Registry

Now you need to push the built image from the Minecraft Build Server to the IBM Cloud Container Registry instance you prepared earlier. Because the Hyper Protect infrastructure needs to verify that it pulled the correct image before running it, you’ll need to sign the image using Docker Content Trust in this step.

Login on the IBM Cloud Container registry using your API Key:

echo  "<API_Key>" | docker login -u "iamapikey" --password-stdin <registry_region>.icr.io

Push the image to your IBM Cloud Container registry instance and sign it using Docker Content Trust:

export DOCKER_CONTENT_TRUST=1 DOCKER_CONTENT_TRUST_SERVER=https://<registry_region>.icr.io:4443
docker push <region>.icr.io/<icr_namespace>/minecraft:latest

The Docker engine will ask for passwords to protect the keys that are generated to sign the images after the push.

4

Create the registration definition file

In this step, I show you how to create the registration definition file which is used as a manifest file for the deployment. The following instructions explain how to provide the necessary information in that file and how to prepare it for creating the instance. The file contains information for the HPVS infrastructure which is required to pull the image you created and pushed in the previous phases. In addition, it includes the public part of the key that was used to sign the image in step 3. This information is used during the deployment to verify that the correct image is started and that it was not tampered during transmission. The data in the registration definition file can contain secrets that you don’t want to expose to anyone. Therefore, the file will be encrypted using a keypair, where the private half is only available in the protected IBM Hyper Protect infrastructure leveraging the IBM Secure Service Container technology so that no person can access it. In addition, the file will be signed by a keypair that you create and should keep safe.

The steps for creating the registration definition file can be performed on any machine that has gpg and jq installed. You will use the Minecraft Build Server where you already installed that in step 2.

Create a file named registration.json with the following content:

{
     "repository_name": "<region>.icr.io/<icr_namespace>/minecraft",
     "docker_username": "iamapikey",
     "docker_password": "",
     "envs_whitelist": ["RUNQ_ROOTDISK", "RUNQ_RUNQENV", "RUNQ_SYSTEMD", "IMAGE_TAG", "REGION", "PHASE", "LPAR_NAME", "CPC", "RUNQ_CPU", "RUNQ_MEM", "POD"],
     "public_key_id": "",
     "public_key": "",
     "vendor_key": ""
}

Replace <region> and <icr_namespace> from the repository_name field with the correct values from your IBM Cloud Container Registry instance.

In the registration.json file, fill in your API key in the docker_password field.

Get the ID of the public key the Docker engine used to sign the image when you pushed it in step 3 by running the following:

export DOCKER_CONTENT_TRUST_SERVER=https://<registry_region>.icr.io:4443
docker trust inspect <region>.icr.io/<icr_namespace>/minecraft

Copy the root key ID from the AdministrativeKeys and paste it into the public_key_id field of the registration.json file.

Replace <region>, <icr_namespace>, and <public_key_id> with the correct values and run to get the public part of the key that was used to sign the image:

cat ~/.docker/trust/tuf/<region>.icr.io/<icr_namespace>/minecraft/metadata/root.json | jq '.signed.keys.<public_key_id>.keyval.public'

Paste it into the public_key field in the registration.json.

Create a file named gpg.batch, fill it with the following content, and replace the <passphrase> with an actual passphrase:

%echo Generating registration definition key
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: isv_user
Expire-Date: 0
Passphrase: <passphrase>
# Do a commit here, so that you can later print "done" :-)
%commit
%echo done

Generate the new keypair by running the following:

gpg -a --batch --generate-key gpg.batch

Then export the public part of the generated key by running this:

gpg --armor --export isv_user | awk 1 ORS='\\n' > isv_user.pub

The awk statement replaces all newlines with \n. Copy the contents of the isv_user.pub file and paste it into the vendor_key field in the registration.json file.

Create a file named hpvs_byoi_ibm_public_key.txt and populate it with the IBM public key content below:

-----BEGIN PGP PUBLIC KEY BLOCK-----
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
mae7WLtydkQnM7Shc1l2CmBCHH8ClSJN
=DsnN
-----END PGP PUBLIC KEY BLOCK-----

Import the public key by running:

gpg --import hpvs_byoi_ibm_public_key.txt

Encrypt the registration.json file with the hpvs_byoi_ibm_public_key and sign it with your generated private key by running:

gpg --encrypt --sign --local-user isv_user --armor -r rtoa_destination registration.json

This will generate the registration.json.asc file which contains the encrypted and signed content.

5

Provision the Virtual Servers using the built image

Switch back to your environment where you can run ibmcloud commands, and download the signed and encrypted registration file from the Minecraft Build server using scp:

scp root@<minecraft_build_server_public_ip>:registration.json.asc .

Select a location and provision a new free Virtual Server using your own Minecraft OCI image. Possible values for the <location> are: dal10, dal12, dal13, fra02, fra04, fra05, syd01, syd04, syd05, wdc04, wdc06, and wdc07.

Then run:

ibmcloud hpvs instance-create "Minecraft Server" free <location> --rd-path registration.json.asc -i latest

Check the provisioning status regularly with the command you get as a response and wait until the instance becomes available. Now you can connect to it with your Minecraft launcher using the public IP address.

Summary

In this tutorial, you have learned how you can run a protected application using Bring Your Own Image (BYOI) from the Hyper Protect Virtual Servers service on the example of a Minecraft Server. This server now runs on IBM LinuxONE hardware leveraging the confidentiality capabilities of the Secure Service Container technology. You can now use what you’ve learned to build and run any other application in the same way. Try it out with the application from the disaster donations code pattern.