Elasticsearch isn’t in Fedora’s repositories, so it comes from Elastic’s own RPM repository, and the package makes three decisions for you on the way in. It turns on TLS and authentication, and it prints the only copy of the elastic superuser’s password in the middle of the dnf output. It also writes http.host: 0.0.0.0 into the config, so the REST API listens on every interface from the first start. On our VMs with 4 GB allocated it also gave itself a heap of about 1.9 GiB.
You’ll add Elastic’s repository, start a single-node Elasticsearch, query it over TLS, keep the API off the network or open it to one subnet, size the heap, and index a first document. Elasticsearch ships its own JDK, so there is no Java step. The install ran on Fedora 45 and Fedora 44 in October 2026, with the heap, index and password steps on Fedora 44.
Add Elastic’s repository
Import Elastic’s signing key first. It imported cleanly on both releases under Fedora’s default crypto policy, so there is no SHA-1 workaround to apply.
curl -s -o /tmp/GPG-KEY-elasticsearch https://artifacts.elastic.co/GPG-KEY-elasticsearch
sudo rpm --import /tmp/GPG-KEY-elasticsearch
Then create the repository file. Elastic keeps it disabled on purpose, which the definition below shows.
sudo vim /etc/yum.repos.d/elasticsearch.repo
This is the definition from Elastic’s RPM install docs for the 9.x line. Note enabled=0. It means a routine dnf upgrade never moves your search cluster to a new version behind your back. You enable it for one command at a time with --enablerepo, both to install and later to upgrade with sudo dnf upgrade --enablerepo=elasticsearch elasticsearch.
[elasticsearch]
name=Elasticsearch repository for 9.x packages
baseurl=https://artifacts.elastic.co/packages/9.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
type=rpm-md
Install Elasticsearch
Install with the repository enabled for this one transaction, and keep the output, because it holds the generated password.
sudo dnf install -y --enablerepo=elasticsearch elasticsearch
It is one large package, about 800 MiB to download and 1.4 GiB on disk, because the Elasticsearch RPM carries its own JDK in /usr/share/elasticsearch/jdk. That bundled runtime reported itself as OpenJDK 27 on our Fedora 45 box, independent of whatever Java Fedora has installed.
Installing:
elasticsearch x86_64 0:9.5.5-1 elasticsearch 1.4 GiB
dnf5 prints the package’s post-install messages with a >>> prefix, so the security summary looks like a log rather than a notice, and it is easy to scroll past. This is the part that matters, with our password removed.
>>> --------------------------- Security autoconfiguration information ------------------------------
>>>
>>> Authentication and authorization are enabled.
>>> TLS for the transport and HTTP layers is enabled and configured.
>>>
>>> The generated password for the elastic built-in superuser is : REDACTED
Copy the password into your password manager now. If you missed it, you can generate a new one later with the reset tool shown at the end, but the original is not stored anywhere you can read back. Here is the full notice from our Fedora 44 run, with the enrollment-token and reset hints in the middle trimmed.

Read the last lines before you move on. The package deliberately leaves the service stopped, so nothing listens until you enable it. If this node should never answer on the network, you can make the http.host change shown two sections down before this first start.
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
Query Elasticsearch over TLS
The HTTP layer uses a certificate signed by a CA that the installer generated, at /etc/elasticsearch/certs/http_ca.crt, readable only by root and the elasticsearch group. Copy it somewhere your user can read, then keep the password out of your shell history by reading it into a variable.
sudo cp /etc/elasticsearch/certs/http_ca.crt ~/http_ca.crt
sudo chown $USER ~/http_ca.crt
read -rsp 'elastic password: ' ESPW; echo
curl --cacert ~/http_ca.crt -u "elastic:$ESPW" https://localhost:9200
A working node answers with its name, which defaults to the hostname, and the version. If curl complains about the certificate instead, the --cacert path is wrong, while a 401 means the password is.
{
"name" : "f44-01",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "224FqeLZR-iIWuSGS9jl0A",
"version" : {
"number" : "9.5.5",
"build_flavor" : "default",
"build_type" : "rpm",
"build_hash" : "48acba663b09e70b115dd879329141506c377890",
"build_date" : "2026-09-30T22:12:03.984586187Z",
"build_snapshot" : false,
"lucene_version" : "10.5.1",
"minimum_wire_compatibility_version" : "8.19.0",
"minimum_index_compatibility_version" : "8.0.0"
},
"tagline" : "You Know, for Search"
}
Fedora 45 returned the same version with its own hostname, and the same session shows the bundled JDK, the SELinux label and the automatic heap discussed below.

