Tutorial - Deploy EJBCA container in MicroK8s
Learn how to deploy the EJBCA container in the Kubernetes distribution MicroK8s.
This tutorial shows you how to use Ingress for external access to EJBCA and deploy Apache HTTPD for internal services to access EJBCA. The power of EJBCA is leveraged by deploying in Kubernetes to use internally in the Kubernetes cluster as well as externally.
In this tutorial, you will learn how to:
Deploy the EJBCA container into a Kubernetes runtime
Use Ingress for external access to EJBCA
Deploy Apache HTTPD container for containers inside of the Kubernetes cluster to access EJBCA
Configure certificates issued from the EJBCA container to terminate TLS for accessing EJBCA
Sorry, the widget is not supported in this export.
But you can reach it using the following URL:
https://www.youtube.com/watch?v=iz2M7V9Pvs4&list=PLt17f5skfOPEcg-Hbn4d-YY22wdmnaEa9
Prerequisites
For this tutorial, EJBCA Community Docker container version 7.11.0 was used.
Before you begin, you need MicroK8s installed and configured. To learn how to install and configure the Kubernetes distribution MicroK8s to deploy the EJBCA container, follow the tutorial Install MicroK8s to run EJBCA.
To issue TLS certificates in a later step, you need to configure EJBCA by following the previous tutorials in this tutorial series Get started with EJBCA and Istio to create a PKI Hierarchy in EJBCA, issue TLS server and client certificates with EJBCA, and create roles in EJBCA.
Additionally, you should be familiar with the YAML format and have a basic understanding of how to use the Kubernetes command line tool kubectl.
Step 1 - Create a namespace and secrets for EJBCA and MariaDB
In Kubernetes, namespaces provide a mechanism for isolating groups of resources within a single cluster and are used in environments with many users spread across multiple teams, or projects. A Kubernetes Secret is an object intended to hold confidential data and contains a small amount of sensitive data such as a password, a token, or a key. Using a Secret means that you do not need to include confidential data in your application code.
To isolate resources into a group in a Kubernetes cluster and create secrets for the database passwords, follow these steps:
SSH to the MicroK8s server.
In your terminal, enter the following to create a namespace:
$ kubectl create namespace ejbca-k8sCreate a secret for the MariaDB root password:
$ kubectl create secret generic -n ejbca-k8s mariadb-secret --from-literal=mariadb-root-password=ejbcaCreate a secret for the EJBCA MariaDB user account:
$ kubectl create secret generic -n ejbca-k8s ejbca-mariadb-secret --from-literal=ejbca-db-password=ejbca
Step 2 - Create Load Balancer Ingress Service
To configure external access to EJBCA, the Metal LB load balancer is leveraged by creating an Ingress service type.
To create a load balancer Ingress service, follow these steps:
Use a text editor such as vim to create the ingress service file ingress-service.yml:
$ vim ingress-service.ymlAdd the following to the file:
apiVersion: v1kind: Servicemetadata:name: ejbca-node1namespace: ingressspec:selector:name: nginx-ingress-microk8stype: LoadBalancer# loadBalancerIP is optional. MetalLB will automatically allocate an IP from its poolifnot# specified. You can also specify one manually.# loadBalancerIP: x.y.z.aports:- name: httpprotocol: TCPport:80targetPort:80- name: httpsprotocol: TCPport:443targetPort:443Save and close the file:
:wqApply the YAML file to create the Ingress service:
$ kubectl apply -f ingress-service.ymlCheck what external IP the ingress service is using:
$ kubectl get all,ingress -n ingressRecord this IP Address that can be added to the hosts file with the name ejbca-node1 for accessing the EJBCA.
Continue to the next step to create a persistent volume claim for the MariaDB database container.
Step 3 - Create a Persistent Volume Claim for the MariaDB container
To maintain the database state when the MariaDB container is stopped or upgraded, a Persistent Volume Claim (PVC) is used to store the DB data in a persistent storage location. For more information on PVCs, refer to the Kubernetes documentation topic Persistent Volumes.
To create a PVC, follow these steps:
Use a text editor such as vim to create the PVC file ejbca-pvc.yml:
$ vim ejbca-pvc.ymlAdd the following to the file:
apiVersion: v1kind: PersistentVolumeClaimmetadata:name: mariadb-pvcnamespace: ejbca-k8sspec:accessModes: [ReadWriteOnce]resources: { requests: { storage: 100M } }Save and close the file:
:wqApply the YAML file to create the PVC:
$ kubectl apply -f ejbca-pvc.yml
Continue with creating the services required for accessing the database and EJBCA.
Step 4 - Create services for the database and EJBCA
EJBCA needs to connect to the MariaDB database container. A service is used to allocate an IP address and port for the connection. EJBCA requires a service for Ingress and Apache HTTPD to connect with using AJP.
To create the two services, follow these steps:
Use a text editor such as vim to create the services file ejbca-svc.yml:
$ vim ejbca-svc.ymlAdd the following to the file:
apiVersion: v1kind: Servicemetadata:name: ejbca-database-servicenamespace: ejbca-k8slabels:app: mariadbspec:type: ClusterIPports:- name: database-portport:3306targetPort:3306selector:app: mariadb---apiVersion: v1kind: Servicemetadata:name: ejbca-servicenamespace: ejbca-k8slabels:app: ejbcaspec:type: ClusterIPports:- name: ajpport:8009targetPort:8009selector:app: ejbcaSave and close the file:
:wqApply the YAML file to create the services:
$ kubectl apply -f ejbca-svc.yml
The services are now created and you can continue to the next step to deploy the MariaDB container.
Step 5 - Create deployment for the MariaDB container
The EJBCA container supports MariaDB, Microsoft SQL Server, Oracle, and PostgreSQL databases. Deploying the EJBCA container with an external database stores the state and configuration. That means if the EJBCA container is stopped or restarted, the PKI configuration is not lost and requires everything to be configured all over again. A deployment is used to deploy the MariaDB container that will use the PVC and service created in the previous steps.
To deploy MariaDB in a container, follow these steps:
Use a text editor such as vim to create the MariaDB deployment file ejbca-db.yml:
$ vim ejbca-db.ymlAdd the following to the file:
apiVersion: apps/v1kind: Deployment # what to create?metadata:name: mariadb-deploymentnamespace: ejbca-k8slabels:app: mariadbspec: # specificationfordeployment resourcereplicas:1# how many replicas of pods we want to createselector:matchLabels:app: mariadbtemplate: # blueprintforpodsmetadata:labels:app: mariadb # service will lookforthislabelspec: # specificationforpodsvolumes:- name: datadirpersistentVolumeClaim:claimName: mariadb-pvccontainers:- name: mariadbimage: mariadb:latestports:- containerPort:3306#defaultoneenv:- name: MARIADB_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mariadb-secretkey: mariadb-root-password- name: MARIADB_PASSWORDvalueFrom:secretKeyRef:name: ejbca-mariadb-secretkey: ejbca-db-password- name: MARIADB_DATABASEvalue: ejbca- name: MARIADB_USERvalue: ejbcavolumeMounts:- name: datadirmountPath: /var/lib/mysql/Save and close the file:
:wqApply the YAML file to create the MariaDB deployment:
$ kubectl apply -f ejbca-db.yml
A deployment of MariaDB running in a container is now being deployed. Continue to the next step to deploy the EJBCA container.
Step 6 - Create deployment for the EJBCA container
As the pieces to support deploying EJBCA in Kubernetes were completed in previous steps, it's now time to create a deployment for the EJBCA container.
To deploy the EJBCA container, follow these steps:
Use a text editor such as vim to create the EJBCA deployment file ejbca-ca.yml:
$ vim ejbca-ca.ymlAdd the following to the file:
apiVersion: apps/v1kind: Deploymentmetadata:name: ejbca-deploymentnamespace: ejbca-k8slabels:app: ejbcaspec:replicas:1selector:matchLabels:app: ejbcatemplate:metadata:labels:app: ejbcaspec:containers:- name: ejbca-node1image: keyfactor/ejbca-ce:latestimagePullPolicy: Alwaysresources:limits:cpu:"16"memory:"4096Mi"requests:cpu: 1000mmemory:"2048Mi"ports:- containerPort:8009name: ejbca-ajpenv:- name: DATABASE_JDBC_URLvalue:"jdbc:mariadb://ejbca-database-service:3306/ejbca?characterEncoding=utf8"- name: DATABASE_USERvalue: ejbca- name: PROXY_AJP_BINDvalue:"0.0.0.0"- name: DATABASE_PASSWORDvalueFrom:secretKeyRef:name: ejbca-mariadb-secretkey: ejbca-db-password- name: LOG_AUDIT_TO_DBvalue:"true"Save and close the file:
:wqApply the YAML file to create the EJBCA deployment:
$ kubectl apply -f ejbca-ca.yml
EJBCA is deploying and the next step is to configure ingress for external access to EJBCA.
Step 7 - Create Ingress for external access to EJBCA
To configure external access to EJBCA using Ingress, follow these steps:
Use a text editor such as vim to create the EJBCA Ingress file ejbca-ingress.yml
$ vim ejbca-ingress.ymlAdd the following the file:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:annotations:# Use AJP with appservernginx.ingress.kubernetes.io/backend-protocol: AJPnginx.ingress.kubernetes.io/auth-tls-verify-client:"optional_no_ca"nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream:"true"name: ejbca-node1namespace: ejbca-k8sspec:ingressClassName:publicrules:- host: ejbca-node1http:paths:- path: /pathType: Prefixbackend:service:name: ejbca-serviceport:number:8009tls:- hosts:- ejbca-node1.ejbca-k8ssecretName: tls-secretSave and close the file:
:wqApply the YAML file to create the EJBCA Ingress:
$ kubectl apply -f ejbca-ingress.ymlQuery the Ingress IP to use for accessing EJBCA:
$ kubectl -n ingress get services -o json | jq -r'.items[] |.status.loadBalancer?|.ingress[]?|.ip '| cut -d : -f2Create a hosts file entry in /etc/hosts file or applicable file if using a none Linux OS with the IP from step 5. and the hostname ejbca-node1.ejbca-k8s, for example:
# Add to the hosts file:172.16.170.187ejbca-node1.ejbca-k8s
External access to EJBCA using Ingress is now configured.
Step 8 - Issue TLS certificates for EJBCA external and internal access
The following provides steps for updating the current TLS server end entity profile and certificate profile to use the Management CA and RSA key type. Once updated, two certificates will be issued to use for TLS termination to access EJBCA
Before you begin, you need to configure EJBCA by following the previous tutorials in this tutorials series, Get started with EJBCA and Istio to create a PKI Hierarchy in EJBCA, Issue TLS server and client certificates with EJBCA, and create roles in EJBCA.
To update the profiles and issue the two TLS certificates to use with the MicroK8s EJBCA deployment, follow these steps:
Log in to EJBCA and click Certificate Profiles under CA Functions.
To edit the server profile values to fit your needs, find the TLS Server Profile in the list and click Edit.
On the Edit page, update the following:
Add RSA to the selection of Available Key Algorithms, ECDSA and RSA should both be selected.
Select 2040 bits - 4096 bits for the Available Bit Lengths.
Scroll down to the Available CAs and additionally select ManagementCA, so that ManagementCA and MyPKISubCA-G1 are both selected.
Click Save.
Next, to add the Management CA to the End Entity Profile, click End Entity Profiles under RA Functions.
Select TLS Server Profile, then click Edit End Entity Profile
Scroll down to the Available CAs and additionally select ManagementCA, so that ManagementCA and MyPKISubCA-G1 are both selected.
Click Save.
In EJBCA, click RA Web to access the EJBCA RA UI.
Select Make New Request from the Enroll menu.
For Certificate Type, select your TLS Server Profile.
For CA, select ManagementCA.
For Key-pair generation, select By the CA.
For Key Algorithm, select RSA 2048 bits.
Specify the following information to be used in the certificate:
For CN, Common Name, specify a name, in this example ejbca-node1.
For the second DNS Name in the Subject Alternative Name Attributes, specify the full cluster name ejbca-node1.ejbca-k8s.
For Username, add ejbca-node1 to register the user under the username identical to the common name. The Username is the name that will go into the database and is often the same as the Common Name.
For Enrollment code, enter a password twice.
Click Download PEM to download and save the ejbca-node1.pem file.
To create a second internal certificate, scroll up and specify the following information to be used in the certificate:
For CN, Common Name, specify a name, in this example ejbca-internal.
For the second DNS Name in the Subject Alternative Name Attributes, specify the full cluster name ejbca-internal.ejbca-k8s.
For Username, add ejbca-internal to register the user under the username identical to the common name. The Username is the name that will go into the database and is often the same as the Common Name.
For Enrollment code, enter a password twice.
Click Download PEM to download and save the ejbca-internal.pem file.
TLS certificates have been issued from the Management CA that will be used to terminate TLS to the EJBCA container. Continue to the steps below to configure these certificates to use.
Step 9 - Create Kubernetes Secret and ConfigMap for the TLS certificates
Next, the two certificates issued in the previous step must be configured to be used with Ingress and Apache HTTPD.
You will create a Kubernetes Secret and ConfigMap for the TLS certificates:
A Kubernetes Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Using a Secret means that you do not need to include confidential data in your application code.
A ConfigMap is an API object used to store non-confidential data in key-value pairs. A ConfigMap allows you to decouple environment-specific configuration from your container images so that your applications are easily portable.
Secrets are similar to ConfigMaps but are specifically intended to hold confidential data. For more information, refer to the Kubernetes documentation topics Secrets and ConfigMaps.
To prepare Ingress and HTTPD to use certificates issued from EJBCA, follow these steps:
Open a new SSH session to the server.
To create the Kubernetes Secret, create three separate files for the ejbca-node1 certificate, key, and CA certificate:
Open the ejbca-node1.pem file with a text editor of your choice.
To create a server.crt file:
Use a text editor such as vim to create the server.crt file:
$ vim server.crtAdd the ejbca-node1 certificate to the file from the ejbca-node1.pem file opened in the text editor. The following shows an example certificate:
-----BEGIN CERTIFICATE-----MIIEnDCCAoSgAwIBAgIUC/uQvaEzLXFrULutwEFoXMdvPekwDQYJKoZIhvcNAQELBQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAzMTkxNzI2NDZaFw0yNDAzMTQxNzI2NDVaMEExCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVuaXR5MRQwEgYDVQQDDAtlamJjYS1ub2RlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAInoar+qRCeeLiuYknOSPjqboJ93W1YxBdYTScnDdXqRut2uDn0LoDijfP9CF3yWS4pvUkoBteOkIWs7eFi+7XA5JWQqrXzMo6dChdhI4tEnQ5XEVj+ISlAjFydTBXM4vNr8RKVMYHVvWLfT3Px6WX6BszueWMGkxwipdTwX4I7SBOt4gt9vnjIvkdIsSGExuzi7h8u+JPhj/6vqgcflHhwWjCqVrEyy3aj7KN1zUJlXHxZ6Jp64WNHPHd7brUCIPr8H+OT30LCZa1QYfMZK5ozHjlYOXJ+gE95NwR5oR2k/pHmqTwK6YhvSiVt33RefQuGXt3ho2rCC7kiMsfm98A0CAwEAAaOBijCBhzAfBgNVHSMEGDAWgBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAgBgNVHREEGTAXghVlamJjYS1ub2RlMS5lamJjYS1rOHMwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFEI3cF7EhrqNZjlafvuMan1gR604MA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEANrdbh+9tIpL+UqNwsqnXgFGCsdDROrIv6ZAfdt1q0UM3iHAaRWT9DF105Nk4J7j2tXacE8vkv35aCwBGJuG1uWoHm/H0+/fOs8pRW/9M4sjfpe/KM/hFjRXGVJfDlfVlrrvn2ixh240V9SkLStb0jStA0Jc4+fm3pnDppyGGYUFyk5gL0JNT67C7i2MR1vmAnHl3Z8Mq+FfteEuDSgYbf7Q5eCbnPOpGs4D6/msw4fEK2YiFPpgcnBR5RYFSLugFiI9p3RPWrfuOamkY43et3K1Ky37WvmrV1KJ7XquLn7xPJc6oOX9WGSvmXOUpZP4tiwqo1Ml7VXkQxtC0/zZjX6OK5d4B/H6TzqJBDDI+jrlNiTevtyieouhnQMx4PtjOGgNbaHpkbbVxFxrB0GgF0XPoKw6rDG7XDruO/6KgrsWYNZ4jJTu7pCIZNfrJPQXIYwsJBE2jNMG5Hpuj87XhM29M0eO2GYXE3fkjnTlz+5NHF0dR2tOQB9ZsCB4OEO8mlJeR5aRVJF+M3+/Lth1lWfZj4p4hHhGX3Bf609YWkrEXkllcMMx1D6hPK0PIMVRIgS1ZbY9vqs+nO3SP+FK0JuN/dpr24yyLnbH68zfToo7oggDlcKOiu4LFdOp51cUB8mcVkwTsNCX1Y3kon2I1CmC7i4wBfSReh6gI1lL6FOY=-----END CERTIFICATE-----Save and close the file:
:wq
To create a server.key file:
Use a text editor such as vim to create the server.key file:
$ vim server.keyAdd the ejbca-node1 private key to the file from the ejbca-node1.pem file opened in the text editor. The following shows an example private key:
-----BEGIN PRIVATE KEY-----MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCJ6Gq/qkQnni4rmJJzkj46m6Cfd1tWMQXWE0nJw3V6kbrdrg59C6A4o3z/Qhd8lkuKb1JKAbXjpCFrO3hYvu1wOSVkKq18zKOnQoXYSOLRJ0OVxFY/iEpQIxcnUwVzOLza/ESlTGB1b1i309z8ell+gbM7nljBpMcIqXU8F+CO0gTreILfb54yL5HSLEhhMbs4u4fLviT4Y/+r6oHH5R4cFowqlaxMst2o+yjdc1CZVx8WeiaeuFjRzx3e261AiD6/B/jk99CwmWtUGHzGSuaMx45WDlyfoBPeTcEeaEdpP6R5qk8CumIb0olbd90Xn0Lhl7d4aNqwgu5IjLH5vfANAgMBAAECggEAFO+bBxpk6uPNbBJnR1LQDisyrQrca58ZHPkEJnR9KPynMwC509t4OSj+sKy6rpANi0hfpHsSfyrbZPFcEZL4rmUKi2ScPlo9zQZhFebowipVDQ9HrbD14SkWmoJ0zRtztkX+cN7BtQpQnGW2QoEbhYRQrrAZFtq6WZMKSHNyhJPeG+VPaR1kgmbqV6sambmdvwQ8ZO3Q+PU5TWrKiNc3iUC03iNMuQpt5coA9MxwumoxvO9j4HWz9SoSn49Ik5M89N8A9D5te2FBoA+Nne6NbT+U1pMJlPSFCFuYzE21Ht4p6IgSLoYiO2fnzpaPdjX2rfW5GHTY1cbvBeqFIotI4QKBgQC+SJEbBdtxJnAffA1yEulN1+w6Lle5CPo6igpMu6otHiB9z1un/v1Kq/I+xwAYDPHGnxOGNeMqzlHPBSQ7dpRbPdWjRgUtKo+mqgQVnRZYrSyZ8Al9fZoU8WBlYSB3f6RpHYiD3UUlir6C58qybA5YV0cLF0RQ6WzcxVXLQbVSIQKBgQC5iTHZZqHrWR8jiMqymJztXxytZi1FJU6n+31j4WbSVbcq3Qh55XvPg5Ujx98dbp8ESRUhO8hpvoFITHH5j1fbjRXNwc2MevlsOF8lT3MOsuD/XlxnLVeetYnsyQUbigkiCTWU0FH5AOzvWjaHMmIlsMCwpWhOF6eUeokkLLr4bQKBgFydQVMfxLEL/mK0pG6zWa6zu5yN1dCP2AsKCP1UEf4nvbS+amQYLfxcOGnpvdf25O7BmmUmcUzyYssaO4pdqtPGAueXOwnCv2xlL9u9O5UppJ3AQT49FfO/kCWH4p+HFuS6pSlZV0BwiU15uCSjh0/kGwYA6xVep8fEnH9zmedBAoGAS7/Ux2Lctt7DFNnzj+k5ILzVU4JE91cc/v5xmkbbmQJ/7xMhM8taukWJrXsb/8M7Tx+bbd8fmvS5idAUNISupSe8AC6hAjru/J0jU3NVkWm87OYUqddcT6LktfT4jd7Ujb3ez2wiG5yiH7LgUmBiq+q3MSfHJyMHO1qwBUHx8B0CgYAYQJQDv3MMtrev6QobFxNcsWFrqzUN9CYJA8OtS5zubPuFoage9P9LUOqqR4VCo4AoIj7xUunrDh0jUDgZ0KRAakfJm2mg7PULx0n4CKfd9gQociNFfQHlwvX9UobsEfNNIxYTHcixMaWOOjBKIXpBgpi9cRgUlgV60HdiVe5jwg==-----END PRIVATE KEY-----Save and close the file:
:wq
To create a ca.crt file:
Use a text editor such as vim to create the ca.crt file:
$ vim ca.crtAdd the Management CA certificate to the file from the ejbca-node1.pem file opened in the text editor. The following shows an example Management CA certificate:
-----BEGIN CERTIFICATE-----MIIFdTCCA12gAwIBAgIUWpEFjDfFuGU6I5s/zCpuXrVmZIswDQYJKoZIhvcNAQELBQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAxMTgwODM0MDJaFw0zMzAxMTUwODM0MDFaMEIxFTATBgNVBAMMDE1hbmFnZW1lbnRDQTEcMBoGA1UECgwTS2V5ZmFjdG9yIENvbW11bml0eTELMAkGA1UEBhMCU0UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDIf6n+++qldacqGvWlgiPx7AnSMuremYdrRhoylF+3kJbDFiMpKpVzEaeguionS4uXqErZAzgzcbu6huf4bRscYk04nCgXsFAMItsiEZ314oE4thv8fbPPu4K1joeDgdHv0QhA3dkRUNorH54wOR6gLDzn6nBwePJAoKxhc/WoaONta2/OtHeTemYZOLt+uMY+Hj3o2sMeTm3B/B/ED5BWzVMSPOCCV6qk5/cW/P2YvWfFHUja8xqqbBuuDZHTuX4X58BsHH+o8bgZjWhdwcZb8Oe2VajFX6DpiBZcESQL+0ir0ZqGzALBc8jADv0VZC0u1Pxj39p19Xosm46jelcH3CBD+65I+1Kg5aQ1tIpBHLvdJEuTX6WkNPMmi0VqawxtlgshlF10kLsHm/r+dlGTQ78EA23JkgglBPovCmWSb6+KJyk/q6dWElqrbdHwieuajb2D9s/P7RDU7h9gSf6C4nbIX1x5H/mpVCdZWDuqL0Y7tn9Kkvhh3TNXZf1TiryJkw3GDxHS88mh+pGEZsnC3hH5rLKj/JFVQtbWeu1QdhI5fFlhPtUjIWeFHbgvMisd4qjouJfhuF2LRfpdn/u52MHTVntVGtGYNV3uUVpVR6YkFH0qGfAqP5clv1qSF5gRANIPVQSpF0wcvTHvgWdv9bOy7a9BLvWFg46Ys4HKWQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNf+MZRDSTxfobte/gWABCwE86DSMB0GA1UdDgQWBBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAC17+M739nb2AG3bpKObDDlW+fYMdEhXtjQcOvHIUrITKryX3lmHyWDFFgFTeTYcoxq8ywFvpvXz4pHgeFWRZYQw7cSWwH8nJfLE+EJlpYU2yUGto/S8NPXV54dAYNsvQQncQixsIYgxsmX7yIzBt1+v3sLmQlp5CfZRCOxj+2fa9jb/jygdQC3AAS5uT86gYz0YcB5VXQ0+jYWsL7MDwgb8ORcmiugduZ0kgBXd40Qg9bJhfz0N+BKWPTbS4dFst4ey5dndLp4QxWXzTt+gbmOMBpiwB6xxH3hw/LrRBEs7hrhVIlJ76cMx/f/5wERD0qS3uPXpCCtcKDBqHFruOI/NMNEVRFwiVxVD8w1jWYXDUyNVErU0LzqGOkyDuRwEDN8svaKn8+WdyumDB21tTWEbYPbFWc9R2epNj8moBVcfnxwsVP5TCXk6tEEOMkCVLNC3JBUWSfGJjg/2PDEdo2cPYCXYU4HueE/SnoUbRh0M34BfaHHt8S/vcEZWSkctJUmRZbTju57FKMlIHcgE5FHN5ahDAiScGgncvFfPKXcEPFh5bhKdhT6FzbKysCoRw16rwhzfsm4X42jvzBEOKpUcFDpRuBJszTk30lhAdmROkG5UTemobyKgDVw50VcFKbMk3Q5Gzs9TZ+uRAWJA7rF6MSc+cSlPqMN+i82CAMeU-----END CERTIFICATE-----Save and close the file:
:wq
Create Kubernetes Secret for the ejbca-node1 certificate, key, and a secret for the CA certificate file that Ingress will use to terminate TLS to the EJBCA container:
$ kubectl create secret tls -n ejbca-k8s tls-ejbca-node1 --cert server.crt --key server.key$ kubectl create secret generic -n ejbca-k8s mtls-trust-chain --from-file=ca.crt=ca.crtTo create the Kubernetes ConfigMap, create two separate files for the ejbca-node1 certificate and key (the CA certificate file ca.crt will be reused for the Management CA certificate).
Open the ejbca-internal.pem file with a text editor.
To create a ejbca-internal.crt file:
Use a text editor such as vim to create the ejbca-internal.crt file:
$ vim ejbca-internal.crtAdd the ejbca-internal certificate to the file from the ejbca-internal.pem file opened in the text editor. The following shows an example certificate:
-----BEGIN CERTIFICATE-----MIIEojCCAoqgAwIBAgIUPaLkQD5t3sJyXqyDZ9oakKCef4IwDQYJKoZIhvcNAQELBQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAzMTkxNzI3MTJaFw0yNDAzMTQxNzI3MTFaMEQxCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVuaXR5MRcwFQYDVQQDDA5lamJjYS1pbnRlcm5hbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIxh+0WaKmw+Yrim+/2c7Li/gWDJKdsd+mS170V6rnHSfRDdqfcW1q9ADwRZyu3Pc3s+w6UmjSciwOtvovPOfC5D0dUog4bgQ/1cSWuVUC8gd/Xyxb7DuKqbGtg8kB5BMD7O3oF89b2iGisfw4Ei9Njf1hrgl9DWuFfQ6+/d5luUXCRvcKYeQl05ZRii8LwLc8vvb613HbQi4n47QbLHMDgQDqdiqvefhyDE8gdgJyOBM5nVdsc2/6sxsKDNTMV86N1POWSXBrM9b4T/jFAik76dGjcCv/WTY/3VbPCuGypB5SaL++8/eLCEmZDgBovZT8WJIGK5odrdFbnSvtCwhZ0CAwEAAaOBjTCBijAfBgNVHSMEGDAWgBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAjBgNVHREEHDAaghhlamJjYS1pbnRlcm5hbC5lamJjYS1rOHMwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFJtUZTtTpL9zsDKstua4doISNMo5MA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEAkTxtIref9DVm4fcB2jzNdaiLPpWQbhREWgdg8oGaaams832JnoiCJjgalBnp8wNb8M9AxgEIU15il0xdw9oOoHAhz04Z3DV6snS1wmPs1u+un9zN0ZdBEEbCzchc/tUg4lVYLlKieTjUcg8Dy/wVBegwBYxDXfzbabhMe8GFCs0qXll2hIetjesqXtILq3Y5L7qVL7CaEeD2SX+Eb9Zz89xl069Jh3wWc34rBTI9L1f+ysBX0FhUyqqgmU8xUjLDaDXpkF+tQH1tIxtu3A1J1k1aRp8jDb2w6urxERy3+Huxl50wrb80HJRg/IdccIckpoFzga76hxV5l/mKlyxerr7Uev9prnTGeGSNF58dkJrGkwenvaYQC/PkI5MdqmrielVy56/o8ldS+12a1BtejMRE7I/KkPFF7ZIcTdh214NQe+FksaU8Wui4ozAb8ULYjodMbrvU798TnXht8ySF0PPdTJ7B7gA9oUGZsnYTKO/M6OP6NHte4ezmt3qvQpzsYeUOILz0+YeBZfCZrn2lJzQSkzaoernYO2igAEv/EGqJQ43hDKBnKKtJWMAHqzfaJuSnJfRnRIg1iDvQ+8XsTyMIY0uGgBWJt0qPAUxpgLBsjN+X9uu6DKuuCEQLNQ0oAbNYKjgqMU7yxf2YkhMP6nppS/I0JgVR9PKyMptyGJ0=-----END CERTIFICATE-----Save and close the file:
:wq
To create a ejbca-internal.key file:
Use a text editor such as vim to create the ejbca-internal.key file:
$ vim ejbca-internal.keyAdd the ejbca-internal private key to the file from the ejbca-internal.pem file opened in the text editor. The following shows an example private key:
-----BEGIN PRIVATE KEY-----MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMYftFmipsPmK4pvv9nOy4v4FgySnbHfpkte9Feq5x0n0Q3an3FtavQA8EWcrtz3N7PsOlJo0nIsDrb6LzznwuQ9HVKIOG4EP9XElrlVAvIHf18sW+w7iqmxrYPJAeQTA+zt6BfPW9ohorH8OBIvTY39Ya4JfQ1rhX0Ovv3eZblFwkb3CmHkJdOWUYovC8C3PL72+tdx20IuJ+O0GyxzA4EA6nYqr3n4cgxPIHYCcjgTOZ1XbHNv+rMbCgzUzFfOjdTzlklwazPW+E/4xQIpO+nRo3Ar/1k2P91WzwrhsqQeUmi/vvP3iwhJmQ4AaL2U/FiSBiuaHa3RW50r7QsIWdAgMBAAECggEACG3wv+DuN7I2TNawDm5AE6biLqzdn8vox2faTn57n5ePTXY1+MGNEhhjXnRC2G1KxqWB63aJZsZyNaDuNLwbHk8RuD42yaBJTNsgCH7+gdnuAh16DMalXc8y+TWHxN1Ot5LF7xoRCnpDnn/JhkVSVPx514LRcueVyaYgqLZXGPwUlLsEzZjy87w+wWYdkaUL0FlZPjJSsUcpDgTo4IVyLHYgKijwKa6GGAC1LRaF7xnGIX7SHhAr8Aec26jd5GNWecJaftSh22GP7o6eaf2IJMc1r7JQE21T+nG//hLHZ9hInwHdKXXjStKpnqLfwZsEt/gOwCJ7MQk+UPo0t+b9MQKBgQDFCOOQ3iU3CPjoyK5beR0XRHdtHNwLFOFP7bMpkwQuS86TUxFau2VOE3yPOU3UI+eWNXU6tHD9J4ep+BWnkqjdeehdBSmZePtGjsktmXf96rVZR3801Lfpar2tMfB8b4ngdIJcBCdsFNUY9VFhU0vO9xDflag5w3GONiiwaJ5GUQKBgQC2ZOdJqebkJ7n9MHY8Yc67anX4m9sLGhX7Sc4U8OLjGAAxXJrutoPYUPeUFGWwMfQvpXbydQRtnG4Jw42qnSino69xhwUqvhPSZqMTU4NEq5DQBIrT9LV2Ih0BkvE9sdfQsvtZzXWDl7yMm1R2YlCwozlZTBn9GCf3EOBxs/VbjQKBgBr4k4YCEqAM912OEufslUHZGmvyNmDB8/Gn/Q1k1X6s29Mo3MhJvJ1KZ5OHaZLvc0UJfkmR56GPpq9qiTRODBV9GYSaL06V0/edlgZK6rT0Suy0r8IAmEg4V0x8+IlgD0SNTkbgPrE5zM3EzuX+q/LhuQqSBtwZV9L6sOks+PVxAoGADSiKZw4S0jLrgBCW9xQ3Td4IVL8ptktTeqWAcJJQTAHXQbhklQQlzt1Ify5Zh7SS4T0Wr7cxcpbueVXaSoy7+hwc9BvBi6va0jsFWMeVmMan09oACfqFfNhJL2via4kBANVovLnN2IiB2cL6/O9q0tNzt7V9ynyLpY9aIdnRwaECgYBe67DpIIF+6o7+epHogfmNSLu/UdGhsBtJqbg9WJv7mXzpHWk+Vmx2HwYn6H9a8YW35C6E2GygVriuB72Ov5GVYPzw/mJ2YNLz1of0iBaH0Skru2kHP5fVNd4bpCz7Wt7WdB6ZEUfZerUEcprY30wrPkZVKHoa6btaotnw2IwNsQ==-----END PRIVATE KEY-----Save and close the file:
:wq
Create a Kubernetes ConfigMap for the ejbca-internal certificate and key, and re-use the CA certificate file created for the Kubernetes Secret (since the certificates are issued off the same CA) to use HTTPD to terminate TLS to the EJBCA container:
$ kubectl -n ejbca-k8s create configmap httpd-certs-configmap --from-file=ejbca-internal.crt=ejbca-internal.crt --from-file=ejbca-internal.key=ejbca-internal.key --from-file=ca.crt=ca.crt
The certificates, keys, and Management CA certificate are now configured to use for TLS by Apache HTTPD and Ingress. Continue to the next step to swap the TLS certificate used by Ingress.
Step 10 - Update EJBCA Ingress configuration to use new TLS certificate
Ingress has been using a self-signed certificate for terminating TLS to access the EJBCA CA UI and RA UI. The following outlines how to update the Ingress configuration to use and trust the certificate issued from the EJBCA Management CA.
To change the TLS certificate used by Ingress to access EJBCA, follow these steps:
Use a text editor such as vim to create the EJBCA Mutual TLS (mTLS) Ingress file ejbca-mtls-ingress.yml
$ vim ejbca-mtls-ingress.ymlAdd the following to the file:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:annotations:# Use AJP with appservernginx.ingress.kubernetes.io/backend-protocol: AJPnginx.ingress.kubernetes.io/auth-tls-verify-client:"optional"nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream:"true"nginx.ingress.kubernetes.io/auth-tls-secret:"ejbca-k8s/mtls-trust-chain"name: ejbca-node1namespace: ejbca-k8sspec:ingressClassName:publicrules:- host: ejbca-node1http:paths:- path: /pathType: Prefixbackend:service:name: ejbca-serviceport:number:8009tls:- hosts:- ejbca-node1.ejbca-k8ssecretName: tls-ejbca-node1Save and close the file:
:wqRemove the current EJBCA Ingress configuration:
$ kubectl delete -f ejbca-ingress.ymlApply the YAML file to create the EJBCA mTLS Ingress:
$ kubectl apply -f ejbca-mtls-ingress.yml
Ingress is now using a certificate issued from the EJBCA Management CA. Continue to the next step to deploy and configure Apache HTTPD.
Step 11 - Deploy Apache HTTPD for internal Kubernetes cluster access
Apache HTTPD is used as a reverse proxy to terminate TLS and provide access to EJBCA for internal cluster access. Containers, service mesh, or whatever else needs to access EJBCA within the cluster will use Apache HTTPD.
To deploy and configure Apache HTTPD, follow these steps:
Use a text editor such as vim to create the EJBCA HTTPD file ejbca-httpd.yml
$ vim ejbca-httpd.ymlAdd the following to the file:
---apiVersion: v1kind: Servicemetadata:name: ejbca-internalnamespace: ejbca-k8slabels:app: ejbca-httpdspec:type: ClusterIPports:- name: apacheport:443targetPort:443- name: openport:80targetPort:80selector:app: ejbca-httpd---apiVersion: v1data:httpd.conf: |+LoadModule mpm_event_module modules/mod_mpm_event.soLoadModule headers_module modules/mod_headers.soLoadModule authz_core_module modules/mod_authz_core.soLoadModule access_compat_module modules/mod_access_compat.soLoadModule log_config_module modules/mod_log_config.soLoadModule proxy_module modules/mod_proxy.soLoadModule proxy_http_module modules/mod_proxy_http.soLoadModule proxy_ajp_module modules/mod_proxy_ajp.soLoadModule unixd_module modules/mod_unixd.soLoadModule filter_module modules/mod_filter.soLoadModule substitute_module modules/mod_substitute.soLoadModule rewrite_module modules/mod_rewrite.soLoadModule socache_shmcb_module modules/mod_socache_shmcb.soLoadModule ssl_module modules/mod_ssl.soMaxKeepAliveRequests1000KeepAlive OnKeepAliveTimeout180# Don't think we needthis# Include conf/extra/httpd-ssl.conf<IfModule unixd_module>User daemonGroup daemon</IfModule>ErrorLog /proc/self/fd/2LogLevel info<IfModule log_config_module>LogFormat"%h %A:%p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""combinedLogFormat"%h %A:%p %l %u %t \"%r\" %>s %b"commonCustomLog /proc/self/fd/1common</IfModule>ServerRoot"/usr/local/apache2"Listen443Listen80<Directory />AllowOverride noneRequire all denied</Directory><VirtualHost *:443>DocumentRoot /var/www/html/# Disallow any HTTP method that is not HEAD, GET or POSTRewriteEngine OnRewriteCond %{REQUEST_METHOD} !^(HEAD|GET|POST|PUT)$ [NC]RewriteRule .* - [F,L]SSLEngine onSSLCipherSuite HIGH:!ADH:!aDSS:!aDHSSLProtocol all -SSLv2 -SSLv3 -TLSv1 +TLSv1.2-TLSv1.3# SSLProtocol -all +TLSv1.2SSLOptions +ExportCertData +StdEnvVarsSSLCertificateFile /etc/httpd/ssl/ejbca-internal.crtSSLCertificateKeyFile /etc/httpd/ssl/ejbca-internal.keySSLVerifyClient optionalSSLVerifyDepth3SSLCACertificateFile /etc/httpd/ssl/ca.crt<Location /ejbca/ejbcaws>SSLVerifyClient require</Location><Location /ejbca/adminweb>SSLVerifyClient require</Location># Allow encoded slashesforOCSP GETAllowEncodedSlashes OnProxyPass /ejbca/ ajp://ejbca-service:8009/ejbca/ keepalive=On ping=500ms retry=1 timeout=300#Add ProxyPassforEST and .well-known URLsProxyPass /.well-known/ ajp://ejbca-service:8009/.well-known/ keepalive=On ping=500ms retry=1 timeout=300# Redirect /, /ejbca, /signserver and non-proxied URLs to /ejbca/RewriteCond %{THE_REQUEST} !(/ejbca/.*|/.well-known/.*)RewriteRule (.*) https://%{HTTP_HOST}/ejbca/</VirtualHost><VirtualHost *:80>DocumentRoot /var/www/html/# Disallow any HTTP method that is not HEAD, GET or POSTRewriteEngine OnRewriteCond %{REQUEST_METHOD} !^(HEAD|GET|POST)$ [NC]RewriteRule .* - [F,L]# Redirect legacy EJBCA enrollment to HTTPSRewriteCond %{HTTPS} !=onRewriteRule ^/?ejbca/enrol/(.*) https://%{SERVER_NAME}/ejbca/enrol/$1 [R,L]# Allow encoded slashesforOCSP GETAllowEncodedSlashes OnProxyPass /ejbca/ ajp://ejbca-service:8009/ejbca/ keepalive=On ping=500ms retry=1 timeout=300 nocanonProxyPass /signserver/ ajp://ejbca-service:8009/signserver/ keepalive=On ping=500ms retry=1 timeout=300# Redirect /, /ejbca, /signserver and non-proxied URLs to /ejbca/RewriteCond %{THE_REQUEST} !(/signserver/.*|/ejbca/.*) [OR]RewriteCond %{THE_REQUEST} (/ejbca/ejbcaws.*)RewriteRule (.*) http://%{HTTP_HOST}/ejbca/RewriteCond %{THE_REQUEST} (/ejbca/ejbcaws.*|/ejbca/adminweb.*)RewriteRule (.*) https://%{HTTP_HOST}/ejbca/</VirtualHost>kind: ConfigMapmetadata:namespace: ejbca-k8sname: config-httpd-configmap---apiVersion: apps/v1kind: Deploymentmetadata:name: ejbca-httpdnamespace: ejbca-k8slabels:app: ejbca-httpdspec:replicas:1selector:matchLabels:app: ejbca-httpdtemplate:metadata:labels:app: ejbca-httpdspec:containers:- name: httpdimage: library/httpd:latestports:- containerPort:443name: httpd-http- containerPort:80name: httpvolumeMounts:- name: config-httpd-volumemountPath: /usr/local/apache2/conf/- name: certificates-volumemountPath: /etc/httpd/sslvolumes:- name: config-httpd-volumeconfigMap:name: config-httpd-configmap- name: certificates-volumeconfigMap:name: httpd-certs-configmapSave and close the file:
:wqApply the YAML file to deploy and configure the Apache HTTPD container:
$ kubectl apply -f ejbca-httpd.yml
Apache HTTPD is now deployed and configured for internal cluster resources to access.
Next steps
In this tutorial, you learned how to deploy EJBCA in MicroK8s using MariaDB as the database and configure access to EJBCA internally and externally.
Here are some next steps we recommend:
To learn how to use a service mesh to issue mutual TLS certificates with EJBCA running in Kubernetes., follow the tutorial Deploy EJBCA container to issue certificates to an Istio service mesh.
Unable to render include or excerpt-include. Could not retrieve page.