Elasticsearch as a secure local search backend

★ ★ ★ ★ ★ Not rated

Design and boundaries

This guide creates a single-node Elasticsearch service for local applications. It is not a multi-node cluster guide and does not publish Elasticsearch on the internet.

Never open ports 9200 or 9300 in UFW. Applications on this VPS connect to loopback HTTPS only. If a future cluster is required, design network segmentation, TLS, enrollment and bootstrap checks separately.

Elasticsearch security stays enabled. The package generates HTTP and transport TLS material; do not disable it simply to make an application connect more easily.

Prepare the host

Elasticsearch uses memory-mapped files. Check the kernel mapping limit and apply the current recommended minimum when necessary.

sysctl vm.max_map_count
printf 'vm.max_map_count=1048576\n' > /etc/sysctl.d/99-elasticsearch.conf
sysctl --system
sysctl vm.max_map_count

Reserve RAM for the operating system, Apache/PHP-FPM, MariaDB and Redis before assigning Elasticsearch heap. Disable or minimize swap for sustained production workloads.

Install from Elastic’s signed APT repository

apt -y install ca-certificates wget gnupg apt-transport-https
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" > /etc/apt/sources.list.d/elastic-9.x.list
apt update
apt -y install elasticsearch

The Debian package includes a supported OpenJDK. Do not install a second Java runtime only for Elasticsearch unless a documented compatibility requirement exists.

Keep security enabled and bind locally

On first startup, Elasticsearch security auto-configuration creates TLS certificates. Debian package installations do not display the elastic password automatically; reset it interactively and store it in the password manager.

systemctl enable --now elasticsearch
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
ls -l /etc/elasticsearch/certs/http_ca.crt

Before changing network settings, make a timestamped backup of the configuration. For this single-node design, change active http.host and transport.host entries to loopback addresses; retain the TLS and security entries generated by Elasticsearch.

cp -a /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.before-local-bind
sed -i -E 's|^[[:space:]]*http.host:.*|http.host: ["127.0.0.1", "::1"]|' /etc/elasticsearch/elasticsearch.yml
sed -i -E 's|^[[:space:]]*transport.host:.*|transport.host: ["127.0.0.1", "::1"]|' /etc/elasticsearch/elasticsearch.yml
systemctl restart elasticsearch
ss -lntp | grep -E ':(9200|9300)'
Review the listener. The expected result contains only 127.0.0.1 and/or ::1. If a public address appears, stop and correct the configuration before connecting an application.

Set a bounded JVM heap

Use a small, explicit heap for a shared VPS and adjust after observing real workloads. Do not edit Elasticsearch’s root jvm.options; Debian packages load custom .options files from /etc/elasticsearch/jvm.options.d.

printf '%s\n' '-Xms1g' '-Xmx1g' > /etc/elasticsearch/jvm.options.d/heap.options
systemctl restart elasticsearch
systemctl --no-pager status elasticsearch

Heap must fit alongside the database and PHP workers. A larger heap is not automatically faster; Elasticsearch also relies on the filesystem cache.

Verify with HTTPS and the generated CA

Export the password only for the current shell session. Do not paste it into the command history.

read -rsp 'Elasticsearch password: ' ELASTIC_PASSWORD; echo
export ELASTIC_PASSWORD
curl --fail --cacert /etc/elasticsearch/certs/http_ca.crt \
  -u "elastic:$ELASTIC_PASSWORD" https://127.0.0.1:9200/
curl --fail --cacert /etc/elasticsearch/certs/http_ca.crt \
  -u "elastic:$ELASTIC_PASSWORD" https://127.0.0.1:9200/_cluster/health?pretty
unset ELASTIC_PASSWORD

The first response identifies the node and version; the health call should return a single-node status. A 401 response without credentials proves HTTPS is reachable but authentication remains enforced.

Operations, backups and upgrades

systemctl is-active elasticsearch
journalctl -u elasticsearch -n 100 --no-pager
df -h /var/lib/elasticsearch
curl --cacert /etc/elasticsearch/certs/http_ca.crt -I https://127.0.0.1:9200/
  • Monitor JVM heap, filesystem space, shard health, rejected requests and service restarts.
  • Use Elasticsearch snapshots for index recovery; database or filesystem backups alone are not a valid substitute for an active index snapshot strategy.
  • Read the version-specific breaking changes before major upgrades.
  • Keep the repository definition singular; duplicate Elastic APT entries cause APT warnings and confusion.

Result: a TLS-protected, authenticated Elasticsearch node accessible only from the local VPS.

0.0
★ ★ ★ ★ ★
0 reviews
5 ★
0 %
4 ★
0 %
3 ★
0 %
2 ★
0 %
1 ★
0 %

Add a comment

There's nothing here.

No comments have been posted here yet.