Autor: Daniel Oliveira

  • Servidor NFS para backup de máquinas virtuais do Proxmox

    Network File System (NFS) é um protocolo de sistema de arquivos sobre rede e permite compartilhamento de pastas e arquivos entre computadores.

    Ele é consideravelmente mais simples que o Server Message Block (SMB), protocolo usado pelo Windows para compartilhamento de pastas e impressoras, de forma que não possui qualquer suporte a autenticação de usuário ou criptografia. O controle de acesso é feito por endereço IP e pelas permissões do próprio sistema de arquivos.

    Ele tem como objetivo ser simples e transparente para aplicações de forma que pareça fazer parte do sistema de arquivos no cliente, enquanto mantém um bom desempenho.

    Esse protocolo existe nativamente em sistemas tipo Unix, como Linux, macOS e FreeBSD. No Windows, o suporte ao protocolo precisa ser adicionado como um pacote extra, mas é oferecida pela própria Microsoft.

    Em servidores Debian, Ubuntu ou derivados, instale o servidor NFS com:

    # apt install nfs-kernel-server

    Crie a pasta a ser exportada e defina as permissões adequadas – Proxmox vai escrever como root no sistema de arquivos exportado:

    # mkdir /pmx-backup
    # chown nobody:nogroup /pmx-backup

    O servidor NFS usa a opção root_squash por padrão na configuração, que mapeia as escritas do root do cliente para a uid e gid de um usuário de privilégio mais baixo no sistema. Escrita e leitura de outros usuários não são afetadas e levam a mesma uid e gid que o usuário do cliente.

    Edite o arquivo /etc/exports para adicionar a pasta a ser exportada, o IP do cliente que vai acessá-la e os parâmetros de configuração da exportação:

    /pmx-backup    192.168.0.2(rw,sync,no_subtree_check)

    E então exporte os sistemas de arquivos configurados:

    # exportfs -ar

    Abra a porta para o NFSv4 (essa versão requer apenas a porta 2049/tcp):

    # ufw allow proto tcp from 192.168.0.2 to any port 2049

    Onde 192.168.0.2 é o IP do servidor Proxmox.

    Para configurar o armazenamento no Proxmox, vá em Datacenter > Storage > Add > NFS e preencha com as informações necessárias:

    E então, basta começar os backups.

  • Configuração do FreeRADIUS para autenticação com Google LDAPS

    Sendo uma alternativa ao ambiente Microsoft, o Google Workspace também conta com um serviço de diretório. O LDAP seguro pode ser usado para autorização e autenticação de usuários. O FreeRADIUS foi usado para implementar autenticação WPA2-Enterprise na rede Wi-Fi, com um detalhe: a autenticação precisava funcionar para 2 domínios de e-mail diferentes, de dois ambientes Google Workspace independentes.

    Enquanto a autenticação com AD no FreeRADIUS é feita através do método de desafio e resposta, MSCHAPv2, o LDAP seguro do Google não implementa esse protocolo e precisa que a senha do usuário seja enviada em texto pleno dentro de um túnel SSL. Isso pode ser feito com a combinação de protocolos EAP-TTLS/PAP. Diferente do EAP-TLS, que exige o par de certificado/chave tanto do cliente quanto do servidor, o EAP-TTLS exige o par apenas do servidor.

    O servidor utilizado foi o Ubuntu 24.04 mas o processo serve também para outras versões. Primeiro passo é criar o cliente LDAP no Google Workspace. No console de administrador, vá em Apps > LDAP > Adicionar Cliente

    Atribua as permissões necessárias para o cliente:

    Em seguida, baixe os certificados e ative o serviço.

    Agora, preparando o servidor FreeRADIUS:

    # apt install freeradius freeradius-ldap

    Diferente do CentOS, o Ubuntu já gera os certificados pro TLS automaticamente no processo de instalação.

    Transfira o par de certificado/chave baixado do Google Workspace para o servidor, armazenando-os em /etc/freeradius/3.0/certs/google/, onde já é esperado pelo FreeRADIUS nas configurações a se seguir.

    Partindo para os arquivos de configuração, a começar pelo LDAP, fazendo uma cópia do arquivo para cada ambiente Workspace:

    # cp -a /etc/freeradius/3.0/mods-available/{ldap_google,ldap_workspace0}
    # cp -a /etc/freeradius/3.0/mods-available/{ldap_google,ldap_workspace1}

    Edite o arquivo, adicionando ou alterando as linhas:

    ldap ldap_workspace0 {
        identity = 'nomeDeClienteObtidoNoGoogleWorkspace'
        password = 'senhaDeClienteObtidaNoGoogleWorkspace'
        base_dn = 'dc=dominio0,dc=com'
        user {
            filter = "(mail=%{%{Stripped-User-Name}:-%{User-Name}})"
        }
        certificate_file = /caminho/do/cert/cliente/ldap
        private_key_file = /caminho/da/chave/cliente/ldap
    }

    Faça o mesmo para ldap_workspace1. Habilite os módulos com:

    # ln -s /etc/freeradius/3.0/mods-available/ldap_workspace0 /etc/freeradius/3.0/mods-enabled/

    No arquivo /etc/freeradius/3.0/mods-enabled/eap, adicione ou altere as seguintes configurações:

    eap {
      default_eap_type = ttls
      ttls {
        default_eap_type = pap
      }
    }

    Caso tenha alterado os certificados a serem usados, você também vai precisar editar as configurações referentes a isso no bloco de configurações comuns de TLS.

    Você pode comentar outros módulos não utilizados, como TLS, PEAP e MSCHAPv2, deixando apenas as configurações comuns de TLS e o bloco do TTLS.

    O arquivo /etc/freeradius/3.0/sites-enabled/default tem diversas opções, muitas podem (e devem) ser desabilitadas. Edite os blocos authorize e authenticate para que fiquem como abaixo:

    server default {
      authorize {
        filter_username
        preprocess
        eap
        expiration
        logintime
      }
      authenticate {
        eap
      }
    }

    No arquivo /etc/freeradius/3.0/sites-enabled/inner-tunnel, edite os mesmos blocos, adicionando a condicional para os dois domínios:

    server inner-tunnel {
    
      authorize {
        filter_username
    
        if ("%{User-Name}" =~ /@dominio0\.com$/) {
          ldap_workspace0
          update control {
            Auth-Type := ldap_workspace0
          }
        } elsif ("%{User-Name}" =~ /@dominio1\.com$/) {
          ldap_workspace1
          update control {
            Auth-Type := ldap_workspace1
          }
        } else {
          reject
        }
    
        expiration
        logintime
      }
    
      authenticate {
        Auth-Type ldap_workspace0 {
          ldap_workspace0
        }
        Auth-Type ldap_workspace1 {
          ldap_workspace1
        }
        Auth-Type PAP {
          pap
        }
      }
    
    }
    

    Terminando a edição dos arquivos, você deve reiniciar o serviço para que as configurações tenham efeito, garantindo antes que todos os arquivos pertencem ao usuário e grupo freerad.

    # chown -hR freerad:freerad /etc/freeradius
    # systemctl restart freeradius.service

    Caso necessário, você pode testar o FreeRADIUS em modo debug parando o serviço e executando-o manualmente da seguinte forma:

    # freeradius -X
  • Integração Nextcloud + Amazon S3

    Nextcloud tem suporte a diferentes tipos de armazenamentos externos através do app “External storage support”, entre eles: SMB (compartilhamento de pasta do Windows), SFTP e Amazon S3.

    Amazon Simple Storage Service (S3) é um serviço de armazenamento de objetos, que se diferencia do armazenamento de arquivos em alguns aspectos. Um deles sendo que, enquanto que em armazenamento de arquivos existe uma hierarquia de pastas ou diretórios, no armazenamento de objetos eles se encontram todos no mesmo ambiente, chamado bucket.

    Aplicações conseguem, no entanto, simular essa estrutura de pastas, graças ao fato de que o caractere / é permitido no nome dos objetos. E é exatamente isso que acontece no Nextcloud e no utilitário de linha de comando aws.

    A forma como o armazenamento de objetos é construído permite uma alta escalabilidade e, diferente de um serviço de armazenamento de arquivos como Google Drive, em que você contrata uma quantidade de armazenamento para ter disponível, nos serviços de armazenamento de objetos você paga pelo que é usado.

    Esse tipo de serviço é comumente usado em cenários de armazenamento de grande escala, como backups, CDNs, dados para treinamento de LLMs como ChatGPT e Gemini, onde não há necessidade de edição de arquivos no armazenamento.

    Partindo para a prática, o bucket foi criado de forma simples, mantendo as opções padrões:

    Agora deve-se criar um usuário, um grupo, adicionar o usuário ao grupo e criar uma política para dar acesso ao bucket para o usuário. Isso pode ser feito através do console:

    https://console.aws.amazon.com/iam

    Você pode permitir acesso do grupo ao bucket através da política de permissão existente AmazonS3FullAccess. Isso daria acesso a todos os buckets existentes na conta para esse grupo. Isso pode não ser desejável. Uma alternativa é criar uma política de permissão, que pode ser feita no formato json:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "FullAccessToChuteiOBucket",
          "Effect": "Allow",
          "Action": "s3:*",
          "Resource": [
            "arn:aws:s3:::chuteiobucket",
            "arn:aws:s3:::chuteiobucket/*"
          ]
        }
      ]
    }

    Substitua o nome do bucket de acordo.

    Para autenticação do usuário, deve-se criar uma chave de acesso.

    Baixe a chave e guarde de forma segura. Você pode usar o utilitário de linha de comando para testar o acesso do usuário.

    Para Debian, Ubuntu e derivados:

    # apt install awscli

    Para Fedora, CentOS Stream, RHEL, etc:

    # dnf install awscli2

    Configure a chave de acesso:

    $ aws configure

    E teste o acesso ao bucket para listar, copiar e deletar arquivos:

    $ aws s3 ls s3://chuteiobucket
    $ aws s3 cp arquivo.txt s3://chuteiobucket
    $ aws s3 rm s3://chuteiobucket/arquivo.txt

    Informação adicional: transferências incrementais podem ser feitas entre um armazenamento local e o bucket (em ambas as direções) com:

    $ aws s3 sync s3://chuteiobucket /pasta/de/destino

    Verificado o funcionamento, basta configurar no Nextcloud: habilite o aplicativo “External storage support” e ajuste as configurações de acordo com as preferências.

    O host foi um pouco difícil de descobrir, não encontrei na AWS de forma tão explícita. Em vez disso, ao selecionar um objeto existente no bucket (que fiz upload com o utilitário de linha de comando), aparecia a opção de copiar URL, e foi como vi que o endereço era: s3.<região da AWS>.amazonaws.com

    Ao conectar, o armazenamento S3 aparece como uma pasta para os usuários que você determinar. Adicionalmente, é possível permitir que usuários adicionem armazenamentos externos, como o S3, para as próprias contas.

  • Problema: timeout em sites atrás do proxy reverso via OpenVPN

    Um dia o nginx que configurei como proxy reverso aqui passou a dar timeout ao tentar carregar o Nextcloud. Ao investigar, verifiquei que mesmo ao fazer a solicitação ao servidor Nextcloud a partir do próprio servidor que hospeda o nginx/OpenVPN, através do comando abaixo, a solicitação não completava.

    $ curl -v http://10.8.0.3

    As solicitações feitas dentro da LAN funcionavam, indicando que o problema acontecia apenas dentro da VPN. No entanto, dentro da VPN o ping funcionava, solicitações para outras páginas do Nextcloud também funcionavam, como:

    $ curl -v http://10.8.0.3/status.php

    Tentei aprofundar a investigação mas eu não sou nenhum especialista em redes, só um entusiasta que se mete profissionalmente. Uma explicação que consegui foi que o problema podia ser relacionado ao MTU (maximum transmission unit) da interface virtual de rede do OpenVPN.

    Tanto a interface virtual do OpenVPN (tun0) quanto a interface de rede da máquina (eth0) possuíam o mesmo MTU: 1500 bytes. Isso pode ser verificado com:

    $ ip a

    Diminui o MTU do tun0 para 1380, tanto no servidor quanto no cliente, que foi uma sugestão que encontrei e funcionou. Esqueci o problema até acontecer com outra instalação do Nextcloud que mantenho. Mesmo problema, mesma solução. Eventualmente retornei o MTU pra 1500 e continuou funcionando.

    O blog não existia na época da primeira ocorrência com o Nextcloud. Agora, tive o mesmo problema com o WordPress e o novo Nextcloud. E o problema parece inconsistente. Tudo funciona, até que de repende para. E em momentos diferentes, sem nenhum gatilho claro, mas claramente alguma tentativa de enviar um pacote maior que não poderia ser fragmentado falhou.

    Dessa vez parei pra investigar um pouco melhor. Já que o MTU da tun0 é 1500, um ping com tamanho de 1472 bytes (-20 do cabeçalho IP -8 do cabeçalho ICMP) deve passar sem ser fragmentado. Não passou. 100% dos pacotes perdidos. Fui baixando até encontrar o ponto onde os pings tem resposta: 1396 bytes. MTU de 1424 bytes.

    Testei então: ping sem opções definidas e com tamanhos 1396 e 1397 bytes, monitorando também com o tcpdump tanto no servidor quanto no cliente:

    $ ping 10.8.0.3
    $ ping -M do -s 1396 10.8.0.3
    $ ping -M do -s 1397 10.8.0.3

    Para o tcpdump:

    # tcpdump -i tun0 icmp

    Resultados:

    • “ping 10.8.0.3” e “ping -M do -s 1396 10.8.0.3”:
      • pra cada 10 pings, 0% de perda de pacotes.
      • tcpdump reporta 20 pacotes capturados tanto no servidor quanto no cliente: solicitação e resposta

    Ótimo. Agora:

    • “ping -M do -s 1397 10.8.0.3” e valores acima:
      • pra cada 10 pings, 100% de perda de pacotes
      • tcpdump reporta 10 pacotes capturados no servidor, 20 no cliente: o pacote sai do servidor e chega ao cliente, que responde, mas as respostas do cliente não chegam ao servidor.

    O mesmo foi feito pingando do cliente para o servidor. Mesmo sucesso para pacotes de 1396 bytes e menores. Já com

    • ping -M do -s 1397 10.8.0.1:
      • pra cada 10 pings, 100% de perda de pacotes
      • tcpdump reporta 10 pacotes capturados no cliente, 0 no servidor.

    Ou seja, o problema está no envio de pacotes dos clientes para o servidor através do túnel.

    O ping não alerta que o pacote é grande demais nem dá qualquer erro específico, apenas para pings com tamanho acima de 1472 (que resultariam num pacote acima do MTU). Em vez disso, apenas falha silenciosamente.

    Adicionalmente ao ping, fiz testes com requisições às páginas que resultavam em timeout usando curl e monitorando com tcpdump.

    Solução: baixar o valor do MTU da interface tun0 do servidor e clientes da VPN para 1424 bytes: tamanho total do maior pacote do ping que funcionou (1396 de payload, 20 do cabeçalho IP e 8 do cabeçalho ICMP).

    Isso pode ser feito de forma não persistente com:

    # ip link set dev tun0 mtu 1424

    O MTU vai voltar para 1500 quando o serviço do OpenVPN for reiniciado. Para configurar de forma persistente, inclua essa linha nos arquivos de configuração do OpenVPN do servidor e dos clientes:

    tun-mtu 1424

    Eu ainda não entendi 100% o que causa esse problema e ele não parece afetar todos os clientes igualmente ou ao mesmo tempo. O servidor recebia resposta do ping com payload de 1472 de alguns clientes sem problemas, que exibiam a página e operavam com a MTU padrão de 1500 bytes no tun0.

    Até então, após a mudança para o MTU de 1424, o problema não reincidiu. Sendo mais conservador, eu colocaria um valor mais baixo, pra deixar uma margem pra possíveis alterações que possam vir a acontecer no OpenVPN ou nos outros servidores, masss eu tô aqui pra ver o que acontece.

  • Implantando contêineres docker para Metabase e GLPI com Portainer

    Docker é uma ferramenta que permite a distribuição de softwares em contêineres, ambientes de execução independentes. Algo como máquinas virtuais, mas sem o mesmo overhead da virtualização de hardware e sem necessidade de outro kernel sendo executado.

    Isso permite que os desenvolvedores tenham um maior controle sobre versões de dependências como bibliotecas e outros programas com que o software interage, independente da distribuição Linux onde o software vai ser executado.

    Isso também facilita a implantação, já que muita coisa no ambiente não precisará ser configurada após a instalação.

    Portainer é uma ferramenta para gerenciamento e monitoramento de contêineres Docker, podendo também gerenciar Podman e Kubernetes. É distribuído também como um contêiner Docker.

    Começando pela instalação do Docker pelas fontes oficiais, nesse caso para o Ubuntu Server 24.04, é necessário primeiro importar a chave do repositório do Docker:

    # curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

    Adicione o repositório Docker em um arquivo /etc/apt/sources.list.d/docker.list:

    deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable

    Atualize os repositórios e instale os pacotes do Docker:

    # apt update
    # apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Verifique que o serviço está sendo executado:

    $ systemctl status docker.service

    Adicione seu usuário ao grupo docker para que não seja necessário usar os comandos com sudo.

    # usermod -aG docker daniel

    Você talvez precise sair do shell atual e abrir outro, ou fazer logout e login novamente.

    Então, crie um volume a ser usado para informações do Portainer:

    $ docker volume create portainer_data

    Isso cria uma pasta em /var/lib/docker/volumes/portainer_data.

    E em seguida, baixe a imagem e execute o Portainer com:

    $ docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts
    • O parâmetro -p é usado para mapear uma porta do host para uma porta do contêiner – docker usa iptables e isso pode contornar o firewall do sistema operacional.
    • O parâmetro -v é usado para mapear um volume docker ou um /caminho/no/seu/sistema para um caminho dentro do contêiner.

    A porta 9443 é usada para acesso à interface web via HTTPS. Por padrão são gerados certificados autoassinados e, enquanto é possível especificar seus certificados já no comando “docker run”, também é possível alterá-los pelas configurações na própria interface web.

    A porta 8000 é usada pela funcionalidade Edge computing, que permite gerenciamento e implantação de contêineres em dispositivos remotos através de um túnel TCP.

    Verifique que o Portainer está sendo executado com:

    $ docker ps

    Então, acesse-o pelo navegador através da porta 9443 com protocolo HTTPS e siga a configuração pela página web.

    Hora de instalar um contêiner: existem alguns templates mas a seção Containers permite que qualquer imagem seja baixada do Docker Hub e o contêiner construído a partir dela, com os parâmetros de configuração escolhidos.

    Um software interessante que é distribuído como um contêiner docker é o Metabase: uma plataforma livre e aberta para análise de dados e Business Intelligence.

    De acordo com o site oficial, a instalação como contêiner docker pode ser feita pelo seguinte comando:

    $ docker run -d -p 3000:3000 --name metabase metabase/metabase

    O que, pelo Portainer, fica:

    Após inicializado, basta acessar o servidor na porta 3000 via HTTP.

    O comando “docker run” é tipicamente usado para softwares ou sistemas que são distribuídos como um único contêiner. Alguns sistemas são compostos de múltiplos contêineres que trabalham em conjunto.

    Nesses casos, em vez de usar o comando “docker run” passando os parâmetros de configuração como argumentos, o comando “docker compose” é usado com um arquivo docker-compose.yml que armazena esses parâmetros de configuração. A configuração do Metabase nesse formato, por exemplo, ficaria:

    services:
      metabase:
        image: metabase
        container_name: metabase
        ports:
          - "3000:3000"

    Outro sistema interessante de ser instalado é o GLPI: um sistema de gerenciamento de Helpdesk e ativos de TI. A instalação usa um arquivo docker-compose.yml, que pode ser encontrado no Docker Hub: https://hub.docker.com/r/glpi/glpi, e especifica dois contêineres: um com o GLPI empacotado com o servidor web e PHP e outro com o banco de dados MySQL. O exemplo abaixo teve alguns parâmetros adaptados:

    volumes:
      glpi:
      glpi_mysql:
    
    services:
      glpi:
        image: "glpi/glpi:latest"
        restart: "unless-stopped"
        volumes:
          - glpi:/var/glpi
        env_file: stack.env
        ports:
          - "8080:80"
      db:
        image: "mysql"
        restart: "unless-stopped"
        volumes:
          - glpi_mysql:/var/lib/mysql
        env_file: stack.env
        expose:
          - "3306"

    Como a configuração especifica um arquivo com variáveis de ambiente, também precisamos dele, o stack.env, com o conteúdo abaixo.

    O Portainer espera que o arquivo seja especificado com esse nome no yml, porque é o nome do arquivo que ele forma a partir das variáveis que são fornecidas. O arquivo para upload pode ter qualquer nome.

    GLPI_DB_HOST=db
    GLPI_DB_PORT=3306
    GLPI_DB_NAME=glpi_db
    GLPI_DB_USER=glpi_operator
    GLPI_DB_PASSWORD=senhaNoPost-it
    
    MYSQL_RANDOM_ROOT_PASSWORD=yes
    MYSQL_DATABASE=glpi_db
    MYSQL_USER=glpi_operator
    MYSQL_PASSWORD=senhaNoPost-it

    Adaptações feitas:

    • Todas as variáveis estão no stack.env. O Portainer não resolve variáveis no arquivo .yml, então todas precisam ser especificadas no stack.env ou no próprio .yml. Isso levou a variáveis com valores redundantes no stack.env
    • Pela mesma questão acima, o teste do banco de dados foi removido.
    • Volumes docker foram especificados em vez de caminhos para pastas no host.

    Para uma implantação desse tipo no Portainer, vá na seção Stacks. Lá é possível fazer upload dos arquivos ou colar o conteúdo no editor web.

    O GLPI leva um tempo após a inicialização do contêiner para ser instalado e ficar disponível na porta mapeada, nesse caso 8080. O MySQL gera uma senha aleatória para o usuário root, que você pode obter com:

    $ docker logs <nome_do_conteiner_mysql> | grep GENERATED

    Para acompanhar a instalação, verifique os logs do contêiner do GLPI via linha de comando ou no Portainer.

    Após concluida, basta fazer login na interface web com o usuário e senha padrão, especificado no log do contêiner:

    • Usuário: glpi
    • Senha: glpi

    Na interface web, o GLPI sugere remover o arquivo install/install.php, o que pode ser feito com:

    $ docker exec -it <nome_do_conteiner_glpi> rm /var/www/glpi/install/install.php

    Voltando ao Metabase: a implantação do Metabase abordada armazena as configurações em um banco de dados H2, no volume do próprio contêiner, sem nenhum volume persistente configurado. Ou seja, ao fazer uma atualização – que é feita por remover e adicionar um novo contêiner, todas as configurações, dashboards e conexões com bancos de dados seriam excluídos.

    Para uso em produção, o metabase precisa ser combinado com um banco de dados para produção, como PostgreSQL. Abaixo, um exemplo de configuração em formato .yml para implantação:

    volumes:
      metabase_config:
    
    services:
      metabase:
        image: metabase/metabase:latest
        container_name: metabase
        hostname: metabase
        restart: "unless-stopped"
        volumes:
          - /dev/urandom:/dev/random:ro
        ports:
          - 3000:3000
        environment:
          MB_DB_TYPE: postgres
          MB_DB_DBNAME: metabase_db
          MB_DB_PORT: 5432
          MB_DB_USER: metabase_operator
          MB_DB_PASS: senhaNoBlocoDeNotas.txt
          MB_DB_HOST: meta_postgres
        networks:
          - metanet1
        healthcheck:
          test: curl --fail -I http://localhost:3000/api/health || exit 1
          interval: 15s
          timeout: 5s
          retries: 5
    
      postgres:
        image: postgres:latest
        container_name: postgres
        hostname: meta_postgres
        restart: "unless-stopped"
        volumes:
          - metabase_config:/var/lib/postgresql/data
        environment:
          POSTGRES_USER: metabase_operator
          POSTGRES_DB: metabase_db
          POSTGRES_PASSWORD: senhaNoBlocoDeNotas.txt
        networks:
          - metanet1
    
    networks:
      metanet1:
        driver: bridge
  • Configurando servidor Rustdesk: alternativa a Anydesk e TeamViewer

    Rustdesk é um software de acesso e controle remoto para Windows, macOS e Linux, tendo também aplicativos para Android e iOS.

    O cliente, ao ser instalado, irá por padrão usar um servidor público gratuito. Você provavelmente não vai querer isso, principalmente por questão de desempenho, já que o público tem uma latência considerável.

    O lado do servidor possui duas edições: uma comercial e uma da comunidade. A edição da comunidade tem algumas limitações, a mais notável sendo a ausência da capacidade própria de gerenciamento de dispositivos. Enquanto a comercial tem uma licença proprietária, a da comunidade é distribuída sob a licença AGPL-3.0.

    O download pode ser feito na página do projeto no GitHub. Para os componentes do servidor:

    Para o cliente:

    O cliente tem uma instalação bem direta para qualquer sistema operacional.

    O servidor é composto de dois serviços:

    • rustdesk-hbbs – É o servidor de ID (rendezvous/sinalização). O papel dele é identificar os dois dispositivos a serem conectados e fazê-los criar uma conexão P2P mesmo através de um firewall ou NAT, através da técnica de “hole punching”, de forma que após estabelecida, a conexão não depende da atuação do servidor.
    • rustdesk-hbbr – Dependendo das configurações da rede em que os dois dispositivos se encontram, nem sempre é possível estabelecer uma conexão P2P. Nesse caso, o hbbr assume como um relay, com a comunicação entre os dois dispositivos sendo mediada por ele.

    Para instalar, basta baixar os pacotes adequados pra arquitetura do seu servidor na seção releases da página do Rustdesk no GitHub e instalá-los no servidor – que deve ser Debian ou Ubuntu, já que apenas pacotes .deb são distribuídos oficialmente.

    A instalação completa consiste em três pacotes, dois sendo os serviços mencionados e outro como um utilitário pra configuração e teste do Rustdesk.

    $ wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.14/rustdesk-server-hbbs_1.1.14_amd64.deb
    $ wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.14/rustdesk-server-hbbr_1.1.14_amd64.deb
    $ wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.14/rustdesk-server-utils_1.1.14_amd64.deb
    
    # apt install ./rustdesk-server-hbbs_1.1.14_amd64.deb
    # apt install ./rustdesk-server-hbbr_1.1.14_amd64.deb
    # apt install ./rustdesk-server-utils_1.1.14_amd64.deb

    Verifique se os serviços estão sendo executados:

    $ systemctl status rustdesk-hbbs
    $ systemctl status rustdesk-hbbr

    Configure o seu firewall: o serviço rustdesk-hbbs escuta nas portas 21115/tcp e 21116/(tcp+udp), e o rustdesk-hbbr na porta 21117/tcp, então:

    # ufw allow 21115:21117/tcp
    # ufw allow 21116/udp

    A instalação gera alguns arquivos em /var/lib/rustdesk-server: um par de chaves público-privada e alguns arquivos de banco de dados SQLite, usado para armazenamento de informações de clientes.

    O par de chaves é gerado automaticamente na instalação e, caso queira, você pode gerar novas com:

    $ rustdesk-utils genkeypair

    e substituir nos arquivos id_ed25519.pub e id_ed25519. Reinicie os serviços para que tenha efeito.

    A chave pública é necessária para a configuração dos clientes.

    No cliente instalado, vá nas configurações > Rede > Servidor de ID/Relay e especifice seu endereço de IP ou nome de domínio para ambos os servidores e sua chave pública – que você pode não querer que seja tão pública.

  • Configuração do nginx como proxy reverso para WordPress, Nextcloud e Proxmox

    Nenhuma das publicações sobre instalação de WordPress ou Nextcloud aborda acesso via HTTPS ou certificados SSL, apenas HTTP.

    Acontece que isso é centralizado em uma instalação do nginx, atuando como proxy reverso. O servidor que hospeda o nginx e o servidor de OpenVPN são a mesma máquina: um VPS com 512mb de RAM e 1vCPU.

    O nginx recebe as requisições em HTTPS e as encaminha em HTTP* de forma segura para os outros servidores – clientes da VPN: WordPress, Nextcloud e Proxmox – 3 máquinas diferentes.

    * Proxmox usa HTTPS por padrão mas com um certificado verificado por uma CA interna

    Vantagens:

    • só é necessário gerenciar os certificados em um servidor, independente de quantos sites são.
    • as 3 máquinas diferentes poderiam estar em qualquer rede, qualquer lugar – isso é, se não fossem virtualizadas dentro do Proxmox, podendo até ser uma rede residencial que bloqueia tráfego de entrada (muito obrigado, Claro), basta se conectar na VPN.

    Desvantagem:

    • existe um pouco de latência devido à distância entre as máquinas (Rio de Janeiro) e o VPS (São Paulo).

    Ainda que fosse possível abrir as portas na rede e o OpenVPN não fosse necessário, usar o nginx como um proxy reverso na mesma LAN ainda poderia ser vantajoso pelo o gerenciamento centralizado dos certificados SSL, logs de acesso e uso de múltiplos nomes de domínio em diferentes servidores pro mesmo IP na mesma porta.

    Os arquivos de configuração do nginx para cada site devem ficar localizados em /etc/nginx/sites-available e para habilitá-los basta criar um symlink em /etc/nginx/sites-enabled com:

    # ln -s /etc/nginx/sites-available/sua_config /etc/nginx/sites-enabled/

    A primeira configuração recomendada é para receber a solicitação HTTP na porta 80 e redirecionar o cliente para fazer uma solicitação HTTPS na porta padrão 443.

    server {
        listen 80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
    }

    Em todos os exemplos de configuração abaixo, substitua o nome do servidor (FQDN), o caminho para o certificado e chave SSL e o IP privado para onde deve ser encaminhada a solicitação.

    Como mencionado, é possível usar a mesma porta para todos os servidores, como a porta padrão HTTPS, desde que cada um tenha o parâmetro server_name diferente, cada um com um nome de domínio (FQDN).

    Configuração para o Proxmox:

    upstream proxmox {
        server "seuproxmox.dominio.com";
    }
    
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name seuproxmox.dominio.com;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        proxy_redirect off;
        location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass https://10.8.0.2:8006;
            proxy_buffering off;
            client_max_body_size 0;
            proxy_connect_timeout  3600s;
            proxy_read_timeout  3600s;
            proxy_send_timeout  3600s;
            send_timeout  3600s;
        }
    }

    Para o Nextcloud:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff";
        server_name seunextcloud.dominio.com;
        location / {
            proxy_pass http://10.8.0.3;
            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;
            proxy_redirect off;
        }
        send_timeout 1800;
    }

    Configurações adicionais são recomendadas no lado do servidor Nextcloud, no arquivo /var/www/nextcloud/config/config.php

      'trusted_proxies' =>
      array (
        0 => '10.8.0.1',
      ),
      'overwritehost' => 'seunextcloud.dominio.com',
      'overwriteprotocol' => 'https',
      'overwritecondaddr' => '^10\\.8\\.0\\.1$',
      'overwritewebroot' => '/',
      'overwrite.cli.url' => 'https://seunextcloud.dominio.com',

    Para o WordPress:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff";
        server_name seuwordpress.dominio.com;
        location / {
            proxy_pass http://10.8.0.4;
            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;
            proxy_redirect off;
        }
        send_timeout 1800;
    }

    Configurações adicionais são requeridas no lado do servidor do WordPress, no arquivo /var/www/html/wp-config.php

    define('WP_HOME', 'https://seuwordpress.dominio.com');
    define('WP_SITEURL', 'https://seuwordpress.dominio.com');
    
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $_SERVER['HTTPS'] = 'on';
    }
    
    if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
        $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
    }

    Sugestão de configuração adicional para o WordPress – o WordPress não tem um mecanismo de proteção contra tentativas de acesso por força bruta. Para mitigar isso, além de usar boas senhas, você pode limitar o acesso por IP às localizações /wp-admin e /wp-login.php na configuração do proxy reverso adicionando essa configuração:

    server {
        location ~* ^/(wp-admin|wp-login.php) {
            allow 186.205.1.165;    # seu IP de casa
            allow 191.252.110.50;    # seu IP do trabalho
            deny all;
            proxy_pass http://10.8.0.4;
            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;
        }
    }

    Por conveniência, você também pode fazer o nginx escutar pra solicitações a HTTP na porta 80 e redirecionar todos os clientes para uma solicitação HTTPS:

    server {
        listen 80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
    }

    Após configurado, inicie o serviço.

    # systemctl enable --now nginx

    Caso ainda não tenha certificados SSL válidos, eles podem ser obtidos gratuitamente com a Let’s Encrypt, uma organização sem fins lucrativos, com o comando certbot. Primeiro, pare o serviço nginx, já que o certbot vai criar um processo que também vai escutar na porta 80. Então, use o comando nesse formato:

    # certbot certonly --standalone -d seu.dominio.com -d seunextcloud.dominio.com -d seuproxmox.dominio.com -d seuwordpress.dominio.com

    Siga os prompts do programa e, ao terminar, inicie o nginx.service novamente.

    Caso esteja usando o proxy reverso para servidores dentro de uma VPN, você pode querer ver isso aqui.

  • Instalação e configuração de servidor Nextcloud

    Nextcloud é uma solução de armazenamento de arquivos acessível via web, como Google Drive, que conta também com aplicativos de calendário, contatos, mensagens e chamadas de vídeo, cliente de e-mail e suporte a compartilhamento de arquivos. Também tem suporte a integração de suíte office, através do ONLYOFFICE ou Nextcloud Office (baseado no LibreOffice).

    Além disso, Nextcloud trás também o conceito de federação: instâncias distintas do Nextcloud podem se comunicar se assim os administradores quiserem, permitindo uma rede descentralizada de servidores, onde um usuário de uma instância pode se comunicar e compartilhar arquivos com um usuário de outra.

    É software livre e aberto, licenciado sob a AGPLv3, e conta também com planos empresariais.

    No momento os sistemas recomendados para o Nextcloud são Ubuntu 24.04 e RHEL 9, mas tem suporte também a outros como OpenSUSE, Debian e Alpine. Aqui vamos usar o Ubuntu 24.04.

    O Nextcloud precisa de: um servidor web, um banco de dados e PHP. Eu segui a instalação com Apache pro servidor web e PostgreSQL pro banco de dados.

    Outras alternativas suportadas são Nginx para o servidor web e MySQL e MariaDB para o banco de dados.

    Instalação e configuração do Apache com PHP:

    # apt install apache2 php

    Caso tenha habilitado o firewall (Ubuntu traz o UFW desabilitado por padrão), permita o acesso por http:

    # ufw allow http

    Visite o seu servidor web via http e verifique que o Apache funciona. Coloque um arquivo como index.php na pasta do servidor web /var/www/html com o conteúdo

    <?php phpinfo() ?>

    e visite sua página no local /index.php para verificar que o Apache está processando PHP.

    Instalando e configurando o banco de dados:

    # apt install postgresql
    # sudo -u postgres psql

    Isso vai te levar à linha de comando do PostgreSQL, onde você pode criar o usuário e o banco de dados a ser usado no Nextcloud:

    > CREATE USER nextcloud_operator WITH PASSWORD 'senhaNoPost-it';
    > CREATE DATABASE nextcloud_db WITH OWNER nextcloud_operator TEMPLATE template0 ENCODING 'UTF8';
    > \q

    Baixe o arquivo do servidor em https://nextcloud.com/install/

    Instale o utilitário unzip com

    # apt install unzip

    Extraia o arquivo .zip na pasta /var/www. Você vai ver uma pasta nextcloud. Mude o proprietário dela e dos arquivos e subpastas para o usuário www-data, que executa o Apache:

    # chown -hR www-data:www-data /var/www/nextcloud

    Edite o arquivo de configuração do Apache,
    /etc/apache2/sites-enabled/000-default.conf
    para alterar/adicionar as seguintes configurações:

    	DocumentRoot /var/www/nextcloud
    
    	<Directory /var/www/nextcloud/>
    	Require all granted
    	AllowOverride All
    	Options Indexes FollowSymLinks MultiViews
    		<IfModule mod_dav.c>
    			Dav off
    		</IfModule>
    	</Directory>

    Instale outros módulos PHP necessário para o Nextcloud:

    # apt install php-curl php-xml php-gd php-mbstring php-zip php-pgsql 

    Reinicie seu servidor web

    # systemctl restart apache2.service

    e dê sequência à instalação pela página web. O básico já está funcionando.

    Agora existem alguns ajustes que podem ser feitos e você pode vê-los na seção de Configurações de administração > Visão geral

    Um dos principais é o limite de memória usada na execução de scripts PHP. O recomendado é pelo menos 512mb mas a configuração padrão usa 128mb.

    Outro é o limite do buffer do módulo OPcache, para o qual é sugerido um valor acima de 8mb.

    Ajuste os seguintes valores no arquivo
    /etc/php/8.3/apache2/php.ini

    memory_limit = 512M
    opcache.interned_strings_buffer=32

    E no arquivo /etc/php/8.3/cli/php.ini

    opcache.interned_strings_buffer=32

    e reinicie o Apache.

    Algumas mensagens de erro vão sugerir que você execute um script occ com algum argumento. Você pode fazer isso com

    # sudo -u www-data php /var/www/nextcloud/occ argumento_sugerido

    Sugestão de configuração adicional: os arquivos de usuários ficam na pasta /var/www/nextcloud/data, dentro da pasta raiz do Nextcloud. No caso de um bug num dos scripts PHP ou no servidor web, arquivos privados poderiam ser expostos. Então você pode querer configurar a pasta data em outro local, fora da raiz /var/www do servidor web, como por exemplo /var/nextcloud_data.

    Essas e outras questões menos críticas de configuração são abordadas também na documentação oficial do Nextcloud.

    O acesso via HTTPS será feito utilizando o servidor web Nginx atuando como proxy reverso, abordado em outra postagem.

  • Instalação do FreeRADIUS integrado com Active Directory

    RADIUS é um protocolo de rede que oferece gerenciamento centralizado de autorização e autenticação para acesso de usuários a serviços de rede. Muito usado, por exemplo, como uma alternativa mais segura de acesso a uma rede Wi-Fi, onde cada usuário usa suas credenciais para se conectar, em vez de todos compartilharem uma única senha.

    FreeRADIUS é um sistema livre e aberto que implementa esse protocolo e pode ser configurado pra usar diferentes back-ends para autorização e autenticação, um deles é o Active Directory.

    Pra configurar esse sistema, garanta antes que o servidor RADIUS possa encontrar e ingressar no domínio – aqui tratado como exemplo.com:

    • Domínio e o controlador de domínio podem ser encontrados por consulta de DNS e são acessíveis na rede.
    • O arquivo /etc/hosts do servidor deve conter o FQDN especificado, algo como:
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.0.10 radius-server.exemplo.com radius-server

    Após isso, instale e configure o Samba, que vai ser usado para ingressar o computador no domínio. A partir daqui, as instruções são válidas para sistemas da família Red Hat, tendo sido usado o CentOS Stream 9.

    # dnf install samba

    Adapte a configuração abaixo para o seu domínio, alterando ou adicionando os seguintes parâmetros no arquivo /etc/samba/smb.conf :

    [global]
        workgroup = EXEMPLO
        security = ads
        winbind use default domain = yes
        realm = EXEMPLO.COM
    
        idmap config * : backend = tdb
        idmap config * : range = 10000-19999
    
        idmap config EXEMPLO : backend = rid
        idmap config EXEMPLO : range = 20000-99999
    

    Remova também o parâmetro a seguir para evitar o risco de conflito na autenticação:

    [global]
        passdb backend = tdbsam

    Verifique se há algum erro na sua configuração com

    # testparm

    Agora, para ingressar o servidor no domínio:

    # net ads join -U Administrator

    Instale o pacote samba-winbind-clients, habilite o serviço winbind e teste a autenticação com ntlm_auth:

    # dnf install samba-winbind-clients
    # systemctl enable --now winbind.service
    # ntlm_auth --request-nt-key --username=daniel --password='senhaqueanoteinoblocodenotas'

    Um output como

    :  (0x0)

    indica sucesso.

    Agora que o servidor já faz parte do domínio e conseguimos autenticar usuários com ntlm_auth, podemos instalar os pacotes do FreeRADIUS para então configurá-lo

    # dnf install freeradius freeradius-utils

    Pra autenticação no AD, vamos usar a combinação de protocolos PEAP/MSCHAPv2.

    Edite a o módulo mschap localizado em /etc/raddb/mods-enabled/mschap para alterar as seguintes configurações

    mschap {
        use_mppe = yes
        require_encryption = yes
        require_strong = yes
        ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}"
    }

    Edite o módulo eap localizado em /etc/raddb/mods-enabled/eap para alterar a seguinte configuração:

    eap {
        default_eap_type = peap
    }

    Dica: os arquivos de configuração do FreeRADIUS são extensivamente comentados. Isso é ótimo porque ajuda a entender a configuração já na hora. Mas se quiser ver só a configuração, sem os comentários e linhas em branco:

    $ grep -vE '^\s*#|^\s*$' /caminho/para/arquivo.txt

    Na pasta /etc/raddb/certs, execute o arquivo bootstrap para gerar os certificados necessários para o TLS usado no PEAP.

    Adicione o usuário radiusd ao grupo wbpriv para que o FreeRADIUS tenha acesso para ler a resposta do winbind à solicitação de autenticação, através do socket em /var/lib/samba/winbindd_privileged/pipe

    # usermod -aG wbpriv radiusd

    Abra as portas necessárias no firewall:

    # firewall-cmd --permanent --add-port=1812/udp
    # firewall-cmd --permanent --add-port=1813/udp
    # firewall-cmd --reload

    E agora basta iniciar o serviço radiusd:

    # systemctl enable --now radiusd.service

    Você pode testar a autenticação pelo FreeRADIUS com

    radtest -t mschap daniel senhaqueanoteinoblocodenotas localhost 0 testing123

    e configurar outros clientes do FreeRADIUS em /etc/raddb/clients.conf

    Alguns clientes podem não aceitar o certificado gerado com as configurações padrão do FreeRADIUS, então é recomendado ajustar as configurações pra que o certificado seja emitido corretamente para o FQDN do servidor. O Easy RSA também pode ajudar a gerar e manter os certificados.

  • Criação de um domínio com Active Directory no Windows Server

    Active Directory Domain Services é um serviço proprietário desenvolvido pela Microsoft usado para gerenciamento centralizado de um domínio de rede em ambientes corporativos, controlando a autorização e autenticação de usuários e computadores, atribuindo e impondo políticas de segurança e instalando ou atualizando softwares.

    Felizmente eu tinha um snapshot da máquina virtual anterior à criação do meu domínio e pude refazer os passos pra colocar umas imagens, porque eu sou uma negação em PowerShell.

    O sistema usado foi o Windows Server 2025 Standard. Antes de instalar o AD DS e criar o domínio, é necessário configurar o sistema com um endereço de IP fixo. Para isso, vá em

    Control Panel > Network and Internet > Network and Sharing Center > Change adapter settings

    Clique com o botão direito no adaptador de rede e clique em Propriedades. Selecione “Internet Protocol Version 4” e clique em Propriedades.

    Configure um endereço de IP estático fora da faixa do DHCP e use o mesmo IP ou 127.0.0.1 para servidor de DNS – que será configurado mais à frente.

    No Server Manager, vá em “Add roles and features”. No Wizard, selecione “Role-based or feature-based installation” e prossiga.

    Na próxima etapa, selecione o seu servidor e prossiga. Em seguida, você vai ver uma lista do que pode ser instalado. Selecione “Active Directory Domain Services” e “DNS Server”.

    O servidor precisará atuar também como servidor de DNS para que clientes possam encontrar e participar do domínio. Esse papel poderia ser delegado a outro servidor de DNS que você tenha configurado no mesmo domínio.

    Na etapa de confirmação, mantenha desmarcada a opção de reiniciar o servidor após instalação, já que só faremos isso após promover o servidor a controlador do domínio.

    Após a instalação, um sinal de atenção vai aparecer nas notificações do Server Manager, onde vai aparecer a opção de promover o servidor a controlador de domínio.

    Isso vai abrir um novo Wizard. Na primeira etapa, selecione “Add a new forest” e determine o seu domínio. Em um caso ideal, você tem nome de domínio público, como exemplo.com, e pode configurar com um subdomínio do tipo ad.exemplo.com. Alternativamente, você pode usar um como privado. Apenas tenha cuidado com possíveis conflitos com domínios externos, escolha algo como exemplo.interno.

    Sobre o nível funcional da floresta e domínio no próximo passo: isso é sobre compatibilidade de funcionalidades e protocolos. Caso não tenha outros controladores de domínio com versões antigas do Windows Server atuando, prossiga com o padrão (mais recente).

    Determine sua senha para o modo de restauração (DSRM). Isso é como o modo de segurança nas versões do Windows Home ou Pro, mas específica para controladores de domínio. Isso porque a autenticação através do AD é desabilitada no modo de restauração, então essa é a senha que você usa pra logar no Administrator.

    Pule a etapa de delegação de DNS, já que estamos configurando nosso servidor de DNS junto com o domínio.

    O nome de domínio NetBIOS é determinado automaticamente a partir do seu nome de domínio totalmente qualificado (FQDN).

    Após isso, siga com as opções padrões até o fim da instalação, onde seu servidor será reiniciado e promovido a controlador de domínio.

    Para que outros computadores possam encontrar o seu domínio e participar dele, você deve alterar as configurações de DHCP do seu roteador para usar seu Windows Server como servidor de DNS.

    Você pode gerenciar usuários e grupos do domínio com dsa.msc, políticas de grupo com gpmc.msc, e o servidor de DNS com dnsmgmt.msc.

    Sugestão de segurança: Princípio do menor privilégio.
    Por padrão, só administradores podem incluir ou remover computadores do domínio. Pra resolver isso você pode criar um usuário ou grupo e delegar as permissões do contêiner Computers em “Active Directory Users and Computers” (dsa.msc).