Setup Elasticsearch with Xpack & SSL on Ubuntu 18.04

Written by: Bagus Facsi Aginsa
Published at: 18 Mar 2021


Elasticsearch is a RESTful distributed search engine built on top of Java. It can search and index document files in diverse formats. In short this is the database. Elasticsearch can be used not only for searh engine, but also a powerful monitoring tools if installed together with logstash, kibana, and beats.

Whatever your usecases, installing Elasticsearch with xpack and SSL enabled is a best practice and a must have feature for production environment. It provides you a basic security for the Elasticsearch.

Prerequisite

  1. Ubuntu 18.04 or later
  2. Valid SSL Certificate & Keys

Sudo Privileges

Before start we make sure that we will have no permission issue on the installation and configuration.

sudo su

Install Elasticsearch

Install dependencies

apt install apt-transport-https

Import elasticsearch gpg key

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -

Update ubuntu repo

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
apt update

Install the latest version of elasticsearch

apt install elasticsearch

Or, If you want a specific version of elasticsearch, check the elasticsearch version available first

apt list elasticsearch -a

And then you can install wich version do you want, for example if you want version 7.14.0, execute this command

apt install elasticsearch=7.14.0

Basic Elasticsearch Configuration

Open the elasticsearch configuration file

nano /etc/elasticsearch/elasticsearch.yml

In the Cluster section, give your elasticsearch cluster name

cluster.name: my-elastic

In the Node section, give this specific elasticsearch node name

node.name: my-elastic-1

In the Network section, you can bind elasticsearch to localhost like this

network.host: 127.0.0.1

Or, if you dont want to bind it to specific address, just write this

network.host: 0.0.0.0

In the Discovery section, config elasticsearch to single node mode

discovery.type: single-node

And then save and exit

Ater that, start the service

service elasticsearch start

Do a quick check using curl

curl http://localhost:9200?pretty

It should return something like this:

{
  "name" : "my-elastic-1",
  "cluster_name" : "my-elastic",
  "cluster_uuid" : "VL2gEVwpVcm9yFIAvwLUdg",
  "version" : {
    "number" : "7.12.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "78722837c38caa25a90782b5b042074cded35b3a",
    "build_date" : "2021-03-18T06:17:15.410153305Z",
    "build_snapshot" : false,
    "lucene_version" : "8.8.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

If error, check again your configuration. Maybe there are some typos.

Enabling Xpack

Execute elasticsearch binary to setup elastic password

/usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

Type All the password for all default elastic user.

After that, go to elasticsearch configuration file

nano /etc/elasticsearch/elasticsearch.yml

Add this line of code in the bottom of the file

xpack.security.enabled: true

Save & Exit, and then restart the elasticsearch service

service elasticsearch restart

Congrats! Right now you already enabled the xpack.

To test it, just do quick check again using curl

curl http://localhost:9200?pretty

It will return a 401 error.

{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "missing authentication credentials for REST request [/?pretty]",
        "header" : {
          "WWW-Authenticate" : [
            "Basic realm=\"security\" charset=\"UTF-8\"",
            "Bearer realm=\"security\"",
            "ApiKey"
          ]
        }
      }
    ],
    "type" : "security_exception",
    "reason" : "missing authentication credentials for REST request [/?pretty]",
    "header" : {
      "WWW-Authenticate" : [
        "Basic realm=\"security\" charset=\"UTF-8\"",
        "Bearer realm=\"security\"",
        "ApiKey"
      ]
    }
  },
  "status" : 401
}

That’s a sign that the xpack is already enabled. You need to use the username and password you previously built to access the elasticsearch. Do quick check again but now use your username and password in this format:

curl -u <username>:<password> http://localhost:9200?pretty

Now it should return the elasticsearch general information.

{
  "name" : "my-elastic-1",
  "cluster_name" : "my-elastic",
  "cluster_uuid" : "VL2gEVwpVcm9yFIAvwLUdg",
  "version" : {
    "number" : "7.12.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "78722837c38caa25a90782b5b042074cded35b3a",
    "build_date" : "2021-03-18T06:17:15.410153305Z",
    "build_snapshot" : false,
    "lucene_version" : "8.8.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

Enabling SSL

Create a folder for your certificate

mkdir /etc/elasticsearch/certs

Place your SSL certificate & Key inside that directory

Give read permission to the certificates

chmod +r /etc/elasticsearch/certs/*

Open the elasticsearch configuration file

nano /etc/elasticsearch/elasticsearch.yml 

Add these line of code in the bottom of the file

xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.key: /etc/elasticsearch/certs/<certificate-key-name>.key
xpack.security.http.ssl.certificate: /etc/elasticsearch/certs/<certificate-name>.crt
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.key: /etc/elasticsearch/certs/<certificate-key-name>.key
xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/<certificate-name>.crt

Edit the <certificate-key-name> & <certificate-name> to match your certificate and key file.

Save & Exit. And the restart the elasticsearch service

service elasticsearch restart

After that, open your hosts file

nano /etc/hosts

Add this line to your hosts file to contain your domain name that match you SSL certificate and key. For example my domain is elastic.example.com

127.0.0.1   elastic.example.com

Save & Exit. To make sure that you hosts file is configured correctly, do q quick check using ping to your domain.

ping elastic.example.com

You should get return from 127.0.0.1

PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.042 ms

To check the SSL is enabled, you can do a curl request to your domain using https, also using your username and password

curl -u <username>:<password> https://elastic.example.com:9200?pretty

This should return the elasticsearch general information.

{
  "name" : "my-elastic-1",
  "cluster_name" : "my-elastic",
  "cluster_uuid" : "VL2gEVwpVcm9yFIAvwLUdg",
  "version" : {
    "number" : "7.12.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "78722837c38caa25a90782b5b042074cded35b3a",
    "build_date" : "2021-03-18T06:17:15.410153305Z",
    "build_snapshot" : false,
    "lucene_version" : "8.8.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

You must hit the elasticsearch using your domain, you cannot use localhost because it will not match the SSL certificate & key.

Congrats! Right now you already setup your Elasticsearch with Xpack & SSL enabled on Ubuntu 18.04. Now, other elastic stack such as kibana, logstash, beats that connect direcly to your Elasticsearch must use username & password to connect.