2026-10-13 23:07:35 +07:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# =============================================================================
|
|
|
|
|
# export-trino-ca.sh — segarkan pin CA TLS Trino milik panel.
|
|
|
|
|
#
|
|
|
|
|
# Trino menyajikan sertifikat **self-signed** dari `keystore.p12`
|
|
|
|
|
# (http-server.https.keystore.*). Setiap kali keystore diregenerasi — install.sh,
|
|
|
|
|
# generate-trino-keystore.sh, atau container Trino dibuat ulang — cert-nya
|
|
|
|
|
# berubah, sehingga pin CA panel (`.ca/trino.crt`) jadi basi dan SEMUA panggilan
|
|
|
|
|
# Trino HTTPS gagal dengan:
|
|
|
|
|
# DEPTH_ZERO_SELF_SIGNED_CERT
|
|
|
|
|
# → /api/query mengembalikan 500 "fetch failed"
|
|
|
|
|
# → kartu "Data Catalog" di SQL IDE tampil "gagal load catalog"
|
|
|
|
|
#
|
2026-10-14 01:20:29 +07:00
|
|
|
# Mode file 0644 (sertifikat PUBLIK, bukan secret) supaya terbaca oleh proses
|
|
|
|
|
# panel yang berjalan sebagai user LAIN di container (uid 1001) — dengan 0600
|
|
|
|
|
# panel di container mendapat "Permission denied" → CA dianggap tak ada.
|
|
|
|
|
#
|
2026-10-13 23:07:35 +07:00
|
|
|
# Script ini mengekspor cert Trino yang berlaku ke file pin, dengan backup, dan
|
|
|
|
|
# idempoten (tidak menulis bila sudah sinkron).
|
|
|
|
|
#
|
|
|
|
|
# Sumber cert:
|
|
|
|
|
# 1. endpoint live (default) — via `openssl s_client`; paling akurat karena
|
|
|
|
|
# persis cert yang harus dipercaya panel.
|
|
|
|
|
# 2. keystore.p12 — set TRINO_KEYSTORE (berguna saat endpoint belum hidup).
|
|
|
|
|
#
|
|
|
|
|
# Config via env (default cocok dgn deploy sicabe-doc & panel .env):
|
|
|
|
|
# TRINO_CA_HOST host:port Trino HTTPS (default: localhost:12443)
|
|
|
|
|
# TRINO_CA_SNI SNI server name (default: host dari TRINO_CA_HOST)
|
|
|
|
|
# TRINO_CA_FILE file pin CA panel (default: <repo>/.ca/trino.crt)
|
|
|
|
|
# TRINO_KEYSTORE path keystore.p12 (opsional; bila di-set, dipakai)
|
|
|
|
|
# TRINO_KEYSTORE_PASS password keystore (default: trino_ssl_dev)
|
|
|
|
|
#
|
|
|
|
|
# Contoh:
|
|
|
|
|
# ./scripts/export-trino-ca.sh
|
|
|
|
|
# TRINO_CA_HOST=trino.example.com:12443 ./scripts/export-trino-ca.sh
|
|
|
|
|
# TRINO_KEYSTORE=/path/sicabe-doc/deploy/config/trino/keystore.p12 \
|
|
|
|
|
# ./scripts/export-trino-ca.sh
|
|
|
|
|
#
|
|
|
|
|
# Setelah dijalankan: RESTART panel (koneksi TLS di-memoize per proses). Agent
|
|
|
|
|
# config tidak perlu restart — ia membaca file ini setiap request.
|
|
|
|
|
# =============================================================================
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
|
|
|
|
|
|
TRINO_CA_HOST="${TRINO_CA_HOST:-localhost:12443}"
|
|
|
|
|
TRINO_CA_SNI="${TRINO_CA_SNI:-${TRINO_CA_HOST%%:*}}"
|
|
|
|
|
TRINO_CA_FILE="${TRINO_CA_FILE:-$REPO_ROOT/.ca/trino.crt}"
|
|
|
|
|
TRINO_KEYSTORE="${TRINO_KEYSTORE:-}"
|
|
|
|
|
TRINO_KEYSTORE_PASS="${TRINO_KEYSTORE_PASS:-trino_ssl_dev}"
|
|
|
|
|
|
|
|
|
|
command -v openssl >/dev/null 2>&1 || { echo "ERROR: openssl tidak ditemukan di PATH" >&2; exit 1; }
|
|
|
|
|
|
|
|
|
|
TMP="$(mktemp)" # cert hasil ekspor
|
|
|
|
|
LIVE="$(mktemp)" # cert dari endpoint live (untuk cross-check)
|
|
|
|
|
trap 'rm -f "$TMP" "$LIVE"' EXIT
|
|
|
|
|
|
|
|
|
|
is_pem_cert() { [ -s "$1" ] && grep -q -- "-----BEGIN CERTIFICATE-----" "$1"; }
|
|
|
|
|
fp_of() { openssl x509 -in "$1" -noout -fingerprint -sha256 | cut -d= -f2 | tr -d ':'; }
|
|
|
|
|
|
|
|
|
|
# ── 1. Ambil cert ────────────────────────────────────────────────────────────
|
|
|
|
|
if [ -n "$TRINO_KEYSTORE" ]; then
|
|
|
|
|
[ -f "$TRINO_KEYSTORE" ] || { echo "ERROR: keystore tidak ditemukan: $TRINO_KEYSTORE" >&2; exit 1; }
|
|
|
|
|
echo "→ Mengekspor cert dari keystore: $TRINO_KEYSTORE"
|
|
|
|
|
# -legacy diperlukan OpenSSL 3 untuk PKCS#12 lama (RC2-40). Bila tidak
|
|
|
|
|
# didukung/berbeda, coba tanpa flag tersebut.
|
|
|
|
|
if ! openssl pkcs12 -in "$TRINO_KEYSTORE" -nokeys -clcerts \
|
|
|
|
|
-passin "pass:$TRINO_KEYSTORE_PASS" -legacy 2>/dev/null \
|
|
|
|
|
| openssl x509 -outform PEM > "$TMP" 2>/dev/null || ! is_pem_cert "$TMP"; then
|
|
|
|
|
openssl pkcs12 -in "$TRINO_KEYSTORE" -nokeys -clcerts \
|
|
|
|
|
-passin "pass:$TRINO_KEYSTORE_PASS" 2>/dev/null \
|
|
|
|
|
| openssl x509 -outform PEM > "$TMP" 2>/dev/null || true
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
echo "→ Mengambil cert dari endpoint live: https://$TRINO_CA_HOST"
|
|
|
|
|
echo | openssl s_client -connect "$TRINO_CA_HOST" -servername "$TRINO_CA_SNI" 2>/dev/null \
|
|
|
|
|
| openssl x509 -outform PEM > "$TMP" 2>/dev/null || true
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! is_pem_cert "$TMP"; then
|
|
|
|
|
echo "ERROR: gagal mengekspor sertifikat (sumber: ${TRINO_KEYSTORE:-https://$TRINO_CA_HOST})" >&2
|
|
|
|
|
[ -z "$TRINO_KEYSTORE" ] && echo " Pastikan Trino hidup & port HTTPS benar (TRINO_CA_HOST)." >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
NEW_FP="$(fp_of "$TMP")"
|
|
|
|
|
echo " subject : $(openssl x509 -in "$TMP" -noout -subject | sed 's/^subject=//')"
|
|
|
|
|
echo " sha256 : $NEW_FP"
|
|
|
|
|
|
|
|
|
|
# ── 2. Tulisan hanya bila berubah (idempoten) ────────────────────────────────
|
|
|
|
|
if [ -f "$TRINO_CA_FILE" ] && [ "$(fp_of "$TRINO_CA_FILE")" = "$NEW_FP" ]; then
|
|
|
|
|
echo "✓ $TRINO_CA_FILE sudah sinkron — tidak ada perubahan."
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
mkdir -p "$(dirname "$TRINO_CA_FILE")"
|
|
|
|
|
if [ -f "$TRINO_CA_FILE" ]; then
|
|
|
|
|
BAK="${TRINO_CA_FILE}.bak-$(date +%Y%m%d-%H%M%S)"
|
|
|
|
|
cp -p "$TRINO_CA_FILE" "$BAK"
|
|
|
|
|
echo "→ Backup pin lama: $BAK"
|
|
|
|
|
echo " (fingerprint lama: $(fp_of "$BAK"))"
|
|
|
|
|
fi
|
2026-10-14 01:20:29 +07:00
|
|
|
install -m 644 "$TMP" "$TRINO_CA_FILE"
|
2026-10-13 23:07:35 +07:00
|
|
|
echo "✓ Pin CA diperbarui: $TRINO_CA_FILE"
|
|
|
|
|
|
|
|
|
|
# ── 3. Cross-check dengan endpoint live (bila sumbernya keystore) ────────────
|
|
|
|
|
if [ -n "$TRINO_KEYSTORE" ]; then
|
|
|
|
|
if echo | openssl s_client -connect "$TRINO_CA_HOST" -servername "$TRINO_CA_SNI" 2>/dev/null \
|
|
|
|
|
| openssl x509 -outform PEM > "$LIVE" 2>/dev/null && is_pem_cert "$LIVE"; then
|
|
|
|
|
if [ "$(fp_of "$LIVE")" = "$NEW_FP" ]; then
|
|
|
|
|
echo "✓ Cocok dengan cert yang disajikan https://$TRINO_CA_HOST"
|
|
|
|
|
else
|
|
|
|
|
echo "WARN: cert keystore BERBEDA dari yang disajikan https://$TRINO_CA_HOST" >&2
|
|
|
|
|
echo " Restart Trino, lalu jalankan ulang script ini." >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
echo "! https://$TRINO_CA_HOST tidak bisa dihubungi — cross-check dilewati."
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
cat <<'EOF'
|
|
|
|
|
|
|
|
|
|
Langkah berikutnya:
|
|
|
|
|
• RESTART panel (Next.js) — koneksi TLS di-memoize per proses:
|
|
|
|
|
kill $(ss -ltnp | grep ':3000' | grep -oE 'pid=[0-9]+' | cut -d= -f2) && npm run dev
|
|
|
|
|
• Agent config TIDAK perlu restart (baca file ini setiap request).
|
|
|
|
|
• Uji cepat: POST /api/query {"query":"SHOW CATALOGS"} → harus 200.
|
|
|
|
|
EOF
|