Over the past year, there have been many data leaks from databases. (, and ) 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.

We check whether the database is exposed on the internet
In most known cases of leaks (, ) 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 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.
- We create a variable with the full domain name:
export DOMAIN_CN="example.com" - We create a private key:
openssl genrsa -out root-ca-key.pem 4096 - 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 - 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 - 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 - 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 - 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 - 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 - We sign the certificate:
openssl x509 -req -in node.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node.pem - 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 - 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
- Use the command below to output the password hash to the console:
sh ${OD_SEC}/tools/hash.sh -p [password] - 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
- Allow the firewall to start:
systemctl enable firewalld - Start it:
systemctl start firewalld - Allow connection to Elasticsearch:
firewall-cmd --set-default-zone work firewall-cmd --zone=work --add-port=9200/TCP --permanent - Reload the firewall rules:
firewall-cmd --reload - Displaying active rules:
firewall-cmd --list-all
Applying all our changes to Elasticsearch
- Creating a variable with the full path to the plugin folder:
export OD_SEC="/usr/share/elasticsearch/plugins/opendistro_security/" - 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 - 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
