tidy up repo
This commit is contained in:
@@ -4,41 +4,6 @@ A fully automated deployment of the ELK (Elasticsearch, Logstash, Kibana) observ
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Minikube Cluster │
|
||||
│ │
|
||||
│ ┌─── Namespace: elk ─────────────────────────────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────┐ SSL ┌──────────┐ ┌────────────────┐ │ │
|
||||
│ │ │ NGINX │◄────────►│ Kibana │◄───────►│ Elasticsearch │ │ │
|
||||
│ │ │ Proxy │ :443 │ :5601 │ :9200 │ (single │ │ │
|
||||
│ │ │ :30443 │ │ │ │ node) │ │ │
|
||||
│ │ └──────────┘ └──────────┘ └────────────────┘ │ │
|
||||
│ │ │ ▲ ▲ │ │
|
||||
│ │ │ :9443 │ OIDC │ │ │
|
||||
│ │ ▼ │ │ │ │
|
||||
│ │ ┌──────────────┐ ┌─────┴──────┐ ┌─────┴──────┐ │ │
|
||||
│ │ │ Authentik │ │ Authentik │ │ Logstash │ │ │
|
||||
│ │ │ PostgreSQL │◄──►│ Server + │ │ (JDBC │ │ │
|
||||
│ │ │ + Redis │ │ Worker │ │ pipelines)│ │ │
|
||||
│ │ └──────────────┘ └────────────┘ └─────┬──────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ └─────────────────────────────────────────────────────┼─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌─── Namespace: database ──────────────────────────────┼─────────────┐ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌────────────┐ │ │
|
||||
│ │ │ MySQL │ │ │
|
||||
│ │ │ 8.4 │ │ │
|
||||
│ │ │ (elkdemo) │ │ │
|
||||
│ │ └────────────┘ │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Tech Stack & Versions
|
||||
|
||||
| Component | Version | Purpose |
|
||||
@@ -72,6 +37,8 @@ sudo apt install -y ansible
|
||||
|
||||
## Project Structure
|
||||
|
||||
**NOTE:** The ansible folder is available [here](), and the BASH scripts can be found in [this repo]().
|
||||
|
||||
```
|
||||
elk-k8s-deployment/
|
||||
├── README.md ← You are here
|
||||
@@ -1,36 +0,0 @@
|
||||
all:
|
||||
hosts:
|
||||
localhost:
|
||||
ansible_connection: local
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
|
||||
vars:
|
||||
# --- Project paths ---
|
||||
project_dir: "{{ playbook_dir }}/.."
|
||||
k8s_manifests_dir: "{{ project_dir }}/k8s"
|
||||
scripts_dir: "{{ project_dir }}/scripts"
|
||||
certs_dir: "{{ project_dir }}/certs"
|
||||
|
||||
# --- Minikube ---
|
||||
minikube_cpus: 4
|
||||
minikube_memory: 8192
|
||||
minikube_disk_size: "40g"
|
||||
minikube_driver: docker
|
||||
|
||||
# --- Domain ---
|
||||
domain: elk.local
|
||||
|
||||
# --- ELK versions ---
|
||||
elk_version: "8.17.0"
|
||||
nginx_version: "1.27"
|
||||
authentik_version: "2024.12"
|
||||
mysql_version: "8.4"
|
||||
|
||||
# --- Passwords (override in vault for production) ---
|
||||
elastic_password: "ElasticP@ss2024!"
|
||||
kibana_system_password: "KibanaP@ss2024!"
|
||||
mysql_root_password: "rootpassword"
|
||||
logstash_mysql_password: "logstash_password"
|
||||
authentik_pg_password: "AuthPgP@ss2024!"
|
||||
authentik_secret_key: "Sup3rS3cretK3yForAuth3nt1k2024ThatIsLongEnough!"
|
||||
authentik_bootstrap_password: "AdminP@ss2024!"
|
||||
@@ -1,351 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# ELK Stack on Kubernetes (Minikube) — Main Deployment Playbook
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# ansible-playbook -i inventory/hosts.yml playbooks/deploy.yml
|
||||
#
|
||||
# Tags:
|
||||
# --tags prereqs Install system dependencies
|
||||
# --tags certs Generate TLS certificates
|
||||
# --tags minikube Start/configure Minikube
|
||||
# --tags namespaces Create K8s namespaces
|
||||
# --tags secrets Create TLS secrets in K8s
|
||||
# --tags mysql Deploy MySQL
|
||||
# --tags elasticsearch Deploy Elasticsearch
|
||||
# --tags es-setup Run Elasticsearch post-setup
|
||||
# --tags kibana Deploy Kibana
|
||||
# --tags logstash Deploy Logstash
|
||||
# --tags nginx Deploy NGINX proxy
|
||||
# --tags authentik Deploy Authentik SSO
|
||||
# --tags dns Configure /etc/hosts
|
||||
# =============================================================================
|
||||
|
||||
- name: Deploy ELK Stack on Kubernetes
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: true
|
||||
|
||||
tasks:
|
||||
# =======================================================================
|
||||
# PHASE 1 — Prerequisites
|
||||
# =======================================================================
|
||||
- name: Install system prerequisites
|
||||
tags: [prereqs]
|
||||
block:
|
||||
- name: Update apt cache
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Install required packages
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- curl
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- openssl
|
||||
- docker.io
|
||||
- conntrack
|
||||
state: present
|
||||
|
||||
- name: Ensure Docker service is running
|
||||
become: true
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Add current user to docker group
|
||||
become: true
|
||||
ansible.builtin.user:
|
||||
name: "{{ ansible_user_id }}"
|
||||
groups: docker
|
||||
append: true
|
||||
|
||||
- name: Install kubectl
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
if ! command -v kubectl &>/dev/null; then
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
rm -f kubectl
|
||||
fi
|
||||
args:
|
||||
creates: /usr/local/bin/kubectl
|
||||
|
||||
- name: Install minikube
|
||||
become: true
|
||||
ansible.builtin.shell: |
|
||||
if ! command -v minikube &>/dev/null; then
|
||||
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
|
||||
install minikube-linux-amd64 /usr/local/bin/minikube
|
||||
rm -f minikube-linux-amd64
|
||||
fi
|
||||
args:
|
||||
creates: /usr/local/bin/minikube
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 2 — TLS Certificates
|
||||
# =======================================================================
|
||||
- name: Generate TLS certificates
|
||||
tags: [certs]
|
||||
block:
|
||||
- name: Create certs directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ certs_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Run certificate generation script
|
||||
ansible.builtin.command:
|
||||
cmd: bash "{{ scripts_dir }}/generate-certs.sh" "{{ certs_dir }}"
|
||||
creates: "{{ certs_dir }}/ca.crt"
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 3 — Minikube
|
||||
# =======================================================================
|
||||
- name: Start and configure Minikube
|
||||
tags: [minikube]
|
||||
block:
|
||||
- name: Check if Minikube is running
|
||||
ansible.builtin.command: minikube status --format='{{.Host}}'
|
||||
register: minikube_status
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Start Minikube
|
||||
ansible.builtin.command: >
|
||||
minikube start
|
||||
--cpus={{ minikube_cpus }}
|
||||
--memory={{ minikube_memory }}
|
||||
--disk-size={{ minikube_disk_size }}
|
||||
--driver={{ minikube_driver }}
|
||||
--addons=default-storageclass,storage-provisioner
|
||||
when: minikube_status.rc != 0 or 'Running' not in minikube_status.stdout
|
||||
|
||||
- name: Enable ingress addon
|
||||
ansible.builtin.command: minikube addons enable ingress
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 4 — Kubernetes Namespaces
|
||||
# =======================================================================
|
||||
- name: Create Kubernetes namespaces
|
||||
tags: [namespaces]
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/namespaces/namespaces.yaml"
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 5 — TLS Secrets in Kubernetes
|
||||
# =======================================================================
|
||||
- name: Create TLS secrets
|
||||
tags: [secrets]
|
||||
block:
|
||||
- name: Delete existing elk-certificates secret (if any)
|
||||
ansible.builtin.command: kubectl delete secret elk-certificates -n elk --ignore-not-found
|
||||
changed_when: false
|
||||
|
||||
- name: Create elk-certificates secret in elk namespace
|
||||
ansible.builtin.command: >
|
||||
kubectl create secret generic elk-certificates -n elk
|
||||
--from-file=ca.crt={{ certs_dir }}/ca.crt
|
||||
--from-file=ca.key={{ certs_dir }}/ca.key
|
||||
--from-file=elasticsearch.crt={{ certs_dir }}/elasticsearch.crt
|
||||
--from-file=elasticsearch.key={{ certs_dir }}/elasticsearch.key
|
||||
--from-file=elasticsearch.p12={{ certs_dir }}/elasticsearch.p12
|
||||
--from-file=http.p12={{ certs_dir }}/elastic-http.p12
|
||||
--from-file=kibana.crt={{ certs_dir }}/kibana.crt
|
||||
--from-file=kibana.key={{ certs_dir }}/kibana.key
|
||||
--from-file=logstash.crt={{ certs_dir }}/logstash.crt
|
||||
--from-file=logstash.key={{ certs_dir }}/logstash.key
|
||||
--from-file=nginx.crt={{ certs_dir }}/nginx.crt
|
||||
--from-file=nginx.key={{ certs_dir }}/nginx.key
|
||||
--from-file=authentik.crt={{ certs_dir }}/authentik.crt
|
||||
--from-file=authentik.key={{ certs_dir }}/authentik.key
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 6 — MySQL (database namespace)
|
||||
# =======================================================================
|
||||
- name: Deploy MySQL
|
||||
tags: [mysql]
|
||||
block:
|
||||
- name: Apply MySQL manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/mysql/"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for MySQL to be ready
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=mysql
|
||||
-n database --timeout=180s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 7 — Elasticsearch
|
||||
# =======================================================================
|
||||
- name: Deploy Elasticsearch
|
||||
tags: [elasticsearch]
|
||||
block:
|
||||
- name: Apply Elasticsearch manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/elasticsearch/elasticsearch.yaml"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Elasticsearch to be ready
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=elasticsearch
|
||||
-n elk --timeout=300s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 8 — Elasticsearch post-setup
|
||||
# =======================================================================
|
||||
- name: Run Elasticsearch setup job
|
||||
tags: [es-setup]
|
||||
block:
|
||||
- name: Delete previous setup job (if any)
|
||||
ansible.builtin.command: kubectl delete job elasticsearch-setup -n elk --ignore-not-found
|
||||
changed_when: false
|
||||
|
||||
- name: Apply setup job
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/elasticsearch/setup-job.yaml"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for setup job completion
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=complete job/elasticsearch-setup
|
||||
-n elk --timeout=120s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 9 — Authentik SSO
|
||||
# =======================================================================
|
||||
- name: Deploy Authentik SSO
|
||||
tags: [authentik]
|
||||
block:
|
||||
- name: Apply Authentik manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/authentik/"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Authentik PostgreSQL
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=authentik-postgresql
|
||||
-n elk --timeout=120s
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Authentik Redis
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=authentik-redis
|
||||
-n elk --timeout=60s
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Authentik Server
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=authentik-server
|
||||
-n elk --timeout=180s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 10 — Kibana
|
||||
# =======================================================================
|
||||
- name: Deploy Kibana
|
||||
tags: [kibana]
|
||||
block:
|
||||
- name: Apply Kibana manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/kibana/"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Kibana to be ready
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=kibana
|
||||
-n elk --timeout=300s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 11 — Logstash
|
||||
# =======================================================================
|
||||
- name: Deploy Logstash
|
||||
tags: [logstash]
|
||||
block:
|
||||
- name: Apply Logstash manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/logstash/"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for Logstash to be ready
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=logstash
|
||||
-n elk --timeout=180s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 12 — NGINX Proxy
|
||||
# =======================================================================
|
||||
- name: Deploy NGINX reverse proxy
|
||||
tags: [nginx]
|
||||
block:
|
||||
- name: Apply NGINX manifests
|
||||
ansible.builtin.command: kubectl apply -f "{{ k8s_manifests_dir }}/nginx/"
|
||||
changed_when: false
|
||||
|
||||
- name: Wait for NGINX to be ready
|
||||
ansible.builtin.command: >
|
||||
kubectl wait --for=condition=ready pod -l app=nginx
|
||||
-n elk --timeout=60s
|
||||
changed_when: false
|
||||
|
||||
# =======================================================================
|
||||
# PHASE 13 — DNS / /etc/hosts
|
||||
# =======================================================================
|
||||
- name: Configure local DNS
|
||||
tags: [dns]
|
||||
block:
|
||||
- name: Get Minikube IP
|
||||
ansible.builtin.command: minikube ip
|
||||
register: minikube_ip
|
||||
changed_when: false
|
||||
|
||||
- name: Add kibana.elk.local to /etc/hosts
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: '.*kibana\.elk\.local.*'
|
||||
line: "{{ minikube_ip.stdout }} kibana.elk.local authentik.elk.local"
|
||||
state: present
|
||||
|
||||
# =======================================================================
|
||||
# FINAL — Summary
|
||||
# =======================================================================
|
||||
- name: Deployment summary
|
||||
tags: [always]
|
||||
block:
|
||||
- name: Get Minikube IP for summary
|
||||
ansible.builtin.command: minikube ip
|
||||
register: minikube_ip_final
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
- name: Print access information
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ ELK Stack Deployment Complete! ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ ║
|
||||
║ Minikube IP: {{ minikube_ip_final.stdout | default('N/A') }}
|
||||
║ ║
|
||||
║ Kibana (NGINX proxy): ║
|
||||
║ https://kibana.elk.local:30443 ║
|
||||
║ User: elastic / ElasticP@ss2024! ║
|
||||
║ ║
|
||||
║ Authentik Admin: ║
|
||||
║ https://authentik.elk.local:30944 ║
|
||||
║ User: akadmin / AdminP@ss2024! ║
|
||||
║ ║
|
||||
║ Elasticsearch: ║
|
||||
║ kubectl port-forward svc/elasticsearch 9200:9200 -n elk ║
|
||||
║ User: elastic / ElasticP@ss2024! ║
|
||||
║ ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
# =============================================================================
|
||||
# Teardown Playbook — Remove the entire ELK stack deployment
|
||||
# =============================================================================
|
||||
# Usage:
|
||||
# ansible-playbook -i inventory/hosts.yml playbooks/teardown.yml
|
||||
# =============================================================================
|
||||
|
||||
- name: Teardown ELK Stack
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Delete elk namespace (removes all ELK resources)
|
||||
ansible.builtin.command: kubectl delete namespace elk --ignore-not-found --timeout=120s
|
||||
changed_when: false
|
||||
|
||||
- name: Delete database namespace (removes MySQL)
|
||||
ansible.builtin.command: kubectl delete namespace database --ignore-not-found --timeout=120s
|
||||
changed_when: false
|
||||
|
||||
- name: Remove /etc/hosts entries
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/hosts
|
||||
regexp: '.*kibana\.elk\.local.*'
|
||||
state: absent
|
||||
|
||||
- name: Optionally stop Minikube
|
||||
ansible.builtin.command: minikube stop
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
when: stop_minikube | default(false) | bool
|
||||
|
||||
- name: Print teardown complete
|
||||
ansible.builtin.debug:
|
||||
msg: "ELK stack teardown complete. Run with -e stop_minikube=true to also stop Minikube."
|
||||
@@ -1,115 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# configure-authentik-oidc.sh
|
||||
# Configures Authentik with an OIDC Provider and Application for Kibana SSO
|
||||
# Run AFTER Authentik is fully started and accessible
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
AUTHENTIK_URL="${1:-http://localhost:9000}"
|
||||
BOOTSTRAP_TOKEN="${2:-bootstrap-token-elk-lab-2024}"
|
||||
KIBANA_URL="https://kibana.elk.local:30443"
|
||||
|
||||
AUTH_HEADER="Authorization: Bearer ${BOOTSTRAP_TOKEN}"
|
||||
CT="Content-Type: application/json"
|
||||
|
||||
echo "=== Configuring Authentik OIDC for Kibana ==="
|
||||
echo "Authentik URL: ${AUTHENTIK_URL}"
|
||||
|
||||
# Wait for Authentik
|
||||
echo ">>> Waiting for Authentik API..."
|
||||
until curl -sf "${AUTHENTIK_URL}/-/health/ready/" > /dev/null 2>&1; do
|
||||
echo " Waiting..."
|
||||
sleep 5
|
||||
done
|
||||
echo " Authentik is ready!"
|
||||
|
||||
# --- Step 1: Create a Certificate-Key Pair (optional, for signed JWTs) ---
|
||||
echo ">>> Creating certificate key pair..."
|
||||
CERT_RESP=$(curl -sf -X POST "${AUTHENTIK_URL}/api/v3/crypto/certificatekeypairs/generate/" \
|
||||
-H "${AUTH_HEADER}" -H "${CT}" \
|
||||
-d '{
|
||||
"common_name": "kibana-oidc-signing",
|
||||
"subject_alt_name": "kibana.elk.local",
|
||||
"validity_days": 365
|
||||
}' 2>/dev/null || echo '{}')
|
||||
CERT_ID=$(echo "$CERT_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('pk',''))" 2>/dev/null || echo "")
|
||||
echo " Certificate ID: ${CERT_ID:-skipped}"
|
||||
|
||||
# --- Step 2: Create Scope Mappings (if not already present) ---
|
||||
echo ">>> Checking scope mappings..."
|
||||
SCOPES_RESP=$(curl -sf "${AUTHENTIK_URL}/api/v3/propertymappings/scope/?ordering=scope_name" \
|
||||
-H "${AUTH_HEADER}" 2>/dev/null || echo '{"results":[]}')
|
||||
|
||||
# --- Step 3: Create OIDC Provider ---
|
||||
echo ">>> Creating OIDC Provider for Kibana..."
|
||||
PROVIDER_BODY=$(cat <<PROVIDER_JSON
|
||||
{
|
||||
"name": "Kibana OIDC Provider",
|
||||
"authorization_flow": "default-provider-authorization-implicit-consent",
|
||||
"client_type": "confidential",
|
||||
"client_id": "kibana",
|
||||
"client_secret": "kibana-client-secret-2024",
|
||||
"redirect_uris": "${KIBANA_URL}/api/security/oidc/callback",
|
||||
"signing_key": ${CERT_ID:+\"$CERT_ID\"}${CERT_ID:-null},
|
||||
"sub_mode": "user_username",
|
||||
"issuer_mode": "per_provider",
|
||||
"access_code_validity": "minutes=1",
|
||||
"access_token_validity": "minutes=5",
|
||||
"refresh_token_validity": "days=30"
|
||||
}
|
||||
PROVIDER_JSON
|
||||
)
|
||||
|
||||
PROVIDER_RESP=$(curl -sf -X POST "${AUTHENTIK_URL}/api/v3/providers/oauth2/" \
|
||||
-H "${AUTH_HEADER}" -H "${CT}" \
|
||||
-d "${PROVIDER_BODY}" 2>/dev/null || echo '{}')
|
||||
PROVIDER_ID=$(echo "$PROVIDER_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('pk',''))" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$PROVIDER_ID" ]; then
|
||||
echo " Provider may already exist, looking it up..."
|
||||
PROVIDER_ID=$(curl -sf "${AUTHENTIK_URL}/api/v3/providers/oauth2/?search=Kibana" \
|
||||
-H "${AUTH_HEADER}" | python3 -c "import sys,json; r=json.load(sys.stdin)['results']; print(r[0]['pk'] if r else '')" 2>/dev/null || echo "")
|
||||
fi
|
||||
echo " Provider ID: ${PROVIDER_ID}"
|
||||
|
||||
# --- Step 4: Create Application ---
|
||||
echo ">>> Creating Kibana Application..."
|
||||
APP_RESP=$(curl -sf -X POST "${AUTHENTIK_URL}/api/v3/core/applications/" \
|
||||
-H "${AUTH_HEADER}" -H "${CT}" \
|
||||
-d "{
|
||||
\"name\": \"Kibana\",
|
||||
\"slug\": \"kibana\",
|
||||
\"provider\": ${PROVIDER_ID},
|
||||
\"meta_launch_url\": \"${KIBANA_URL}\",
|
||||
\"meta_description\": \"ELK Stack - Kibana Dashboard\",
|
||||
\"policy_engine_mode\": \"any\"
|
||||
}" 2>/dev/null || echo '{}')
|
||||
APP_SLUG=$(echo "$APP_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get('slug',''))" 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$APP_SLUG" ]; then
|
||||
echo " Application may already exist."
|
||||
APP_SLUG="kibana"
|
||||
fi
|
||||
echo " Application slug: ${APP_SLUG}"
|
||||
|
||||
echo ""
|
||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||
echo "║ Authentik OIDC Configuration Complete! ║"
|
||||
echo "╠══════════════════════════════════════════════════════════════╣"
|
||||
echo "║ ║"
|
||||
echo "║ OIDC Provider: Kibana OIDC Provider ║"
|
||||
echo "║ Client ID: kibana ║"
|
||||
echo "║ Client Secret: kibana-client-secret-2024 ║"
|
||||
echo "║ Application: kibana ║"
|
||||
echo "║ ║"
|
||||
echo "║ Issuer URL: ║"
|
||||
echo "║ ${AUTHENTIK_URL}/application/o/kibana/ ║"
|
||||
echo "║ ║"
|
||||
echo "║ Endpoints: ║"
|
||||
echo "║ Authorization: .../application/o/authorize/ ║"
|
||||
echo "║ Token: .../application/o/token/ ║"
|
||||
echo "║ UserInfo: .../application/o/userinfo/ ║"
|
||||
echo "║ JWKS: .../application/o/kibana/jwks/ ║"
|
||||
echo "║ ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# generate-certs.sh — Generate a custom CA and TLS certificates for ELK stack
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
CERT_DIR="${1:-./certs}"
|
||||
DAYS_VALID=825
|
||||
CA_SUBJECT="/C=US/ST=State/L=City/O=ELK-Lab/OU=Infrastructure/CN=ELK-Lab-CA"
|
||||
DOMAIN="elk.local"
|
||||
|
||||
mkdir -p "${CERT_DIR}"
|
||||
|
||||
echo ">>> Generating Custom CA..."
|
||||
openssl genrsa -out "${CERT_DIR}/ca.key" 4096
|
||||
openssl req -x509 -new -nodes \
|
||||
-key "${CERT_DIR}/ca.key" \
|
||||
-sha256 -days ${DAYS_VALID} \
|
||||
-out "${CERT_DIR}/ca.crt" \
|
||||
-subj "${CA_SUBJECT}"
|
||||
|
||||
# --- Function to generate a certificate signed by the CA ---
|
||||
generate_cert() {
|
||||
local NAME="$1"
|
||||
local CN="$2"
|
||||
local SANS="$3"
|
||||
|
||||
echo ">>> Generating certificate for ${NAME} (CN=${CN})..."
|
||||
|
||||
openssl genrsa -out "${CERT_DIR}/${NAME}.key" 2048
|
||||
|
||||
cat > "${CERT_DIR}/${NAME}.cnf" <<SSLCNF
|
||||
[req]
|
||||
distinguished_name = req_dn
|
||||
req_extensions = v3_req
|
||||
prompt = no
|
||||
|
||||
[req_dn]
|
||||
C = US
|
||||
ST = State
|
||||
L = City
|
||||
O = ELK-Lab
|
||||
OU = ${NAME}
|
||||
CN = ${CN}
|
||||
|
||||
[v3_req]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth, clientAuth
|
||||
subjectAltName = ${SANS}
|
||||
SSLCNF
|
||||
|
||||
openssl req -new -nodes \
|
||||
-key "${CERT_DIR}/${NAME}.key" \
|
||||
-out "${CERT_DIR}/${NAME}.csr" \
|
||||
-config "${CERT_DIR}/${NAME}.cnf"
|
||||
|
||||
openssl x509 -req \
|
||||
-in "${CERT_DIR}/${NAME}.csr" \
|
||||
-CA "${CERT_DIR}/ca.crt" \
|
||||
-CAkey "${CERT_DIR}/ca.key" \
|
||||
-CAcreateserial \
|
||||
-out "${CERT_DIR}/${NAME}.crt" \
|
||||
-days ${DAYS_VALID} \
|
||||
-sha256 \
|
||||
-extensions v3_req \
|
||||
-extfile "${CERT_DIR}/${NAME}.cnf"
|
||||
|
||||
rm -f "${CERT_DIR}/${NAME}.csr" "${CERT_DIR}/${NAME}.cnf"
|
||||
}
|
||||
|
||||
# --- Elasticsearch ---
|
||||
generate_cert "elasticsearch" "elasticsearch" \
|
||||
"DNS:elasticsearch,DNS:elasticsearch.elk.svc.cluster.local,DNS:elasticsearch.elk.svc,DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
# --- Kibana ---
|
||||
generate_cert "kibana" "kibana" \
|
||||
"DNS:kibana,DNS:kibana.elk.svc.cluster.local,DNS:kibana.elk.svc,DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
# --- Logstash ---
|
||||
generate_cert "logstash" "logstash" \
|
||||
"DNS:logstash,DNS:logstash.elk.svc.cluster.local,DNS:logstash.elk.svc,DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
# --- NGINX ---
|
||||
generate_cert "nginx" "kibana.${DOMAIN}" \
|
||||
"DNS:kibana.${DOMAIN},DNS:nginx,DNS:nginx.elk.svc.cluster.local,DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
# --- Authentik ---
|
||||
generate_cert "authentik" "authentik.${DOMAIN}" \
|
||||
"DNS:authentik.${DOMAIN},DNS:authentik,DNS:authentik-server,DNS:authentik-server.elk.svc.cluster.local,DNS:localhost,IP:127.0.0.1"
|
||||
|
||||
# --- Create Elasticsearch PKCS12 keystore ---
|
||||
echo ">>> Creating Elasticsearch PKCS12 keystore..."
|
||||
openssl pkcs12 -export \
|
||||
-in "${CERT_DIR}/elasticsearch.crt" \
|
||||
-inkey "${CERT_DIR}/elasticsearch.key" \
|
||||
-CAfile "${CERT_DIR}/ca.crt" \
|
||||
-chain \
|
||||
-out "${CERT_DIR}/elasticsearch.p12" \
|
||||
-passout pass:changeit
|
||||
|
||||
# --- Create Elasticsearch HTTP PKCS12 keystore ---
|
||||
cp "${CERT_DIR}/elasticsearch.p12" "${CERT_DIR}/elastic-http.p12"
|
||||
|
||||
# --- Cleanup serial file ---
|
||||
rm -f "${CERT_DIR}/ca.srl"
|
||||
|
||||
echo ""
|
||||
echo "=== Certificates generated in ${CERT_DIR}/ ==="
|
||||
ls -la "${CERT_DIR}/"
|
||||
echo ""
|
||||
echo "CA certificate: ${CERT_DIR}/ca.crt"
|
||||
echo "CA private key: ${CERT_DIR}/ca.key"
|
||||
echo "Elasticsearch cert: ${CERT_DIR}/elasticsearch.crt"
|
||||
echo "Kibana cert: ${CERT_DIR}/kibana.crt"
|
||||
echo "Logstash cert: ${CERT_DIR}/logstash.crt"
|
||||
echo "NGINX cert: ${CERT_DIR}/nginx.crt"
|
||||
echo "Authentik cert: ${CERT_DIR}/authentik.crt"
|
||||
Reference in New Issue
Block a user