Skip to content

Instantly share code, notes, and snippets.

@svnscha
Last active April 24, 2024 19:46
Show Gist options
  • Save svnscha/676291c9e1cdbfa261202b3897afba37 to your computer and use it in GitHub Desktop.
Save svnscha/676291c9e1cdbfa261202b3897afba37 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# https://svnscha.de/posts/simplify-elasticsearch-kibana/
#
# Setup Script for Elasticsearch and Kibana on a Single Node Cluster
# Why do it manually when a script can handle it all? Let's make life easy!
#
# This script sets up everything you need for Elasticsearch and Kibana on a single machine. It's perfect for getting started on either cloud or local servers, and here's what it does:
# 1. Check for Root Access: - Makes sure the script is running with all the necessary permissions to install and configure everything.
# 2. Update and Install Packages: - Refreshes the list of available packages and installs the essentials like `apt-transport-https`, `gnupg`, `curl`, and `jq`.
# 3. Set Up the Repository: - Adds the official Elasticsearch repository to your system after importing the needed GPG key.
# 4. Install Elasticsearch: - Installs Elasticsearch and sets it up to accept connections from any computer.
# 5. Install Kibana: - Does the same for Kibana, making it ready to use from your network.
# 6. Manage Services: - Makes sure both Elasticsearch and Kibana start up automatically when your server boots, and keeps them running.
# 7. Secure the Setup: - Resets the default superuser password for Elasticsearch and creates a token for Kibana setup.
# 8. Wait for Kibana to Start: - Holds on until Kibana is ready and then finishes setting it up with the new token and password.
# 9. Log the Details: - Writes down important info about how to access and manage your Elasticsearch and Kibana into the system's welcome message.
#
# Things to Keep in Mind
# By default, Elasticsearch and Kibana can be accessed from any computer. This is fine for testing but change it for serious use!
#
# Ready to make your data management a breeze?
# This script is great for testing, developing setup on a single server.
set -e
# Make sure the script is not running with "normal user" privileges because we're too cool for that
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root, because it's more powerful that way!" 1>&2
exit 1
fi
# Update the system because fresh is always better
apt update
apt install -y apt-transport-https gnupg curl jq # Install the essentials: apt-transport for secure sources, gnupg for keys, curl for web requests, jq for JSON joy
# Trust is hard to earn, let's just import it
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch.gpg
# Let's tell APT where the good stuff is
echo "deb [signed-by=/usr/share/keyrings/elasticsearch.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list
# Getting the latest package info because outdated information is so 1990s
apt update
# Install Elasticsearch, because obviously, we need to search through heaps of data effortlessly
apt install -y elasticsearch
# Let everyone connect, because who needs security anyway?
sed -i '/network.host: /c\network.host: 0.0.0.0' /etc/elasticsearch/elasticsearch.yml
# Inform the system who's boss now
systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl start elasticsearch.service
# Reset the password and forget what it was, because security
ELASTIC_PASSWORD=$(yes y | /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic 2>/dev/null | grep 'New value:' | awk '{print $3}')
KIBANA_ENROLLMENT_TOKEN=$(/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana)
# Let's stop Elasticsearch because we don't want it to have all the fun without Kibana
systemctl stop elasticsearch.service
# Install Kibana, so we can actually understand what Elasticsearch is talking about
apt install -y kibana
# Make Kibana accessible from the network, because hermit mode is off
echo "" >> /etc/kibana/kibana.yml
echo "# === init-elastic-search-kibana-vm.sh ===" >> /etc/kibana/kibana.yml
echo "server.host: \"0.0.0.0\"" >> /etc/kibana/kibana.yml
# Wake up Elasticsearch, it's not nap time yet
systemctl start elasticsearch.service
# Give Kibana some power too
systemctl enable kibana.service
systemctl start kibana.service
# Wait for Kibana because good things come to those who wait...
sleep 10
# Let everyone know the good news
echo -e "=== init-elastic-search-kibana-vm.sh: Initial ===" >> /etc/motd
echo -e "[> Elasticsearch 'elastic' password: $ELASTIC_PASSWORD" >> /etc/motd
echo -e "[> Test instance with 'curl -k -X GET https://elastic:$ELASTIC_PASSWORD@localhost:9200'" >> /etc/motd
echo -e "=== init-elastic-search-kibana-vm.sh: Get started ===" >> /etc/motd
echo -e "[> Reset 'elastic' password with '/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'." >> /etc/motd
# Because who likes doing setup manually, right?
# Decode the token from Base64, because everything's better in Base64
decoded_token=$(echo $KIBANA_ENROLLMENT_TOKEN | base64 --decode)
# Extract the meaningful stuff using jq, because JSON doesn't parse itself
address=$(echo $decoded_token | jq -r '.adr[0]')
fingerprint=$(echo $decoded_token | jq -r '.fgr')
api_key=$(echo $decoded_token | jq -r '.key')
# Digging up more secrets: version and build from the depths of Kibana's soul
ver=$(jq -r '.version' /usr/share/kibana/package.json)
build=$(jq -r '.build.number' /usr/share/kibana/package.json)
# Re-encode the API key because Kibana likes its secrets whispered in Base64
encoded_api_key=$(echo -n $api_key | base64)
# Play the secret agent and get the verification code, because double verification is double fun
output=$(/usr/share/kibana/bin/kibana-verification-code)
# Extract the verification code, removing spaces because who likes whitespace?
verification_code=$(echo $output | awk -F": " '{print $2}' | sed 's/ //g')
# Finally, enroll Kibana like a boss
curl -k -v -X POST "http://localhost:5601/internal/interactive_setup/enroll" \
-H "Accept: */*" \
-H "Content-Type: application/json" \
-H "Host: localhost:5601" \
-H "Origin: http://localhost:5601" \
-H "Referer: http://localhost:5601/" \
-H "kbn-build-number: $build" \
-H "kbn-version: $ver" \
-H "x-elastic-internal-origin: Kibana" \
-H "x-kbn-context: %7B%22type%22%3A%22application%22%2C%22name%22%3A%22interactiveSetup%22%2C%22url%22%3A%22%2F%22%7D" \
-d '{"hosts":["https://'$address'"],"apiKey":"'$encoded_api_key'","caFingerprint":"'$fingerprint'","code":"'$verification_code'"}'
# Script ends here. Elasticsearch and Kibana are ready to roll.
# You're welcome!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment