Set up secure communication between Jaeger and Elasticsearch using TLS encryption, authentication, and production-grade security hardening for distributed tracing infrastructure.
Prerequisites
- Elasticsearch cluster running
- Administrative access to servers
- Basic understanding of TLS certificates
- Familiarity with Jaeger components
What this solves
Jaeger with Elasticsearch backend requires proper security configuration for production environments. This tutorial configures TLS encryption between Jaeger components and Elasticsearch, sets up authentication mechanisms, and implements security hardening measures. You'll establish secure communication channels, configure X-Pack security features, and implement role-based access control for your distributed tracing infrastructure.
Prerequisites
You need a running Elasticsearch cluster and basic familiarity with Jaeger components. This builds on basic Jaeger installation and requires understanding of TLS certificate management. The configuration assumes you have administrative access to both Jaeger and Elasticsearch instances.
Step-by-step configuration
Install required packages
Install Elasticsearch, Jaeger components, and certificate management tools needed for secure configuration.
sudo apt update
sudo apt install -y elasticsearch jaeger-collector jaeger-query jaeger-agent openssl curl
Configure Elasticsearch X-Pack security
Enable X-Pack security features in Elasticsearch to provide authentication and authorization capabilities for Jaeger access.
cluster.name: jaeger-cluster
node.name: jaeger-node-1
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
Enable X-Pack security
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
TLS configuration
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.client_authentication: required
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
Audit logging for security events
xpack.security.audit.enabled: true
Generate TLS certificates
Create certificate authority and TLS certificates for secure communication between Jaeger and Elasticsearch components.
sudo mkdir -p /etc/elasticsearch/certs
sudo chown elasticsearch:elasticsearch /etc/elasticsearch/certs
sudo chmod 750 /etc/elasticsearch/certs
Generate CA and certificates
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca --out /etc/elasticsearch/certs/elastic-ca.p12 --pass ""
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca /etc/elasticsearch/certs/elastic-ca.p12 --ca-pass "" --out /etc/elasticsearch/certs/http.p12 --pass ""
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca /etc/elasticsearch/certs/elastic-ca.p12 --ca-pass "" --out /etc/elasticsearch/certs/transport.p12 --pass ""
Set appropriate permissions
sudo chown elasticsearch:elasticsearch /etc/elasticsearch/certs/*
sudo chmod 660 /etc/elasticsearch/certs/*
Create Jaeger service account
Set up dedicated Elasticsearch user account for Jaeger with minimal required permissions for tracing data access.
sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch
Wait for Elasticsearch to start
sleep 30
Reset built-in user passwords
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto > /tmp/es-passwords.txt
Extract elastic password for admin operations
ELASTIC_PASSWORD=$(grep "PASSWORD elastic" /tmp/es-passwords.txt | awk '{print $4}')
echo "Elastic password: $ELASTIC_PASSWORD"
Create Jaeger user and roles
Configure role-based access control with custom roles for Jaeger tracing operations and read-only access patterns.
# Create jaeger_writer role for collector
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/role/jaeger_writer" -H "Content-Type: application/json" -d '
{
"indices": [
{
"names": ["jaeger-*"],
"privileges": ["create", "index", "write", "delete", "manage"]
}
]
}'
Create jaeger_reader role for query service
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/role/jaeger_reader" -H "Content-Type: application/json" -d '
{
"indices": [
{
"names": ["jaeger-*"],
"privileges": ["read"]
}
]
}'
Create jaeger_admin role for index management
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/role/jaeger_admin" -H "Content-Type: application/json" -d '
{
"indices": [
{
"names": ["jaeger-*"],
"privileges": ["all"]
}
]
}'
Create Jaeger service users
Set up individual user accounts for Jaeger collector, query service, and administrative operations with appropriate role assignments.
# Create user for Jaeger collector
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/user/jaeger_collector" -H "Content-Type: application/json" -d '
{
"password": "JaegerCollector2024!",
"roles": ["jaeger_writer"],
"full_name": "Jaeger Collector Service"
}'
Create user for Jaeger query
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/user/jaeger_query" -H "Content-Type: application/json" -d '
{
"password": "JaegerQuery2024!",
"roles": ["jaeger_reader"],
"full_name": "Jaeger Query Service"
}'
Create user for Jaeger admin operations
curl -k -u elastic:$ELASTIC_PASSWORD -X POST "https://localhost:9200/_security/user/jaeger_admin" -H "Content-Type: application/json" -d '
{
"password": "JaegerAdmin2024!",
"roles": ["jaeger_admin"],
"full_name": "Jaeger Administrator"
}'
Extract certificates for Jaeger
Convert Elasticsearch certificates to PEM format for use by Jaeger components and configure certificate access permissions.
sudo mkdir -p /etc/jaeger/certs
Extract CA certificate
sudo openssl pkcs12 -in /etc/elasticsearch/certs/elastic-ca.p12 -cacerts -nokeys -out /etc/jaeger/certs/ca.crt -passin pass:""
Extract client certificate and key
sudo openssl pkcs12 -in /etc/elasticsearch/certs/http.p12 -clcerts -nokeys -out /etc/jaeger/certs/client.crt -passin pass:""
sudo openssl pkcs12 -in /etc/elasticsearch/certs/http.p12 -nocerts -out /etc/jaeger/certs/client.key -passin pass:"" -passout pass:""
Set appropriate permissions
sudo chown -R jaeger:jaeger /etc/jaeger/certs
sudo chmod 750 /etc/jaeger/certs
sudo chmod 644 /etc/jaeger/certs/ca.crt
sudo chmod 644 /etc/jaeger/certs/client.crt
sudo chmod 600 /etc/jaeger/certs/client.key
Configure Jaeger collector with security
Set up Jaeger collector with TLS encryption, authentication credentials, and secure connection parameters for Elasticsearch backend.
es:
server-urls: https://localhost:9200
username: jaeger_collector
password: JaegerCollector2024!
tls:
enabled: true
ca: /etc/jaeger/certs/ca.crt
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
server-name: localhost
insecure-skip-verify: false
num-shards: 3
num-replicas: 1
index-prefix: jaeger
create-index-templates: true
timeout: 30s
max-span-age: 72h
collector:
grpc:
host-port: 0.0.0.0:14250
tls:
enabled: true
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
http:
host-port: 0.0.0.0:14268
tls:
enabled: true
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
zipkin:
host-port: 0.0.0.0:9411
Configure Jaeger query service
Set up Jaeger query service with read-only Elasticsearch access, TLS encryption, and UI security configuration for web interface access.
es:
server-urls: https://localhost:9200
username: jaeger_query
password: JaegerQuery2024!
tls:
enabled: true
ca: /etc/jaeger/certs/ca.crt
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
server-name: localhost
insecure-skip-verify: false
index-prefix: jaeger
timeout: 30s
max-lookback: 168h
query:
http:
host-port: 0.0.0.0:16686
tls:
enabled: true
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
grpc:
host-port: 0.0.0.0:16685
tls:
enabled: true
cert: /etc/jaeger/certs/client.crt
key: /etc/jaeger/certs/client.key
ui:
config:
archive:
enabled: false
dependencies:
menuEnabled: true
tracking:
gaID: ""
menu:
- label: "About Jaeger"
url: "https://jaegertracing.io"
Configure systemd services
Create systemd service files for Jaeger components with proper security context and resource limits for production deployment.
[Unit]
Description=Jaeger Collector
Documentation=https://jaegertracing.io
After=network.target elasticsearch.service
Requires=elasticsearch.service
[Service]
Type=simple
User=jaeger
Group=jaeger
ExecStart=/usr/bin/jaeger-collector --config-file=/etc/jaeger/collector.yaml
Restart=always
RestartSec=10
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/jaeger
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
Resource limits
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
Create Jaeger query service
Set up systemd service for Jaeger query with security hardening and proper dependency management on Elasticsearch availability.
[Unit]
Description=Jaeger Query Service
Documentation=https://jaegertracing.io
After=network.target elasticsearch.service
Requires=elasticsearch.service
[Service]
Type=simple
User=jaeger
Group=jaeger
ExecStart=/usr/bin/jaeger-query --config-file=/etc/jaeger/query.yaml
Restart=always
RestartSec=10
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
Security settings
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/jaeger
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
Resource limits
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
Configure log directories and permissions
Set up proper logging directory structure with appropriate permissions for Jaeger service user and log rotation configuration.
sudo mkdir -p /var/log/jaeger
sudo chown jaeger:jaeger /var/log/jaeger
sudo chmod 750 /var/log/jaeger
Create jaeger user if not exists
sudo useradd -r -s /bin/false jaeger 2>/dev/null || true
Ensure all certificate permissions are correct
sudo chown -R jaeger:jaeger /etc/jaeger
sudo chmod -R o-rwx /etc/jaeger/certs
Start and enable services
Start Jaeger services with systemd and verify they connect securely to Elasticsearch with proper authentication and encryption.
sudo systemctl daemon-reload
sudo systemctl enable jaeger-collector
sudo systemctl enable jaeger-query
sudo systemctl start jaeger-collector
sudo systemctl start jaeger-query
Check service status
sudo systemctl status jaeger-collector
sudo systemctl status jaeger-query
Configure firewall rules
Set up specific firewall rules for Jaeger ports with TLS encryption and restrict access to authorized networks only.
sudo ufw allow from 203.0.113.0/24 to any port 14250 comment 'Jaeger gRPC collector'
sudo ufw allow from 203.0.113.0/24 to any port 14268 comment 'Jaeger HTTP collector'
sudo ufw allow from 203.0.113.0/24 to any port 16686 comment 'Jaeger UI'
sudo ufw allow from 203.0.113.0/24 to any port 16685 comment 'Jaeger query gRPC'
sudo ufw reload
Verify your setup
Test the secure connection between Jaeger and Elasticsearch and verify all authentication mechanisms are working properly.
# Check Elasticsearch cluster health with authentication
curl -k -u elastic:$ELASTIC_PASSWORD "https://localhost:9200/_cluster/health?pretty"
Verify Jaeger can connect to Elasticsearch
curl -k "https://localhost:16686/api/services"
Check TLS certificate validity
echo | openssl s_client -connect localhost:16686 -servername localhost 2>/dev/null | openssl x509 -noout -dates
Verify collector is receiving data
curl -k "https://localhost:14268/api/traces" -X POST -H "Content-Type: application/json" -d '{
"data": [
{
"traceID": "test-trace-id",
"spans": [
{
"traceID": "test-trace-id",
"spanID": "test-span-id",
"operationName": "test-operation",
"startTime": 1640995200000000,
"duration": 1000000
}
]
}
]
}'
Check Jaeger indices in Elasticsearch
curl -k -u jaeger_query:JaegerQuery2024! "https://localhost:9200/_cat/indices/jaeger-*?v"
Production security hardening
Configure index lifecycle management
Set up automated index lifecycle policies for secure data retention and automated cleanup of old tracing data.
# Create ILM policy for Jaeger indices
curl -k -u elastic:$ELASTIC_PASSWORD -X PUT "https://localhost:9200/_ilm/policy/jaeger_policy" -H "Content-Type: application/json" -d '
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "7d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"allocate": {
"number_of_replicas": 0
}
}
},
"delete": {
"min_age": "30d"
}
}
}
}'
Apply policy to Jaeger index templates
curl -k -u elastic:$ELASTIC_PASSWORD -X PUT "https://localhost:9200/_index_template/jaeger_template" -H "Content-Type: application/json" -d '
{
"index_patterns": ["jaeger-*"],
"template": {
"settings": {
"index.lifecycle.name": "jaeger_policy",
"index.lifecycle.rollover_alias": "jaeger-write"
}
}
}'
Enable audit logging
Configure comprehensive audit logging for security monitoring and compliance tracking of Jaeger access patterns.
# Add to existing elasticsearch.yml
xpack.security.audit.enabled: true
xpack.security.audit.outputs: [index, logfile]
xpack.security.audit.logfile.events.include: [
"access_denied",
"access_granted",
"anonymous_access_denied",
"authentication_failed",
"connection_denied",
"tampered_request",
"run_as_denied",
"run_as_granted"
]
xpack.security.audit.logfile.events.exclude: ["access_granted"]
xpack.security.audit.index.rollover: "daily"
xpack.security.audit.index.events.include: ["authentication_failed", "access_denied", "tampered_request"]
Set up monitoring alerts
Configure security monitoring and alerting for authentication failures, unauthorized access attempts, and certificate expiration tracking.
# Create watcher for failed authentications
curl -k -u elastic:$ELASTIC_PASSWORD -X PUT "https://localhost:9200/_watcher/watch/jaeger_auth_failures" -H "Content-Type: application/json" -d '
{
"trigger": {
"schedule": {
"interval": "5m"
}
},
"input": {
"search": {
"request": {
"search_type": "query_then_fetch",
"indices": [".security-audit-*"],
"body": {
"query": {
"bool": {
"must": [
{
"term": {
"event_type": "authentication_failed"
}
},
{
"range": {
"@timestamp": {
"gte": "now-5m"
}
}
}
]
}
}
}
}
}
},
"condition": {
"compare": {
"ctx.payload.hits.total.value": {
"gt": 5
}
}
},
"actions": {
"log_alert": {
"logging": {
"level": "warn",
"text": "Multiple authentication failures detected for Jaeger users"
}
}
}
}'
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Jaeger can't connect to Elasticsearch | TLS certificate mismatch or invalid credentials | Check certificate paths and verify user credentials with curl -k -u jaeger_collector:password "https://localhost:9200" |
| SSL handshake failures | Certificate authority not trusted | Verify CA certificate is properly extracted and accessible: openssl verify -CAfile /etc/jaeger/certs/ca.crt /etc/jaeger/certs/client.crt |
| Authentication failed errors | Wrong username/password or user permissions | Verify user exists and has correct roles: curl -k -u elastic:password "https://localhost:9200/_security/user/jaeger_collector" |
| Index creation failures | Insufficient Elasticsearch permissions | Check jaeger_collector user has jaeger_writer role: curl -k -u elastic:password "https://localhost:9200/_security/role/jaeger_writer" |
| Certificate expiration warnings | TLS certificates approaching expiration | Check certificate validity: openssl x509 -in /etc/jaeger/certs/client.crt -noout -dates and regenerate if needed |
Next steps
- Configure OAuth2 authentication for Jaeger UI
- Implement sampling strategies for production
- Set up monitoring and alerting for Jaeger
- Configure automated backup and data retention policies
- Set up multi-datacenter Jaeger deployment for disaster recovery
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Script configuration
SCRIPT_NAME="jaeger-elasticsearch-secure-install"
ES_CLUSTER_NAME="${ES_CLUSTER_NAME:-jaeger-cluster}"
ES_NODE_NAME="${ES_NODE_NAME:-jaeger-node-1}"
ES_HTTP_PORT="${ES_HTTP_PORT:-9200}"
ES_TRANSPORT_PORT="${ES_TRANSPORT_PORT:-9300}"
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Usage function
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " --cluster-name NAME Elasticsearch cluster name (default: jaeger-cluster)"
echo " --node-name NAME Elasticsearch node name (default: jaeger-node-1)"
echo ""
echo "Environment variables:"
echo " ES_CLUSTER_NAME Override cluster name"
echo " ES_NODE_NAME Override node name"
exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
;;
--cluster-name)
ES_CLUSTER_NAME="$2"
shift 2
;;
--node-name)
ES_NODE_NAME="$2"
shift 2
;;
*)
print_error "Unknown option: $1"
usage
;;
esac
done
# Cleanup function
cleanup() {
print_warning "Installation failed. Cleaning up..."
systemctl stop elasticsearch 2>/dev/null || true
systemctl stop jaeger-collector 2>/dev/null || true
systemctl stop jaeger-query 2>/dev/null || true
rm -f /tmp/es-passwords.txt
}
# Set trap for cleanup on error
trap cleanup ERR
# Check if running as root or with sudo
check_privileges() {
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root or with sudo"
exit 1
fi
}
# Detect distribution and package manager
detect_distro() {
print_status "Detecting operating system..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
ES_CONFIG_DIR="/etc/elasticsearch"
ES_USER="elasticsearch"
ES_GROUP="elasticsearch"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
ES_CONFIG_DIR="/etc/elasticsearch"
ES_USER="elasticsearch"
ES_GROUP="elasticsearch"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
ES_CONFIG_DIR="/etc/elasticsearch"
ES_USER="elasticsearch"
ES_GROUP="elasticsearch"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_status "Detected: $PRETTY_NAME using $PKG_MGR"
else
print_error "Cannot detect operating system"
exit 1
fi
}
# Install Elasticsearch repository
install_elasticsearch_repo() {
print_status "[1/8] Setting up Elasticsearch repository..."
case "$PKG_MGR" in
apt)
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/8.x/apt stable main" > /etc/apt/sources.list.d/elastic-8.x.list
$PKG_UPDATE
;;
dnf|yum)
cat > /etc/yum.repos.d/elasticsearch.repo << EOF
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
EOF
;;
esac
}
# Install required packages
install_packages() {
print_status "[2/8] Installing required packages..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL elasticsearch openssl curl wget gnupg
;;
dnf|yum)
$PKG_INSTALL --enablerepo=elasticsearch elasticsearch openssl curl wget
;;
esac
}
# Configure Elasticsearch
configure_elasticsearch() {
print_status "[3/8] Configuring Elasticsearch with security features..."
# Backup original configuration
cp "$ES_CONFIG_DIR/elasticsearch.yml" "$ES_CONFIG_DIR/elasticsearch.yml.backup"
# Create new configuration
cat > "$ES_CONFIG_DIR/elasticsearch.yml" << EOF
# Cluster configuration
cluster.name: $ES_CLUSTER_NAME
node.name: $ES_NODE_NAME
network.host: 0.0.0.0
http.port: $ES_HTTP_PORT
transport.port: $ES_TRANSPORT_PORT
# Path configuration
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
# Memory settings
bootstrap.memory_lock: true
# X-Pack Security
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
# TLS configuration
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.client_authentication: required
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
# Audit logging
xpack.security.audit.enabled: true
EOF
chown root:$ES_GROUP "$ES_CONFIG_DIR/elasticsearch.yml"
chmod 660 "$ES_CONFIG_DIR/elasticsearch.yml"
}
# Generate TLS certificates
generate_certificates() {
print_status "[4/8] Generating TLS certificates..."
# Create certificates directory
mkdir -p "$ES_CONFIG_DIR/certs"
chown $ES_USER:$ES_GROUP "$ES_CONFIG_DIR/certs"
chmod 750 "$ES_CONFIG_DIR/certs"
# Generate CA certificate
/usr/share/elasticsearch/bin/elasticsearch-certutil ca --out "$ES_CONFIG_DIR/certs/elastic-ca.p12" --pass "" --silent
# Generate HTTP certificate
/usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca "$ES_CONFIG_DIR/certs/elastic-ca.p12" --ca-pass "" --out "$ES_CONFIG_DIR/certs/http.p12" --pass "" --silent
# Generate transport certificate
/usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca "$ES_CONFIG_DIR/certs/elastic-ca.p12" --ca-pass "" --out "$ES_CONFIG_DIR/certs/transport.p12" --pass "" --silent
# Set proper permissions
chown $ES_USER:$ES_GROUP "$ES_CONFIG_DIR/certs"/*
chmod 660 "$ES_CONFIG_DIR/certs"/*
}
# Configure system settings
configure_system() {
print_status "[5/8] Configuring system settings..."
# Configure memory lock limits
cat > /etc/security/limits.d/elasticsearch.conf << EOF
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
EOF
# Configure systemd
mkdir -p /etc/systemd/system/elasticsearch.service.d
cat > /etc/systemd/system/elasticsearch.service.d/override.conf << EOF
[Service]
LimitMEMLOCK=infinity
EOF
systemctl daemon-reload
}
# Start and setup Elasticsearch
start_elasticsearch() {
print_status "[6/8] Starting Elasticsearch and setting up authentication..."
# Start and enable Elasticsearch
systemctl enable elasticsearch
systemctl start elasticsearch
# Wait for Elasticsearch to start
print_status "Waiting for Elasticsearch to start..."
sleep 30
# Check if Elasticsearch is running
if ! systemctl is-active --quiet elasticsearch; then
print_error "Elasticsearch failed to start"
journalctl -u elasticsearch --no-pager -l
exit 1
fi
# Setup passwords
echo "y" | /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto > /tmp/es-passwords.txt
# Extract passwords
ELASTIC_PASSWORD=$(grep "PASSWORD elastic" /tmp/es-passwords.txt | awk '{print $4}')
KIBANA_PASSWORD=$(grep "PASSWORD kibana_system" /tmp/es-passwords.txt | awk '{print $4}')
print_status "Elasticsearch authentication configured"
chmod 600 /tmp/es-passwords.txt
}
# Configure Jaeger roles and users
configure_jaeger_security() {
print_status "[7/8] Configuring Jaeger security roles..."
# Wait a bit more for ES to be fully ready
sleep 10
# Create jaeger_writer role
curl -k -u "elastic:$ELASTIC_PASSWORD" -X POST "https://localhost:$ES_HTTP_PORT/_security/role/jaeger_writer" \
-H "Content-Type: application/json" -d '{
"indices": [
{
"names": ["jaeger-*"],
"privileges": ["create", "index", "write", "delete", "manage"]
}
]
}'
# Create jaeger_reader role
curl -k -u "elastic:$ELASTIC_PASSWORD" -X POST "https://localhost:$ES_HTTP_PORT/_security/role/jaeger_reader" \
-H "Content-Type: application/json" -d '{
"indices": [
{
"names": ["jaeger-*"],
"privileges": ["read", "view_index_metadata"]
}
]
}'
# Create Jaeger users
JAEGER_PASSWORD=$(openssl rand -base64 32)
curl -k -u "elastic:$ELASTIC_PASSWORD" -X POST "https://localhost:$ES_HTTP_PORT/_security/user/jaeger_user" \
-H "Content-Type: application/json" -d "{
\"password\": \"$JAEGER_PASSWORD\",
\"roles\": [\"jaeger_writer\", \"jaeger_reader\"],
\"full_name\": \"Jaeger Service User\"
}"
# Save Jaeger credentials
cat > /etc/jaeger-credentials.txt << EOF
Jaeger Username: jaeger_user
Jaeger Password: $JAEGER_PASSWORD
EOF
chmod 600 /etc/jaeger-credentials.txt
chown root:root /etc/jaeger-credentials.txt
}
# Verify installation
verify_installation() {
print_status "[8/8] Verifying installation..."
# Check Elasticsearch health
if curl -k -u "elastic:$ELASTIC_PASSWORD" -s "https://localhost:$ES_HTTP_PORT/_cluster/health" | grep -q '"status":"green\|yellow"'; then
print_status "Elasticsearch cluster is healthy"
else
print_error "Elasticsearch cluster health check failed"
exit 1
fi
# Check security features
if curl -k -u "elastic:$ELASTIC_PASSWORD" -s "https://localhost:$ES_HTTP_PORT/_security/user" | grep -q "elastic"; then
print_status "Elasticsearch security is configured"
else
print_error "Elasticsearch security configuration failed"
exit 1
fi
print_status "Installation completed successfully!"
echo ""
print_warning "IMPORTANT: Save these credentials securely:"
echo "Elasticsearch admin password: $ELASTIC_PASSWORD"
echo "Jaeger credentials saved to: /etc/jaeger-credentials.txt"
echo "Certificate files location: $ES_CONFIG_DIR/certs/"
echo ""
print_status "Next steps:"
echo "1. Configure Jaeger components to use the jaeger_user credentials"
echo "2. Set up proper firewall rules for ports $ES_HTTP_PORT and $ES_TRANSPORT_PORT"
echo "3. Configure Jaeger collector and query services with TLS certificates"
}
# Main execution
main() {
print_status "Starting Jaeger with Elasticsearch secure installation"
check_privileges
detect_distro
install_elasticsearch_repo
install_packages
configure_elasticsearch
generate_certificates
configure_system
start_elasticsearch
configure_jaeger_security
verify_installation
# Cleanup temporary files
rm -f /tmp/es-passwords.txt
}
# Execute main function
main "$@"
Review the script before running. Execute with: bash install.sh