Beyond the version, the package took care of the system settings older guides walk you through by hand, so check them rather than repeat them:
vm.max_map_countat 262144, from/usr/lib/sysctl.d/elasticsearch.conf- a CA, node certificates and keystores under
/etc/elasticsearch/certs - a systemd unit that runs as
unconfined_service_tunder SELinux enforcing
That last point cuts both ways. SELinux needs no extra policy for Elasticsearch, and it also does nothing to confine it, so the network and password settings below are your real protection.
Keep port 9200 off the network
The auto-configuration appends http.host: 0.0.0.0 to /etc/elasticsearch/elasticsearch.yml, so ss -ltn showed 9200 on every interface right after the first start, while the cluster transport port 9300 stayed on localhost.
LISTEN 0 4096 *:9200 *:*
LISTEN 0 4096 [::ffff:127.0.0.1]:9300 *:*
LISTEN 0 4096 [::1]:9300 [::]:*
TLS and the password protect it, but an API that only local applications use has no reason to listen on the network. Change the line to loopback in the same file.
sudo vim /etc/elasticsearch/elasticsearch.yml
It sits near the end of the file, under the security block the installer wrote, at line 113 on our install. Change that line in place rather than adding a second http.host further down, so the file gives one answer.
http.host: 127.0.0.1
After sudo systemctl restart elasticsearch, port 9200 listened on 127.0.0.1 only and cluster health still reported green. When application servers elsewhere need the API, keep 0.0.0.0 and limit it in firewalld to their subnet instead. Short of binding to a single private interface, the free tier gives a single node no way to filter clients itself. Fedora’s cloud images ship without firewalld, so install it there first. Fedora’s zones allow SSH on port 22, so if your SSH daemon listens elsewhere, allow that port before you start the firewall.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
Then check which zone is in charge with sudo firewall-cmd --get-default-zone, because the answer decides whether a rule restricts anything. Our Fedora 45 node reported FedoraServer, which rejects ports you have not opened. The FedoraWorkstation zone works the other way round: it opens every TCP and UDP port from 1025 to 65535, so 9200 is already reachable and the rule below would restrict nothing. On a Workstation install, switch to a stricter zone first with sudo firewall-cmd --set-default-zone=public, as our firewalld on Fedora guide explains. Confirm the interface moved with sudo firewall-cmd --get-active-zones, since a NetworkManager connection can pin its own zone. Then add the rule for the application subnet.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" port port="9200" protocol="tcp" accept'
sudo firewall-cmd --reload
We tested it with a single /32 source. Our Fedora 44 box reached the Fedora 45 node by IP, and with a copy of http_ca.crt the TLS check passed and the server answered 401, asking for the password. A Fedora 45 Workstation box outside the rule had its connection refused, with curl exiting on code 7.

