Untitled


SUBMITTED BY: Guest

DATE: Jan. 11, 2024, 11:22 p.m.

FORMAT: Text only

SIZE: 20.0 kB

HITS: 292

  1. #!/bin/bash
  2. # Por Tales A. Mendonça (talesam@gmail.com)
  3. # Faz a instalação da aplicação IHX Access Pro em Docker
  4. # Versão do script
  5. Ver="v1.8.6"
  6. # Definição de Cores
  7. CIN='\e[30;1m' # Cinza
  8. RED='\e[31;1m' # Vermelho
  9. GRE='\e[32;1m' # Verde
  10. YEL='\e[33;1m' # Amarelo
  11. BLU='\e[34;1m' # Azul
  12. ROS='\e[35;1m' # Rosa
  13. CYA='\e[36;1m' # Ciano
  14. NEG='\e[37;1m' # Negrito
  15. CUI='\e[40;31;5m' # Vermelho pisacando, aviso!
  16. STD='\e[m' # Fechamento de cor
  17. ### INÍCIO FUNÇÕES ###
  18. # Função pause
  19. pause(){
  20. read -p "$*"
  21. }
  22. ### Função Alerta Vermelho
  23. alertaVermelho() {
  24. echo -e "${RED}*${STD} ${NEG} $1 ${STD}"
  25. echo ""
  26. }
  27. ### Função Alerta Amarelo
  28. alertaAmarelo() {
  29. echo -e "${YEL}*${STD} ${NEG} $1 ${STD}"
  30. echo ""
  31. sleep 1
  32. }
  33. ### Função Alerta Verde
  34. alertaVerde() {
  35. echo -e "${GRE}*${STD} ${NEG} $1 ${STD}"
  36. echo ""
  37. sleep 1
  38. }
  39. ### Função Alerta Verde
  40. alertaAzul() {
  41. echo -e "${BLU}*${STD} ${NEG} $1 ${STD}"
  42. echo ""
  43. sleep 1
  44. }
  45. ### Função coleta de dados
  46. coletaDados() {
  47. # Este é um loop infinito que continuará até que seja quebrado com 'break'
  48. while : ; do
  49. # Solicitar entrada do usuário
  50. alertaAzul "Insira o nome do cliente:"
  51. read cliente
  52. # Definir o caminho para o diretório do cliente
  53. caminho="$HOME/Docker/IHX_Access_Pro/$cliente"
  54. # Converte a entrada do usuário para minúsculas
  55. cliente=${cliente,,}
  56. # Verificar se a entrada não está vazia
  57. if [ -z "$cliente" ]; then
  58. alertaAmarelo "O nome do cliente não pode ser vazio."
  59. else
  60. break # Se a entrada não estiver vazia, quebra o loop e continua o script
  61. fi
  62. done
  63. # Verificar se o diretório já existe
  64. if [ -d "$caminho" ]; then
  65. alertaAmarelo "Diretório $caminho já existe."
  66. else
  67. # Criar o diretório se ele não existir
  68. mkdir -p "$caminho"
  69. alertaVerde "Diretório $caminho criado com sucesso."
  70. fi
  71. # caminho para o arquivo .env
  72. envPath="$caminho/.env"
  73. # Encontra e configura a porta disponível
  74. if ! encontrarPortaDisponivel "$envPath"; then
  75. alertaVermelho "Erro ao encontrar uma porta disponível."
  76. exit 1
  77. fi
  78. # Escrever as variáveis no arquivo .env para o docker-compose.yml
  79. {
  80. echo "cliente=$cliente"
  81. echo "db_Container_Name=db_ihx_$cliente"
  82. echo "db_Root_Password=1hx@p4550rd"
  83. echo "db_Name=ihx_access_pro"
  84. echo "db_User=db_user"
  85. echo "db_Password=1hx@p4550rd"
  86. echo "app_Container_Name=ihx_$cliente"
  87. echo "network_Name=ihx-net_$cliente"
  88. } >> "$envPath"
  89. # Carregar arquivo .env
  90. source "$envPath"
  91. }
  92. # Função para encontrar uma porta disponível
  93. encontrarPortaDisponivel() {
  94. local envPath="$1" # Adiciona um argumento para o caminho do arquivo .env
  95. local basePort=33601 # Porta base para começar a busca
  96. local maxPort=34000 # Porta máxima que queremos verificar
  97. local port=$basePort
  98. # Loop para encontrar uma porta disponível
  99. while : ; do
  100. # Checa se a porta está em uso (necessário ter o net-tools instalado)
  101. if ! netstat -tuln | grep -q ":$port"; then
  102. # Porta está disponível
  103. alertaVerde "Porta disponível encontrada: $port"
  104. # Escreve a porta disponível no arquivo .env e verifica se foi bem-sucedido
  105. echo "porta_db=$port" >> "$envPath" && \
  106. alertaVerde "Porta escrita no arquivo .env com sucesso." || \
  107. { alertaVermelho "Falha ao escrever a porta no arquivo .env."; return 1; }
  108. # Adiciona a regra no firewall para permitir a porta encontrada (necessário ter permissões de superusuário)
  109. if ! sudo ufw allow $port/tcp; then
  110. alertaVermelho "Falha ao adicionar regra no firewall para a porta $port."
  111. return 1
  112. else
  113. alertaVerde "Regra no firewall adicionada com sucesso para a porta $port."
  114. return 0
  115. fi
  116. else
  117. # Porta está em uso, incrementa e tenta a próxima
  118. ((port++))
  119. if [ $port -ge $maxPort ]; then
  120. alertaVermelho "Não foi possível encontrar uma porta disponível."
  121. return 1
  122. fi
  123. fi
  124. done
  125. }
  126. ### Função para baixa os arquivos necessários
  127. arquivosNecessarios() {
  128. # Diretório temporário para extração dos arquivos baixados
  129. dirTmp="/tmp/IHX"
  130. rm -rf $dirTmp
  131. # Cria o diretório temporário
  132. mkdir -p $dirTmp
  133. # Nome do arquivo
  134. arquivo="docker-compose_v1.8.tar.bz2"
  135. # Baixa o arquivo
  136. wget -q https://cloud.talesam.org/s/zekHJye2ncwM4pk/download/$arquivo -P $dirTmp
  137. # Verifica se o arquivo foi baixado corretamente
  138. if [ ! -f "$dirTmp/$arquivo" ]; then
  139. alertaVermelho "Erro: O arquivo não foi baixado corretamente."
  140. exit 1
  141. fi
  142. # Extrai o arquivo
  143. tar -xvJf $dirTmp/$arquivo -C $caminho
  144. # Verifica se o arquivo foi extraído corretamente
  145. if [ $? -ne 0 ]; then
  146. alertaVermelho "Erro: Falha ao extrair o arquivo."
  147. exit 1
  148. else
  149. alertaVerde "Arquivos extraídos com sucesso para $caminho."
  150. fi
  151. }
  152. ### Função para instalar aplicação IHX
  153. instalarIHX() {
  154. # Limpa a tela
  155. clear
  156. # Chama a função para coleta de dados
  157. coletaDados
  158. # Chama a funçao para baixar os arquivos
  159. arquivosNecessarios
  160. # Inicia os Conteiners
  161. alertaAzul "Ativando todos os containers, aguarde..."
  162. # Deixa os conteiners rodando em segundo plano
  163. cd $caminho
  164. docker-compose up -d && sleep 1
  165. # Nomes dos contêineres a serem verificados
  166. containers=("$db_Container_Name")
  167. # Verifica a saúde dos contêineres
  168. for container in "${containers[@]}"; do
  169. statusSaude=""
  170. tentativasMax=100
  171. tentativas=0
  172. pontos=""
  173. while [[ "$statusSaude" != "healthy" && $tentativas -lt $tentativasMax ]]; do
  174. statusSaude=$(docker inspect --format='{{json .State.Health.Status}}' "$container" | tr -d '"')
  175. if [[ "$statusSaude" == "healthy" ]]; then
  176. alertaVerde "Contêiner $container saudável!"
  177. else
  178. pontos+="."
  179. printf " ${YEL}*${STD} ${NEG}Contêiner{STD} ${YEL}%-22s${STD} ${NEG}ainda está iniciando, aguardando$pontos${STD}\r" "$container"
  180. fi
  181. ((tentativas++))
  182. sleep 1
  183. done
  184. echo ""
  185. if [[ "$statusSaude" != "healthy" ]]; then
  186. alertaVermelho "Contêiner $container não ficou saudável após $tentativasMax tentativas."
  187. exit 1
  188. fi
  189. # O contêiner está saudável, executar criação de tabelas
  190. alertaAzul "Iniciando a criação das tabelas e importação do banco de dados no contêiner $app_Container_Name..."
  191. docker exec $app_Container_Name bash -c "source /ihx_access_pro/env/bin/activate && python2 /ihx_access_pro/manage.py syncdb --noinput"
  192. if [[ $? -eq 0 ]]; then
  193. alertaVerde "Tabelas criadas e sincronizadas com sucesso!"
  194. sqlFileS=("funcoes.sql" "inserts.sql" "updates.sql")
  195. sucessoImportacao=true
  196. for sqlFile in "${sqlFileS[@]}"; do
  197. alertaAzul "Copiando e importando $sqlFile"
  198. docker cp $caminho/Config/db/$sqlFile $db_Container_Name:/tmp/$sqlFile
  199. docker exec $db_Container_Name mysql -u$db_User -p$db_Password ihx_access_pro -e "source /tmp/$sqlFile"
  200. if [[ $? -ne 0 ]]; then
  201. alertaVermelho "Falha ao importar $sqlFile"
  202. sucessoImportacao=false
  203. break
  204. else
  205. alertaVerde "$sqlFile importado com sucesso!"
  206. fi
  207. done
  208. else
  209. alertaVermelho "Falha ao criar tabelas ou importar banco de dados!"
  210. exit 1
  211. fi
  212. done
  213. # Chama a função pause
  214. pause " Tecle [Enter] para voltar ao menu..." && sleep 1 ; clear
  215. }
  216. ### Função para instalar certificado SSL
  217. instalarCertificado() {
  218. # Limpa a tela
  219. clear
  220. # Listar os Diretórios
  221. baseDir="$HOME/Docker/IHX_Access_Pro/"
  222. IFS=$'\n' read -d '' -r -a dirArray < <(ls -d "$baseDir"*/ && printf '\0')
  223. # Exibir o Menu
  224. alertaAzul "Escolha onde deseja instalar o certificado SSL:"
  225. for i in "${!dirArray[@]}"; do
  226. dirName=$(basename "${dirArray[$i]}")
  227. echo -e "${BLU}$((i + 1)))${STD} $dirName"
  228. done
  229. # Adicionada a opção de voltar
  230. echo -e "${ROS}$(( ${#dirArray[@]} + 1 )))${STD} Voltar ao menu principal"
  231. # Seleção do Usuário
  232. echo ""
  233. read -p "Escolha um número: " choice
  234. # Se o usuário escolher 'Voltar ao menu principal'
  235. if [ "$choice" -eq "$(( ${#dirArray[@]} + 1 ))" ]; then
  236. return
  237. fi
  238. cliente=$(basename "${dirArray[$((choice - 1))]}")
  239. # Define o caminho para o diretório do cliente
  240. caminho="$HOME/Docker/IHX_Access_Pro/$cliente"
  241. # Desativando contêineres para gerar e importar das chaves e certificados SSL
  242. alertaAzul "Desativando os contêineres para gerar e importar as chaves e certificados SSL, aguarde..."
  243. if ! cd "$caminho" || ! docker-compose down; then
  244. alertaVermelho "Falha ao desativar os contêineres."
  245. exit 1
  246. fi
  247. # Define o diretório para armazenar as chaves SSL
  248. sslKeyDir="$caminho/mysql_keys"
  249. # Cria o diretório para armazenar as chaves SSL, se não existir
  250. if ! mkdir -p "$sslKeyDir"; then
  251. alertaVermelho "Erro ao criar o diretório $sslKeyDir"
  252. exit 1
  253. fi
  254. # Modifica a propriedade do diretório para o usuário ihx e o grupo ihx
  255. if ! sudo chown ihx:ihx "$sslKeyDir"; then
  256. alertaVermelho "Erro ao mudar a propriedade do diretório $sslKeyDir para ihx:ihx"
  257. exit 1
  258. fi
  259. # Gera uma senha randômica
  260. senhaChave=$(openssl rand -base64 48)
  261. echo "$senhaChave" > "$sslKeyDir/senha.txt"
  262. chmod 600 "$sslKeyDir/senha.txt"
  263. # Gera a chave e o certificado do servidor
  264. if ! openssl req -x509 -newkey rsa:2048 -keyout "$sslKeyDir/server-key-enc.pem" \
  265. -out "$sslKeyDir/server-cert.pem" \
  266. -subj "/C=BR/ST=MG/L=Juiz de Fora/O=IHX Sistema/OU=Tecnologia/CN=server/emailAddress=contato@ihxsistema.com.br" \
  267. -passout pass:"$senhaChave"; then
  268. alertaVermelho "Erro ao gerar a chave e certificado do servidor."
  269. exit 1
  270. else
  271. alertaVerde "Chave e o certificado do servidor gerados com sucesso!"
  272. fi
  273. # Decodifica a chave do servidor
  274. if ! openssl rsa -in "$sslKeyDir/server-key-enc.pem" -out "$sslKeyDir/server-key.pem" \
  275. -passin pass:"$senhaChave" -passout pass:"$senhaChave"; then
  276. alertaVermelho "Erro ao decodificar chave servidor."
  277. exit 1
  278. else
  279. alertaVerde "Chave do servidor decodificada com sucesso!"
  280. fi
  281. # Gera a chave e o certificado do cliente
  282. if ! openssl req -x509 -newkey rsa:2048 -keyout "$sslKeyDir/client-key-enc.pem" \
  283. -out "$sslKeyDir/client-cert.pem" \
  284. -subj "/C=BR/ST=MG/L=Juiz de Fora/O=IHX Sistema/OU=Tecnologia/CN=client/emailAddress=contato@ihxsistema.com.br" \
  285. -passout pass:"$senhaChave"; then
  286. alertaVermelho "Erro ao gerar a chave e certificado do cliente."
  287. exit 1
  288. else
  289. alertaVerde "Chave e o certificado do cliente gerados com sucesso!"
  290. fi
  291. # Decodifica a chave do cliente
  292. if ! openssl rsa -in "$sslKeyDir/client-key-enc.pem" -out "$sslKeyDir/client-key.pem" \
  293. -passin pass:"$senhaChave" -passout pass:"$senhaChave"; then
  294. alertaVermelho "Erro ao decodificar chave cliente."
  295. exit 1
  296. else
  297. alertaVerde "Chave do cliente decodificada com sucesso!"
  298. fi
  299. # Combina os certificados de cliente e servidor no arquivo de certificados CA
  300. if ! cat "$sslKeyDir/server-cert.pem" "$sslKeyDir/client-cert.pem" > "$sslKeyDir/ca-cert.pem"; then
  301. alertaVermelho "Erro ao combinar certificado do cliente e servidor no arquivo de certificados CA."
  302. exit 1
  303. else
  304. alertaVerde "Certificado do cliente e servidor combinados no arquivo de certificados CA com sucesso!"
  305. fi
  306. # Verifica o Certificado do Servidor
  307. if ! openssl verify -CAfile "$sslKeyDir/ca-cert.pem" "$sslKeyDir/server-cert.pem"; then
  308. alertaVermelho "Erro ao verificar certificado do servidor."
  309. exit 1
  310. else
  311. alertaVerde "Certificado do servidor verificado com sucesso!"
  312. fi
  313. # Verifica o Certificado do Cliente
  314. if ! openssl verify -CAfile "$sslKeyDir/ca-cert.pem" "$sslKeyDir/client-cert.pem"; then
  315. alertaVermelho "Erro ao verificar certificado do cliente."
  316. exit 1
  317. else
  318. alertaVerde "Certificado do cliente verificado com sucesso!"
  319. fi
  320. # Substituição do arquivo custom_ssl.cnf pelo arquivo custom.cnf
  321. alertaAzul "Substituindo o arquivo custom_ssl.cnf pelo arquivo custom.cnf..."
  322. if ! cp -f "$caminho/Config/custom_ssl.cnf" "$caminho/Config/custom.cnf"; then
  323. alertaVermelho "Erro ao realizar a substituição do arquivo custom.cnf."
  324. exit 1
  325. else
  326. alertaVerde "Substituição do arquivo custom.cnf realizada com sucesso!"
  327. fi
  328. # Remove as chaves codificadas para garantir a segurança
  329. alertaAzul "Removendo as chaves codificadas..."
  330. if ! rm -f "$sslKeyDir/client-key-enc.pem" "$sslKeyDir/server-key-enc.pem"; then
  331. alertaVermelho "Erro ao remover as chaves codificadas."
  332. exit 1
  333. else
  334. alertaVerde "Chaves codificadas removidas com sucesso!"
  335. fi
  336. # Obtém a data atual no formato AAAA-MM-DD
  337. dataAtual=$(date +%F)
  338. # Nome do arquivo zip seguindo o padrão keys_data_cliente.zip
  339. nomeArquivoZip="keys_${dataAtual}_${cliente}.zip"
  340. # Compacta os arquivos especificados em um arquivo .zip
  341. alertaAzul "Compactando as chaves..."
  342. if zip -j "$sslKeyDir/$nomeArquivoZip" \
  343. "$sslKeyDir/ca-cert.pem" \
  344. "$sslKeyDir/client-cert.pem" \
  345. "$sslKeyDir/client-key.pem"; then
  346. alertaVerde "Chaves compactadas com sucesso no arquivo $nomeArquivoZip."
  347. # Altera a propriedade do arquivo zip para o usuário ihx e o grupo ihx
  348. if sudo chown ihx:ihx "$sslKeyDir/$nomeArquivoZip"; then
  349. alertaVerde "Propriedade do arquivo $nomeArquivoZip alterada para ihx:ihx com sucesso."
  350. else
  351. alertaVermelho "Erro ao alterar a propriedade do arquivo $nomeArquivoZip."
  352. exit 1
  353. fi
  354. else
  355. alertaVermelho "Erro ao compactar as chaves."
  356. exit 1
  357. fi
  358. # Define os detalhes de login do Nextcloud
  359. nextcloudUser='talesam@gmail.com'
  360. nextcloudPass='nmYiiahisDA5653' # Substitua MINHA_SENHA pela sua senha real
  361. nextcloudURL="https://cloud.talesam.org/remote.php/dav/files/$nextcloudUser/"
  362. # O caminho completo da pasta no Nextcloud onde o arquivo será salvo
  363. # Os espaços e caracteres especiais são codificados para URL
  364. nextcloudDirPath="Servidor/Docker/Fran%C3%A7ois/IHX%20Access%20Pro/Keys"
  365. # Caminho local do arquivo que deseja enviar
  366. localFilePath="$sslKeyDir/$nomeArquivoZip"
  367. # Nome do arquivo no Nextcloud, incluindo o caminho da pasta onde deve ser salvo
  368. nextcloudFilePath="$nextcloudDirPath/$nomeArquivoZip"
  369. # Envia o arquivo para o Nextcloud e captura a resposta HTTP
  370. alertaAzul "Enviando o arquivo com as keys para o Nextcloud..."
  371. response=$(curl -w "%{http_code}" -u "$nextcloudUser:$nextcloudPass" -T "$localFilePath" "$nextcloudURL$nextcloudFilePath" -o /dev/null -s)
  372. # Verifica se o upload foi bem-sucedido analisando o código de resposta HTTP
  373. if [ "$response" -eq 201 ]; then
  374. alertaVerde "Arquivo enviado para o Nextcloud com sucesso!!"
  375. elif [ "$response" -eq 204 ]; then
  376. alertaVerde "Arquivo substituído com sucesso no Nextcloud."
  377. else
  378. alertaVermelho "Erro ao enviar arquivo para o Nextcloud: HTTP status $response."
  379. exit 1
  380. fi
  381. # Iniciar os contêineres
  382. alertaAzul "Iniciando os contêineres com SSL ativo no banco de dados..."
  383. if ! cd "$caminho" || ! docker-compose up -d; then
  384. alertaVermelho "Erro ao iniciar contêineres."
  385. exit 1
  386. else
  387. alertaVerde "Contêineres iniciados com sucesso!"
  388. fi
  389. # Chama a função pause
  390. pause " Tecle [Enter] para voltar ao menu..." && sleep 1 && clear
  391. }
  392. ### Função para remover uma aplicação
  393. removerAplicacao() {
  394. # Limpa a tela
  395. clear
  396. # Listar os Diretórios
  397. baseDir="$HOME/Docker/IHX_Access_Pro/"
  398. IFS=$'\n' read -d '' -r -a dirArray < <(ls -d "$baseDir"*/ && printf '\0')
  399. # Exibir o Menu
  400. alertaAzul "Escolha a aplicação que deseja remover:"
  401. for i in "${!dirArray[@]}"; do
  402. dirName=$(basename "${dirArray[$i]}")
  403. echo -e "${BLU}$((i + 1)))${STD} $dirName"
  404. done
  405. # Adicionada a opção de voltar
  406. echo -e "${ROS}$(( ${#dirArray[@]} + 1 )))${STD} Voltar ao menu principal"
  407. # Seleção do Usuário
  408. echo ""
  409. read -p "Escolha um número: " choice
  410. # Se o usuário escolher 'Voltar ao menu principal'
  411. if [ "$choice" -eq "$(( ${#dirArray[@]} + 1 ))" ]; then
  412. return
  413. fi
  414. cliente=$(basename "${dirArray[$((choice - 1))]}")
  415. # Define o caminho do diretório do cliente
  416. caminho="$HOME/Docker/IHX_Access_Pro/$cliente"
  417. # Entra no diretório do cliente
  418. if ! cd "$caminho"; then
  419. alertaVermelho "Erro ao entrar no diretório $caminho."
  420. exit 1
  421. fi
  422. # Desativa a aplicação
  423. alertaAzul "Desativando a aplicação para ser removida..."
  424. if ! docker-compose down; then
  425. alertaVermelho "Erro ao desativar a aplicação com docker-compose down."
  426. exit 1
  427. else
  428. alertaVerde "Aplicação desativada com sucesso."
  429. fi
  430. # Lê a porta que estava em uso a partir do arquivo .env
  431. if [ -f ".env" ]; then
  432. source .env
  433. porta=${porta_db:-}
  434. if [ -z "$porta" ]; then
  435. alertaVermelho "Porta não definida no arquivo .env."
  436. exit 1
  437. fi
  438. else
  439. alertaVermelho "Arquivo .env não encontrado. Não é possível determinar a porta para bloquear no firewall."
  440. exit 1
  441. fi
  442. # Retorna ao diretório anterior
  443. cd - > /dev/null 2>&1 || { alertaVermelho "Erro ao retornar ao diretório anterior."; return 1; }
  444. # Remove o diretório da aplicação
  445. if ! sudo rm -rf "$caminho"; then
  446. alertaVermelho "Erro ao remover o diretório $caminho."
  447. exit 1
  448. else
  449. alertaVerde "Diretório $caminho removido com sucesso."
  450. fi
  451. # Bloqueia a porta no firewall
  452. if ! sudo ufw delete allow "$porta/tcp"; then
  453. alertaVermelho "Erro ao bloquear a porta $porta no firewall."
  454. exit 1
  455. else
  456. alertaVerde "Porta $porta bloqueada no firewall com sucesso."
  457. fi
  458. alertaVerde "Aplicação removida e porta bloqueada com sucesso."
  459. # Chama a função pause
  460. pause " Tecle [Enter] para voltar ao menu..."
  461. }
  462. ### FIM FUNÇÕES ###
  463. # ------- MENU -------
  464. # Mostra o menu
  465. while true; do
  466. clear
  467. echo -e " ${BLU}SCRIPT DE INSTALAÇÃO DO IHX ACCESS PRO -${STD} ${YEL}${Ver}${STD}"
  468. echo ""
  469. echo ""
  470. echo -e " ${BLU}1) Instalar aplicação IHX${STD}"
  471. echo -e " ${GRE}2) Instalar certificado${STD}"
  472. echo -e " ${RED}3) Remover aplicação IHX${STD}"
  473. echo -e " ${YEL}0) Sair${STD}"
  474. echo ""
  475. read -p " Escolha uma opção: " escolha
  476. case $escolha in
  477. 1) instalarIHX ;;
  478. 2) instalarCertificado ;;
  479. 3) removerAplicacao ;;
  480. 0) exit ;;
  481. *) alertaAmarelo "Opção inválida" ;;
  482. esac
  483. done

comments powered by Disqus