527 lines
15 KiB
Bash
Executable File
527 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Script de configuração interativa do Jitsi Meet para SGSE
|
||
# Este script facilita a configuração inicial do Jitsi no sistema SGSE
|
||
|
||
set -e
|
||
|
||
# Cores para output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Variáveis
|
||
DOMAIN=""
|
||
APP_ID=""
|
||
ROOM_PREFIX=""
|
||
USE_HTTPS=false
|
||
ACCEPT_SELF_SIGNED=false
|
||
JWT_SECRET=""
|
||
JWT_AUDIENCE=""
|
||
JWT_ISSUER=""
|
||
AMBIENTE=""
|
||
TEST_ONLY=false
|
||
VALIDATE_ONLY=false
|
||
NON_INTERACTIVE=false
|
||
|
||
# Função para imprimir mensagens
|
||
print_info() {
|
||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||
}
|
||
|
||
print_success() {
|
||
echo -e "${GREEN}✅ $1${NC}"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}❌ $1${NC}"
|
||
}
|
||
|
||
# Função para validar formato de domínio
|
||
validar_dominio() {
|
||
local dominio=$1
|
||
if [[ -z "$dominio" ]]; then
|
||
return 1
|
||
fi
|
||
|
||
# Padrão para localhost:porta
|
||
if [[ $dominio =~ ^(localhost|127\.0\.0\.1|0\.0\.0\.0)(:[0-9]+)?$ ]]; then
|
||
return 0
|
||
fi
|
||
|
||
# Padrão para FQDN
|
||
if [[ $dominio =~ ^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(:[0-9]+)?$ ]]; then
|
||
return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
# Função para validar App ID
|
||
validar_app_id() {
|
||
local app_id=$1
|
||
if [[ -z "$app_id" ]]; then
|
||
return 1
|
||
fi
|
||
|
||
if [[ $app_id =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
||
return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
# Função para validar JWT Secret
|
||
validar_jwt_secret() {
|
||
local secret=$1
|
||
if [[ -z "$secret" ]]; then
|
||
return 0 # Opcional
|
||
fi
|
||
|
||
if [[ ${#secret} -lt 16 ]]; then
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Função para testar conectividade
|
||
testar_conectividade() {
|
||
local dominio=$1
|
||
local use_https=$2
|
||
|
||
print_info "Testando conectividade com $dominio..."
|
||
|
||
# Extrair host e porta
|
||
local host=$(echo $dominio | cut -d: -f1)
|
||
local porta=$(echo $dominio | cut -d: -f2)
|
||
|
||
if [[ -z "$porta" ]]; then
|
||
if [[ "$use_https" == "true" ]]; then
|
||
porta=443
|
||
else
|
||
porta=80
|
||
fi
|
||
fi
|
||
|
||
local protocol="http"
|
||
if [[ "$use_https" == "true" ]]; then
|
||
protocol="https"
|
||
fi
|
||
|
||
local url="$protocol://$host:$porta/http-bind"
|
||
|
||
# Testar conexão
|
||
if command -v curl &> /dev/null; then
|
||
local response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$url" 2>&1 || echo "000")
|
||
if [[ "$response" == "200" ]] || [[ "$response" == "405" ]] || [[ "$response" == "000" ]]; then
|
||
# 405 é esperado (Method Not Allowed para GET em /http-bind)
|
||
print_success "Servidor acessível em $url"
|
||
return 0
|
||
else
|
||
print_warning "Servidor retornou status $response (pode ser normal para /http-bind)"
|
||
return 0
|
||
fi
|
||
elif command -v wget &> /dev/null; then
|
||
if wget --spider --timeout=10 "$url" 2>&1 | grep -q "200 OK\|405\|connected"; then
|
||
print_success "Servidor acessível em $url"
|
||
return 0
|
||
else
|
||
print_warning "Não foi possível verificar conectividade (wget)"
|
||
return 1
|
||
fi
|
||
else
|
||
print_warning "curl ou wget não encontrado. Pulando teste de conectividade."
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Função para validar certificado SSL
|
||
validar_certificado_ssl() {
|
||
local dominio=$1
|
||
|
||
if [[ ! "$dominio" =~ ^localhost ]]; then
|
||
print_info "Validando certificado SSL para $dominio..."
|
||
|
||
local host=$(echo $dominio | cut -d: -f1)
|
||
local porta=$(echo $dominio | cut -d: -f2)
|
||
|
||
if [[ -z "$porta" ]]; then
|
||
porta=443
|
||
fi
|
||
|
||
if command -v openssl &> /dev/null; then
|
||
local cert_info=$(echo | openssl s_client -connect "$host:$porta" -servername "$host" 2>&1 | grep -A 2 "Certificate chain\|Verify return code")
|
||
if echo "$cert_info" | grep -q "Verify return code: 0"; then
|
||
print_success "Certificado SSL válido"
|
||
return 0
|
||
else
|
||
print_warning "Certificado SSL não válido ou autoassinado"
|
||
return 1
|
||
fi
|
||
else
|
||
print_warning "openssl não encontrado. Pulando validação de certificado."
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Função para gerar JWT Secret
|
||
gerar_jwt_secret() {
|
||
if command -v openssl &> /dev/null; then
|
||
openssl rand -hex 32
|
||
elif [[ -r /dev/urandom ]]; then
|
||
head -c 32 /dev/urandom | base64 | tr -d '\n' | head -c 64
|
||
else
|
||
print_error "Não foi possível gerar JWT Secret. Instale openssl ou forneça manualmente."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Função para ler entrada do usuário
|
||
ler_entrada() {
|
||
local prompt=$1
|
||
local default=$2
|
||
local var_name=$3
|
||
|
||
if [[ "$NON_INTERACTIVE" == "true" ]]; then
|
||
if [[ -n "$default" ]]; then
|
||
eval "$var_name='$default'"
|
||
return
|
||
else
|
||
print_error "Modo não-interativo requer valor para: $prompt"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
local input
|
||
if [[ -n "$default" ]]; then
|
||
read -p "$(echo -e ${BLUE}$prompt${NC} [padrão: $default]): " input
|
||
eval "$var_name=\${input:-$default}"
|
||
else
|
||
read -p "$(echo -e ${BLUE}$prompt${NC}): " input
|
||
eval "$var_name='$input'"
|
||
fi
|
||
}
|
||
|
||
# Função para exibir ajuda
|
||
mostrar_ajuda() {
|
||
cat << EOF
|
||
Uso: $0 [OPÇÕES]
|
||
|
||
Script de configuração interativa do Jitsi Meet para SGSE.
|
||
|
||
OPÇÕES:
|
||
--ambiente NOME Especificar ambiente (desenvolvimento, staging, producao)
|
||
--domain DOMINIO Configurar domínio do servidor Jitsi
|
||
--app-id ID Configurar App ID
|
||
--jwt-secret SECRET Configurar JWT Secret (ou gerar automaticamente se não fornecido)
|
||
--room-prefix PREFIXO Configurar prefixo de sala
|
||
--use-https Usar HTTPS
|
||
--accept-self-signed Aceitar certificados autoassinados
|
||
--test-only Apenas testar configuração existente
|
||
--validate-only Apenas validar sem salvar
|
||
--non-interactive Modo não-interativo (para CI/CD)
|
||
--help Mostrar esta ajuda
|
||
|
||
EXEMPLOS:
|
||
# Modo interativo
|
||
$0
|
||
|
||
# Modo não-interativo
|
||
$0 --domain meet.example.com --app-id sgse-app --use-https
|
||
|
||
# Apenas validar
|
||
$0 --validate-only --domain meet.example.com
|
||
|
||
# Apenas testar
|
||
$0 --test-only
|
||
EOF
|
||
}
|
||
|
||
# Processar argumentos da linha de comando
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--ambiente)
|
||
AMBIENTE="$2"
|
||
shift 2
|
||
;;
|
||
--domain|--domínio)
|
||
DOMAIN="$2"
|
||
shift 2
|
||
;;
|
||
--app-id)
|
||
APP_ID="$2"
|
||
shift 2
|
||
;;
|
||
--jwt-secret)
|
||
JWT_SECRET="$2"
|
||
shift 2
|
||
;;
|
||
--room-prefix)
|
||
ROOM_PREFIX="$2"
|
||
shift 2
|
||
;;
|
||
--use-https)
|
||
USE_HTTPS=true
|
||
shift
|
||
;;
|
||
--accept-self-signed)
|
||
ACCEPT_SELF_SIGNED=true
|
||
shift
|
||
;;
|
||
--test-only)
|
||
TEST_ONLY=true
|
||
shift
|
||
;;
|
||
--validate-only)
|
||
VALIDATE_ONLY=true
|
||
shift
|
||
;;
|
||
--non-interactive)
|
||
NON_INTERACTIVE=true
|
||
shift
|
||
;;
|
||
--help|-h)
|
||
mostrar_ajuda
|
||
exit 0
|
||
;;
|
||
*)
|
||
print_error "Opção desconhecida: $1"
|
||
mostrar_ajuda
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Banner
|
||
echo -e "${BLUE}"
|
||
cat << "EOF"
|
||
╔═══════════════════════════════════════════════════════════╗
|
||
║ Configuração do Jitsi Meet para SGSE ║
|
||
╚═══════════════════════════════════════════════════════════╝
|
||
EOF
|
||
echo -e "${NC}"
|
||
|
||
# Modo apenas teste
|
||
if [[ "$TEST_ONLY" == "true" ]]; then
|
||
print_info "Modo de teste apenas. Validando configuração existente..."
|
||
# Aqui você pode adicionar lógica para testar configuração existente
|
||
# Por exemplo, buscar do banco de dados ou arquivo de configuração
|
||
exit 0
|
||
fi
|
||
|
||
# Coletar informações
|
||
if [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
print_info "Coletando informações de configuração..."
|
||
echo
|
||
fi
|
||
|
||
# Ambiente
|
||
if [[ -z "$AMBIENTE" ]]; then
|
||
ler_entrada "Ambiente (desenvolvimento, staging, producao)" "" AMBIENTE
|
||
fi
|
||
|
||
# Domínio
|
||
while [[ -z "$DOMAIN" ]] || ! validar_dominio "$DOMAIN"; do
|
||
if [[ -z "$DOMAIN" ]]; then
|
||
ler_entrada "Domínio do servidor Jitsi (ex: localhost:8443 ou meet.example.com)" "" DOMAIN
|
||
else
|
||
print_error "Domínio inválido: $DOMAIN"
|
||
DOMAIN=""
|
||
ler_entrada "Domínio do servidor Jitsi" "" DOMAIN
|
||
fi
|
||
done
|
||
|
||
# Detectar HTTPS automaticamente
|
||
if [[ "$DOMAIN" =~ :8443$ ]] || [[ "$DOMAIN" =~ ^[^:]+$ ]] && [[ ! "$DOMAIN" =~ ^localhost ]]; then
|
||
if [[ "$USE_HTTPS" != "true" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
read -p "$(echo -e ${BLUE}Usar HTTPS? (S/n)${NC}): " resposta
|
||
if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then
|
||
USE_HTTPS=true
|
||
fi
|
||
elif [[ -z "$USE_HTTPS" ]]; then
|
||
USE_HTTPS=true
|
||
fi
|
||
fi
|
||
|
||
# Aceitar certificados autoassinados
|
||
if [[ "$USE_HTTPS" == "true" ]] && [[ "$DOMAIN" =~ localhost ]]; then
|
||
if [[ "$ACCEPT_SELF_SIGNED" != "true" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
read -p "$(echo -e ${BLUE}Aceitar certificados autoassinados? (S/n)${NC}): " resposta
|
||
if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then
|
||
ACCEPT_SELF_SIGNED=true
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# App ID
|
||
while [[ -z "$APP_ID" ]] || ! validar_app_id "$APP_ID"; do
|
||
if [[ -z "$APP_ID" ]]; then
|
||
ler_entrada "App ID" "sgse-app" APP_ID
|
||
else
|
||
print_error "App ID inválido: $APP_ID (deve conter apenas letras, números, hífens e underscores)"
|
||
APP_ID=""
|
||
ler_entrada "App ID" "sgse-app" APP_ID
|
||
fi
|
||
done
|
||
|
||
# Room Prefix
|
||
if [[ -z "$ROOM_PREFIX" ]]; then
|
||
ler_entrada "Prefixo de sala" "sgse" ROOM_PREFIX
|
||
fi
|
||
|
||
# JWT Secret
|
||
if [[ -z "$JWT_SECRET" ]]; then
|
||
if [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
read -p "$(echo -e ${BLUE}Gerar JWT Secret automaticamente? (S/n)${NC}): " resposta
|
||
if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then
|
||
JWT_SECRET=$(gerar_jwt_secret)
|
||
print_success "JWT Secret gerado: ${JWT_SECRET:0:16}..."
|
||
else
|
||
ler_entrada "JWT Secret (deixe vazio para desabilitar JWT)" "" JWT_SECRET
|
||
fi
|
||
else
|
||
JWT_SECRET=$(gerar_jwt_secret)
|
||
fi
|
||
fi
|
||
|
||
# Validar JWT Secret se fornecido
|
||
if [[ -n "$JWT_SECRET" ]] && ! validar_jwt_secret "$JWT_SECRET"; then
|
||
print_error "JWT Secret deve ter no mínimo 16 caracteres"
|
||
exit 1
|
||
fi
|
||
|
||
# JWT Audience (opcional)
|
||
if [[ -z "$JWT_AUDIENCE" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
ler_entrada "JWT Audience (opcional, padrão: domínio)" "$DOMAIN" JWT_AUDIENCE
|
||
fi
|
||
|
||
# JWT Issuer (opcional)
|
||
if [[ -z "$JWT_ISSUER" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
ler_entrada "JWT Issuer (opcional, padrão: App ID)" "$APP_ID" JWT_ISSUER
|
||
fi
|
||
|
||
# Validações
|
||
print_info "Validando configuração..."
|
||
|
||
# Validar domínio
|
||
if ! validar_dominio "$DOMAIN"; then
|
||
print_error "Domínio inválido: $DOMAIN"
|
||
exit 1
|
||
fi
|
||
|
||
# Validar App ID
|
||
if ! validar_app_id "$APP_ID"; then
|
||
print_error "App ID inválido: $APP_ID"
|
||
exit 1
|
||
fi
|
||
|
||
# Validar JWT Secret
|
||
if [[ -n "$JWT_SECRET" ]] && ! validar_jwt_secret "$JWT_SECRET"; then
|
||
print_error "JWT Secret inválido (mínimo 16 caracteres)"
|
||
exit 1
|
||
fi
|
||
|
||
print_success "Validações básicas passaram"
|
||
|
||
# Testes de conectividade
|
||
if [[ "$VALIDATE_ONLY" != "true" ]]; then
|
||
print_info "Testando conectividade..."
|
||
if testar_conectividade "$DOMAIN" "$USE_HTTPS"; then
|
||
print_success "Conectividade OK"
|
||
else
|
||
print_warning "Não foi possível testar conectividade (servidor pode estar offline)"
|
||
fi
|
||
|
||
# Validar certificado SSL se HTTPS
|
||
if [[ "$USE_HTTPS" == "true" ]]; then
|
||
validar_certificado_ssl "$DOMAIN"
|
||
fi
|
||
fi
|
||
|
||
# Resumo
|
||
echo
|
||
print_info "Resumo da configuração:"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo " Ambiente: ${AMBIENTE:-padrão}"
|
||
echo " Domínio: $DOMAIN"
|
||
echo " App ID: $APP_ID"
|
||
echo " Prefixo de Sala: $ROOM_PREFIX"
|
||
echo " HTTPS: $USE_HTTPS"
|
||
echo " Cert. Autoassinado: $ACCEPT_SELF_SIGNED"
|
||
if [[ -n "$JWT_SECRET" ]]; then
|
||
echo " JWT Secret: ${JWT_SECRET:0:16}... (${#JWT_SECRET} caracteres)"
|
||
else
|
||
echo " JWT Secret: (não configurado)"
|
||
fi
|
||
if [[ -n "$JWT_AUDIENCE" ]]; then
|
||
echo " JWT Audience: $JWT_AUDIENCE"
|
||
fi
|
||
if [[ -n "$JWT_ISSUER" ]]; then
|
||
echo " JWT Issuer: $JWT_ISSUER"
|
||
fi
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
||
# Se apenas validar, sair aqui
|
||
if [[ "$VALIDATE_ONLY" == "true" ]]; then
|
||
print_success "Validação concluída"
|
||
exit 0
|
||
fi
|
||
|
||
# Confirmar antes de salvar
|
||
if [[ "$NON_INTERACTIVE" != "true" ]]; then
|
||
echo
|
||
read -p "$(echo -e ${BLUE}Salvar esta configuração? (S/n)${NC}): " confirmar
|
||
if [[ ! "$confirmar" =~ ^[Ss]$ ]] && [[ -n "$confirmar" ]]; then
|
||
print_info "Configuração cancelada pelo usuário"
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
# Gerar JSON de configuração
|
||
CONFIG_JSON=$(cat <<EOF
|
||
{
|
||
"domain": "$DOMAIN",
|
||
"appId": "$APP_ID",
|
||
"roomPrefix": "$ROOM_PREFIX",
|
||
"useHttps": $USE_HTTPS,
|
||
"acceptSelfSignedCert": $ACCEPT_SELF_SIGNED,
|
||
"ambiente": "${AMBIENTE:-}",
|
||
"jwtSecret": "${JWT_SECRET:-}",
|
||
"jwtAudience": "${JWT_AUDIENCE:-}",
|
||
"jwtIssuer": "${JWT_ISSUER:-}"
|
||
}
|
||
EOF
|
||
)
|
||
|
||
# Salvar em arquivo
|
||
CONFIG_FILE="jitsi-config-$(date +%Y%m%d-%H%M%S).json"
|
||
echo "$CONFIG_JSON" > "$CONFIG_FILE"
|
||
print_success "Configuração salva em: $CONFIG_FILE"
|
||
|
||
# Instruções finais
|
||
echo
|
||
print_info "Próximos passos:"
|
||
echo "1. Revise o arquivo de configuração: $CONFIG_FILE"
|
||
echo "2. Acesse o painel SGSE: TI > Configurações do Jitsi"
|
||
echo "3. Preencha os campos com os valores acima"
|
||
echo "4. Teste a conexão usando o botão 'Testar Conexão'"
|
||
echo "5. Salve a configuração no painel"
|
||
|
||
if [[ -n "$JWT_SECRET" ]]; then
|
||
echo
|
||
print_warning "IMPORTANTE: Guarde o JWT Secret em local seguro!"
|
||
print_warning "O JWT Secret não será exibido novamente."
|
||
fi
|
||
|
||
print_success "Configuração concluída!"
|