ti-enxame.com

Quais permissões os arquivos / pastas do meu site devem ter em um servidor da Web Linux?

Esta é uma Pergunta Canonical sobre Permissões de Arquivo em um servidor Web Linux.

Eu tenho um servidor web Linux executando o Apache2 que hospeda vários sites. Cada site tem sua própria pasta em/var/www /.

/var/www/contoso.com/
/var/www/contoso.net/
/var/www/fabrikam.com/

O diretório base/var/www/pertence a root: root. O Apache está sendo executado como www-data: www-data. O site da Fabrikam é mantido por dois desenvolvedores, Alice e Bob. Ambos os sites da Contoso são mantidos por um desenvolvedor, Eve. Todos os sites permitem que os usuários enviem imagens. Se um site estiver comprometido, o impacto deve ser o mais limitado possível.

Quero saber a melhor maneira de configurar permissões para que o Apache possa veicular o conteúdo, o site esteja protegido contra ataques e os desenvolvedores ainda possam fazer alterações. Um dos sites está estruturado da seguinte maneira:

/var/www/fabrikam.com
    /cache
    /modules
    /styles
    /uploads
    /index.php

Como as permissões devem ser definidas nesses diretórios e arquivos? Li em algum lugar que você nunca deve usar permissões 777 em um site, mas não entendo quais problemas podem causar. Durante os períodos de maior movimento, o site armazena em cache automaticamente algumas páginas e armazena os resultados na pasta de cache. Todo o conteúdo enviado pelos visitantes do site é salvo na pasta de uploads.

324
Nic

Ao decidir quais permissões usar, você precisa saber exatamente quem são seus usuários e o que eles precisam. Um servidor da web interage com dois tipos de usuário.

Usuários autenticados têm uma conta de usuário no servidor e podem receber privilégios específicos. Isso geralmente inclui administradores de sistema, desenvolvedores e contas de serviço. Eles geralmente fazem alterações no sistema usando SSH ou SFTP.

Usuários anônimos são os visitantes do seu site. Embora eles não tenham permissões para acessar arquivos diretamente, eles podem solicitar uma página da Web e o servidor da Web age em seu nome. Você pode limitar o acesso de usuários anônimos, tomando cuidado com as permissões que o processo do servidor da web possui. Em muitas distribuições Linux, o Apache é executado como o www-data usuário, mas pode ser diferente. Usar ps aux | grep httpd ou ps aux | grep Apache para ver qual usuário o Apache está usando no seu sistema.


Notas sobre permissões linux

Linux e outros sistemas compatíveis com POSIX usam permissões unix tradicionais. Há um excelente artigo na Wikipedia sobre Permissões do sistema de arquivos , portanto não repetirei tudo aqui. Mas há algumas coisas que você deve estar ciente.

O bit de execução
Os scripts interpretados (por exemplo, Ruby, PHP) funcionam muito bem sem a permissão de execução. Somente binários e scripts Shell precisam do bit de execução. Para percorrer (inserir) um diretório, você precisa ter permissão de execução nesse diretório. O servidor da web precisa dessa permissão para listar um diretório ou servir qualquer arquivo dentro dele.

Novas permissões de arquivo padrão
Quando um arquivo é criado, ele normalmente herda a identificação do grupo de quem o criou. Mas, às vezes, você deseja que novos arquivos herdem o ID do grupo da pasta em que são criados, para ativar o bit SGID na pasta pai.

Os valores de permissão padrão dependem do seu umask. O umask subtrai permissões de arquivos recém-criados, portanto, o valor comum de 022 resulta na criação de arquivos com o 755. Ao colaborar com um grupo, é útil alterar o seu umask para 002, para que os arquivos criados possam ser modificados pelos membros do grupo. E se você deseja personalizar as permissões dos arquivos enviados, é necessário alterar o umask para Apache ou executar o chmod após o upload do arquivo.


O problema com o 777

Quando você chmod 777 seu site, você não tem nenhuma segurança. Qualquer usuário do sistema pode alterar ou excluir qualquer arquivo no seu site. Mas, mais sério, lembre-se de que o servidor da web age em nome dos visitantes do seu site e agora o servidor da web pode alterar os mesmos arquivos que está executando. Se houver vulnerabilidades de programação em seu site, elas poderão ser exploradas para desfigurá-lo, inserir ataques de phishing ou roubar informações do servidor sem que você saiba.

