PKI CA OpenShift - dogtagpki/pki GitHub Wiki
This page describes the procedure to deploy a PKI instance on OpenShift.
- This is still a work in progress.
- The PKI instance cannot be created in OpenShift yet. The instance needs to be created locally then uploaded to OpenShift.
- The database configuration needs to be updated.
- The auth-method.properties needs to be fixed.
- The SSL certificate needs to be regenerated.
- Log files need to be cleaned up.
Create a PKI instance in the local machine.
Then create a backup:
$ pki-server stop
$ tar czvf pki-tomcat.tar.gz -C / \
etc/pki/pki-tomcat \
etc/sysconfig/pki-tomcat \
etc/sysconfig/pki/tomcat/pki-tomcat \
etc/systemd/system/pki-tomcatd.target.wants/[email protected] \
var/lib/pki/pki-tomcat \
var/log/pki/pki-tomcat
Put the pki-tomcat.tar.gz in a backup dir.
Prepare a configuration file (e.g. pki-pvc.yaml):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pki
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Then execute the following command:
$ oc create -f pki-pvc.yaml
Deploy a temporary application (e.g. Fedora OpenShift).
Mount the storage into the application's pod into /data.
Upload the backup file:
$ oc rsync <backup dir> <pod>:/data
Open a remote shell:
$ oc rsh <pod>
Execute the following commands:
$ cd /data $ tar xvf pki-tomcat.tar.gz $ rm pki-tomcat.tar.gz
Edit /data/var/lib/pki/pki-tomcat/conf/ca/CS.cfg:
internaldb.ldapconn.host=ds.pki-demo.svc internaldb.ldapconn.port=10389
Unmount the storage. The temporary application can be undeployed as well.
FROM fedora:30
EXPOSE 8080 8443
RUN dnf install -y dnf-plugins-core && dnf copr enable -y edewata/pki
RUN dnf install -y abrt-java-connector dogtag-pki && dnf clean all
RUN ln -s /data/var/lib/pki/pki-tomcat/conf /var/lib/pki/pki-tomcat/conf && \
ln -s /data/etc/sysconfig/pki-tomcat /etc/sysconfig/pki-tomcat && \
ln -s /data/etc/sysconfig/pki/tomcat/pki-tomcat /etc/sysconfig/pki/tomcat/pki-tomcat && \
ln -s /data/etc/systemd/system/pki-tomcatd.target.wants/[email protected] \
/etc/systemd/system/pki-tomcatd.target.wants/[email protected] && \
ln -s /data/var/lib/pki/pki-tomcat /var/lib/pki/pki-tomcat && \
ln -s /data/var/log/pki/pki-tomcat /var/log/pki/pki-tomcat
USER pkiuser
VOLUME /data
CMD [ "pki-server", "run", "--as-current-user", "--debug" ]
$ docker build -t pki .
$ docker tag pki:latest <username>/pki:latest $ docker push <username>/pki:latest
Prepare a configuration file (e.g. pki-is.yaml):
apiVersion: v1
kind: ImageStream
metadata:
labels:
app: ca
name: pki
spec:
lookupPolicy:
local: false
tags:
- from:
kind: DockerImage
name: 'edewata/pki:latest'
name: latest
referencePolicy:
type: Source
Then execute the following command:
$ oc create -f pki-is.yaml
Prepare a configuration file (e.g. pki-dc.yaml):
apiVersion: v1
kind: DeploymentConfig
metadata:
labels:
app: pki
name: pki
spec:
selector:
app: pki
deploymentconfig: pki
template:
metadata:
labels:
app: pki
deploymentconfig: pki
spec:
containers:
- image: edewata/pki
name: pki
ports:
- containerPort: 8080
protocol: TCP
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: pki
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- pki
from:
kind: ImageStreamTag
name: 'pki:latest'
type: ImageChange
Then execute the following command:
$ oc create -f pki-dc.yaml
$ oc scale dc pki --replicas=1
Generate a new CSR for the PKI service (e.g. pki.pki-demo.svc):
$ cd /var/lib/pki/pki-tomcat/conf/alias $ openssl rand -out noise.bin 2048 $ echo Secret.123 > password.txt $ certutil -R \ -d . \ -f password.txt \ -z noise.bin \ -k rsa \ -g 2048 \ -Z SHA256 \ -s "CN=pki.pki-demo.svc,O=EXAMPLE" \ --keyUsage critical,dataEncipherment,keyEncipherment,digitalSignature \ --extKeyUsage serverAuth \ -o sslserver.csr.der $ openssl req -inform der -in sslserver.csr.der -out sslserver.csr
Get the SKID and OCSP URL from the CA signing certificate:
$ pki-server cert-export ca_signing --cert-file ca_signing.crt $ openssl x509 -text -noout -in ca_signing.crt $ SKID=0x`openssl x509 -text -noout -in ca_signing.crt | grep "keyid:" | sed -e 's/ *keyid://g' -e 's/://g'` $ OCSP=http://pki.pki-demo.svc:8080/ca/ocsp
Issue a new certificate for the SSL server certificate:
$ echo -e "y\n${SKID}\n\n\nn\n2\n7\n${OCSP}\n\n\n\n" | \
certutil -C \
-d . \
-f password.txt \
-m $RANDOM \
-a \
-i sslserver.csr \
-o sslserver.crt \
-c "ca_signing" \
-v 12 \
-3 \
--extAIA \
--keyUsage critical,dataEncipherment,keyEncipherment,digitalSignature \
--extKeyUsage serverAuth
Replace the server certificate:
$ certutil -F -d . -f password.txt -n "sslserver" $ certutil -A -d . -f password.txt -n "sslserver" -i sslserver.crt -t ",,"
$ oc scale dc pki --replicas=0 $ sleep 10 $ oc scale dc pki --replicas=1
Prepare a configuration file (e.g. pki-svc.yaml):
apiVersion: v1
kind: Service
metadata:
labels:
app: pki
name: pki
spec:
ports:
- name: 8080-tcp
port: 8080
protocol: TCP
targetPort: 8080
- name: 8443-tcp
port: 8443
protocol: TCP
targetPort: 8443
selector:
app: pki
deploymentconfig: pki
sessionAffinity: None
type: ClusterIP
Then execute the following command:
$ oc create -f pki-svc.yaml
Create a CNAME record for the public hostname (e.g. pki.demo.dogtagpki.org) pointing to the router's canonical hostname provided by OpenShift.
Prepare a configuration file (e.g. pki-route.yaml):
apiVersion: v1
kind: Route
metadata:
labels:
app: pki
name: pki
spec:
host: pki.demo.dogtagpki.org
port:
targetPort: 8080-tcp
to:
kind: Service
name: pki
weight: 100
wildcardPolicy: None
Then execute the following command:
$ oc create -f pki-route.yaml
Run the following command to request a certificate from Let's Encrypt:
$ certbot certonly --manual -d pki.demo.dogtagpki.org --register-unsafely-without-email
Create the ACME response:
$ oc rsh <pod> mkdir -p /var/lib/pki/pki-tomcat/webapps/.well-known/acme-challenge $ oc rsync acme-challenge/ <pod>:/var/lib/pki/pki-tomcat/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/pki.demo.dogtagpki.org/fullchain.pem
- key: /etc/letsencrypt/live/pki.demo.dogtagpki.org/privkey.pem
Remove the current route:
$ oc delete routes/pki
Prepare a configuration file (e.g. pki-route-secure.yaml):
apiVersion: v1
kind: Route
metadata:
labels:
app: pki
name: pki
spec:
host: pki.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: pki
weight: 100
wildcardPolicy: None
Then execute the following command:
$ oc create -f pki-route-secure.yaml
To validate, open https://pki.demo.dogtagpki.org with a browser.
If newer container image is available, it can be deployed with the following command:
$ oc import-image <username>/ca