Xi
Security Azure

XiPKI on Ubuntu 24.04 on Azure User Guide

| Product: XiPKI on Ubuntu 24.04 LTS on Azure

Overview

This image runs XiPKI, a high performance Certificate Authority and Public Key Infrastructure server. XiPKI issues, renews and revokes X.509 certificates for the services, devices and people in your organisation, and answers certificate status queries so relying parties can check whether a certificate is still valid.

The image is delivered as a complete, self contained PKI. All three XiPKI components run on this one VM, each in its own Tomcat instance as upstream requires:

  • xipki-ca — the certificate authority itself. It holds your signing key, issues certificates against a set of certificate profiles, maintains revocation state and publishes certificate revocation lists.
  • xipki-gateway — the protocol gateway, which puts standard enrolment protocols (CMP, EST and REST) in front of the certificate authority.
  • xipki-ocsp — the OCSP responder, which reads the certificate database directly and answers status queries with signed responses.

A PostgreSQL database holds the certificate authority configuration, every certificate issued and all revocation state.

This is a headless product. There is no web interface. XiPKI is operated through its management command line interface and its protocol endpoints.

Every VM generates its own certificate authority on first boot. A new signing key is created locally on your machine, a new self issued certificate authority certificate is produced, a new database password is set and a new enrolment credential is generated. No key material is shared between instances and none ships in the image.

What's included:

  • XiPKI 6.7.0, Apache 2.0 licensed
  • A per VM certificate authority with an ECDSA P-256 signing key, generated on first boot
  • CMP, EST and REST enrolment through the protocol gateway
  • An OCSP responder with its own signing certificate issued by your certificate authority
  • PostgreSQL as the certificate database
  • A certificate round trip self test at /usr/local/sbin/xipki-pki-roundtrip.sh
  • 24/7 cloudimg support

Key facts:

Item Value
Platform Microsoft Azure
Default user azureuser
CA management interface 127.0.0.1:8444 (loopback only, mutual TLS)
Enrolment gateway (HTTPS) 127.0.0.1:8445 (loopback only)
OCSP responder 127.0.0.1:8080 (loopback only)
Certificate database PostgreSQL on 127.0.0.1:5432 (loopback only)
Service user xipki
Credentials file /root/xipki-credentials.txt
Recommended size Standard_B2s (2 vCPU, 4 GB)

Every PKI port is bound to the loopback interface in the shipped image. This is deliberate. An openly reachable certificate authority management interface would let anyone issue certificates your organisation trusts. Step 11 explains how to expose the enrolment gateway and the OCSP responder safely when you are ready.

Prerequisites

  • An Azure subscription with permission to create virtual machines
  • An SSH key pair
  • The Azure CLI, if you prefer to launch from the command line
  • A network security group that allows inbound SSH (port 22) from your address

Step 1: Launch the VM from the Azure Marketplace

  1. Sign in to the Azure portal.
  2. Search the Marketplace for XiPKI on Ubuntu 24.04 LTS by cloudimg and select Create.
  3. Choose your subscription, resource group and region.
  4. Set the VM size. Standard_B2s (2 vCPU, 4 GB) is the recommended minimum, and the JVM heap sizes in this image are tuned for it.
  5. Set the authentication type to SSH public key, with username azureuser.
  6. Under Inbound port rules, allow SSH (22) only. Do not open the PKI ports yet.
  7. Select Review + create, then Create.

First boot generates your certificate authority and then proves it works before reporting ready. Allow two to three minutes after the VM reaches Running before connecting.

Step 2: Launch the VM from the Azure CLI

az group create --name xipki-rg --location eastus

az vm create \
  --resource-group xipki-rg \
  --name xipki-vm \
  --image cloudimg:xipki-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --storage-sku StandardSSD_LRS \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open SSH only:

az vm open-port --resource-group xipki-rg --name xipki-vm --port 22 --priority 1001

Step 3: Connect to Your VM

ssh azureuser@<vm-ip>

The message of the day shows your certificate authority and its SHA-256 fingerprint:

  XiPKI 6.7.0 on Ubuntu 24.04 (cloudimg Azure Marketplace image)
  Certificate authority: CN=xipki-vm Issuing CA
  CA SHA-256:            31:D6:0D:32:23:87:98:93:59:19:8A:15:16:45:D7:4E:...
  Services:      systemctl status xipki-ca xipki-gateway xipki-ocsp
  Prove the CA:  sudo /usr/local/sbin/xipki-pki-roundtrip.sh
  CA details:    sudo cat /root/xipki-credentials.txt
  All PKI ports are loopback-only. See the guide before exposing them.