Além disso, se o servidor for executado em porta conhecida (que deve impedir que usuários não raiz gerem serviços de escuta acessíveis ao mundo), isso significa que o servidor deve ser iniciado pela raiz ( embora qualquer servidor sadio caia imediatamente para uma conta menos privilegiada quando a porta estiver vinculada). Em outras palavras, se você estiver executando um servidor da web em que o executável principal faz parte do controle de versão (por exemplo, um aplicativo CGI), deixe suas permissões (ou, nesse caso, as permissões do diretório que contém, pois o usuário poderá renomear o executável) em 777 permite qualquer usuário executar qualquer executável como root .


Definir os requisitos

  • Os desenvolvedores precisam de acesso de leitura/gravação aos arquivos para que possam atualizar o site
  • Os desenvolvedores precisam ler/gravar/executar nos diretórios para que possam navegar
  • O Apache precisa de acesso de leitura a arquivos e scripts interpretados
  • O Apache precisa de acesso de leitura/execução a diretórios úteis
  • O Apache precisa de acesso de leitura/gravação/execução aos diretórios para o conteúdo carregado

Mantido por um único usuário

Se apenas um usuário for responsável pela manutenção do site, defina-o como proprietário do usuário no diretório do site e conceda ao usuário permissões completas de rwx. O Apache ainda precisa de acesso para poder servir os arquivos, então defina www-data como o proprietário do grupo e dê ao grupo permissões r-x.

No seu caso, Eve, cujo nome de usuário pode ser eve, é o único usuário que mantém contoso.com:

chown -R eve contoso.com/
chgrp -R www-data contoso.com/
chmod -R 750 contoso.com/
chmod g+s contoso.com/
ls -l
drwxr-s--- 2 eve      www-data   4096 Feb  5 22:52 contoso.com

Se você possui pastas que precisam ser gravadas pelo Apache, você pode modificar os valores de permissão do proprietário do grupo para que www-data tenha acesso de gravação.

chmod g+w uploads
ls -l
drwxrws--- 2 eve      www-data   4096 Feb  5 22:52 uploads

O benefício dessa configuração é que fica mais difícil (mas não impossível *) para outros usuários do sistema bisbilhotar, já que apenas os usuários e os proprietários do grupo podem navegar no diretório do site. Isso é útil se você tiver dados secretos em seus arquivos de configuração. Tenha cuidado com o seu umask! Se você criar um novo arquivo aqui, os valores de permissão provavelmente serão padronizados para 755. Você pode executar umask 027 para que os novos arquivos sejam padronizados como 640 (rw- r-- ---).


Mantido por um grupo de usuários

Se mais de um usuário for responsável pela manutenção do site, você precisará criar um grupo para usar na atribuição de permissões. É uma boa prática criar um grupo separado para cada site e nomear o grupo depois desse site.

groupadd dev-fabrikam
usermod -a -G dev-fabrikam alice
usermod -a -G dev-fabrikam bob

No exemplo anterior, usamos o proprietário do grupo para conceder privilégios ao Apache, mas agora isso é usado para o grupo de desenvolvedores. Como o proprietário do usuário não é mais útil para nós, configurá-lo como root é uma maneira simples de garantir que nenhum privilégio seja vazado. O Apache ainda precisa de acesso, por isso, damos acesso de leitura ao resto do mundo.

chown -R root fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 775 fabrikam.com
chmod g+s fabrikam.com
ls -l
drwxrwxr-x 2 root     dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Se você possui pastas que precisam ser gravadas pelo Apache, você pode tornar o Apache o proprietário do usuário ou o proprietário do grupo. De qualquer forma, ele terá todo o acesso necessário. Pessoalmente, prefiro torná-lo o proprietário do usuário para que os desenvolvedores ainda possam navegar e modificar o conteúdo das pastas de upload.

chown -R www-data uploads
ls -l
drwxrwxr-x 2 www-data     dev-fabrikam   4096 Feb  5 22:52 uploads

Embora essa seja uma abordagem comum, há uma desvantagem. Como todos os outros usuários do sistema têm os mesmos privilégios do site que o Apache, é fácil para outros usuários navegar no site e ler arquivos que podem conter dados secretos, como os arquivos de configuração.

Você pode comer o seu bolo e também

