Tag: selinux

  • Migração de Nextcloud de Ubuntu para CentOS Stream

    Após a reconfiguração do Apache e PHP-FPM para hospedar múltiplos sites, uma das coisas que eu quis fazer foi migrar minha instância do Nextcloud do Ubuntu 24.04 para o CentOS Stream 10.

    Para organizar, eu pensei em algo similar ao que fiz para o WordPress:

    • /var/www/exemplo.com/nextcloud – pasta do Nextcloud
    • /var/www/exemplo.com/data – pasta de dados do Nextcloud

    Foi criado um disco virtual separado para o Nextcloud, criada a partição com cfdisk e formatada como XFS – sistema de arquivos padrão na linhagem de servidores RHEL/CentOS/Fedora. Então, os arquivos foram transferidos para o disco, que depois será montado em /var/www/exemplo.com:

    # rsync -av /var/www/nextcloud /mnt/nextcloud
    # rsync -av /var/nextcloud-data /mnt/data

    Então, foi feito o dump do banco de dados:

    # sudo -u postgres pg_dump nextcloud_db > nextcloud.sql
    # mv nextcloud.sql /mnt

    Montado o disco no CentOS, é necessário instalar os pacotes faltantes:

    # dnf install php-pecl-zip php-pgsql postgresql-server

    Um módulo adicional (em relação à instalação do Ubuntu) necessário para execução de alguns scripts é o php-process:

    # dnf install php-process

    Sem esse módulo, a tentativa de execução do cron.php dá o seguinte erro:

    “The posix extensions are required – see https://www.php.net/manual/en/book.posix.php“.

    Outros módulos do PHP já haviam sido instalados por causa do WordPress. Em uma instalação limpa:

    # dnf install php-common php-xml php-gd php-mbstring php-pecl-zip php-pgsql php-process postgresql-server

    Então, começando a configuração do banco de dados:

    # postgresql-setup --initdb
    # systemctl enable --now postgresql
    # sudo -u postgres psql

    Dentro do banco de dados:

    postgres=# CREATE ROLE nextcloud_user WITH PASSWORD 'umaSenhaCriativa';
    postgres=# CREATE DATABASE nextcloud_db WITH OWNER nextcloud_user TEMPLATE template0 ENCODING 'UTF8';

    Então, podemos importar o dump do banco de dados da instalação antiga:

    # sudo -u postgres psql nextcloud_db < /var/www/exemplo.com/nextcloud.sql

    O PostgreSQL tem um arquivo com as configurações de autenticação. Para descobrir onde está esse arquivo:

    # sudo -u postgres psql -c "SHOW hba_file;"

    No caso do CentOS Stream: /var/lib/pgsql/data/pg_hba.conf

    Curiosidade: HBA significa “host-based authentication”.

    Então, podemos configurá-lo. Isso pode ser necessário porque, como você vai ver, a coluna de método de autenticação está toda como peer.

    Isso significa que ele faz um mapeamento entre o nome do usuário do sistema operacional para o usuário existente no banco de dados, de forma que ambos precisam ter o mesmo nome e o servidor SQL não exige uma senha – por isso o psql é executado com a opção “-u postgres” no sudo.

    Para o tipo de conexão local – isso é, através do socket unix – isso não é problema. Mas o Nextcloud, no momento do setup, explicitamente solicita endereço, porta e senha para a configuração do banco de dados – ou seja, a conexão ao servidor é através de TCP em vez de socket unix.

    No arquivo de configuração, o tipo de conexão TCP é representado por host, enquanto que a conexão por socket unix é representada por local.

    Para configurar o banco de dados para utilizar autenticação por senha em conexões TCP, basta substituir peer por scram-sha-256 nas linhas em que o tipo de conexão é host.

    O motivo de eu estar aprofundando um pouco mais na questão do método de autenticação no servidor de banco de dados é devido a um problema que se apresentou no final de tudo:

    Após configurar o pool dedicado do PHP-FPM e o site para o Apache, a página do Nextcloud estava retornando erro 500. Em algum momento eu lembro que fui testar os scripts cron.php e “occ upgrade” do Nextcloud e lembro que eles apresentavam uma exceção ao tentar conecta no banco de dados. Alterei a senha, porque imaginei que pudesse ser algum problema em como caracteres especiais foram interpretados, sem sucesso.

    O problema era devido a uma boolean do SELinux: http_can_network_connect_db estava desativada. Isso pôde ser verificado com:

    $ getsebool http_can_network_connect_db

    Como a conexão é feita através de TCP no localhost na porta 5432, o SELinux identificava essa tentativa de conexão e bloqueava. O servidor passou a responder apropriadamente quando a conexão a bancos de dados foi permitida com:

    # setsebool http_can_network_connect_db on

    No entanto, eu não queria afrouxar as regras do SELinux e busquei uma alternativa. Encontrei em fóruns do Nextcloud que era possível conectá-lo ao banco de dados através do socket unix.

    O socket unix é um ponto de comunicação entre processos que aparece representado por um arquivo na árvore de diretórios do sistema operacional.

    Já que estaremos utilizando esse tipo de conexão, podemos seguir com o método padrão de autenticação tipo peer e dispensar o uso de senha para conexão ao banco de dados.

    Para que isso funcione, é necessário:

    • Fazer com que pool do PHP-FPM seja executado por um usuário de mesmo nome que o usuário usado para acessar o banco de dados – ajustando também o proprietário dos arquivos do Nextcloud.
    • Ajustar o arquivo de configuração do Nextcloud.

    Criando o usuário no sistema operacional e ajustando as permissões do Nextcloud:

    # useradd -s /usr/sbin/nologin nextcloud_user
    # chown -hR nextcloud_user:nextcloud_user /var/www/exemplo.com/{nextcloud,data}

    Ajustando também o contexto no SELinux para esses arquivos:

    # semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/exemplo.com/nextcloud(/.*)?"
    # semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/exemplo.com/data(/.*)?"
    # restorecon -Rv /var/www/exemplo.com

    Para ajustar as configurações do Nextcloud, deve-se ajustar os parâmetros dbhost e… só. A linhas da senha, porta de conexão e até mesmo o usuário do banco de dados podem ser deletadas ou comentadas com //.

    O dbhost deve ser a pasta em que o socket unix se encontra, e isso pode ser descoberto com:

    # sudo -u postgres psql -c "SHOW unix_socket_directories;"

    No arquivo de configuração do Nextcloud fica.

    'dbhost' => '/var/run/postgresql',

    Vale lembrar de ajustar também o caminho da pasta de dados:

    'datadirectory' => '/var/www/exemplo.com/data',

    A configuração do pool do PHP-FPM fica:

    ; /etc/php-fpm.d/exemplo.com.conf
    
    [exemplo.com]
    user = nextcloud_user
    group = nextcloud_user
    
    listen = /run/php-fpm/nextcloud.sock
    listen.acl_users = apache,nginx
    listen.allowed_clients = 127.0.0.1
    
    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 5
    pm.min_spare_servers = 5
    pm.max_spare_servers = 35
    
    slowlog = /var/log/php-fpm/exemplo.com/nextcloud-slow.log
    
    php_admin_value[error_log] = /var/log/php-fpm/exemplo.com/nextcloud-error.log
    php_admin_flag[log_errors] = on
    php_value[session.save_handler] = files
    php_value[session.save_path] = /var/lib/php/session
    php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache

    Criando a pasta de log do PHP-FPM:

    # mkdir -m 700 /var/log/php-fpm/exemplo.com
    # chown nextcloud_user:nextcloud_user /var/log/php-fpm/exemplo.com

    A configuração do Apache:

    # /etc/httpd/conf.d/exemplo.com.conf
    
    <VirtualHost *:80>
        ServerName exemplo.com
    
        DocumentRoot /var/www/exemplo.com/nextcloud
    
        <Directory /var/www/exemplo.com/nextcloud>
            AllowOverride All
            Require all granted
        </Directory>
    
        <FilesMatch \.php$>
            SetHandler "proxy:unix:/run/php-fpm/nextcloud.sock|fcgi://localhost/"
        </FilesMatch>
    
        ErrorLog /var/log/httpd/exemplo.com_error.log
        CustomLog /var/log/httpd/exemplo.com_access.log combined
    </VirtualHost>

    A permissão do SELinux para processos com rótulo httpd se conectarem a bancos de dados através da rede pode então ser desativada e tudo deve continuar funcionando:

    # setsebool httpd_can_network_connect_db off

    Mas então, outro problema apareceu ao tentar fazer login. Ao inserir o usuário e a senha e clicar no botão de login, a página apenas recarregava.

    Nos logs do Nextcloud, em /var/www/exemplo.com/data/nextcloud.log, a seguinte linha apareceu:

    {"reqId":"aoYPLBNDXYPyR-ZrzrzodwAAAE8","level":2,"time":"2026-08-19T20:16:44+00:00","remoteAddr":"177.192.15.123","user":"--","app":"PHP","method":"GET","url":"/index.php/apps/files/preview-service-worker.js","scriptName":"/index.php","message":"session_start(): Failed to read session data: files (path: /var/lib/php/session) at /var/www/exemplo.com/nextcloud/lib/private/Session/Internal.php#214","userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0","version":"34.0.3.2","data":{"app":"PHP"}}

    Atenção para a parte “Failed to read session data: files (path: /var/lib/php/session)”.

    Esse caminho é configurado no pool do PHP-FPM como onde as sessões devem ser armazenadas. O problema era que o usuário do pool, nextcloud_user, não tem acesso a essa pasta. Então, novas pastas foram criadas com as permissões adequadas, atualizando o arquivo de configuração do pool com:

    php_value[session.save_path] = /var/lib/php/exemplo.com/session
    php_value[soap.wsdl_cache_dir] = /var/lib/php/exemplo.com/wsdlcache

    Diretórios também foram criados separadamente para o WordPress e a configuração do pool foi ajustada, apesar de não ter tido nenhum problema ainda.

    Por fim, foi feito um ajuste de memória que um script PHP pode consumir. O mínimo recomendado é 512 MB. Isso pode ser ajustado no arquivo /etc/php.ini, no parâmetro memory_limit.

    Outros ajustes menores a serem feitos podem ser verificados no painel de administração do Nextcloud.

    post scriptum