Navigation
This version of the documentation is archived and no longer supported. To learn how to upgrade your version of MongoDB Kubernetes Operator, refer to the upgrade documentation.

Generate X.509 Client Certificates

The MongoDB Enterprise Kubernetes Operator can deploy MongoDB instances with X.509 authentication enabled. If X.509 authentication has been enabled for the deployment, you must generate and use an X.509 certificate to connect to the deployment. This new client certificate must be signed by the Kubernetes CA to be accepted by the MongoDB deployment.

Use the procedure outlined in this document to:

  • Generate an X.509 certificate.
  • Get that certificate signed by the Kubernetes CA.
  • Use the certificate to connect to your X.509-enabled MongoDB deployment.

Prerequisites

Note

A full description of Transport Layer Security (TLS), Public Key Infrastructure (PKI) certificates, and Certificate Authorities is beyond the scope of this document. This page assumes prior knowledge of TLS and X.509 authentication.

  • To complete this tutorial, you must have the MongoDB Enterprise Kubernetes Operator installed. For instructions on installing the Kubernetes Operator, see Install the MongoDB Enterprise Kubernetes Operator.
  • This tutorial assumes you have a MongoDB deployment which requires X.509 authentication. For instructions on deploying MongoDB resources, see Deploy a MongoDB Database Resource.
  • This tutorial uses CFSSL to generate X.509 certificates. CFSSL is a certificate generation tool built by Cloudflare. For instructions on installing CFSSL, refer to the CFSSL GitHub page.

Procedure

Note

The user configuration files used in this tutorial are strictly examples. You may need to adjust the values in the examples to suit your deployment’s needs. For more information on formatting user ConfigMaps, see Manage Database Users.

Generate a Private Key and Certificate Signing Request

1

Create a new directory to complete this tutorial.

Run the following command to create a new directory for the configuration files used in this tutorial:

mkdir client-x509-certs-tutorial
2

Enter your newly created directory.

cd client-x509-certs-tutorial
3

Copy and save the following example JSON.

In the client-x509-certs-tutorial directory, save the following JSON as x509_user.json:

{
  "names": [
    {"O": "organization"},
    {"OU": "organizationalunit"}
  ],
  "CN": "my-x509-authenticated-user",
  "key": {
    "algo": "rsa",
    "size": 4096
  }
}
4

Generate a key file.

Run the following command to pass the JSON from the previous step to CFSSL and generate a key file:

cfssl genkey x509_user.json > x509_user_key.json

You should see output similar to the following:

2019/06/04 18:12:38 [INFO] generate received request
2019/06/04 18:12:38 [INFO] received CSR
2019/06/04 18:12:38 [INFO] generating key: rsa-4096
2019/06/04 18:12:40 [INFO] encoded CSR

You now have a file called x509_user_key.json containing a new private key.

5

Generate the Certificate Signing Request.

Run the following command to use your x509_user_key.json key file to generate a certificate signing request (CSR):

cfssljson -f x509_user_key.json -bare x509_user

This command generates two files:

  • x509_user-key.pem, the private key for the user
  • x509_user.csr, the CSR that represents the user

Submit the New CSR to the Kubernetes CA

Kubernetes’ own certificate authority provides the trusted CA for the Kubernetes cluster. You need the .csr and .pem files generated in the previous section to request a new certificate from Kubernetes.

1

Create a CSR in Kubernetes.

Run the following command to create a CSR in Kubernetes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: x509-user.some-namespace
spec:
  groups:
  - system:authenticated
  request: $(cat x509_user.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - client auth
EOF
2

View your CSRs.

Run the following command to view a list of CSRs:

kubectl get csr

You should see an output similar to the following:

NAME                         AGE    REQUESTOR                                 CONDITION
x509-user.some-namespace     1m     system:serviceaccount:some-namespace      Pending
3

Approve the CSR.

The CSR remains in Pending condition until Kubernetes approves it. Run the following command to approve the certificate:

kubectl certificate approve x509-user.some-namespace

You should see an output similar to the following:

certificatesigningrequest.certificates.k8s.io/x509-user.some-namespace approved
4

Verify that your certificate has been approved

Run the following command to verify that the Kubernetes CA has approved your certificate:

kubectl get csr

You should see an output similar to the following:

NAME                       AGE   REQUESTOR                              CONDITION
x509-user.some-namespace   45m   system:serviceaccount:some-namespace   Approved,Issued

Obtain the Newly Issued Certificate from the Kubernetes CA

You can use the new certificate. The status.certificate attribute of the CSR generated in the previous section contains the certificate.

1

Generate the X.509 certificate from the CSR.

Run the following command to generate the certificate from the CSR object to a file called client.crt:

kubectl get csr x509-user.some-namespace -o jsonpath='{.status.certificate}' | base64 --decode > client.crt

A mongod client can use the client.crt certificate to connect to the X.509-enabled MongoDB deployment.

2

Concatenate the user private key and Kubernetes certificate.

You need both the x509_user-key.pem and client.crt files to connect to the deployment. Run the following command to concatenate the two files into the a new .pem file:

cat x509_user-key.pem client.crt > x509-full.pem

Connect to the X.509-Enabled MongoDB Deployment

With the client certificate created, you can create a MongoDB user and connect to the X.509-enabled deployment.

1

Configure kubectl to default to your namespace.

If you have not already, run the following command to execute all kubectl commands in the namespace you created:

kubectl config set-context $(kubectl config current-context) --namespace=<namespace>
2

Copy and save the following example ConfigMap.

Save the following ConfigMap as x509-mongodb-user.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
---
apiVersion: mongodb.com/v1
kind: MongoDBUser
metadata:
  name: new-x509-user
spec:
  username: "CN=my-x509-authenticated-user, OU=organizationalunit, O=organization"
  db: "$external"
  mongodbResourceRef:
    name: '<name of the MongoDB resource>'
  roles:
    - db: "admin"
      name: "clusterAdmin"

This ConfigMap .yaml file describes a MongoDBUser custom object. You can use these custom objects to create MongoDB users.

In this example, the ConfigMap describes the user as an X.509 user that the client can use to connect to MongoDB with the corresponding X.509 certificate.

3

Create the X.509 MongoDB user.

Run the following command to apply the ConfigMap and create the X.509 MongoDB user:

kubectl apply -f x509-mongodb-user.yaml

You should see an output similar to the following:

mongodbuser.mongodb.com/new-x509-user created
4

Verify your newly created user

Run the following command to check the state of the new-x509-user:

kubectl get mdbu/new-x509-user -o yaml

You should see an output similar to the following:

NAME            CREATED AT
new-x509-user   8m
5

Use your X.509 user to connect to the MongoDB deployment

Once you have created your X.509 user, try to connect to the deployment using the mongo Shell:

mongo --host {host} --tls --tlsCAFile /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --tlsCertificateKeyFile x509-full.pem --authenticationMechanism MONGODB-X509 --authenticationDatabase '$external'
mongo --host {host} --ssl --sslCAFile /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --sslPEMKeyFile x509-full.pem --authenticationMechanism MONGODB-X509 --authenticationDatabase '$external'

Note

On Kubernetes Pods, the CA file is saved in /var/run/secrets/kubernetes.io/serviceaccount/ca.crt, which is the file location used for the --sslCAFile connection option.