Step 4: Confirm the Services

systemctl is-active postgresql xipki-ca xipki-gateway xipki-ocsp

Expected output:

active
active
active
active

XiPKI services active

Step 5: Confirm Every PKI Port Is Loopback Only

sudo ss -ltnp | grep -E ':(8080|8082|8444|8445|5432)\b'

Every local address is a loopback address. Nothing is bound to a routable interface:

LISTEN 0 100 127.0.0.1:5432       0.0.0.0:*
LISTEN 0 100 [::ffff:127.0.0.1]:8080 *:*
LISTEN 0 100 [::ffff:127.0.0.1]:8082 *:*
LISTEN 0 100 [::ffff:127.0.0.1]:8444 *:*
LISTEN 0 100 [::ffff:127.0.0.1]:8445 *:*

[::ffff:127.0.0.1] is the IPv4 mapped IPv6 form of 127.0.0.1, which is how the Tomcat connector binds loopback.

Step 6: Read Your Certificate Authority Details

The credentials file is readable only by root and holds your certificate authority details, the enrolment credential and the database password.

sudo cat /root/xipki-credentials.txt

It contains, among other entries:

xipki.ca.name=cloudimgca
xipki.ca.alias=cloudimg
xipki.ca.subject=C=GB,O=cloudimg,CN=xipki-vm Issuing CA
xipki.ca.fingerprint.sha256=31:D6:0D:32:...
xipki.gateway.requestor.user=cloudimg
xipki.gateway.requestor.password=<GATEWAY_PASSWORD>
xipki.gateway.rest.url=https://127.0.0.1:8445/gw/rest/cloudimg
xipki.ocsp.url=http://127.0.0.1:8080/ocsp/

Confirm the file is protected:

sudo stat -c '%a %U:%G' /root/xipki-credentials.txt
600 root:root

XiPKI certificate authority details

Step 7: Prove a Real Certificate Round Trip

This is the fastest way to confirm your PKI genuinely works. The self test obtains your certificate authority certificate from the CA server's management interface, enrols a fresh certificate signing request through the gateway, and cryptographically verifies that the certificate returned chains to your certificate authority. It also confirms that an unauthenticated request is refused and that an unrelated certificate authority cannot verify the certificate.

sudo /usr/local/sbin/xipki-pki-roundtrip.sh
OK ca=cloudimgca ca_sha256=31:D6:0D:32:23:87:98:93:59:19:8A:15:16:45:D7:4E:A6:51:FA:2E:EE:6C:4F:84:B0:F9:33:F4:0F:58:BE:B6 issued_cn=rt-a-20260719215726-35841.pki.cloudimg.internal unauth_http=401 wrongpw_http=401 ocsp=good+revoked

Reading that line: a certificate was issued and verified against your certificate authority; an unauthenticated enrolment attempt was refused with HTTP 401; an attempt with the wrong password was also refused; and the OCSP responder reported good for a live certificate and revoked for one that had been revoked.

XiPKI certificate round trip

Step 8: Enrol a Certificate Yourself over REST

Read your enrolment credential and the gateway URL:

sudo grep -E '^xipki.gateway' /root/xipki-credentials.txt

Generate a key and a certificate signing request. The tls profile requires the common name to be a fully qualified domain name.

cd /tmp
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout myservice.key -out myservice.csr -outform DER \
  -subj "/C=GB/O=cloudimg/CN=myservice.example.internal"

Enrol it. The gateway serves HTTPS with a certificate issued by your own certificate authority, so curl is pointed at the certificate authority certificate rather than the system trust store.

sudo bash -c '
GW=$(grep "^xipki.gateway.rest.url=" /root/xipki-credentials.txt | cut -d= -f2-)
U=$(grep "^xipki.gateway.requestor.user=" /root/xipki-credentials.txt | cut -d= -f2-)
P=$(grep "^xipki.gateway.requestor.password=" /root/xipki-credentials.txt | cut -d= -f2-)
curl -sS -k -o /tmp/myservice.der -w "HTTP %{http_code}\n" \
  --data-binary @/tmp/myservice.csr \
  -H "Content-Type: application/pkcs10" \
  -u "$U:$P" \
  "$GW/enroll-cert?profile=tls"
'
HTTP 200

Convert and inspect the certificate you were issued:

