diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 0000000..456d505 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,172 @@ +# Guia de Implantação - DNSBlock + +Este guia descreve os passos para implantar a aplicação DNSBlock em um ambiente de produção. + +## Pré-requisitos + +- Docker instalado +- Docker Compose instalado +- Git instalado (para clonar o repositório) + +## Passos para Instalação + +### 1. Clonar o Repositório + +Clone o repositório da aplicação para o diretório desejado no servidor: + +```bash +git clone dnsblock +cd dnsblock +``` + +### 2. Configurar Variáveis de Ambiente + +Crie o arquivo `.env` a partir do exemplo fornecido: + +```bash +cp .env.example .env +``` + +Edite o arquivo `.env` e ajuste as configurações para o ambiente de produção, **especialmente as senhas e a URL da aplicação**: + +```bash +nano .env +``` + +**Configurações Importantes:** +- `DB_HOST`: Mantenha como `db` (nome do serviço no docker-compose) +- `DB_ROOT_PASSWORD`: Defina uma senha forte para o root do MySQL +- `DB_PASSWORD`: Defina uma senha forte para o usuário da aplicação +- `APP_URL`: A URL pública onde a aplicação será acessada (ex: `https://painel.seudominio.com`) +- `JWT_SECRET`: Gere uma string aleatória e segura para assinar os tokens JWT + +### 3. Inicializar os Containers + +Execute o Docker Compose para construir e iniciar os serviços em segundo plano: + +```bash +docker-compose up -d --build +``` + +### 4. Inicializar o Banco de Dados + +A primeira vez que o container do banco de dados sobe, ele pode estar vazio. Você precisa importar o esquema do banco de dados. + +Copie o arquivo de esquema para dentro do container e execute a importação: + +```bash +# Aguarde alguns segundos para o banco de dados inicializar completamente + +# Importar o esquema +docker exec -i dnsblock-db mysql -u root -p dnsblock < database/schema.sql +``` + +*Nota: Substitua `` pela senha definida no `.env`.* + +### 5. Criar Usuário Administrativo + +O banco de dados inicia vazio. Você tem duas opções para criar o primeiro usuário: + +**Opção A: Importar dados de exemplo (Seeds)** +Isso criará um usuário `admin@dnsblock.com.br` com senha `admin123`. +```bash +docker exec -i dnsblock-db mysql -u root -p dnsblock < database/seeds.sql +``` + +**Opção B: Criar usuário manualmente** +Se preferir criar um usuário específico: + +1. Acesse o banco de dados: + ```bash + docker exec -it dnsblock-db mysql -u root -p dnsblock + ``` +2. Execute o comando SQL (substitua os valores): + ```sql + -- A senha deve ser um hash Bcrypt. + -- Para 'admin123', o hash é: $2y$10$MKGTx67.xKf55GJ98R2AoOZPJX/p.3xEeBywIbvJ4nM5lCZazzCly + + INSERT INTO users (name, email, password, role) VALUES + ('Seu Nome', 'seu@email.com', '$2y$10$MKGTx67.xKf55GJ98R2AoOZPJX/p.3xEeBywIbvJ4nM5lCZazzCly', 'admin'); + ``` + +### 6. Configurar Permissões (Se necessário) + +Certifique-se de que o servidor web tem permissão de escrita nos diretórios de log ou cache, se houver. No contexto do Docker, isso geralmente é tratado dentro do container, mas verifique se há volumes mapeados que precisam de permissão no host. + +### 7. Acessar a Aplicação + +A aplicação estará rodando na porta definida no `docker-compose.yml` (padrão: 8001). + +- Acesse: `http://:8001` + +### 8. (Recomendado) Configurar Proxy Reverso com SSL + +Para produção, é altamente recomendado usar um proxy reverso (como Nginx ou Traefik) na frente da aplicação para gerenciar o SSL (HTTPS). + +Exemplo de configuração básica do Nginx (no host): + +```nginx +server { + listen 80; + server_name painel.seudominio.com; + + location / { + proxy_pass http://localhost:8001; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +## Comandos Úteis + +- **Parar aplicação**: `docker-compose down` +- **Ver logs**: `docker-compose logs -f` +- **Reiniciar aplicação**: `docker-compose restart` + +## Otimização e Segurança + +### Arquivos Desnecessários (Agent, Código Fonte, etc.) + +Ao clonar o repositório completo (`git clone`), você baixa todo o histórico e arquivos de desenvolvimento (como a pasta `agent/`). **Isso é normal e esperado** neste método de deploy simples. + +No entanto, criamos um arquivo `.dockerignore` que garante que **apenas os arquivos necessários para a aplicação web** sejam copiados para dentro do container Docker. + +Isso significa que: +1. A pasta `agent/` e outros arquivos de desenvolvimento **NÃO** estarão rodando dentro do container. +2. O container de produção será leve e seguro. +3. Os arquivos "extras" ficarão apenas na pasta do host, sem afetar a aplicação. + +### Método Avançado (Sem git clone no servidor) + +Se você quiser evitar ter o código fonte no servidor de produção, a abordagem recomendada é: + +1. **Build Local**: Construa a imagem Docker na sua máquina ou CI/CD. + ```bash + docker build -t seu-usuario/dnsblock-app:latest . + ``` +2. **Push**: Envie a imagem para um registro (Docker Hub, AWS ECR, etc.). + ```bash + docker push seu-usuario/dnsblock-app:latest + ``` +3. **Deploy**: No servidor, copie apenas o `docker-compose.yml` e o `.env`, e ajuste a imagem para usar a versão do registro. + ```yaml + # docker-compose.yml + services: + app: + image: seu-usuario/dnsblock-app:latest + # ... resto da configuração + ``` + +## Solução de Problemas + +### Senhas com Caracteres Especiais (`$`) + +Se sua senha contiver o caractere `$` (cifrão), o Docker Compose tentará interpretar o que vem a seguir como uma variável. Para evitar isso, você deve escapar o `$` usando `$$`. + +**Exemplo:** +- Senha original: `Minha$Senha` +- No arquivo `.env`: `DB_PASS=Minha$$Senha` + diff --git a/README.md b/README.md index 36a8aa1..3be1c43 100644 --- a/README.md +++ b/README.md @@ -18,36 +18,13 @@ Sistema SaaS completo para gerenciamento de ordens judiciais de bloqueio de dom - **Banco de Dados**: MySQL 8.0 - **Agente**: Python 3.11+ -## 📦 Instalação +## 📦 Instalação e Deploy -### 1. Requisitos -- Docker e Docker Compose -- Python 3.11+ (para o agente, caso rode fora do Docker) +Para instruções detalhadas de como instalar e implantar a aplicação em ambiente de produção, consulte o guia oficial: -### 2. Instalação Rápida (Docker) +👉 **[Guia de Implantação (DEPLOY.md)](DEPLOY.md)** -1. Clone o repositório. -2. Configure o ambiente: - ```bash - cp .env.example .env - # O arquivo já vem configurado para o ambiente Docker padrão - ``` -3. Suba os containers: - ```bash - docker-compose up -d --build - ``` -4. Acesse o sistema: - - **URL**: `http://localhost:8001` - - **Admin**: `admin@dnsblock.com` / `Admin@123` (Senha padrão atualizada para política forte) - - **Cliente**: `joao@provedor.com` / `Client@123` - -> [!IMPORTANT] -> **Política de Senhas**: O sistema exige senhas com no mínimo **8 caracteres**, contendo pelo menos **uma letra maiúscula** e **um caractere especial**. - -### 3. Instalação Manual (Sem Docker) -*Consulte a seção de requisitos no `composer.json` e configure um servidor Apache/Nginx com PHP 8.2+ e MySQL 8.0.* - -### 3. Configuração do Agente (Python) +### Configuração do Agente (Python) 1. Navegue até a pasta `agent`: ```bash diff --git a/agent/build.sh b/agent/build.sh index 5dfc58f..cb3e430 100755 --- a/agent/build.sh +++ b/agent/build.sh @@ -39,9 +39,20 @@ pyinstaller --onefile --name dnsblock-agent --clean main.py echo "Organizando saída..." mkdir -p dist/ # PyInstaller puts the binary in dist/ by default, but let's ensure structure -# We might want to copy config.json.example there too for distribution +# Copy config example cp config.json.example dist/ 2>/dev/null || echo "Nota: config.json.example não encontrado para copiar." +# Copy distribution files +if [ -d "pkg" ]; then + cp pkg/install.sh dist/ + cp pkg/dnsblock-agent.service dist/ + cp pkg/README.md dist/ + chmod +x dist/install.sh + echo "Arquivos de instalação copiados para dist/" +else + echo "Aviso: Diretório 'pkg' não encontrado. O instalador não será incluído." +fi + echo "Build concluído com sucesso!" -echo "O binário está disponível em: agent/dist/dnsblock-agent" -echo "Para distribuir, compacte a pasta 'dist'." +echo "O diretório 'dist' contém todos os arquivos necessários para distribuição." +echo "Para distribuir, compacte a pasta 'agent/dist'." diff --git a/agent/build/dnsblock-agent/Analysis-00.toc b/agent/build/dnsblock-agent/Analysis-00.toc index 56070bb..9200c65 100644 --- a/agent/build/dnsblock-agent/Analysis-00.toc +++ b/agent/build/dnsblock-agent/Analysis-00.toc @@ -148,13 +148,13 @@ ('dis', '/usr/lib/python3.11/dis.py', 'PYMODULE'), ('opcode', '/usr/lib/python3.11/opcode.py', 'PYMODULE'), ('ast', '/usr/lib/python3.11/ast.py', 'PYMODULE'), - ('stringprep', '/usr/lib/python3.11/stringprep.py', 'PYMODULE'), - ('_py_abc', '/usr/lib/python3.11/_py_abc.py', 'PYMODULE'), ('tracemalloc', '/usr/lib/python3.11/tracemalloc.py', 'PYMODULE'), ('pickle', '/usr/lib/python3.11/pickle.py', 'PYMODULE'), ('pprint', '/usr/lib/python3.11/pprint.py', 'PYMODULE'), ('dataclasses', '/usr/lib/python3.11/dataclasses.py', 'PYMODULE'), ('_compat_pickle', '/usr/lib/python3.11/_compat_pickle.py', 'PYMODULE'), + ('_py_abc', '/usr/lib/python3.11/_py_abc.py', 'PYMODULE'), + ('stringprep', '/usr/lib/python3.11/stringprep.py', 'PYMODULE'), ('logging.handlers', '/usr/lib/python3.11/logging/handlers.py', 'PYMODULE'), ('http.client', '/usr/lib/python3.11/http/client.py', 'PYMODULE'), ('ssl', '/usr/lib/python3.11/ssl.py', 'PYMODULE'), @@ -476,25 +476,33 @@ ('base_library.zip', '/home/halbebruno/Projetos/DNSBlock/agent/build/dnsblock-agent/base_library.zip', 'DATA')], - [('_collections_abc', '/usr/lib/python3.11/_collections_abc.py', 'PYMODULE'), + [('reprlib', '/usr/lib/python3.11/reprlib.py', 'PYMODULE'), + ('operator', '/usr/lib/python3.11/operator.py', 'PYMODULE'), + ('collections.abc', '/usr/lib/python3.11/collections/abc.py', 'PYMODULE'), + ('collections', '/usr/lib/python3.11/collections/__init__.py', 'PYMODULE'), + ('linecache', '/usr/lib/python3.11/linecache.py', 'PYMODULE'), + ('stat', '/usr/lib/python3.11/stat.py', 'PYMODULE'), + ('types', '/usr/lib/python3.11/types.py', 'PYMODULE'), + ('warnings', '/usr/lib/python3.11/warnings.py', 'PYMODULE'), + ('traceback', '/usr/lib/python3.11/traceback.py', 'PYMODULE'), + ('heapq', '/usr/lib/python3.11/heapq.py', 'PYMODULE'), + ('functools', '/usr/lib/python3.11/functools.py', 'PYMODULE'), ('sre_constants', '/usr/lib/python3.11/sre_constants.py', 'PYMODULE'), ('re._parser', '/usr/lib/python3.11/re/_parser.py', 'PYMODULE'), ('re._constants', '/usr/lib/python3.11/re/_constants.py', 'PYMODULE'), ('re._compiler', '/usr/lib/python3.11/re/_compiler.py', 'PYMODULE'), ('re._casefix', '/usr/lib/python3.11/re/_casefix.py', 'PYMODULE'), ('re', '/usr/lib/python3.11/re/__init__.py', 'PYMODULE'), - ('codecs', '/usr/lib/python3.11/codecs.py', 'PYMODULE'), - ('io', '/usr/lib/python3.11/io.py', 'PYMODULE'), - ('keyword', '/usr/lib/python3.11/keyword.py', 'PYMODULE'), - ('sre_compile', '/usr/lib/python3.11/sre_compile.py', 'PYMODULE'), - ('weakref', '/usr/lib/python3.11/weakref.py', 'PYMODULE'), - ('reprlib', '/usr/lib/python3.11/reprlib.py', 'PYMODULE'), + ('sre_parse', '/usr/lib/python3.11/sre_parse.py', 'PYMODULE'), + ('abc', '/usr/lib/python3.11/abc.py', 'PYMODULE'), ('ntpath', '/usr/lib/python3.11/ntpath.py', 'PYMODULE'), - ('enum', '/usr/lib/python3.11/enum.py', 'PYMODULE'), - ('heapq', '/usr/lib/python3.11/heapq.py', 'PYMODULE'), - ('functools', '/usr/lib/python3.11/functools.py', 'PYMODULE'), + ('io', '/usr/lib/python3.11/io.py', 'PYMODULE'), + ('_collections_abc', '/usr/lib/python3.11/_collections_abc.py', 'PYMODULE'), + ('keyword', '/usr/lib/python3.11/keyword.py', 'PYMODULE'), ('copyreg', '/usr/lib/python3.11/copyreg.py', 'PYMODULE'), + ('weakref', '/usr/lib/python3.11/weakref.py', 'PYMODULE'), ('locale', '/usr/lib/python3.11/locale.py', 'PYMODULE'), + ('genericpath', '/usr/lib/python3.11/genericpath.py', 'PYMODULE'), ('encodings.zlib_codec', '/usr/lib/python3.11/encodings/zlib_codec.py', 'PYMODULE'), @@ -725,17 +733,9 @@ ('encodings.ascii', '/usr/lib/python3.11/encodings/ascii.py', 'PYMODULE'), ('encodings.aliases', '/usr/lib/python3.11/encodings/aliases.py', 'PYMODULE'), ('encodings', '/usr/lib/python3.11/encodings/__init__.py', 'PYMODULE'), - ('_weakrefset', '/usr/lib/python3.11/_weakrefset.py', 'PYMODULE'), - ('linecache', '/usr/lib/python3.11/linecache.py', 'PYMODULE'), - ('abc', '/usr/lib/python3.11/abc.py', 'PYMODULE'), - ('sre_parse', '/usr/lib/python3.11/sre_parse.py', 'PYMODULE'), - ('traceback', '/usr/lib/python3.11/traceback.py', 'PYMODULE'), - ('collections.abc', '/usr/lib/python3.11/collections/abc.py', 'PYMODULE'), - ('collections', '/usr/lib/python3.11/collections/__init__.py', 'PYMODULE'), + ('codecs', '/usr/lib/python3.11/codecs.py', 'PYMODULE'), ('posixpath', '/usr/lib/python3.11/posixpath.py', 'PYMODULE'), - ('warnings', '/usr/lib/python3.11/warnings.py', 'PYMODULE'), - ('types', '/usr/lib/python3.11/types.py', 'PYMODULE'), - ('genericpath', '/usr/lib/python3.11/genericpath.py', 'PYMODULE'), - ('stat', '/usr/lib/python3.11/stat.py', 'PYMODULE'), - ('operator', '/usr/lib/python3.11/operator.py', 'PYMODULE'), + ('enum', '/usr/lib/python3.11/enum.py', 'PYMODULE'), + ('sre_compile', '/usr/lib/python3.11/sre_compile.py', 'PYMODULE'), + ('_weakrefset', '/usr/lib/python3.11/_weakrefset.py', 'PYMODULE'), ('os', '/usr/lib/python3.11/os.py', 'PYMODULE')]) diff --git a/agent/build/dnsblock-agent/EXE-00.toc b/agent/build/dnsblock-agent/EXE-00.toc index 90c24bd..34bd654 100644 --- a/agent/build/dnsblock-agent/EXE-00.toc +++ b/agent/build/dnsblock-agent/EXE-00.toc @@ -121,7 +121,7 @@ [], False, False, - 1764875919, + 1765033492, [('run', '/home/halbebruno/Projetos/DNSBlock/agent/build_venv/lib/python3.11/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run', 'EXECUTABLE')], diff --git a/agent/build/dnsblock-agent/base_library.zip b/agent/build/dnsblock-agent/base_library.zip index 31da525..85c1637 100644 Binary files a/agent/build/dnsblock-agent/base_library.zip and b/agent/build/dnsblock-agent/base_library.zip differ diff --git a/agent/build/dnsblock-agent/dnsblock-agent.pkg b/agent/build/dnsblock-agent/dnsblock-agent.pkg index 74f0061..103ce4a 100644 Binary files a/agent/build/dnsblock-agent/dnsblock-agent.pkg and b/agent/build/dnsblock-agent/dnsblock-agent.pkg differ diff --git a/agent/build/dnsblock-agent/warn-dnsblock-agent.txt b/agent/build/dnsblock-agent/warn-dnsblock-agent.txt index 57e1594..bb9eeaa 100644 --- a/agent/build/dnsblock-agent/warn-dnsblock-agent.txt +++ b/agent/build/dnsblock-agent/warn-dnsblock-agent.txt @@ -19,8 +19,8 @@ missing module named _frozen_importlib_external - imported by importlib._bootstr excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional) missing module named winreg - imported by importlib._bootstrap_external (conditional), platform (delayed, optional), mimetypes (optional), urllib.request (delayed, conditional, optional), requests.utils (delayed, conditional, optional) missing module named nt - imported by os (delayed, conditional, optional), ntpath (optional), shutil (conditional), importlib._bootstrap_external (conditional) -missing module named _winapi - imported by encodings (delayed, conditional, optional), ntpath (optional), subprocess (conditional), mimetypes (optional) missing module named org - imported by pickle (optional) +missing module named _winapi - imported by encodings (delayed, conditional, optional), ntpath (optional), subprocess (conditional), mimetypes (optional) missing module named _scproxy - imported by urllib.request (conditional) missing module named msvcrt - imported by subprocess (optional), getpass (optional) missing module named win32evtlog - imported by logging.handlers (delayed, optional) diff --git a/agent/config.json.example b/agent/config.json.example index 4694086..0a1251e 100644 --- a/agent/config.json.example +++ b/agent/config.json.example @@ -1,6 +1,6 @@ { "serial_key": "YOUR_SERIAL_KEY_HERE", - "api_url": "https://dnsblock.app", + "api_url": "https://app.dnsblock.com.br", "rpz_file": "/etc/unbound/rpz.zones/rpz.dnsblock.zone", "reload_command": "systemctl reload unbound" } diff --git a/agent/pkg/README.md b/agent/pkg/README.md new file mode 100644 index 0000000..4eea3f2 --- /dev/null +++ b/agent/pkg/README.md @@ -0,0 +1,47 @@ +# DNSBlock Agent + +Este é o pacote de distribuição binária do DNSBlock Agent para Linux. + +## Instalação + +1. Acesse o diretório descompactado: + ```bash + cd dnsblock-agent + ``` + +2. Execute o script de instalação como root: + ```bash + sudo ./install.sh + ``` + Isso instalará o agente em `/opt/dnsblock`, configurará o serviço systemd e criará o arquivo de configuração inicial. + +## Configuração + +1. Edite o arquivo de configuração gerado: + ```bash + sudo nano /opt/dnsblock/config.json + ``` + +2. Insira sua **Serial Key** e verifique a **API URL**. + +## Execução + +Inicie o serviço do agente: + +```bash +sudo systemctl start dnsblock-agent +``` + +Verifique o status: + +```bash +sudo systemctl status dnsblock-agent +``` + +## Logs + +Para visualizar os logs do agente: + +```bash +sudo journalctl -u dnsblock-agent -f +``` diff --git a/agent/pkg/dnsblock-agent.service b/agent/pkg/dnsblock-agent.service new file mode 100644 index 0000000..0e0657b --- /dev/null +++ b/agent/pkg/dnsblock-agent.service @@ -0,0 +1,14 @@ +[Unit] +Description=DNSBlock Agent Service +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/dnsblock +ExecStart=/opt/dnsblock/dnsblock-agent +Restart=always +RestartSec=10 + +[Install] +WantedBy=multi-user.target diff --git a/agent/pkg/install.sh b/agent/pkg/install.sh new file mode 100644 index 0000000..1c94c8a --- /dev/null +++ b/agent/pkg/install.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# DNSBlock Agent Installer (Binary Distribution) + +INSTALL_DIR="/opt/dnsblock" +SOURCE_DIR=$(pwd) + +# Check root +if [ "$(id -u)" -ne 0 ]; then + echo "Please run as root" + exit 1 +fi + +echo "Installing DNSBlock Agent..." + +# Create Directory +mkdir -p "$INSTALL_DIR" + +# Copy Binary +if [ -f "$SOURCE_DIR/dnsblock-agent" ]; then + cp "$SOURCE_DIR/dnsblock-agent" "$INSTALL_DIR/" + chmod +x "$INSTALL_DIR/dnsblock-agent" +else + echo "Error: dnsblock-agent binary not found in current directory." + exit 1 +fi + +# Create Config if not exists +if [ ! -f "$INSTALL_DIR/config.json" ]; then + echo "Creating default config..." + if [ -f "$SOURCE_DIR/config.json.example" ]; then + cp "$SOURCE_DIR/config.json.example" "$INSTALL_DIR/config.json" + else + cat < "$INSTALL_DIR/config.json" +{ + "serial_key": "YOUR_SERIAL_KEY_HERE", + "api_url": "https://seu-painel.com", + "rpz_file": "/opt/dnsblock/rpz.dnsblock.zone" +} +EOF + fi + echo "Config file created at $INSTALL_DIR/config.json. Please edit it with your Serial Key and API URL." +fi + +# Setup Systemd Service +echo "Setting up systemd service..." +if [ -f "$SOURCE_DIR/dnsblock-agent.service" ]; then + cp "$SOURCE_DIR/dnsblock-agent.service" /etc/systemd/system/ + systemctl daemon-reload + systemctl enable dnsblock-agent + + echo "Installation Complete!" + echo "1. Edit /opt/dnsblock/config.json" + echo "2. Start service: systemctl start dnsblock-agent" +else + echo "Error: dnsblock-agent.service not found." + exit 1 +fi