Uploads do Apache PHP - propriedade e permissões

4

Estou dando meus primeiros passos para instalar um servidor web VPS (Debian 8 + Apache 2 + PHP 5.6) e preciso de ajuda com permissões de arquivos / pastas, por favor.

Eu já encontrei alguns tópicos semelhantes sobre este assunto (não exatamente o mesmo), e todos de 4 ou 5 anos de idade. Alguns deles apontam soluções usando métodos PHP obsoletos. Talvez hoje existam alguns novos métodos ou soluções.

Bem, existe o Apache 2 que é executado em www-data user / group. Então eu criei um usuário chamado webadmin , coloquei no grupo www-data e o configurei como o dono da pasta principal do site:

adduser webadmin
usermod -a -G www-data webadmin
chown -R webadmin:www-data /var/www/website.com

Também alterei as permissões da pasta public_html da seguinte forma:

find /var/www/website.com/public_html -type f -exec chmod 644 {} +
find /var/www/website.com/public_html -type d -exec chmod 755 {} +
find /var/www/website.com/public_html -type d -exec chmod g+s {} +

E criou a pasta que receberá os arquivos enviados (somente arquivos estáticos - imagens):

mkdir /var/www/website.com/public_html/uploads
chown webadmin:www-data /var/www/website.com/public_html/uploads
chmod 774 /var/www/website.com/public_html/uploads

Agora, o que está acontecendo: todas as pastas e arquivos PHP / Html que eu carrego usando o SFTP (logado como webadmin ) obviamente obtêm webadmin como proprietário. Quando uso o PHP para criar subpastas e carregar as imagens, elas obtêm o usuário www-data como proprietário. Neste cenário, estou tendo alguns problemas de permissão, como excluir arquivos através de SFTP.

Eu poderia atribuir o Apache para ser executado como webadmin user e www-data group, mas acho que posso ter problemas de segurança (não é?). Por favor, existe um padrão e melhor prática para configurar o servidor ou o script PHP que irá criar as pastas e fazer o upload dos arquivos para evitar esse problema?

    
por Guybrush 23.09.2017 / 23:12

2 respostas

2

Seu problema é que os novos arquivos não podem ser gravados em grupo. Em vez de usar setgid no diretório para definir o grupo, use ACL s que oferecem mais flexibilidade.

A entrada ACL padrão é herdada para novos arquivos e diretórios, concedendo permissões definidas na ACL. Para definir uma entrada ACL padrão para o grupo webadmin para permitir rwx :

setfacl -m default:g:webadmin:rwx /var/www/website.com/public_html/uploads

Novos arquivos criados no diretório serão legíveis e graváveis para o grupo webadmin .

Se a ACL não for uma opção , você precisará alterar o umask , que determina as permissões padrão do UNIX para novos arquivos. As escolhas sensatas para as novas umask são 002 (mascarado por todo mundo) e 007 (todos os bits de permissão do mundo mascarados, ou seja, apenas grupo e proprietário têm acesso).

Para definir o Apache umask , copie o arquivo da unidade systemd para / etc :

cp /lib/systemd/system/apache2.service /etc/systemd/system/

Configure umask em /etc/systemd/system/apache2.service anexando UMask=<umask> para a seção [Service] . Observe que isso afeta todos os arquivos criados pelo Apache.

Mudar umask para sftp é necessário apenas se você precisar alterar os arquivos / diretórios enviados do PHP / Apache. O padrão umask 022 cria um grupo de arquivos e é legível por todo o mundo, mas não pode ser gravado em grupo. A maneira mais fácil de configurar o umask padrão para sftp é pam_umask .

Para aplicar seu umask personalizado apenas para usuários em um grupo específico e somente ao usar sftp , anexe /etc/pam.d/sshd com:

session [default=1 success=ignore] pam_succeed_if.so user notingroup <yourgroup>
session optional                   pam_umask.so umask=<umask>

A primeira regra informa ao pam para pular a próxima regra se o usuário não estiver no grupo <yourgroup> , ou seja, aplicar a próxima regra somente se o usuário estiver no grupo <yourgroup> . A segunda regra define o umask para <umask> .

Adendo : observe que os arquivos existentes movidos com mv mantêm suas permissões e propriedade originais. Você pode aplicar permissões padrão de umask e diretório setgid / ACLs copiando arquivos com cp -d .

    
por 24.09.2017 / 14:14
-3

A coisa boa sobre os padrões é que geralmente há muito por onde escolher.

Parabéns por pensar em permissões e em impedir que o seu servidor da Web seja capaz de gravar arquivos que não sejam de conteúdo carregado. Espero que você tenha desativado completamente a execução do php no diretório de upload. No momento, seu modelo é um tanto defeituoso, pois você está adicionando o apache a um grupo com privilégios extras. Mas isso é apenas parte do problema - mas eu discordo da pergunta que você fez.

O fato de você ter criado um usuário significa que você tem privilégios de root na caixa (você deveria ter explicitamente mencionado isso). Mas você não disse se está usando seu próprio software ou um pacote de prateleira. O último cria algumas complicações, pois a personalização pode comprometer o patch regular que você deve realizar. Se o apache for o único uid que você pretende ter direitos altamente controlados no destino, você poderá resolver o problema provisionando o acesso ao arquivo do apache como "outro" em vez de usuário ou grupo.

Como alternativa, para provisionar o acesso ao upload de conteúdo para outras contas, basta usar um umask de 000 / chmod para 666. Observe que move_uploaded_file () na verdade cria uma cópia e exclui o original e criticamente, a criação do arquivo respeita o umask . Assim, qualquer php devidamente escrito pode armazenar o conteúdo carregado http como legível e gravável, sem qualquer alteração de código, definindo uma umask de 000 para o servidor da Web.

Como alternativa, você pode escrever um script de shell para alterar as permissões do conteúdo carregado de http para algo que permita manipular o conteúdo com uma conta de usuário normal e dar ao seu servidor da Web o direito de invocar esse script pelo sudo. Isso precisaria ser chamado pelo seu código após move_uploaded_file ().

Alternativamente, uma solução bastante feia seria colocar um relógio inotify no diretório de upload vinculado a um script para corrigir as permissões (por exemplo, usando incron )

Como último recurso, você poderia executar um cron job regular no diretório de upload para corrigir as permissões.

Eu recomendo usar a abordagem umask .

    
por 24.09.2017 / 00:59