#!/usr/bin/env bash # # Entrix — RDP/SSH/SFTP Bastion Gateway kurulum betiği (Ubuntu/Debian). # # Kullanım: # curl -fsSL https://install.entrix.com.tr | sudo bash # set -euo pipefail BASE_URL="${ENTRIX_BASE_URL:-https://install.entrix.com.tr}" INSTALL_DIR="${ENTRIX_DIR:-/opt/entrix}" HOSTNAME_CN="${ENTRIX_HOSTNAME:-}" LISTEN_PORT="${ENTRIX_PORT:-}" TIMEZONE="${ENTRIX_TIMEZONE:-}" ADMIN_USER="${ENTRIX_ADMIN_USER:-}" ADMIN_PW="${ENTRIX_ADMIN_PASSWORD:-}" SERVICE_USER="entrix" SERVICE_NAME="entrix" BIN_NAME="rdpjumpbox" BIN_PATH="$INSTALL_DIR/$BIN_NAME" CONF_DIR="$INSTALL_DIR/configs" DATA_DIR="$INSTALL_DIR/data" CONF_FILE="$CONF_DIR/config.yaml" ENV_FILE="$INSTALL_DIR/entrix.env" UNIT_FILE="/etc/systemd/system/${SERVICE_NAME}.service" if [ -t 1 ]; then B=$'\e[1m'; G=$'\e[32m'; Y=$'\e[33m'; R=$'\e[31m'; C=$'\e[36m'; N=$'\e[0m'; else B= G= Y= R= C= N=; fi say() { echo "${C}${B}==>${N} $*"; } ok() { echo " ${G}✓${N} $*"; } warn() { echo " ${Y}!${N} $*"; } die() { echo "${R}HATA:${N} $*" >&2; exit 1; } trap 'die "kurulum ${LINENO}. satırda kesildi"' ERR if [ -r /dev/tty ] && [ -w /dev/tty ]; then INTERACTIVE=1; else INTERACTIVE=0; fi ask() { local __v="$1" __q="$2" __d="$3" __a="" if [ -n "${!__v}" ]; then return 0; fi if [ "$INTERACTIVE" -eq 1 ]; then printf '%s' "$__q" > /dev/tty IFS= read -r __a < /dev/tty || __a="" fi if [ -z "$__a" ]; then __a="$__d"; fi printf -v "$__v" '%s' "$__a" } ask_secret() { local __v="$1" __q="$2" __a="" __b="" if [ -n "${!__v}" ]; then return 0; fi if [ "$INTERACTIVE" -eq 1 ]; then while :; do printf '%s' "$__q" > /dev/tty IFS= read -rs __a < /dev/tty || __a=""; printf '\n' > /dev/tty if [ -z "$__a" ]; then break; fi printf ' Parolayı tekrar girin: ' > /dev/tty IFS= read -rs __b < /dev/tty || __b=""; printf '\n' > /dev/tty if [ "$__a" = "$__b" ]; then break; fi printf ' Parolalar uyuşmadı, tekrar deneyin.\n' > /dev/tty done fi printf -v "$__v" '%s' "$__a" } banner() { echo "${C}${B}" echo " ███████ ███ ██ ████████ ██████ ██ ██ ██" echo " ██ ████ ██ ██ ██ ██ ██ ██ ██ " echo " █████ ██ ██ ██ ██ ██████ ██ ███ " echo " ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ " echo " ███████ ██ ████ ██ ██ ██ ██ ██ ██" echo "${N} RDP / SSH / SFTP Bastion Gateway — kurulum${N}" echo } banner [ "$(id -u)" -eq 0 ] || die "root gerekli — 'sudo' ile çalıştırın." command -v systemctl >/dev/null 2>&1 || die "systemd gerekli (Ubuntu/Debian)." command -v curl >/dev/null 2>&1 || die "curl gerekli." case "$(uname -m)" in x86_64|amd64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; *) die "desteklenmeyen mimari: $(uname -m) (amd64/arm64 destekleniyor)" ;; esac ok "sistem: $(. /etc/os-release 2>/dev/null && echo "$PRETTY_NAME" || echo Linux) · $ARCH" NEW_CONFIG=0; [ -f "$CONF_FILE" ] || NEW_CONFIG=1 FRESH=0; [ -f "$DATA_DIR/jumpbox.db" ] || FRESH=1 if { [ "$NEW_CONFIG" -eq 1 ] || [ "$FRESH" -eq 1 ]; } && [ "$INTERACTIVE" -eq 1 ]; then echo; say "Kurulum ayarları — Enter ile varsayılanı kabul edin:" fi if [ "$NEW_CONFIG" -eq 1 ]; then ask HOSTNAME_CN " • Sunucu adı (TLS sertifikası + erişim) [entrix]: " "entrix" ask LISTEN_PORT " • RDP portu [3389]: " "3389" ask TIMEZONE " • Zaman dilimi [Europe/Istanbul]: " "Europe/Istanbul" fi if [ "$FRESH" -eq 1 ]; then ask ADMIN_USER " • Yönetici kullanıcı adı [admin]: " "admin" ask_secret ADMIN_PW " • Yönetici parolası (boş = rastgele üretilir): " fi : "${HOSTNAME_CN:=entrix}"; : "${LISTEN_PORT:=3389}"; : "${TIMEZONE:=Europe/Istanbul}"; : "${ADMIN_USER:=admin}" if ! id "$SERVICE_USER" >/dev/null 2>&1; then useradd --system --home-dir "$INSTALL_DIR" --shell /usr/sbin/nologin "$SERVICE_USER" ok "servis kullanıcısı oluşturuldu: $SERVICE_USER" else ok "servis kullanıcısı mevcut: $SERVICE_USER" fi mkdir -p "$CONF_DIR" "$DATA_DIR" "$DATA_DIR/recordings" ok "dizinler hazır: $INSTALL_DIR" if ! command -v ffmpeg >/dev/null 2>&1; then say "ffmpeg kuruluyor (RDP kaydı için; başarısız olursa kayıt devre dışı kalır)" (apt-get update -qq && apt-get install -y -qq ffmpeg >/dev/null 2>&1 && ok "ffmpeg kuruldu") \ || warn "ffmpeg kurulamadı — RDP ekran kaydı çalışmayabilir (SSH kaydı etkilenmez)." else ok "ffmpeg mevcut" fi DL="$BASE_URL/rdpjumpbox-linux-$ARCH" say "uygulama indiriliyor: $DL" tmp="$(mktemp)" curl -fSL --retry 3 -o "$tmp" "$DL" || die "indirme başarısız: $DL" if curl -fsSL "$DL.sha256" -o "$tmp.sha" 2>/dev/null; then want="$(awk '{print $1}' "$tmp.sha")" got="$(sha256sum "$tmp" | awk '{print $1}')" [ "$want" = "$got" ] || die "SHA256 doğrulaması başarısız (beklenen $want, gelen $got)" ok "SHA256 doğrulandı" else warn "sha256 dosyası bulunamadı — bütünlük doğrulaması atlandı." fi install -m 0755 "$tmp" "$BIN_PATH" rm -f "$tmp" "$tmp.sha" ln -sf "$BIN_PATH" /usr/local/bin/entrix # kolay CLI: 'entrix audit verify' vb. ok "kuruldu: $BIN_PATH ($("$BIN_PATH" version 2>/dev/null || echo '?'))" if [ ! -f "$ENV_FILE" ]; then SECRET="$("$BIN_PATH" gen-secret 2>/dev/null | sed -n 's/^RDPJB_SECURITY_SECRET_KEY=//p')" [ -n "$SECRET" ] || SECRET="$(head -c32 /dev/urandom | base64)" umask 077 printf 'RDPJB_SECURITY_SECRET_KEY=%s\n' "$SECRET" > "$ENV_FILE" ok "kimlik-bilgisi şifreleme anahtarı üretildi (data'daki parolalar AES-256-GCM ile şifrelenir)" else ok "şifreleme anahtarı mevcut (korunuyor)" fi if [ ! -f "$CONF_FILE" ]; then cat > "$CONF_FILE" </dev/null ok "TLS sertifikası üretildi: CN=$HOSTNAME_CN (NLA kapalı; mstsc uyarı vermez)" else ok "TLS sertifikası mevcut (korunuyor)" fi set -a; . "$ENV_FILE"; set +a # RDPJB_SECURITY_SECRET_KEY'i migrate/useradd için yükle say "veritabanı hazırlanıyor (migrate)" "$BIN_PATH" migrate -config "$CONF_FILE" >/dev/null ok "migrate tamam" ADMIN_PW_RANDOM=0 if [ "$FRESH" -eq 1 ]; then if [ -z "$ADMIN_PW" ]; then ADMIN_PW="$(head -c32 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | cut -c1-20)" ADMIN_PW_RANDOM=1 fi RDPJB_USERADD_PASSWORD="$ADMIN_PW" "$BIN_PATH" useradd -config "$CONF_FILE" --admin --username "$ADMIN_USER" >/dev/null ok "ilk yönetici oluşturuldu: $ADMIN_USER" else ok "mevcut kurulum — yönetici/veri korundu" fi chown -R "$SERVICE_USER":"$SERVICE_USER" "$INSTALL_DIR" chmod 600 "$ENV_FILE" "$CONF_FILE" 2>/dev/null || true [ -f "$CONF_DIR/server.key" ] && chmod 600 "$CONF_DIR/server.key" || true ok "sahiplik ve izinler ayarlandı" cat > "$UNIT_FILE" </dev/null 2>&1 || true systemctl restart "$SERVICE_NAME" sleep 1 IP="$(hostname -I 2>/dev/null | awk '{print $1}')"; IP="${IP:-}" echo if systemctl is-active --quiet "$SERVICE_NAME"; then say "${G}Kurulum tamamlandı — servis çalışıyor.${N}" else warn "servis başlamadı; günlükler: journalctl -u ${SERVICE_NAME} -e" fi echo echo " ${B}Bağlan (Windows mstsc):${N} ${IP}:${LISTEN_PORT}" echo " .rdp dosyasına ekleyin: enablecredsspsupport:i:0 ve authentication level:i:0" echo if [ "$FRESH" -eq 1 ] && [ "$ADMIN_PW_RANDOM" -eq 1 ]; then echo " ${B}Yönetici girişi:${N} kullanıcı ${G}${ADMIN_USER}${N} parola ${G}${ADMIN_PW}${N}" echo " ${Y}Bu parolayı kaydedin — tekrar gösterilmez.${N} İlk girişte OTP (2FA) kurulur." elif [ "$FRESH" -eq 1 ]; then echo " ${B}Yönetici girişi:${N} kullanıcı ${G}${ADMIN_USER}${N} (belirlediğiniz parola)" echo " İlk girişte OTP (2FA) kurulur." else echo " ${B}Yönetici:${N} mevcut hesabınızla girin." fi echo echo " ${B}Servis yönetimi:${N}" echo " systemctl status ${SERVICE_NAME} · durum" echo " journalctl -u ${SERVICE_NAME} -f · canlı günlük" echo " systemctl restart ${SERVICE_NAME} · yeniden başlat" echo " entrix audit verify · denetim günlüğü bütünlüğü" echo echo " Yapılandırma: ${CONF_FILE} Veri: ${DATA_DIR}" echo