Remote clients need that CA copy, exactly as the local curl above did. Leave 9300 closed, since it carries node-to-node traffic and matters only once you add a second node; our guide to deploying an Elasticsearch cluster with Ansible covers that step.
Set the heap size
Without a setting, Elasticsearch sizes its heap from the machine’s RAM. On our VMs, which the node sees as 3.7 GiB, it chose -Xms1940m -Xmx1940m, and the process used about 2.3 GiB of resident memory, more than half the box. That is right on a dedicated search server and too much on a machine that also runs the application. Set it explicitly in a drop-in, which survives package upgrades.
sudo vim /etc/elasticsearch/jvm.options.d/heap.options
Keep the minimum and maximum equal, so the heap never resizes under load.
-Xms1g
-Xmx1g
Restart and ask the node what it is using. The _cat/nodes API puts the heap ceiling next to the RAM the node sees, which is quicker than reading JVM flags out of ps.
sudo systemctl restart elasticsearch
curl -s --cacert ~/http_ca.crt -u "elastic:$ESPW" "https://localhost:9200/_cat/nodes?h=heap.max,ram.max&v"
The heap dropped to 1 GB, and resident memory with it, to about 1.4 GiB on our Fedora 44 box:
heap.max ram.max
1gb 3.7gb
Here is what ps reported for the Java process on each box. The automatic heap cost close to a gigabyte more than the fixed one, and that gigabyte comes straight out of the filesystem cache and whatever else runs on the server.
| Box and heap setting | JVM flags | Resident memory (ps rss) |
|---|---|---|
| Fedora 45, automatic | -Xms1940m -Xmx1940m | 2,335,716 KiB |
| Fedora 44, automatic | -Xms1941m -Xmx1941m | 2,434,736 KiB |
Fedora 44, heap.options at 1g | -Xms1g -Xmx1g | 1,447,404 KiB |
Elasticsearch also needs memory outside the heap for the filesystem cache it reads indexes through, so leave at least as much RAM free as you give the heap. On a dedicated server Elastic recommends the automatic sizing, and if you set it by hand there, keep it to no more than half the RAM and under about 26 GB, the safe limit for compressed object pointers on most systems. See Elastic’s JVM settings reference for the details.
Index and search a document
Create an index first, the same way any log shipper or application will, and if you want the Logstash and Kibana side as well, our ELK stack on Ubuntu guide builds the full pipeline. On a single node, set replicas to zero, because a replica can never be placed on the node that holds its primary, and the cluster would report yellow forever:
curl -s --cacert ~/http_ca.crt -u "elastic:$ESPW" -X PUT "https://localhost:9200/books?pretty" -H "Content-Type: application/json" -d '{"settings":{"number_of_replicas":0}}'
Elasticsearch confirms the index and its shards. shards_acknowledged set to true means the primary shard actually started, not only that the request was accepted.
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "books"
}
Add a document, with refresh=true so it is searchable immediately, then search for it:
curl -s --cacert ~/http_ca.crt -u "elastic:$ESPW" -X POST "https://localhost:9200/books/_doc?refresh=true" -H "Content-Type: application/json" -d '{"title":"The Linux Command Line","year":2019}'
curl -s --cacert ~/http_ca.crt -u "elastic:$ESPW" "https://localhost:9200/books/_search?q=title:linux&pretty" | grep -E '"total"|"value"|title'
The search found the document by a lowercase word from its title, which shows the default analyzer at work, and cluster health stayed green with four active shards, the books primary plus three belonging to system indices.
"total" : 1,
"total" : {
"value" : 1,
"title" : "The Linux Command Line",
Check cluster health after every index you create, because it is the quickest way to see whether every shard found a node.
curl -s --cacert ~/http_ca.crt -u "elastic:$ESPW" "https://localhost:9200/_cluster/health?pretty"
Our whole Fedora 44 sequence ran in one session, from creating the index to that health check, which came back green on a single node.

Green holds on a single node only while every index keeps replicas at zero. Create an index without that setting and health drops to yellow, which is the unassigned replica described above rather than a fault.
Reset the elastic password
If the install-time password is lost, or you want to rotate it, the package ships a reset tool. The -b flag skips the confirmation prompt, and the -s flag prints only the new password, which lets you redirect it into a file that only you can read instead of leaving it in your terminal scrollback.
sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -b -s > ~/.espw
chmod 600 ~/.espw
Without -s it reports Password for the [elastic] user successfully reset. followed by the value. After a reset the $ESPW variable from earlier holds the old password, so reload it from the file with ESPW=$(< ~/.espw), and on our Fedora 44 node cluster health answered green with the new one. Applications should not use the elastic superuser at all, so create a role and user per application once the node is up, and keep elastic for administration. If you are on Rocky Linux instead, our Elasticsearch and Kibana guide for Rocky Linux adds the Kibana side. If you also want dashboards on top, our Grafana on Fedora guide lists the grafana_can_tcp_connect_elasticsearch_port boolean that Fedora’s confined Grafana needs before it can query this node.