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