Setting Up a Certificate Authority

You can set up your own Certificate Authority (CA) to sign node certificates. Using a CA makes it easier to manage trust within your cluster than using self-signed certificates. Each node only needs to trust the CA, rather that trusting all of the other nodes' certificates individually. When nodes are added to the cluster, as long as their certificates are signed by a trusted CA, the new nodes are trusted automatically. In contrast, if you use self-signed certificates, you would have to manually configure each node to trust the new node and restart Elasticsearch.

This topic shows how you can use OpenSSL to create a self-signed CA certificate and sign CSRs. While it demonstrates how you can set up a CA, it does not necessarily address your organization’s particular security requirements. Before moving to production, you should consult your organization’s security experts to discuss the security requirements for your use case.

Important

Because a Certificate Authority is a central point of trust, the private keys to the CA must be protected from compromise.

To set up a CA:

  1. Create the directory structure where the CA configuration and certificates will be stored. You need to create a ca directory and three subdirectories: private, certs, and conf.

    mkdir -p ca/private ca/certs ca/conf
  2. Populate two required files, serial and index.txt.

    cd ca
    echo '01' > serial
    touch index.txt
  3. Create a CA configuration template and store it in conf/caconfig.cnf. You use the configuration template to set options for the CA that cannot be passed in from the command line. The following template defines a basic CA configuration you can use as a starting point.

    #..................................
    [ ca ]
    default_ca = CA_default
    [ CA_default ]
    copy_extensions = copy 
    dir = /PATH/TO/YOUR/DIR/ca 
    serial = $dir/serial
    database = $dir/index.txt
    new_certs_dir = $dir/certs
    certificate = $dir/certs/cacert.pem
    private_key = $dir/private/cakey.pem
    default_days = 712 
    default_md = sha256
    preserve = no
    email_in_dn = no
    x509_extensions = v3_ca
    name_opt = ca_default
    cert_opt = ca_default
    policy = policy_anything
    [ policy_anything ]
    countryName             = optional
    stateOrProvinceName     = optional
    localityName            = optional
    organizationName        = optional
    organizationalUnitName  = optional
    commonName              = supplied
    emailAddress            = optional
    [ req ]
    default_bits = 2048 # Size of keys
    default_keyfile = key.pem # name of generated keys
    default_md = sha256 # message digest algorithm
    string_mask = nombstr # permitted characters
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    [ req_distinguished_name ]
    # Variable name Prompt string
    #------------------------- ----------------------------------
    0.organizationName = Organization Name (company)
    organizationalUnitName = Organizational Unit Name (department, division)
    emailAddress = Email Address
    emailAddress_max = 40
    localityName = Locality Name (city, district)
    stateOrProvinceName = State or Province Name (full name)
    countryName = Country Name (2 letter code)
    countryName_min = 2
    countryName_max = 2
    commonName = Common Name (hostname, IP, or your name)
    commonName_max = 64
    # Default values for the above, for consistency and less typing.
    # Variable name Value
    #------------------------ ------------------------------
    0.organizationName_default = Elasticsearch Test Org 
    localityName_default = Amsterdam
    stateOrProvinceName_default = Amsterdam
    countryName_default = NL
    emailAddress_default = cacerttest@YOUR.COMPANY.TLD
    [ v3_ca ]
    basicConstraints = CA:TRUE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer:always
    [ v3_req ]
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash

    Copy extensions: Copies all X509 V3 extensions from a Certificate Signing Request into the signed certificate. With the value set to copy, you need to ensure the extensions and their values are valid for the certificate being requested prior to signing the certificate.

    CA directory: Add the full path to this newly created CA.

    Certificate validity period: The default number of days that a certificate signed by this CA is valid for. Note that certificates signed by a CA must expire before the CA certificate expires.

    Certificate defaults: The OrganizationName, localityName, stateOrProvinceName, countryName, and emailAddress fields specify the default Distinguished Name information.

  4. Generate a self-signed CA certificate to establish your CA as an authority. For example, the following command generates a key and certificate using the caconfig.cnf template. You specify where you want to store the CA’s private key and certificate with the -keyout and -out options, and specify how long the certificate is valid with the -days option.

    openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out certs/cacert.pem -days 1460  -config conf/caconfig.cnf
    Note

    When the CA certificate expires, trust in the CA is revoked and you need to generate a new CA certificate and re-sign your node certificates.

    When you run openssl to generate a CA certificate, you are prompted to enter a PEM passphrase to encrypt the CA’s private key and can override the default Distinguished Name information.

    Warning

    You cannot recover the CA without the PEM passphrase.

    The following example shows what the interaction looks like:

    openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out certs/cacert.pem -days 1460 -config conf/caconfig.cnf
    Generating a 2048 bit RSA private key
    .....................++++++
    .......++++++
    writing new private key to 'private/cakey.pem'
    Enter PEM pass phrase:
    Verifying - Enter PEM pass phrase:
    #-----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    #-----
    Organization Name (company) [Elasticsearch Test Org]:
    Organizational Unit Name (department, division) []:.
    Email Address [cacerttest@YOUR.COMPANY.TLD]:.
    Locality Name (city, district) [Amsterdam]:.
    State or Province Name (full name) [Amsterdam]:.
    Country Name (2 letter code) [NL]:.
    Common Name (hostname, IP, or your name) []:Elasticsearch Test CA

Once you’ve generated a certificate for your CA, you can use it to enable trust between your nodes. You sign each node’s certificate using your CA, and install the CA certificate and signed node certificate in each node’s keystore or truststore. For more information, see Signing CSRs and Installing Node Certificates.

Signing CSRs

You sign a node’s certificate to vouch for that node’s identity. If a node trusts your CA certificate, it automatically trusts any certificates you sign.

To sign a node’s certificate:

  1. Generate a certificate signing request (CSR) from the node.
  2. Use your CA to sign the CSR using openssl. For example, the following command signs the node01.csr and saves the signed certificate in node01-signed.crt. You must specify your CA’s configuration file with the -config option.

    openssl ca -in node01.csr -notext -out node01-signed.crt -config conf/caconfig.cnf -extensions v3_req

    The signed certificate contains the node’s original unsigned certificate, your CA certificate, and a signature.

Once you’ve signed the CSR, you need to install the signed certificate in the node’s keystore.