Deploy EJBCA as RA with automation
ENTERPRISE
This outlines how to deploy a Registration Authority (RA) using the EJBCA Enterprise configuration export/import tool EJBCA ConfigDump.
Prerequisites
Before you begin, you should be familiar with how to deploy EJBCA CA in Kubernetes.
Enroll server TLS certificates.
Configure Ingress and internal services with TLS.
Prepare database and other credentials.
EJBCA installation with ConfigDump import does not support replication during the installation stage. Instead, use helm install
with ConfigDump and replicaCount: 1
. After installation, perform a helm upgrade
to the desired replicaCount
.
Step 1 - Deploy EJBCA RA
Prepare configuration dump for the RA installation
The following attributes are created using the EJBCA ConfigDump configuration file in the examples provided:
Certification Authorities (CAs): Import the existing CAs as external CAs in the RA instance. You need to configure the CA certificate and subjectDN for this example. Note that these are truncated in the following ConfigMap example.
Roles and Role Members: Roles used for certificate authentication with CN (common name) SuperAdmin and AutomationAdmin.
Protocols: Configuration that enables REST, ACME and other protocols.
Prepare the configuration dump file as a Kubernetes ConfigMap.
Example filename: ejbca-ra-init-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ejbca-ra-init-configmap
data:
configdump.json: |
{
"certification-authorities": {
"ManagementCA": {
"Object Type": "Certification Authority",
"Version": 2,
"Name": "ManagementCA",
"Type of CA": "X.509",
"Description": "CA created by certificate import.",
"Serial Number Octet Size": 20,
"Pre-produce OCSP Responses": false,
"Microsoft CA Compatible Mode Used": false,
"Store responses on-demand": false,
"Pre-produce OCSP Responses Upon certificate issuance/revocation": false,
"Certificate Profile": "ROOTCA",
"Default Certificate Profile": "Not used",
"Use Append-Only Table": false,
"Certificate Chain": [
"MIIDLTC....truncated.....GHKxovrA=="
],
"Enforce Unique Public Keys": true,
"Enforce key renewal": false,
"Enforce Unique DN": true,
"User Storage": true,
"Certificate Storage": true,
"Accept Revocations for Non-Existing Entries": false,
"Subject DN": "CN=ManagementCA,OU=SomeOrg",
"Signed By": "Self Signed",
"Validity": "0d",
"Subject Alternative Name": null,
"Use UTF-8 in Policy Notice Text": true,
"LDAP DN Order": true,
"Authority Key Id Used": true,
"CRL Number Used": true,
"Partitioned CRL Used": false,
"CRL Expiration Period": "1d",
"CRL Issue Interval": "0m",
"CRL Overlap Time": "10m",
"Delta CRL Period": "0m",
"Generate CRL Upon Revocation": false,
"Allow Changing Revocation Reason": false,
"Finish User": true,
"CA Healthcheck Enabled": true,
"Request Processor": null
},
"RootCA": {
"Object Type": "Certification Authority",
"Version": 2,
"Name": "RootCA",
"Type of CA": "X.509",
"Description": "CA created by certificate import.",
"Serial Number Octet Size": 20,
"Pre-produce OCSP Responses": false,
"Microsoft CA Compatible Mode Used": false,
"Store responses on-demand": false,
"Pre-produce OCSP Responses Upon certificate issuance/revocation": false,
"Certificate Profile": "ROOTCA",
"Default Certificate Profile": "Not used",
"Use Append-Only Table": false,
"Certificate Chain": [
"MIIDLTC....truncated.....GHKxovrA=="
],
"Enforce Unique Public Keys": true,
"Enforce key renewal": false,
"Enforce Unique DN": true,
"User Storage": true,
"Certificate Storage": true,
"Accept Revocations for Non-Existing Entries": false,
"Subject DN": "CN=RootCA,C=SE",
"Signed By": "Self Signed",
"Validity": "0d",
"Subject Alternative Name": null,
"Use UTF-8 in Policy Notice Text": true,
"LDAP DN Order": true,
"Authority Key Id Used": true,
"CRL Number Used": true,
"Partitioned CRL Used": false,
"CRL Expiration Period": "1d",
"CRL Issue Interval": "0m",
"CRL Overlap Time": "10m",
"Delta CRL Period": "0m",
"Generate CRL Upon Revocation": false,
"Allow Changing Revocation Reason": false,
"Finish User": true,
"CA Healthcheck Enabled": true,
"Request Processor": null
}
},
"available-protocols": {
"available-protocol-configuration": {
"Object Type": "Available Protocols",
"Version": 1,
"Name": "available-protocol-configuration",
"ACME": true,
"Certstore": true,
"CMP": true,
"CRLstore": true,
"EST": true,
"MSAE": true,
"OCSP": false,
"SCEP": true,
"RA Web": true,
"REST CA Management": false,
"REST Certificate Management": false,
"REST Coap Management": false,
"REST Crypto Token Management": false,
"REST End Entity Management": true,
"REST End Entity Management V2": true,
"REST Configdump": true,
"REST Certificate Management V2": true,
"REST SSH V1": true,
"REST System V1": false,
"Webdist": true,
"Web Service": true,
"ITS Certificate Management": false,
"Custom header name for REST calls from browser": "X-Keyfactor-Requested-With"
}
},
"peer-connectors": {
"global-peer-configuration": {
"Object Type": "Peer Global Configuration",
"Version": 1,
"Allow incoming connections": true,
"Allow outgoing connections": false
}
},
"admin-roles": {
"Super Administrator Role": {
"Object Type": "Role",
"Version": 1,
"Name": "Super Administrator Role",
"Role Members": [
{
"Token Type": "CertificateAuthenticationToken",
"Issuer": "ManagementCA",
"Match With": "WITH_COMMONNAME",
"Match Value": "AutomationAdmin"
},
{
"Token Type": "CertificateAuthenticationToken",
"Issuer": "ManagementCA",
"Match With": "WITH_COMMONNAME",
"Match Value": "SuperAdmin"
},
{
"Token Type": "CliAuthenticationToken",
"Issuer": null,
"Match With": "USERNAME",
"Match Value": "ejbca"
}
],
"Namespace": "",
"RA Style Id": 0,
"Access Rules": {
"/": "Allow"
}
},
"raIncomingCaPeer": {
"Object Type": "Role",
"Version": 1,
"Name": "raIncomingCaPeer",
"Role Members": [
{
"Token Type": "CertificateAuthenticationToken",
"Issuer": "ManagementCA",
"Match With": "WITH_COMMONNAME",
"Match Value": "peer-key"
}
],
"Namespace": "",
"RA Style Id": 0,
"Access Rules": {
"/ca/RootCA/": "Allow",
"/ca/ManagementCA/": "Allow",
"/peerincoming/": "Allow",
"/ra_slave/manage/": "Allow"
}
}
}
}
Create the ConfigMap:
kubectl apply -f ejbca-ra-init-configmap.yaml
Deployment customization with values.yaml
image:
variant: ra
#imagePullSecrets:
# - name: keyfactor-registry
ejbca:
configdumpImport:
enabled: true
initialize: true
configMapName: ejbca-ra-init-configmap
configMapKey: configdump.json
env:
DATABASE_JDBC_URL: "jdbc:mariadb://ra-database-service:3306/ejbca?characterEncoding=utf8"
DATABASE_USER: ejbca
envRaw:
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: mariadb-passwords
key: mariadb-password
nginx:
enabled: true
host: "ejbca-ra-internal-host"
mountInternalNginxCert: true
secretInternalNginxCert: "internal-nginx-credential-secret-ra1"
ingress:
enabled: true
className: "nginx"
annotations:
nginx.ingress.kubernetes.io/auth-tls-verify-client: "optional"
nginx.ingress.kubernetes.io/auth-tls-secret: "default/ejbca-ingress-trust-secret"
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
hosts:
- host: "ejbcara.example.com"
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- "ejbcara.example.com"
secretName: ingress-credential-secret-ra1
Step 2 - Configure Peer Connection
To configure the Peer setup in the CA instance with ConfigDump, you need to make a ConfigDump REST POST call to the CA instance with a SuperAdmin token with initialize set to true.
You can use the following script where SuperAdmin.p12
or ADMINP12
is the SuperAdmin token enrolled after the CA installation:
#!/bin/bash
# usage
# ./configdump-rest.sh ejbcaca1.example.com add_ra_in_ca_configdump SuperAdmin.p12 foo123
SERVER_HOST="$1"
CONFIGDUMP_JSON="$2"
ADMINP12="$3"
ADMINP12PASS="$4"
curl -k -X POST \
"https://$SERVER_HOST/ejbca/ejbca-rest-api/v1/configdump?ignoreerrors=false&initialize=true&continue=false&overwrite=yes&resolve=abort" \
--cert-type P12 --cert "$ADMINP12:$ADMINP12PASS" -H "Content-Type: application/json" \
-d "@$CONFIGDUMP_JSON" -v
Ensure peer-connectors.{peer-name}.URL
is configured according to the service name attached to the NGINX sidecar of the peer. Typically, this is {peer-chart-release-name}.{peer-namespace}
.
Additionally, the common name(CN) of the server TLS certificate must match the Match Value
in admin-roles.Role Members
, such as ejbcara.example.com
in the following example.
{
"peer-connectors": {
"ejbca-ra1": {
"Object Type": "Peer Connector",
"Version": 1,
"Name": "ejbca-ra1",
"Peer Enabled": true,
"URL": "https://ejbcara-deployment-nginx/ejbca/peer/v1",
"Long Hanging Connections Enabled": true,
"Min Long Hanging Connections": 10,
"Max Long Hanging Connections": 20,
"Authentication Key Binding": "peer-key"
}
},
"internal-key-bindings": {
"peer-key": {
"Object Type": "Internal Key Binding",
"Version": 1,
"Name": "peer-key",
"Type": "AuthenticationKeyBinding",
"Status": "ACTIVE",
"Crypto Token": "PeerToken",
"Key Pair Alias": "peerkey",
"Next Key Pair Alias": null,
"Signature Algorithm": "SHA256WithRSA",
"Enrollment info: Key Binding SubjectDN": "CN=peer-key",
"Enrollment info: Signing CA SubjectDN": "CN=ManagementCA,OU=SomeOrg",
"Enrollment info: Certificate profile": "ENDUSER",
"Enrollment info: End entity profile": "EMPTY",
"Enrollment info: Key spec or curve": "RSA2048",
"Trusted certificates": {},
"Signed on behalf of CAs": {},
"Properties": {
"Protocol and Cipher Suite": "TLSv1.2;TLS_RSA_WITH_AES_256_CBC_SHA256"
}
}
},
"admin-roles": {
"RA-Peer-Connection": {
"Object Type": "Role",
"Version": 1,
"Name": "RA-Peer-Connection",
"Role Members": [
{
"Token Type": "CertificateAuthenticationToken",
"Issuer": "ManagementCA",
"Match With": "WITH_COMMONNAME",
"Match Value": "ejbcara.example.com"
}
],
"Namespace": "",
"RA Style Id": 0,
"Access Rules": {
"/administrator/": "Allow",
"/ca/": "Allow",
"/ca_functionality/create_certificate/": "Allow",
"/ca_functionality/use_approval_request_id/": "Allow",
"/ca_functionality/use_username/": "Allow",
"/ca_functionality/view_ca/": "Allow",
"/ca_functionality/view_certificate/": "Allow",
"/endentityprofilesrules/": "Allow",
"/endentityprofilesrules/EMPTY/": "Deny",
"/protocol/acme/": "Allow",
"/protocol/cmp/": "Allow",
"/protocol/est/": "Allow",
"/protocol/rest/": "Allow",
"/protocol/scep/": "Allow",
"/protocol/web_services/": "Allow",
"/ra_functionality/approve_end_entity/": "Allow",
"/ra_functionality/create_end_entity/": "Allow",
"/ra_functionality/delete_end_entity/": "Allow",
"/ra_functionality/edit_end_entity/": "Allow",
"/ra_functionality/revoke_end_entity/": "Allow",
"/ra_functionality/view_approvals/": "Allow",
"/ra_functionality/view_end_entity/": "Allow",
"/ra_functionality/view_end_entity_history/": "Allow",
"/ra_functionality/view_end_entity_profiles/": "Allow",
"/ra_master/invoke_api/": "Allow"
}
}
}
}
Step 3 - Verify the setup
To verify the EJBCA RA setup, refer to instructions in Deploy RA and VA in Kubernetes.