Isso pode ser melhorado ainda mais. É perfeitamente legal que o proprietário tenha menos privilégios que o grupo. Portanto, em vez de desperdiçar o proprietário do usuário atribuindo-o ao root, podemos tornar o Apache o proprietário do usuário nos diretórios e arquivos do seu site. Isso é uma reversão do cenário de mantenedor único, mas funciona igualmente bem.

chown -R www-data fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 570 fabrikam.com
chmod g+s fabrikam.com
ls -l
dr-xrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Se você possui pastas que precisam ser gravadas pelo Apache, você pode modificar os valores de permissão do proprietário do usuário para que www-data tenha acesso de gravação.

chmod u+w uploads
ls -l
drwxrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Uma coisa a ter cuidado com esta solução é que o proprietário do usuário de novos arquivos corresponderá ao criador em vez de ser definido como www-data. Portanto, quaisquer novos arquivos que você criar não serão legíveis pelo Apache até que você os reproduza.


* Separação de privilégios do Apache

Eu mencionei anteriormente que é realmente possível que outros usuários bisbilhotem seu site, independentemente dos tipos de privilégios que você está usando. Por padrão, todos os processos do Apache são executados como o mesmo usuário de dados www, portanto, qualquer processo do Apache pode ler arquivos de todos os outros sites configurados no mesmo servidor e, às vezes, até fazer alterações. Qualquer usuário que pode fazer com que o Apache execute um script pode obter o mesmo acesso que o próprio Apache possui.

Para combater esse problema, existem várias abordagens para separação de privilégios no Apache. No entanto, cada abordagem vem com várias desvantagens de desempenho e segurança. Na minha opinião, qualquer site com requisitos de segurança mais altos deve ser executado em um servidor dedicado, em vez de usar o VirtualHosts em um servidor compartilhado.


Considerações adicionais

Eu não mencionei isso antes, mas geralmente é uma prática ruim ter desenvolvedores editando o site diretamente. Para sites maiores, é muito melhor ter algum tipo de sistema de release que atualize o servidor da Web a partir do conteúdo de um sistema de controle de versão. A abordagem de mantenedor único é provavelmente ideal, mas em vez de uma pessoa, você tem um software automatizado.

Se o seu site permitir envios que não precisam ser veiculados, esses envios deverão ser armazenados em algum lugar fora da raiz da web. Caso contrário, você poderá descobrir que as pessoas estão baixando arquivos que deveriam ser secretos. Por exemplo, se você permitir que os alunos enviem tarefas, eles deverão ser salvos em um diretório que não seja atendido pelo Apache. Essa também é uma boa abordagem para arquivos de configuração que contêm segredos.

Para um site com requisitos mais complexos, convém examinar o uso de Listas de controle de acesso . Isso permite um controle de privilégios muito mais sofisticado.

Se o seu site tiver requisitos complexos, você pode escrever um script que configure todas as permissões. Teste-o cuidadosamente e mantenha-o em segurança. Pode valer a pena o seu peso em ouro, se você precisar reconstruir seu site por algum motivo.

347
Nic

Estou me perguntando por que tantas pessoas usam (ou recomendam) a "outra" (o) parte dos direitos do Linux para controlar o que pode fazer o Apache (e/ou PHP). Ao definir esta parte correta para algo diferente de "0", você apenas permite que o mundo inteiro faça algo no arquivo/diretório.

Minha abordagem é a seguinte:

  • Eu crio dois usuários separados. Um para o acesso SSH/SFTP (se necessário), que possuirá todos os arquivos, e um para o usuário PHP FastCGI (o usuário no qual o site será executado). Vamos chamar esses usuários respectivamente bob e bob-www.
  • bob terá direitos totais (rwx nas pastas, rw - nos arquivos), para que ele possa ler e editar o site inteiro.
  • O processo PHP FastCGI precisa de direitos r-x em pastas e r - em arquivos, exceto em pastas muito específicas como cache/ ou uploads/, onde a permissão "write" também é necessária. Para fornecer essa habilidade a PHP FastCGI, ela será executada como bob-www, e bob-www serão adicionadas ao criado automaticamente - bob grupo.
  • Agora, garantimos que o proprietário e o grupo de todos os diretórios e arquivos sejam bob bob.
  • Algo está faltando: até usamos o FastCGI, mas o Apache ainda precisa de acesso de leitura, para conteúdo estático, ou arquivos .htaccess que ele tentará ler se AllowOverride estiver definido como algo diferente de None. Para evitar o uso da parte o dos direitos, adiciono o usuário www-data ao grupo bob.

