How to configure Elasticsearch to prevent leaks

Over the past year, there have been many data leaks from databases. Elasticsearch (here, here and here) In many cases, personal data was stored in the database. These leaks could have been avoided if administrators had taken the time to check a few simple settings after deploying the database. Today, we will talk about them.

Let’s clarify right away that in our practice, we use Elasticsearch for storing logs and analyzing information security, OS, and software logs in our IaaS platform, which complies with the requirements of Federal Law 152-FZ, Cloud-152. 

How to configure Elasticsearch to prevent leaks

We check whether the database is exposed on the internet

In most known cases of leaks (here, here) attackers gained access to the data simply and without any complexity: the database was published on the internet and could be accessed without authentication.  

First, let’s address the issue of publishing on the internet. Why does this happen? The fact is that for more flexible operation, Elasticsearch it is recommended creates a cluster of three servers. To allow the databases to communicate with each other, ports need to be opened. As a result, administrators do not restrict access to the database, and it can be accessed from anywhere. It’s easy to check if the database is accessible from the outside. Just enter http://[IP/Elasticsearch Name]:9200/_cat/nodes?v

If you can access it, then quickly close it.

Securing the database connection

Now let’s configure it so that the database cannot be accessed without authentication.

Elasticsearch has an authentication module that restricts access to the database, but it is only available in the paid plugin set X-Pack (1 month of free use).

The good news is that in the fall of 2019, Amazon opened its developments that overlap with X-Pack. The authentication feature when connecting to the database became available under a free license for version Elasticsearch 7.3.2, and a new release for Elasticsearch 7.4.0 is already in progress.

This plugin is easy to install. Enter the server console and connect the repository:

RPM Based:

curl https://d3g5vo6xdbdb9a.cloudfront.net/yum/opendistroforelasticsearch-artifacts.repo -o /etc/yum.repos.d/opendistroforelasticsearch-artifacts.repo

yum update

yum install opendistro-security


DEB Based:

wget -qO ‐ https://d3g5vo6xdbdb9a.cloudfront.net/GPG-KEY-opendistroforelasticsearch | sudo apt-key add -

Configuring interaction between servers via SSL

When installing the plugin, the database connection port configuration changes. SSL encryption is enabled on it. In order for the cluster servers to continue to work together, it is necessary to configure the interaction between them using SSL.

Trust between hosts can be established using your own certificate authority or without it. The first method is straightforward: just reach out to CA specialists. Let’s move on to the second method.

  1. We create a variable with the full domain name:

    export DOMAIN_CN="example.com"

  2. We create a private key:

    openssl genrsa -out root-ca-key.pem 4096

  3. We sign the root certificate. Keep it as a prized possession: if it is lost or compromised, trust between all hosts will need to be reconfigured.

    openssl req -new -x509 -sha256 -subj "\/C=RU\/ST=Moscow\/O=Moscow, Inc.\/CN=${DOMAIN_CN}" 
    -key root-ca-key.pem -out root-ca.pem

  4. We create an administrator key:

    openssl genrsa -out admin-key-temp.pem 4096
    openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt 
    -v1 PBE-SHA1-3DES -out admin-key.pem

  5. We create a certificate signing request:

    openssl req -new -subj "\/C=RU\/ST=Moscow\/O=Moscow Inc.\/CN=${DOMAIN_CN}\/CN=admin " 
    -key admin-key.pem -out admin.csr

  6. We create the administrator certificate:

    openssl x509 -req -extensions usr_cert -in admin.csr -CA root-ca.pem 
    -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem

  7. We create certificates for the Elasticsearch node:

    export NODENAME="node-01"
    openssl genrsa -out ${NODENAME}-key-temp.pem 4096
    openssl pkcs8 -inform PEM -outform PEM -in ${NODENAME}-key-temp.pem -topk8 -nocrypt 
    -v1 PBE-SHA1-3DES -out ${NODENAME}-key.pem

  8. We create a signing request:

    openssl req -new -subj "\/C=RU\/ST=Moscow\/O=Moscow Inc.\/CN=${NODENAME}.${DOMAIN_CN}"  
    -addext"subjectAltName=DNS:${NODENAME}.${DOMAIN_CN},DNS:www.${NODENAME}.${DOMAIN_CN}" 
    -key ${NODENAME}-key.pem -out ${NODENAME}.csr

  9. We sign the certificate:

    openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial 
    -sha256 -out node.pem

  10. We distribute the certificate among Elasticsearch nodes into the folder:

    /etc/elasticsearch/


    We will need the following files:

            node-01-key.pem
    	node-01.pem
    	admin-key.pem
    	admin.pem
    	root-ca.pem

  11. Configuring /etc/elasticsearch/elasticsearch.yml – we rename the certificate files to those generated by us:

    opendistro_security.ssl.transport.pemcert_filepath: node-01.pem
    	opendistro_security.ssl.transport.pemkey_filepath: node-01-key.pem
    	opendistro_security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
    	opendistro_security.ssl.transport.enforce_hostname_verification: false
    	opendistro_security.ssl.http.enabled: true
    	opendistro_security.ssl.http.pemcert_filepath: node-01.pem
    	opendistro_security.ssl.http.pemkey_filepath: node-01-key.pem
    	opendistro_security.ssl.http.pemtrustedcas_filepath: root-ca.pem
    	opendistro_security.allow_unsafe_democertificates: false
    	opendistro_security.allow_default_init_securityindex: true
    	opendistro_security.authcz.admin_dn:
    	  − CN=admin,CN=example.com,O=Moscow Inc.,ST=Moscow,C=RU
    	opendistro_security.nodes_dn:
    	  − CN=node-01.example.com,O=Moscow Inc.,ST=Moscow,C=RU

Changing passwords for internal users

  1. Use the command below to output the password hash to the console:

    sh ${OD_SEC}/tools/hash.sh -p [password]

  2. Change the hash in the file to the obtained one:

    /usr/share/elasticsearch/plugins/opendistro_security/securityconfig/internal_users.yml

Configuring the firewall in the OS

  1. Allow the firewall to start:

    systemctl enable firewalld

  2. Start it:

    systemctl start firewalld

  3. Allow connection to Elasticsearch:

    firewall-cmd --set-default-zone work
    firewall-cmd --zone=work --add-port=9200/TCP --permanent

  4. Reload the firewall rules:

    firewall-cmd --reload

  5. Displaying active rules:

    firewall-cmd --list-all

Applying all our changes to Elasticsearch

  1. Creating a variable with the full path to the plugin folder:

    export  OD_SEC="/usr/share/elasticsearch/plugins/opendistro_security/"

  2. Running the script that will update the passwords and check the settings:

    ${OD_SEC}/tools/securityadmin.sh -cd ${OD_SEC}/securityconfig/ 
    -icl -nhnv -cacert /etc/elasticsearch/root-ca.pem 
    -cert /etc/elasticsearch/admin.pem  
    -key /etc/elasticsearch/admin-key.pem

  3. Checking if the changes have been applied:

    curl -XGET https://[IP/Elasticsearch Name]:9200/_cat/nodes?v -u admin:[password] --insecure

That’s it, these are the minimum settings that secure Elasticsearch from unauthorized access.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster