Proteger o PHP nos diretórios de usuários

1

Sou um administrador de sistemas para um pequeno servidor da minha universidade, que é usado pelos alunos para experimentar e executar longos trabalhos à vontade.

Eu habilitei o PHP em diretórios de usuários para que eles pudessem experimentar websites e todos com algum conforto.

Recentemente, percebi que todo o código PHP em diretórios de usuários é executado pelo usuário do servidor web (www-data), que tem alguns privilégios que eu obviamente não quero dar aos usuários. Um site vulnerável ou um usuário mal-intencionado pode excluir o site normal do servidor.

Existe uma maneira de executar o PHP do usuário com os privilégios do usuário?

Pensei em uma solução alternativa para isso que está dando ao servidor da Web quase zero privilégios, de modo que uma violação não comprometa nada grave. Isso é factível na minha situação, pois o site é muito simples (índice html simples).

O servidor está executando o Debian Jessie com o Apache 2.4.10.

    
por Guido 01.11.2014 / 21:49

1 resposta

4

Eu fiz isso várias vezes usando nginx, lighttpd e apache. O conceito é basicamente o mesmo em todos eles: [Rápido] processos CGI executados como usuário.

Se quiser poupar muitos problemas, tente mexer com as permissões sugeridas por outras pessoas. Em particular, se os sites de seus usuários forem de propriedade dos usuários e o seu site principal for de propriedade root ou similar, você estará em boa forma. Mas os usuários ainda não serão segregados e poderão ler os arquivos uns dos outros, etc. (senhas de banco de dados?). A execução de servidores virtuais separados para cada usuário / site lhe dará mais segurança, e certamente é mais simples do que tentar segregar usuários com o apache.

A maneira padrão aceita de segregar os usuários do PHP no apache é via SuExec (também existe o mpm-itk). Se você usa o Google por apache fastcgi suexec ou similar, você deve obter muitos resultados. Acho que seria impraticável incluir as direções completas aqui. Pode variar com base em várias decisões de design e na distribuição em uso. Em vez disso, tentarei fornecer alguns pontos que considero importantes e uma breve descrição da minha configuração. Minha configuração fica bem complicada (e, além disso, eu executo um módulo personalizado do SELinux). Aqui está uma breve síntese [esperançosa]:

  • Hosts virtuais baseados em nome apontando * .somedomain para o servidor: user.somedomain é o nome do host virtual (suponho que você poderia fazer a mesma coisa com diretórios de usuários?).
  • Um /etc/httpd/vhosts.d/user.conf para cada usuário.
  • Um diretório em /var/www/vhosts_config para cada usuário.
    • /var/www/vhosts_config/$USER/wrapper-bin contém o wrapper para executar o PHP (mais sobre isso depois)
    • /var/www/vhosts_config/$USER/php/php.ini : gosto de ter um php.ini por usuário separado.
    • /var/www/vhosts_config/$USER/php/ext/*.ini : um arquivo ini por extensão disponível
    • /var/www/vhosts_config/$USER/php/ext-active/*.ini : links simbólicos de volta para ../ext para cada extensão ativada (para que eu possa ativar / desativar extensões por usuário também)
  • /var/www/vhosts/user contém o conteúdo real do vhost. Eu recomendo sempre usar um subdiretório public_html como raiz do documento para que os usuários tenham um diretório que esteja fora da raiz do documento para armazenar arquivos de configuração, etc.
  • Os usuários não devem conseguir ler os arquivos uns dos outros. Você precisa permitir o servidor web +x nos usuários '. Existem várias maneiras de fazer isso. Eu uso ACLs POSIX.

A configuração do httpd por usuário é semelhante a essa (alterada para brevidade):

<VirtualHost *:80>
        ServerName someuser.somedomain
        DocumentRoot /var/www/vhosts/someuser/public_html

        SuexecUserGroup someuser someuser    

        FcgidWrapper /var/www/vhosts_config/someuser/wrapper-bin/php .php

        #max of 5 cgis per vhost
        FcgidMaxProcessesPerClass 5
        FcgidMinProcessesPerClass 0

        AddHandler php-fcgi .php
        Action php-fcgi /wrapper-bin/php

        Alias /wrapper-bin/ /var/www/vhosts_config/someuser/wrapper-bin/

        <Location /wrapper-bin/>
                Options +ExecCGI
                SetHandler fcgid-script
        </Location>
</VirtualHost>

suexec é um programa de raiz setuid que o apache invoca para iniciar processos como um determinado usuário. É muito exigente. Ele requer que o programa que ele executa seja de propriedade do usuário e esteja contido em um subdiretório do diretório /var/www (isso varia em diferentes distribuições do Linux e está configurado em tempo de compilação) que é de propriedade do usuário. É por isso que cada usuário precisa de seu próprio script de wrapper PHP.

/var/www/vhosts_config/someuser/wrapper-bin/php parece algo como:

export PHPRC=/var/www/vhosts_config/someuser/php
export PHP_INI_SCAN_DIR=$PHPRC/ext-active/
export PHP_FCGI_CHILDREN=0
umask 0077
exec /usr/bin/php-cgi
  • PHP_INI_SCAN_DIR define um diretório para procurar por arquivos php.ini adicionais, que eu uso para carregar configurações específicas de extensões.
  • PHPRC lista o diretório no qual encontrar o arquivo php.ini .

Você não tem para usar uma configuração PHP separada para cada usuário, e isso certamente complica as coisas. Eu gosto de dar aos usuários uma configuração simplificada e ativada apenas o que é necessário (e algumas extensões comuns por padrão). Eu também carrego suhosion com diferentes configurações para cada usuário (diferentes chaves de criptografia).

    
por 10.11.2014 / 03:55