Agora:

  • Para controlar o que o desenvolvedor pode fazer, podemos brincar com a parte dos direitos (mas esta é a nota abaixo).
  • Para controlar o que o Apache e o PHP podem fazer, podemos brincar com a parte g dos direitos.
  • A parte o é sempre definida como 0, para que mais ninguém no servidor possa ler ou editar o site.
  • Não há problema quando o usuário bob cria novos arquivos, pois ele pertence automaticamente ao seu grupo principal (bob).

Esta é uma recapitulação, mas nessa situação, bob é permitido ao SSH. Se não houver nenhum usuário autorizado a modificar o site (por exemplo, o cliente modifica o site apenas por meio de um painel de administração do CMS e não possui conhecimento do Linux), crie dois usuários de qualquer maneira, mas dê /bin/false como Shell para bob também e desabilite seu login.

    adduser --home /var/www/bobwebsite --Shell /bin/bash bob
    adduser --no-create-home --Shell /bin/false --disabled-login --ingroup bob bob-www
    adduser www-data bob
    cd /var/www/bobwebsite
    chown -R bob:bob .
    find -type d -exec chmod 750 {} \;
    find -type f -exec chmod 640 {} \;

Nota: as pessoas tendem a esquecer que limitar os direitos (proprietário) é na maioria das vezes inútil e inseguro, pois o proprietário de um arquivo pode executar o chmod comando, mesmo os direitos são 000.

Diga-me se minha abordagem tem alguns problemas de segurança, porque não tenho 100% de certeza, mas é o que estou usando.

Eu acho que essa configuração tem um problema: quando o PHP/Apache cria um novo arquivo (por exemplo, upload), ele pertence a bob-www: bob, e bob apenas ser capaz de lê-lo. Talvez o setuid no diretório possa resolver o problema.

14
Fox

Dada a classificação do Google na excelente resposta acima, acho que há uma coisa que deve ser observada e não consigo deixar uma nota após a resposta.

Continuando com o exemplo, se você planeja usar www-data como proprietário e dev-fabrikam como grupo com 570 permissões no diretório (ou arquivo), é importante observar que Linux ignorasetuid, para que todos os novos arquivos sejam de propriedade do usuário que os criou. Isso significa que, após criar novos diretórios e arquivos, você terá que usar algo semelhante a:

chown -R www-data /newdirectory/
chmod -R 570 /newdirectory/

No Ubuntu 12.04 para Rackspace OpenStack, eu tinha um problema estranho, onde não conseguia obter as permissões 570 para funcionar até reiniciar o servidor, o que resolveu magicamente o problema. Estava perdendo pêlos a uma taxa crescente sobre essa questão aparentemente simples ....

9
Paul

Quando você tem um usuário de FTP chamado "leo", precisa enviar arquivos para o diretório da web example.com e também exige que o usuário "Apache" seja capaz de criar arquivos uploa-files/sessions/cache no diretório cache, faça o seguinte:

Este comando atribui leo como proprietário e grupo como Apache a example.com, o usuário do Apache faz parte do grupo Apache, portanto herdará as permissões do grupo Apache

chown -R leo: Apache example.com

Outro comando que garante a permissão correta e atende também às preocupações de segurança.

chmod -R 2774 example.com

Aqui o primeiro número 2 é para diretório e garante que cada novo arquivo criado permaneça nas mesmas permissões de grupo e proprietário. 77 é para proprietário e grupo significa que eles têm acesso total. 4 é para outros significa que eles só podem ler através.

a seguir, é útil entender os números de permissão

Number  Octal Permission Representation
0   No permission
1   Execute permission
2   Write permission
3   Execute and write permission: 1 (execute) + 2 (write) = 3
4   Read permission
5   Read and execute permission: 4 (read) + 1 (execute) = 5
6   Read and write permission: 4 (read) + 2 (write) = 6
7   All permissions: 4 (read) + 2 (write) + 1 (execute) = 7
3
Krishan Gopal

