Elasticsearch PKI Authentication in OpenSearch

By Opster Expert Team - Gustavo

Updated: Jun 28, 2023

| 4 min read

This article is part of a series:

Quick links:

Introduction and background

In this article we will learn how to authenticate to OpenSearch using PKI (Public Key Infrastructure) via Client Certificates.

What is PKI? 

PKI (Private Key Infrastructure) is a set of actors and procedures to manage digital certificates. The main goal is to protect the communications and business transactions in the network. The main concepts are “private key”, “public key”, and “certificate authority (CA)”.

  • Public key: Public portion of an entity identity. Is known by everyone and can be used by a sender to encrypt a message and make it accessible for the private key owner.
  • Private key: Private portion of an entity identity. Is known only by the owner and used to decrypt a message. Can be also used to encrypt messages which can be decrypted with the public key to prove identity (e.g digital sign).
  • Certificate Authority: Entities that ensure the validity of the public keys and other attributes.

Why use PKI?

The main benefit of PKI is that it is very hard for someone who intercepts a message to access its content, because the private key needed to decrypt it is not going through the wire, making this method very secure.

Client certificates can be used with, or without basic authentication (user and password).

  • As an alternative: Basic auth OR certificate
  • Added up: Basic auth AND certificate

How to set up PKI authentication in OpenSearch

Steps to set up PKI authentication in OpenSearch

  1. Basic secured installation via OpenSearch tar

  2. Config.yml file

  3. Enable client certificates

  4. Generate certificates

  5. Configure OpenSearch role-mappings

  6. Test query

The first step is to configure the certificates. Refer to this article to generate and configure your own certificates. For this guide we will focus on the authentication method so we assume you already created the certificates for admin and nodes.

Step 1: Basic secured installation via OpenSearch tar

Download Opensearch tar file from this link, and extract.

Step 2: Config.yml file 

Cd to config/opensearch-security/config.yml and configure the following:

 clientcert_auth_domain:
       description: "Authenticate via SSL client certificates"
       http_enabled: true
       transport_enabled: true
       order: 0
       http_authenticator:
         type: clientcert
         config:
           username_attribute: cn #optional, if omitted DN becomes username
         challenge: false
       authentication_backend:
         type: noop

Take a note on username_attribue: cn , so we are going to use the CN section as the username for role mappings.

If you make any changes to the config.yml, you have to run the securityadmin.sh script.

Step 3: Enable client certificates

Add the following to opensearch.yml:

plugins.security.ssl.http.clientauth_mode: OPTIONAL

Step 4: Generate certificates

Run the following to create a new root CA, and certificates for admin, node and client: 

# Root CA
openssl genrsa -out root-ca-key.pem 2048
openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=localhost" -out root-ca.pem -days 730
# Admin cert
openssl genrsa -out admin-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
openssl req -new -key admin-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=A" -out admin.csr
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 730
# Node cert 1
openssl genrsa -out node1-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node1-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node1-key.pem
openssl req -new -key node1-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=localhost" -out node1.csr
echo 'subjectAltName=DNS:localhost' > node1.ext
openssl x509 -req -in node1.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node1.pem -days 730 -extfile node1.ext
 
# Client Cert
openssl genrsa -out gustavo-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in gustavo-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out gustavo-key.pem
openssl req -new -key gustavo-key.pem -subj "/C=CL/ST=RM/L=SANTIAGO/O=ME/OU=ME/CN=gustavo" -out gustavo.csr
openssl x509 -req -in gustavo.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out gustavo.pem -days 730
 
# Cleanup
rm *-temp.pem
rm *.csr
Rm *.ext

If you decide to use different certificate file names than the defaults, make sure to update the paths for root-ca, and node certificate in opensearch.yml .

plugins.security.ssl.transport.pemcert_filepath: node1.pem
plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node1.pem
plugins.security.ssl.http.pemkey_filepath: node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem

Also make the admin certificate DN to match with the DN defined when creating the certificates:

plugins.security.authcz.admin_dn:
 - CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA

*Remember to restart the node after making changes in the opensearch.yml file.

Step 5: Configure OpenSearch role-mappings

Now we need to add some permissions to the client certificate we created: 

"/C=CL/ST=RM/L=SANTIAGO/O=ME/OU=ME/CN=gustavo"

Remember: The cn portion will be the username, so in this case, “gustavo”.

We can use the admin user to add our user to the all_access role mapping:

curl --location --request PUT 'https://admin:admin@localhost:9200/_plugins/_security/api/rolesmapping/all_access' \
--header 'Content-Type: application/json' \
--data-raw '{
 "backend_roles" : ["admin"],
 "users" : ["gustavo"]
}'

We use the API for non-system role mappings, and the yml files for system role mappings.

Make sure to include the “admin” backend role to keep the admin user active with “all_access”.

Step 6: Test query

We will run an index creation query to test our certificate.

curl -k --location --request POST 'https://localhost:9200/new_index/_doc?pretty' \
--header 'Content-Type: application/json' \
--data-raw '{
"name":"gustavo"
}' \
--cert gustavo.pem \
--key gustavo-key.pem

-k is to disable CA verification, because we are using self signed certificates.

We should see the following:

{
  "_index" : "new_index",
  "_id" : "1Y3nOIMBo9OQgzxSkACd",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

Conclusion

Using client certificates you can authenticate and authorize requests in a few steps, and smoothly transition from existent permissions to OpenSearch via Role Mappings.