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-k8s
Create a secret for the MariaDB root password:
$ kubectl create secret generic -n ejbca-k8s mariadb-secret --from-literal=mariadb-root-password=ejbca
Create 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.yml
Add the following to the file:
apiVersion: v1
kind: Service
metadata:
name: ejbca-node1
namespace: ingress
spec:
selector:
name: nginx-ingress-microk8s
type: LoadBalancer
# loadBalancerIP is optional. MetalLB will automatically allocate an IP from its pool
if
not
# specified. You can also specify one manually.
# loadBalancerIP: x.y.z.a
ports:
- name: http
protocol: TCP
port:
80
targetPort:
80
- name: https
protocol: TCP
port:
443
targetPort:
443
Save and close the file:
:wq
Apply the YAML file to create the Ingress service:
$ kubectl apply -f ingress-service.yml
Check what external IP the ingress service is using:
$ kubectl get all,ingress -n ingress
Record 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.yml
Add the following to the file:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
namespace: ejbca-k8s
spec:
accessModes: [ReadWriteOnce]
resources: { requests: { storage: 100M } }
Save and close the file:
:wq
Apply 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.yml
Add the following to the file:
apiVersion: v1
kind: Service
metadata:
name: ejbca-database-service
namespace: ejbca-k8s
labels:
app: mariadb
spec:
type: ClusterIP
ports:
- name: database-port
port:
3306
targetPort:
3306
selector:
app: mariadb
---
apiVersion: v1
kind: Service
metadata:
name: ejbca-service
namespace: ejbca-k8s
labels:
app: ejbca
spec:
type: ClusterIP
ports:
- name: ajp
port:
8009
targetPort:
8009
selector:
app: ejbca
Save and close the file:
:wq
Apply 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.yml
Add the following to the file:
apiVersion: apps/v1
kind: Deployment # what to create?
metadata:
name: mariadb-deployment
namespace: ejbca-k8s
labels:
app: mariadb
spec: # specification
for
deployment resource
replicas:
1
# how many replicas of pods we want to create
selector:
matchLabels:
app: mariadb
template: # blueprint
for
pods
metadata:
labels:
app: mariadb # service will look
for
this
label
spec: # specification
for
pods
volumes:
- name: datadir
persistentVolumeClaim:
claimName: mariadb-pvc
containers:
- name: mariadb
image: mariadb:latest
ports:
- containerPort:
3306
#
default
one
env:
- name: MARIADB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-secret
key: mariadb-root-password
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: ejbca-mariadb-secret
key: ejbca-db-password
- name: MARIADB_DATABASE
value: ejbca
- name: MARIADB_USER
value: ejbca
volumeMounts:
- name: datadir
mountPath: /var/lib/mysql/
Save and close the file:
:wq
Apply 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.yml
Add the following to the file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ejbca-deployment
namespace: ejbca-k8s
labels:
app: ejbca
spec:
replicas:
1
selector:
matchLabels:
app: ejbca
template:
metadata:
labels:
app: ejbca
spec:
containers:
- name: ejbca-node1
image: keyfactor/ejbca-ce:latest
imagePullPolicy: Always
resources:
limits:
cpu:
"16"
memory:
"4096Mi"
requests:
cpu: 1000m
memory:
"2048Mi"
ports:
- containerPort:
8009
name: ejbca-ajp
env:
- name: DATABASE_JDBC_URL
value:
"jdbc:mariadb://ejbca-database-service:3306/ejbca?characterEncoding=utf8"
- name: DATABASE_USER
value: ejbca
- name: PROXY_AJP_BIND
value:
"0.0.0.0"
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: ejbca-mariadb-secret
key: ejbca-db-password
- name: LOG_AUDIT_TO_DB
value:
"true"
Save and close the file:
:wq
Apply 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.yml
Add the following the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# Use AJP with appserver
nginx.ingress.kubernetes.io/backend-protocol: AJP
nginx.ingress.kubernetes.io/auth-tls-verify-client:
"optional_no_ca"
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream:
"true"
name: ejbca-node1
namespace: ejbca-k8s
spec:
ingressClassName:
public
rules:
- host: ejbca-node1
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ejbca-service
port:
number:
8009
tls:
- hosts:
- ejbca-node1.ejbca-k8s
secretName: tls-secret
Save and close the file:
:wq
Apply the YAML file to create the EJBCA Ingress:
$ kubectl apply -f ejbca-ingress.yml
Query the Ingress IP to use for accessing EJBCA:
$ kubectl -n ingress get services -o json | jq -r
'.items[] |.status.loadBalancer?|.ingress[]?|.ip '
| cut -d : -f
2
Create 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.187
ejbca-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.crt
Add 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/uQvaEzLXFrULutwEFoXMdvPekwDQYJKoZIhvcNAQEL
BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAzMTkxNzI2NDZaFw0yNDAzMTQx
NzI2NDVaMEExCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVu
aXR5MRQwEgYDVQQDDAtlamJjYS1ub2RlMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAInoar+qRCeeLiuYknOSPjqboJ93W1YxBdYTScnDdXqRut2uDn0L
oDijfP9CF3yWS4pvUkoBteOkIWs7eFi+7XA5JWQqrXzMo6dChdhI4tEnQ5XEVj+I
SlAjFydTBXM4vNr8RKVMYHVvWLfT3Px6WX6BszueWMGkxwipdTwX4I7SBOt4gt9v
njIvkdIsSGExuzi7h8u+JPhj/6vqgcflHhwWjCqVrEyy3aj7KN1zUJlXHxZ6Jp64
WNHPHd7brUCIPr8H+OT30LCZa1QYfMZK5ozHjlYOXJ+gE95NwR5oR2k/pHmqTwK6
YhvSiVt33RefQuGXt3ho2rCC7kiMsfm98A0CAwEAAaOBijCBhzAfBgNVHSMEGDAW
gBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAgBgNVHREEGTAXghVlamJjYS1ub2RlMS5l
amJjYS1rOHMwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFEI3cF7EhrqN
ZjlafvuMan1gR604MA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEA
Nrdbh+9tIpL+UqNwsqnXgFGCsdDROrIv6ZAfdt1q0UM3iHAaRWT9DF105Nk4J7j2
tXacE8vkv35aCwBGJuG1uWoHm/H0+/fOs8pRW/9M4sjfpe/KM/hFjRXGVJfDlfVl
rrvn2ixh240V9SkLStb0jStA0Jc4+fm3pnDppyGGYUFyk5gL0JNT67C7i2MR1vmA
nHl3Z8Mq+FfteEuDSgYbf7Q5eCbnPOpGs4D6/msw4fEK2YiFPpgcnBR5RYFSLugF
iI9p3RPWrfuOamkY43et3K1Ky37WvmrV1KJ7XquLn7xPJc6oOX9WGSvmXOUpZP4t
iwqo1Ml7VXkQxtC0/zZjX6OK5d4B/H6TzqJBDDI+jrlNiTevtyieouhnQMx4PtjO
GgNbaHpkbbVxFxrB0GgF0XPoKw6rDG7XDruO/6KgrsWYNZ4jJTu7pCIZNfrJPQXI
YwsJBE2jNMG5Hpuj87XhM29M0eO2GYXE3fkjnTlz+5NHF0dR2tOQB9ZsCB4OEO8m
lJeR5aRVJF+M3+/Lth1lWfZj4p4hHhGX3Bf609YWkrEXkllcMMx1D6hPK0PIMVRI
gS1ZbY9vqs+nO3SP+FK0JuN/dpr24yyLnbH68zfToo7oggDlcKOiu4LFdOp51cUB
8mcVkwTsNCX1Y3kon2I1CmC7i4wBfSReh6gI1lL6FOY=
-----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.key
Add 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/qkQnni4r
mJJzkj46m6Cfd1tWMQXWE0nJw3V6kbrdrg59C6A4o3z/Qhd8lkuKb1JKAbXjpCFr
O3hYvu1wOSVkKq18zKOnQoXYSOLRJ0OVxFY/iEpQIxcnUwVzOLza/ESlTGB1b1i3
09z8ell+gbM7nljBpMcIqXU8F+CO0gTreILfb54yL5HSLEhhMbs4u4fLviT4Y/+r
6oHH5R4cFowqlaxMst2o+yjdc1CZVx8WeiaeuFjRzx3e261AiD6/B/jk99CwmWtU
GHzGSuaMx45WDlyfoBPeTcEeaEdpP6R5qk8CumIb0olbd90Xn0Lhl7d4aNqwgu5I
jLH5vfANAgMBAAECggEAFO+bBxpk6uPNbBJnR1LQDisyrQrca58ZHPkEJnR9KPyn
MwC509t4OSj+sKy6rpANi0hfpHsSfyrbZPFcEZL4rmUKi2ScPlo9zQZhFebowipV
DQ9HrbD14SkWmoJ0zRtztkX+cN7BtQpQnGW2QoEbhYRQrrAZFtq6WZMKSHNyhJPe
G+VPaR1kgmbqV6sambmdvwQ8ZO3Q+PU5TWrKiNc3iUC03iNMuQpt5coA9Mxwumox
vO9j4HWz9SoSn49Ik5M89N8A9D5te2FBoA+Nne6NbT+U1pMJlPSFCFuYzE21Ht4p
6IgSLoYiO2fnzpaPdjX2rfW5GHTY1cbvBeqFIotI4QKBgQC+SJEbBdtxJnAffA1y
EulN1+w6Lle5CPo6igpMu6otHiB9z1un/v1Kq/I+xwAYDPHGnxOGNeMqzlHPBSQ7
dpRbPdWjRgUtKo+mqgQVnRZYrSyZ8Al9fZoU8WBlYSB3f6RpHYiD3UUlir6C58qy
bA5YV0cLF0RQ6WzcxVXLQbVSIQKBgQC5iTHZZqHrWR8jiMqymJztXxytZi1FJU6n
+31j4WbSVbcq3Qh55XvPg5Ujx98dbp8ESRUhO8hpvoFITHH5j1fbjRXNwc2Mevls
OF8lT3MOsuD/XlxnLVeetYnsyQUbigkiCTWU0FH5AOzvWjaHMmIlsMCwpWhOF6eU
eokkLLr4bQKBgFydQVMfxLEL/mK0pG6zWa6zu5yN1dCP2AsKCP1UEf4nvbS+amQY
LfxcOGnpvdf25O7BmmUmcUzyYssaO4pdqtPGAueXOwnCv2xlL9u9O5UppJ3AQT49
FfO/kCWH4p+HFuS6pSlZV0BwiU15uCSjh0/kGwYA6xVep8fEnH9zmedBAoGAS7/U
x2Lctt7DFNnzj+k5ILzVU4JE91cc/v5xmkbbmQJ/7xMhM8taukWJrXsb/8M7Tx+b
bd8fmvS5idAUNISupSe8AC6hAjru/J0jU3NVkWm87OYUqddcT6LktfT4jd7Ujb3e
z2wiG5yiH7LgUmBiq+q3MSfHJyMHO1qwBUHx8B0CgYAYQJQDv3MMtrev6QobFxNc
sWFrqzUN9CYJA8OtS5zubPuFoage9P9LUOqqR4VCo4AoIj7xUunrDh0jUDgZ0KRA
akfJm2mg7PULx0n4CKfd9gQociNFfQHlwvX9UobsEfNNIxYTHcixMaWOOjBKIXpB
gpi9cRgUlgV60HdiVe5jwg==
-----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.crt
Add 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/zCpuXrVmZIswDQYJKoZIhvcNAQEL
BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAxMTgwODM0MDJaFw0zMzAxMTUw
ODM0MDFaMEIxFTATBgNVBAMMDE1hbmFnZW1lbnRDQTEcMBoGA1UECgwTS2V5ZmFj
dG9yIENvbW11bml0eTELMAkGA1UEBhMCU0UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQDIf6n+++qldacqGvWlgiPx7AnSMuremYdrRhoylF+3kJbDFiMp
KpVzEaeguionS4uXqErZAzgzcbu6huf4bRscYk04nCgXsFAMItsiEZ314oE4thv8
fbPPu4K1joeDgdHv0QhA3dkRUNorH54wOR6gLDzn6nBwePJAoKxhc/WoaONta2/O
tHeTemYZOLt+uMY+Hj3o2sMeTm3B/B/ED5BWzVMSPOCCV6qk5/cW/P2YvWfFHUja
8xqqbBuuDZHTuX4X58BsHH+o8bgZjWhdwcZb8Oe2VajFX6DpiBZcESQL+0ir0ZqG
zALBc8jADv0VZC0u1Pxj39p19Xosm46jelcH3CBD+65I+1Kg5aQ1tIpBHLvdJEuT
X6WkNPMmi0VqawxtlgshlF10kLsHm/r+dlGTQ78EA23JkgglBPovCmWSb6+KJyk/
q6dWElqrbdHwieuajb2D9s/P7RDU7h9gSf6C4nbIX1x5H/mpVCdZWDuqL0Y7tn9K
kvhh3TNXZf1TiryJkw3GDxHS88mh+pGEZsnC3hH5rLKj/JFVQtbWeu1QdhI5fFlh
PtUjIWeFHbgvMisd4qjouJfhuF2LRfpdn/u52MHTVntVGtGYNV3uUVpVR6YkFH0q
GfAqP5clv1qSF5gRANIPVQSpF0wcvTHvgWdv9bOy7a9BLvWFg46Ys4HKWQIDAQAB
o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNf+MZRDSTxfobte/gWA
BCwE86DSMB0GA1UdDgQWBBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAOBgNVHQ8BAf8E
BAMCAYYwDQYJKoZIhvcNAQELBQADggIBAC17+M739nb2AG3bpKObDDlW+fYMdEhX
tjQcOvHIUrITKryX3lmHyWDFFgFTeTYcoxq8ywFvpvXz4pHgeFWRZYQw7cSWwH8n
JfLE+EJlpYU2yUGto/S8NPXV54dAYNsvQQncQixsIYgxsmX7yIzBt1+v3sLmQlp5
CfZRCOxj+2fa9jb/jygdQC3AAS5uT86gYz0YcB5VXQ0+jYWsL7MDwgb8ORcmiugd
uZ0kgBXd40Qg9bJhfz0N+BKWPTbS4dFst4ey5dndLp4QxWXzTt+gbmOMBpiwB6xx
H3hw/LrRBEs7hrhVIlJ76cMx/f/5wERD0qS3uPXpCCtcKDBqHFruOI/NMNEVRFwi
VxVD8w1jWYXDUyNVErU0LzqGOkyDuRwEDN8svaKn8+WdyumDB21tTWEbYPbFWc9R
2epNj8moBVcfnxwsVP5TCXk6tEEOMkCVLNC3JBUWSfGJjg/2PDEdo2cPYCXYU4Hu
eE/SnoUbRh0M34BfaHHt8S/vcEZWSkctJUmRZbTju57FKMlIHcgE5FHN5ahDAiSc
GgncvFfPKXcEPFh5bhKdhT6FzbKysCoRw16rwhzfsm4X42jvzBEOKpUcFDpRuBJs
zTk30lhAdmROkG5UTemobyKgDVw50VcFKbMk3Q5Gzs9TZ+uRAWJA7rF6MSc+cSlP
qMN+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.crt
To 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.crt
Add 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-----
MIIEojCCAoqgAwIBAgIUPaLkQD5t3sJyXqyDZ9oakKCef4IwDQYJKoZIhvcNAQEL
BQAwQjEVMBMGA1UEAwwMTWFuYWdlbWVudENBMRwwGgYDVQQKDBNLZXlmYWN0b3Ig
Q29tbXVuaXR5MQswCQYDVQQGEwJTRTAeFw0yMzAzMTkxNzI3MTJaFw0yNDAzMTQx
NzI3MTFaMEQxCzAJBgNVBAYTAlNFMRwwGgYDVQQKDBNLZXlmYWN0b3IgQ29tbXVu
aXR5MRcwFQYDVQQDDA5lamJjYS1pbnRlcm5hbDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAIxh+0WaKmw+Yrim+/2c7Li/gWDJKdsd+mS170V6rnHSfRDd
qfcW1q9ADwRZyu3Pc3s+w6UmjSciwOtvovPOfC5D0dUog4bgQ/1cSWuVUC8gd/Xy
xb7DuKqbGtg8kB5BMD7O3oF89b2iGisfw4Ei9Njf1hrgl9DWuFfQ6+/d5luUXCRv
cKYeQl05ZRii8LwLc8vvb613HbQi4n47QbLHMDgQDqdiqvefhyDE8gdgJyOBM5nV
dsc2/6sxsKDNTMV86N1POWSXBrM9b4T/jFAik76dGjcCv/WTY/3VbPCuGypB5SaL
++
8
/eLCEmZDgBovZT8WJIGK5odrdFbnSvtCwhZ0CAwEAAaOBjTCBijAfBgNVHSME
GDAWgBTX/jGUQ0k8X6G7Xv4FgAQsBPOg0jAjBgNVHREEHDAaghhlamJjYS1pbnRl
cm5hbC5lamJjYS1rOHMwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFJtU
ZTtTpL9zsDKstua4doISNMo5MA4GA1UdDwEB/wQEAwIFoDANBgkqhkiG9w0BAQsF
AAOCAgEAkTxtIref9DVm4fcB2jzNdaiLPpWQbhREWgdg8oGaaams832JnoiCJjga
lBnp8wNb8M9AxgEIU15il0xdw9oOoHAhz04Z3DV6snS1wmPs1u+un9zN0ZdBEEbC
zchc/tUg4lVYLlKieTjUcg8Dy/wVBegwBYxDXfzbabhMe8GFCs0qXll2hIetjesq
XtILq3Y5L7qVL7CaEeD2SX+Eb9Zz89xl069Jh3wWc34rBTI9L1f+ysBX0FhUyqqg
mU8xUjLDaDXpkF+tQH1tIxtu3A1J1k1aRp8jDb2w6urxERy3+Huxl50wrb80HJRg
/IdccIckpoFzga76hxV5l/mKlyxerr7Uev9prnTGeGSNF58dkJrGkwenvaYQC/Pk
I5MdqmrielVy56/o8ldS+12a1BtejMRE7I/KkPFF7ZIcTdh214NQe+FksaU8Wui4
ozAb8ULYjodMbrvU798TnXht8ySF0PPdTJ7B7gA9oUGZsnYTKO/M6OP6NHte4ezm
t3qvQpzsYeUOILz0+YeBZfCZrn2lJzQSkzaoernYO2igAEv/EGqJQ43hDKBnKKtJ
WMAHqzfaJuSnJfRnRIg1iDvQ+8XsTyMIY0uGgBWJt0qPAUxpgLBsjN+X9uu6DKuu
CEQLNQ0oAbNYKjgqMU7yxf2YkhMP6nppS/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.key
Add 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-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMYftFmipsPmK4
pvv9nOy4v4FgySnbHfpkte9Feq5x0n0Q3an3FtavQA8EWcrtz3N7PsOlJo0nIsDr
b6LzznwuQ9HVKIOG4EP9XElrlVAvIHf18sW+w7iqmxrYPJAeQTA+zt6BfPW9ohor
H8OBIvTY39Ya4JfQ1rhX0Ovv3eZblFwkb3CmHkJdOWUYovC8C3PL72+tdx20IuJ+
O0GyxzA4EA6nYqr3n4cgxPIHYCcjgTOZ1XbHNv+rMbCgzUzFfOjdTzlklwazPW+E
/4xQIpO+nRo3Ar/1k2P91WzwrhsqQeUmi/vvP3iwhJmQ4AaL2U/FiSBiuaHa3RW5
0r7QsIWdAgMBAAECggEACG3wv+DuN7I2TNawDm5AE6biLqzdn8vox2faTn57n5eP
TXY1+MGNEhhjXnRC2G1KxqWB63aJZsZyNaDuNLwbHk8RuD42yaBJTNsgCH7+gdnu
Ah16DMalXc8y+TWHxN1Ot5LF7xoRCnpDnn/JhkVSVPx514LRcueVyaYgqLZXGPwU
lLsEzZjy87w+wWYdkaUL0FlZPjJSsUcpDgTo4IVyLHYgKijwKa6GGAC1LRaF7xnG
IX7SHhAr8Aec26jd5GNWecJaftSh22GP7o6eaf2IJMc1r7JQE21T+nG
//hLHZ9hI
nwHdKXXjStKpnqLfwZsEt/gOwCJ7MQk+UPo0t+b9MQKBgQDFCOOQ3iU3CPjoyK5b
eR0XRHdtHNwLFOFP7bMpkwQuS86TUxFau2VOE3yPOU3UI+eWNXU6tHD9J4ep+BWn
kqjdeehdBSmZePtGjsktmXf96rVZR3801Lfpar2tMfB8b4ngdIJcBCdsFNUY9VFh
U0vO9xDflag5w3GONiiwaJ5GUQKBgQC2ZOdJqebkJ7n9MHY8Yc67anX4m9sLGhX7
Sc4U8OLjGAAxXJrutoPYUPeUFGWwMfQvpXbydQRtnG4Jw42qnSino69xhwUqvhPS
ZqMTU4NEq5DQBIrT9LV2Ih0BkvE9sdfQsvtZzXWDl7yMm1R2YlCwozlZTBn9GCf3
EOBxs/VbjQKBgBr4k4YCEqAM912OEufslUHZGmvyNmDB8/Gn/Q1k1X6s29Mo3MhJ
vJ1KZ5OHaZLvc0UJfkmR56GPpq9qiTRODBV9GYSaL06V0/edlgZK6rT0Suy0r8IA
mEg4V0x8+IlgD0SNTkbgPrE5zM3EzuX+q/LhuQqSBtwZV9L6sOks+PVxAoGADSiK
Zw4S0jLrgBCW9xQ3Td4IVL8ptktTeqWAcJJQTAHXQbhklQQlzt1Ify5Zh7SS4T0W
r7cxcpbueVXaSoy7+hwc9BvBi6va0jsFWMeVmMan09oACfqFfNhJL2via4kBANVo
vLnN2IiB2cL6/O9q0tNzt7V9ynyLpY9aIdnRwaECgYBe67DpIIF+6o7+epHogfmN
SLu/UdGhsBtJqbg9WJv7mXzpHWk+Vmx2HwYn6H9a8YW35C6E2GygVriuB72Ov5GV
YPzw/mJ2YNLz1of0iBaH0Skru2kHP5fVNd4bpCz7Wt7WdB6ZEUfZerUEcprY30wr
PkZVKHoa6btaotnw2IwNsQ==
-----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.yml
Add the following to the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# Use AJP with appserver
nginx.ingress.kubernetes.io/backend-protocol: AJP
nginx.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-node1
namespace: ejbca-k8s
spec:
ingressClassName:
public
rules:
- host: ejbca-node1
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ejbca-service
port:
number:
8009
tls:
- hosts:
- ejbca-node1.ejbca-k8s
secretName: tls-ejbca-node1
Save and close the file:
:wq
Remove the current EJBCA Ingress configuration:
$ kubectl delete -f ejbca-ingress.yml
Apply 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.yml
Add the following to the file:
---
apiVersion: v1
kind: Service
metadata:
name: ejbca-internal
namespace: ejbca-k8s
labels:
app: ejbca-httpd
spec:
type: ClusterIP
ports:
- name: apache
port:
443
targetPort:
443
- name: open
port:
80
targetPort:
80
selector:
app: ejbca-httpd
---
apiVersion: v1
data:
httpd.conf: |+
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule headers_module modules/mod_headers.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule filter_module modules/mod_filter.so
LoadModule substitute_module modules/mod_substitute.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
MaxKeepAliveRequests
1000
KeepAlive On
KeepAliveTimeout
180
# Don't think we need
this
# Include conf/extra/httpd-ssl.conf
<IfModule unixd_module>
User daemon
Group daemon
</IfModule>
ErrorLog /proc/self/fd/
2
LogLevel info
<IfModule log_config_module>
LogFormat
"%h %A:%p %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
combined
LogFormat
"%h %A:%p %l %u %t \"%r\" %>s %b"
common
CustomLog /proc/self/fd/
1
common
</IfModule>
ServerRoot
"/usr/local/apache2"
Listen
443
Listen
80
<Directory />
AllowOverride none
Require all denied
</Directory>
<VirtualHost *:
443
>
DocumentRoot /var/www/html/
# Disallow any HTTP method that is not HEAD, GET or POST
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !^(HEAD|GET|POST|PUT)$ [NC]
RewriteRule .* - [F,L]
SSLEngine on
SSLCipherSuite HIGH:!ADH:!aDSS:!aDH
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 +TLSv1.
2
-TLSv1.
3
# SSLProtocol -all +TLSv1.
2
SSLOptions +ExportCertData +StdEnvVars
SSLCertificateFile /etc/httpd/ssl/ejbca-internal.crt
SSLCertificateKeyFile /etc/httpd/ssl/ejbca-internal.key
SSLVerifyClient optional
SSLVerifyDepth
3
SSLCACertificateFile /etc/httpd/ssl/ca.crt
<Location /ejbca/ejbcaws>
SSLVerifyClient require
</Location>
<Location /ejbca/adminweb>
SSLVerifyClient require
</Location>
# Allow encoded slashes
for
OCSP GET
AllowEncodedSlashes On
ProxyPass /ejbca/ ajp:
//ejbca-service:8009/ejbca/ keepalive=On ping=500ms retry=1 timeout=300
#Add ProxyPass
for
EST and .well-known URLs
ProxyPass /.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 POST
RewriteEngine On
RewriteCond %{REQUEST_METHOD} !^(HEAD|GET|POST)$ [NC]
RewriteRule .* - [F,L]
# Redirect legacy EJBCA enrollment to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^/?ejbca/enrol/(.*) https:
//%{SERVER_NAME}/ejbca/enrol/$1 [R,L]
# Allow encoded slashes
for
OCSP GET
AllowEncodedSlashes On
ProxyPass /ejbca/ ajp:
//ejbca-service:8009/ejbca/ keepalive=On ping=500ms retry=1 timeout=300 nocanon
ProxyPass /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: ConfigMap
metadata:
namespace: ejbca-k8s
name: config-httpd-configmap
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ejbca-httpd
namespace: ejbca-k8s
labels:
app: ejbca-httpd
spec:
replicas:
1
selector:
matchLabels:
app: ejbca-httpd
template:
metadata:
labels:
app: ejbca-httpd
spec:
containers:
- name: httpd
image: library/httpd:latest
ports:
- containerPort:
443
name: httpd-http
- containerPort:
80
name: http
volumeMounts:
- name: config-httpd-volume
mountPath: /usr/local/apache2/conf/
- name: certificates-volume
mountPath: /etc/httpd/ssl
volumes:
- name: config-httpd-volume
configMap:
name: config-httpd-configmap
- name: certificates-volume
configMap:
name: httpd-certs-configmap
Save and close the file:
:wq
Apply 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.