Eu vou com esta configuração:

  1. Todos os diretórios, exceto o upload de um conjunto para o proprietário root e o grupo root, permissões para 0755.
  2. Todos os arquivos configurados como proprietário root e grupo root, permissões para 0644.
  3. Carrega o diretório definido como proprietário root, grupo www-data, permissões para 1770. O bit persistente não permite que o proprietário do grupo remova ou renomeie o diretório e os arquivos dentro dele.
  4. Dentro da pasta de uploads, um novo diretório com www-data usuário e grupo proprietário e 0700 permissões para cada www-data usuário que faz upload de arquivos.
  5. Configuração do Apache:

Negue AllowOverride e Index no diretório de uploads, para que o Apache não leia .htaccess arquivos, e o usuário do Apache não pode indexar o conteúdo da pasta de uploads:

<Directory /siteDir>
   Options -Indexes
</Directory>

<Directory /siteDir/uploadDir>
   AllowOverride none
</Directory>

6. php.ini configuração:

open_basedir = /siteDir:/tmp:/usr/share/phpmyadmin
post_max_size = 5M
file_uploads = On
upload_max_filesize = 3M
max_file_uploads = 20

Com esta configuração, o www-data o usuário não poderá acessar diretórios diferentes de siteDir//tmp e /usr/share/phpmyadmin. Além disso, você pode controlar o tamanho máximo do arquivo, o tamanho máximo da postagem e o máximo de arquivos a serem carregados na mesma solicitação.

3
Manolo

Na IMO é preciso levar em consideração:

  • você confia em um processo que lê seus arquivos? por exemplo. PHP?

Vamos supor que você tenha um servidor com vários dados sob o 'teste' do usuário.

O usuário 'test' possui lá:

  • seus dados em $HOMEDIR
  • o correio dele em $MAIL
  • seus dados para a web em /var/www/test

Agora vamos pensar sobre:

  • um aplicativo da web é executado sob test user (PHP-FPM) - ele pode excluir qualquer um dos seus arquivos!
  • um aplicativo da web é executado sob test group (PHP-FPM) - ele pode excluir qualquer um de seus arquivos em que o diretório tenha 'w' para o grupo e pode modificar qualquer arquivo que tenha 'r' para o grupo; e ainda pode lê-los - suas teclas ssh, por exemplo!

Vamos supor que PHP é buggy, e é, você confia na sua open_basedir? Você chroot seu PHP processo? O que você não faz, você quer que ele rastreie por todo o sistema de arquivos?

Seu processo de aplicativo da web, por exemplo. PHP-FPM, então deve:

  • seja restrito ao caminho específico via chroot
  • não deve ser executado sob a permissão do usuário principal ou do grupo principal do proprietário dos dados

Assim você pode fazer:

  • o usuário de teste é: test:test
  • o usuário de teste está em um grupo secundário, por exemplo. test-www
  • um aplicativo da web (PHP-FPM) é executado em test-www:test-www
  • teste o usuário se ele quiser que o aplicativo Web possa ler seus arquivos: chmod u=rwX,g=rX,o= /var/www/test/public
  • teste o usuário se ele desejar que o aplicativo Web possa gravar em seu caminho de dados da Web: chmod u=rwX,g=rwXs,o= /var/www/test/public/upload (portanto, o aplicativo criará novos arquivos como: test-www:test-www - ele terá o grupo test-www por causa do setgid no diretório!)

Portanto, se o processo do aplicativo da Web for falso, basta ler os arquivos específicos que terão leitura de grupo e poderá gravar apenas em upload dir. Eu recomendaria fortemente que upload dir em um sistema de arquivos com noexec,nodev,nosuidmount opções e possui monitoramento constante para quaisquer novos arquivos bizzare nesse diretório, além de monitorar qualquer novo processo em test-wwwid.

No Linux, pode-se usar a ACL para ajustar melhor as permissões. Se mais de um humano precisar fazer upload de dados da web, seria melhor separar a conta humana da conta usada para fazer upload de arquivos de dados da web, ou seja. para criar uma nova conta, por exemplo. test-upload, e o usuário de teste gerenciaria as chaves ssh para restringir quais humanos poderiam ssh/sftp lá. sshd_config conhece ExposeAuthInfo opções, portanto, ele pode ser configurado para registrar qual chave ssh foi usada para carregar os dados.

Eu realmente duvido que a maioria dos serviços de hospedagem de sites se preocupe com a separação de privilégios, quando eles escrevem 'seguro' sem nenhuma informação, você diria que eles mentem.

1
Jiri B