Over the past year, there have been many leaks from Elasticsearch databases ( here , here and there ). In many cases, personal data was stored in the database. These leaks could be avoided if, after deploying the database, administrators took the trouble to check out a few simple settings. Today weโll talk about them.Weโll immediately make a reservation that in our practice we use Elasticsearch to store logs and analyze logs of information protection tools, OS and software in our IaaS platform that meets the requirements of 152-, Cloud-152. 
Check if the database is โstickingโ
In most of the known cases of leaks ( here , here ), the attacker gained access to the data simply and unpretentiously: the database was published on the Internet, and it was possible to connect to it without authentication. First, weโll deal with publishing on the Internet. Why is this so? The fact is that for more flexible operation of Elasticsearch, it is recommended to create a cluster of three servers. In order for the databases to communicate with each other, you need to open the ports. As a result, administrators do not restrict access to the database, and you can connect to the database from anywhere. Checking if there is external access to the database is easy. Just enter http: // [IP / Elasticsearch Name]: 9200 / _cat / nodes? In the browser ? VIf you manage to log in, then run to close.We protect the connection to the database
Now we will make it impossible to connect to the database without authentication.Elasticsearch has an authentication module that restricts access to the database, but it is only in the paid set of X-Pack plugins (1 month of free use).The good news is that in the fall of 2019, Amazon opened its groundwork that intersects with the X-Pack. The authentication function when connecting to the database has become available under a free license for version Elasticsearch 7.3.2., And a new release for Elasticsearch 7.4.0 is already in operation.Installing this plugin is easy. We go into 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 -
We configure interaction between servers through SSL
When installing the plugin, the configuration of the database connection port changes. It includes SSL encryption. In order for the cluster servers to continue working with each other, you need to configure the interaction between them using SSL.Trust between hosts can be established with or without your own certification authority. With the first method, everything is clear: you just need to contact a specialist in CA. We proceed immediately to the second.- Create a variable with the fully qualified domain name:
export DOMAIN_CN="example.com"
- Create a private key:
openssl genrsa -out root-ca-key.pem 4096
- We sign the root certificate. Keep it as the apple of your eye: if it is lost or compromised, the 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
- Create an admin 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
- Create a request for signing a certificate:
openssl req -new -subj "/C=RU/ST=Moscow/O=Moscow Inc./CN=${DOMAIN_CN}/CN=admin " \
-key admin-key.pem -out admin.csr
- Create an 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
- 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
- Create a request for signature:
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 decompose the certificate between Elasticsearch nodes into the folder:
/etc/elasticsearch/
we need the files:
node-01-key.pem
node-01.pem
admin-key.pem
admin.pem
root-ca.pem
- Set up /etc/elasticsearch/elasticsearch.yml - change the name of the certificate files to the ones 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
We change passwords of internal users
- Using the command below, we display the password hash in the console:
sh ${OD_SEC}/tools/hash.sh -p []
- Change the hash in the file to the one received:
/usr/share/elasticsearch/plugins/opendistro_security/securityconfig/internal_users.yml
Configure the firewall in OS
- Allow the launch of the firewall:
systemctl enable firewalld
- Run it:
systemctl start firewalld
- We allow connection to Elasticsearch:
firewall-cmd --set-default-zone work
firewall-cmd --zone=work --add-port=9200/TCP --permanent
- Rebooting firewall rules:
firewall-cmd --reload
- We derive the working rules:
firewall-cmd --list-all
Apply all our changes to Elasticsearch
- Create a variable with the full path to the folder with the plugin:
export OD_SEC="/usr/share/elasticsearch/plugins/opendistro_security/"
- Run a script that will update passwords and check 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
- Check if the changes applied:
curl -XGET https://[IP/ Elasticsearch]:9200/_cat/nodes?v -u admin:[] --insecure
That's all, these are the minimum settings that block Elasticsearch from an unauthorized connection.