openssl x509 -inform der -in /tmp/myservice.der -out /tmp/myservice.pem
openssl x509 -in /tmp/myservice.pem -noout -subject -issuer -dates -nameopt RFC2253
subject=CN=myservice.example.internal,O=cloudimg,C=GB
issuer=CN=xipki-vm Issuing CA,O=cloudimg,C=GB
notBefore=Jul 19 22:43:38 2026 GMT
notAfter=Jul 19 22:43:38 2031 GMT

XiPKI certificate enrolled over REST

Step 9: Verify the Certificate Against Your Certificate Authority

Fetch the certificate authority certificate from the gateway's public endpoint, then verify the chain:

sudo bash -c '
GW=$(grep "^xipki.gateway.rest.url=" /root/xipki-credentials.txt | cut -d= -f2-)
curl -sS -k -o /tmp/ca.der "$GW/cacert"
'
openssl x509 -inform der -in /tmp/ca.der -out /tmp/ca.pem
openssl verify -CAfile /tmp/ca.pem /tmp/myservice.pem
/tmp/myservice.pem: OK

The cacert endpoint is deliberately public: a certificate authority certificate contains no secret, and relying parties need it to verify the certificates you issue.

Step 10: Revoke a Certificate and Check Status with OCSP

Check the status of the certificate while it is still valid:

openssl ocsp -CAfile /tmp/ca.pem -issuer /tmp/ca.pem -cert /tmp/myservice.pem \
  -url http://127.0.0.1:8080/ocsp/ -noverify 2>/dev/null | head -2
/tmp/myservice.pem: good

Revoke it. Revocation requires the SHA-1 fingerprint of the issuing certificate authority as well as the certificate serial number:

sudo bash -c '
GW=$(grep "^xipki.gateway.rest.url=" /root/xipki-credentials.txt | cut -d= -f2-)
U=$(grep "^xipki.gateway.requestor.user=" /root/xipki-credentials.txt | cut -d= -f2-)
P=$(grep "^xipki.gateway.requestor.password=" /root/xipki-credentials.txt | cut -d= -f2-)
SER=$(openssl x509 -in /tmp/myservice.pem -noout -serial | cut -d= -f2)
CASHA1=$(openssl x509 -in /tmp/ca.pem -noout -fingerprint -sha1 | cut -d= -f2 | tr -d ":")
curl -sS -k -o /dev/null -w "HTTP %{http_code}\n" -u "$U:$P" \
  "$GW/revoke-cert?ca-sha1=${CASHA1}&serial-number=0x${SER}&reason=KEY_COMPROMISE"
'
HTTP 200

Check the status again:

openssl ocsp -CAfile /tmp/ca.pem -issuer /tmp/ca.pem -cert /tmp/myservice.pem \
  -url http://127.0.0.1:8080/ocsp/ -noverify 2>/dev/null | head -2
/tmp/myservice.pem: revoked

Step 11: Use the Management Command Line Interface

The management CLI runs as the xipki service user, which owns the management client certificate it authenticates with.

sudo -u xipki bash -c 'cd /opt/xipki/run/xipki-setup/xipki-mgmt-cli && printf "ca-info cloudimgca\n" | ./bin/xipki' | head -30

Start it interactively to explore:

sudo -u xipki bash -c 'cd /opt/xipki/run/xipki-setup/xipki-mgmt-cli && ./bin/xipki'

Type help for the full command list and exit to leave. Useful commands include ca-info, caprofile-info, careq-info and cacert.

The certificate profiles available to your certificate authority are tls, tls-c, smime, ocsp, scep, tls-sm2 and tls-sm2-enc. Pass the one you want as the profile query parameter when enrolling.

Step 12: Expose the Gateway and OCSP Responder Safely

Every PKI port is loopback only in the shipped image. Expose them deliberately, and never expose the certificate authority management port.

Never expose port 8444. That is the certificate authority management interface. Anyone who reaches it with a valid management client certificate can reconfigure your certificate authority.

The OCSP responder (port 8080) is the usual first port to expose. OCSP responses are signed and are meant to be publicly readable, so relying parties can check certificate status. To expose it, edit the OCSP Tomcat connector and open the port:

sudo sed -i 's|<Connector address="127.0.0.1" port="8080"|<Connector address="0.0.0.0" port="8080"|' \
  /opt/xipki/run/ocsp-tomcat/conf/server.xml
sudo systemctl restart xipki-ocsp

Then open the port in the VM's network security group:

az vm open-port --resource-group xipki-rg --name xipki-vm --port 8080 --priority 1010

For the enrolment gateway (port 8445), put a reverse proxy in front of it rather than exposing Tomcat directly, so you control TLS termination, rate limiting and access logging. Restrict the source addresses in your network security group to the hosts that need to enrol, and prefer client certificate authentication over the password requestor for anything beyond testing.

Certificates issued by this certificate authority already carry an OCSP URL pointing at this VM's address, so once port 8080 is open, relying parties can check status without further configuration.

Server Components

Component Purpose Port
xipki-ca Certificate authority: issues and revokes certificates 8444 (mutual TLS)
xipki-gateway CMP, EST and REST enrolment 8445 (HTTPS), 8082 (HTTP)
xipki-ocsp OCSP responder 8080
PostgreSQL Certificate database (ca, caconf) 5432

Filesystem Layout

Path Contents
/opt/xipki/pristine/ The unmodified XiPKI release and Tomcat base. No secrets.
/opt/xipki/run/ Your provisioned PKI, rebuilt from pristine on first boot
/opt/xipki/run/ca-tomcat/ Certificate authority Tomcat instance
/opt/xipki/run/gateway-tomcat/ Protocol gateway Tomcat instance
/opt/xipki/run/ocsp-tomcat/ OCSP responder Tomcat instance
/opt/xipki/run/xipki-setup/xipki-mgmt-cli/ Management command line interface
/opt/xipki/LICENSE The upstream Apache 2.0 licence
/root/xipki-credentials.txt Your certificate authority details and credentials (mode 0600)

All private key material is mode 0600 and owned by the xipki service user.

Managing the Services

sudo systemctl status xipki-ca
sudo systemctl restart xipki-gateway
sudo systemctl restart xipki-ocsp

The certificate authority must be running for the gateway to enrol certificates. Restart in the order xipki-ca, then xipki-gateway and xipki-ocsp.

Log Files

Log Path
Certificate authority /opt/xipki/run/ca-tomcat/logs/
Gateway (including audit) /opt/xipki/run/gateway-tomcat/logs/
OCSP responder /opt/xipki/run/ocsp-tomcat/logs/
First boot journalctl -u xipki-firstboot

The gateway audit log records every enrolment and revocation with the requestor, the certificate profile and the subject requested. It is the first place to look when an enrolment is rejected.

On Startup

The three XiPKI services are enabled and start on every boot. They are gated on a first boot marker, so on the very first boot they wait until your certificate authority has been generated. First boot runs the certificate round trip self test and only reports success once a real certificate has been issued and verified.

Troubleshooting

An enrolment returns HTTP 500. Check the gateway audit log:

sudo grep -h 'status: FAILED' /opt/xipki/run/gateway-tomcat/logs/gateway-audit_*.log | tail -5

The most common cause is a subject that the certificate profile rejects. The tls profile requires the common name to be a fully qualified domain name, so a bare label such as myservice is refused with BAD_CERT_TEMPLATE.

An enrolment returns HTTP 401. The enrolment credential is wrong. Read the current one with sudo grep '^xipki.gateway.requestor' /root/xipki-credentials.txt.

A revocation returns HTTP 400. The ca-sha1 parameter is required as well as serial-number. See Step 10.

OCSP still reports good after a revocation. The OCSP responder refreshes its view of the certificate database on an interval. Wait up to a minute and query again.

The services did not start. Check that first boot completed:

sudo systemctl status xipki-firstboot
sudo journalctl -u xipki-firstboot --no-pager | tail -30

Security Recommendations

  • Never expose the certificate authority management port (8444) to any network.
  • Put a reverse proxy in front of the enrolment gateway and restrict the source addresses that may enrol.
  • Prefer client certificate authentication over the password requestor for production enrolment.
  • Back up the PostgreSQL ca and caconf databases and the certificate authority keystore together. Losing the keystore means losing the ability to issue and revoke.
  • Treat /root/xipki-credentials.txt as secret. Anyone holding the enrolment credential can cause your certificate authority to issue certificates.
  • Consider a PKCS#11 hardware security module for the signing key in production. XiPKI supports this through xipki/security/pkcs11.json.

Support

cloudimg provides 24/7 technical support for this product by email at support@cloudimg.co.uk and by live chat. We help with certificate profile configuration, enrolment protocol selection, revocation and OCSP, certificate authority hierarchy planning, hardware security module integration, database sizing and backup, and version upgrades. Critical issues receive a one hour average response time.