PKI ACME OpenShift

From Dogtag
Jump to: navigation, search

Overview

This page describes the process to deploy PKI ACME Container on OpenShift.

Current Issues

  • This is still a work in progress.
  • The ACME instance cannot be created in OpenShift yet. The instance needs to be created locally then uploaded to OpenShift.

Creating Local ACME Instance

Create Tomcat instance:

$ pki-server create tomcat@acme

Deploy ACME web application:

$ pki-server acme-create -i tomcat@acme
$ pki-server acme-deploy -i tomcat@acme

Then create a backup:

$ tar czvf acme.tar.gz -C / \
    var/lib/tomcats/acme

Creating Persistent Storage

Prepare a configuration file (e.g. acme-pvc.yaml):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: acme
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Then execute the following command:

$ oc create -f acme-pvc.yaml

Deploying ACME Image

To deploy ACME image:

$ oc new-app edewata/acme:latest --name acme
$ oc expose svc/acme --name=acme --hostname=acme.demo.dogtagpki.org

Add a CNAME DNS record to map to the canonical hostname.

Verify by opening the following URL in a browser:

Creating ACME Service

Prepare a configuration file (e.g. acme-svc.yaml):

apiVersion: v1
kind: Service
metadata:
  labels:
    app: acme
  name: acme
spec:
  ports:
    - name: 8080-tcp
      port: 8080
      protocol: TCP
      targetPort: 8080
    - name: 8443-tcp
      port: 8443
      protocol: TCP
      targetPort: 8443
  selector:
    app: acme
    deploymentconfig: acme
  sessionAffinity: None
  type: ClusterIP

Then execute the following command:

$ oc create -f acme-svc.yaml

Creating DNS Record

Create a CNAME record for the public hostname (e.g. acme.demo.dogtagpki.org) pointing to the router's canonical hostname provided by OpenShift.

Creating ACME Route

Prepare a configuration file (e.g. acme-route.yaml):

apiVersion: v1
kind: Route
metadata:
  labels:
    app: acme
  name: acme
spec:
  host: acme.demo.dogtagpki.org
  port:
    targetPort: 8080-tcp
  to:
    kind: Service
    name: acme
    weight: 100
  wildcardPolicy: None

Then execute the following command:

$ oc create -f acme-route.yaml

Generating Internal SSL Certificate

To generate HTTPS connector:

$ pki-server http-connector-add -i tomcat@acme \
  --port 8443 \
  --scheme https \
  --secure true \
  --sslEnabled true \
  --sslProtocol SSL \
  Secure

To generate internal SSL certificate:

$ openssl req \
  -newkey rsa:2048 \
  -x509 \
  -nodes \
  -days 365 \
  -subj "/CN=acme.pki-demo.svc" \
  -keyout /var/lib/tomcats/acme/conf/sslserver.key \
  -out /var/lib/tomcats/acme/conf/sslserver.crt

To install internal SSL certificate:

$ pki-server http-connector-cert-add -i tomcat@acme \
  --certFile /var/lib/tomcats/acme/conf/sslserver.crt \
  --keyFile /var/lib/tomcats/acme/conf/sslserver.key

Generating External SSL Certificate

Run the following command to request a certificate from Let's Encrypt:

$ certbot certonly --manual -d acme.demo.dogtagpki.org --register-unsafely-without-email

Create the ACME response:

$ oc rsh <pod> mkdir -p /var/lib/tomcats/acme/webapps/.well-known/acme-challenge
$ oc rsync acme-challenge/ <pod>:/var/lib/tomcats/acme/webapps/.well-known/acme-challenge

Create an unsecure HTTP route for port 8080 of the PKI CA service, then complete the ACME validation. The results will be stored in:

  • certificate: /etc/letsencrypt/live/acme.demo.dogtagpki.org/fullchain.pem
  • key: /etc/letsencrypt/live/acme.demo.dogtagpki.org/privkey.pem

Installing External SSL Certificate

Remove the current route:

$ oc delete routes/acme

Prepare a configuration file (e.g. acme-route-secure.yaml):

apiVersion: v1
kind: Route
metadata:
  labels:
    app: acme
  name: acme
spec:
  host: acme.demo.dogtagpki.org
  port:
    targetPort: 8443-tcp
  tls:
    caCertificate: |-
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    certificate: |-
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    destinationCACertificate: |-
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    insecureEdgeTerminationPolicy: Redirect
    key: |-
      -----BEGIN PRIVATE KEY-----
      ...
      -----END PRIVATE KEY-----
    termination: reencrypt
  to:
    kind: Service
    name: acme
    weight: 100
  wildcardPolicy: None

Then execute the following command:

$ oc create -f acme-route-secure.yaml

To validate, open https://acme.demo.dogtagpki.org with a browser.

Updating ACME Image

To deploy newer ACME image:

$ oc import-image edewata/acme

It will automatically respawn the pods with the new image.

Testing with an ACME Client

To submit an ACME request:

$ certbot certonly --manual \
    -d server.example.com \
    --register-unsafely-without-email \
    --preferred-challenges dns \
    --server http://acme.demo.dogtagpki.org/acme/directory

See Also