Esta é uma pergunta canônica sobre permissões de arquivo em um servidor web Linux.
Eu tenho um servidor web Linux rodando 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/ é de propriedade de 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 façam upload de 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 servir o conteúdo, o site esteja protegido contra ataques e os desenvolvedores ainda possam fazer alterações. Um dos sites está estruturado assim:
/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 isso pode causar. Durante os períodos de maior movimento, o site armazena automaticamente algumas páginas em cache e armazena os resultados na pasta de cache. Todo o conteúdo enviado pelos visitantes do site é salvo na pasta de uploads.
Ao decidir quais permissões usar, você precisa saber exatamente quem são seus usuários e o que eles precisam. Um servidor web interage com dois tipos de usuário.
Os 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.
Os usuários anônimos são os visitantes do seu site. Embora eles não tenham permissões para acessar os 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 do processo do servidor web. Em muitas distribuições Linux, o Apache é executado como
www-data
usuário, mas pode ser diferente. Useps aux | grep httpd
oups aux | grep apache
para ver qual usuário o Apache está usando em seu sistema.Notas sobre permissões do 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, então não vou repetir tudo aqui. Mas há algumas coisas que você deve estar ciente.
Os scripts interpretados de bit de execução
(por exemplo, Ruby, PHP) funcionam bem sem a permissão de execução. Apenas binários e scripts de shell precisam do bit de execução. Para percorrer (entrar) em 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.
Permissões de novo arquivo padrão
Quando um arquivo é criado, ele normalmente herda o ID do grupo de quem o criou. Mas às vezes você quer que novos arquivos herdem o ID do grupo da pasta onde eles foram criados, então você habilitaria o bit SGID na pasta pai.
Os valores de permissão padrão dependem de sua umask. O umask subtrai permissões de arquivos recém-criados, então o valor comum de 022 resulta em arquivos sendo criados com 755. Ao colaborar com um grupo, é útil alterar seu umask para 002 para que os arquivos que você cria possam ser modificados pelos membros do grupo. E se você quiser personalizar as permissões dos arquivos carregados, você precisa alterar o umask para apache ou executar chmod após o upload do arquivo.
O problema com 777
Quando você
chmod 777
acessa seu site, você não tem segurança alguma. Qualquer usuário do sistema pode alterar ou excluir qualquer arquivo do seu site. Mas, falando 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 podem ser exploradas para desfigurar seu site, inserir ataques de phishing ou roubar informações de seu servidor sem que você saiba.Além disso, se o seu servidor for executado em uma porta bem conhecida (o que deve impedir que usuários não root gerem serviços de escuta acessíveis por todo o mundo), isso significa que seu servidor deve ser iniciado pelo root (embora qualquer servidor sensato seja descartado imediatamente para uma conta menos privilegiada assim que a porta estiver vinculada). Em outras palavras, se você estiver executando um servidor web onde o executável principal faz parte do controle de versão (por exemplo, um aplicativo CGI), deixando suas permissões (ou, nesse caso, as permissões do diretório que o contém, pois o usuário pode renomear o executável) em 777 permite que qualquer usuário execute qualquer executável como root.
Defina os requisitos
Mantido por um único usuário
Se apenas um usuário for responsável pela manutenção do site, defina-o como o proprietário do usuário no diretório do site e conceda ao usuário permissões rwx completas. O Apache ainda precisa de acesso para que possa servir os arquivos, então defina www-data como o proprietário do grupo e dê ao grupo permissões rx.
No seu caso, Eve, cujo nome de usuário pode ser
eve
, é o único usuário que mantémcontoso.com
:Se você tiver pastas que precisam ser graváveis pelo Apache, basta modificar os valores de permissão para o proprietário do grupo para que www-data tenha acesso de gravação.
O benefício dessa configuração é que fica mais difícil (mas não impossível*) para outros usuários no sistema bisbilhotar, já que apenas os proprietários do usuário e do grupo podem navegar no diretório do seu 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 para 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 com o nome desse site.
No exemplo anterior, usamos o proprietário do grupo para dar 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, então damos acesso de leitura ao resto do mundo.
Se você tiver pastas que precisam ser graváveis 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 de que precisa. 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.
Embora esta seja uma abordagem comum, há uma desvantagem. Como todos os outros usuários do sistema têm os mesmos privilégios no seu site que o Apache, é fácil para outros usuários navegarem em seu site e lerem arquivos que possam conter dados secretos, como seus arquivos de configuração.
Você pode ter seu bolo e comê-lo também
Isso pode ser melhorado ainda mais. É perfeitamente legal para o proprietário ter menos privilégios do que o grupo, então, 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. Esta é uma reversão do cenário de mantenedor único, mas funciona igualmente bem.
Se você tiver pastas que precisam ser graváveis pelo Apache, basta modificar os valores de permissão para o proprietário do usuário para que www-data tenha acesso de gravação.
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 poderão ser lidos pelo Apache até que você os execute.
* Separação de privilégios do Apache
Mencionei anteriormente que é realmente possível para outros usuários bisbilhotar seu site, não importa que tipo de privilégios você esteja usando. Por padrão, todos os processos do Apache são executados com o mesmo usuário www-data, 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 consiga que o Apache execute um script pode obter o mesmo acesso que o próprio Apache tem.
Para combater esse problema, existem várias abordagens para a 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 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 lançamento que atualize o servidor web a partir do conteúdo de um sistema de controle de versão. A abordagem de um único mantenedor provavelmente é ideal, mas em vez de uma pessoa, você automatizou o software.
Se seu site permite uploads que não precisam ser entregues, esses uploads devem ser armazenados em algum lugar fora da raiz da web. Caso contrário, você pode descobrir que as pessoas estão baixando arquivos que deveriam ser secretos. Por exemplo, se você permitir que os alunos enviem tarefas, elas deverão ser salvas em um diretório que não seja servido 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, convém escrever um script que configure todas as permissões. Teste-o completamente e, em seguida, mantenha-o seguro. Pode valer seu peso em ouro se você precisar reconstruir seu site por algum motivo.
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 essa parte certa para algo diferente de "0", você apenas permite que o mundo inteiro faça algo no arquivo/diretório.
Minha abordagem é a seguinte:
cache/
ouuploads/
, onde a permissão "write" também é necessária. Para dar ao PHP FastCGI essa habilidade, ele será executado como bob-www e bob-www será adicionado ao grupo bob criado automaticamente .AllowOverride
estiver definido para algo diferente deNone
. Para evitar o uso da parte o dos direitos, adiciono o usuário www-data ao grupo bob .Agora:
Esta é uma recapitulação, mas nesta situação, bob tem permissão para SSH. Se não houver nenhum usuário com permissão para modificar o site (por exemplo, o cliente só modifica o site através de um painel de administração do CMS e não tem conhecimento de Linux), crie dois usuários de qualquer maneira, mas dê
/bin/false
como shell para bob também, e desabilite seu login.Nota: as pessoas tendem a esquecer que limitar os direitos de u (proprietário) é na maioria das vezes inútil e inseguro, já que o dono 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 esta configuração tem um problema: quando o PHP/Apache cria um novo arquivo (por exemplo, upload), ele pertencerá a bob-www:bob , e bob só poderá lê-lo. Talvez o setuid no diretório possa resolver o problema.
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 notar que o Linux ignora
setuid
, então todos os novos arquivos serão de propriedade do usuário que os criou. Isso significa que depois de criar novos diretórios e arquivos, você terá que usar algo semelhante a:No Ubuntu 12.04 para Rackspace OpenStack, tive um problema estranho em que não consegui permissões 570 para funcionar até reiniciar o servidor, o que magicamente corrigiu o problema. Estava perdendo cabelos a uma taxa crescente por causa desse problema aparentemente simples ....
Vou com esta configuração:
root
e gruporoot
, permissões para0755
.root
e gruporoot
, permissões para0644
.root
, grupowww-data
, permissões para1770
. O sticky bit não permite que o proprietário do grupo remova ou renomeie o diretório e os arquivos dentro dele.www-data
usuário e grupo proprietário e0700
permissões para cadawww-data
usuário que faz upload de arquivos.Negar
AllowOverride
eIndex
no diretório de uploads, para que o Apache não leia.htaccess
os arquivos e o usuário do Apache não possa indexar o conteúdo da pasta de uploads:6.
php.ini
configuração:Com esta configuração, o
www-data
usuário não poderá entrar em diretórios que não sejamsiteDir/
/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 para upload na mesma solicitação.When you have a FTP user called "leo" need to upload files to example.com web directory and you also require your "apache" user to be able to create uploa-files/sessions/cache files in cache directory then do as follows:
This command assigns leo as owner and group as apache to example.com, apache user is a part of group apache so it will inherit the permissions of apache group
Another command which insures right permission and fulfill security concerns as well.
Here first number 2 is for directory and insures each new file created will be remain in same group and owner permissions. 77 is for owner and group means they have full access. 4 is for others mean they can only read trough.
following is helpful to understand permission numbers
IMO one has to take into account:
Let's assume you have a server which various data under user 'test'.
The 'test' user has there:
$HOMEDIR
$MAIL
/var/www/test
Now let's think about:
test
user (PHP-FPM) - it can delete any of his files!test
group (PHP-FPM) - it can delete any of his files where directory has 'w' for the group and can modify any file which has 'r' for the group; and it could still read them - your ssh keys for example!Let's assume PHP is buggy, and it is, do you trust its
open_basedir
? Do youchroot
your PHP process? What is you don't, do you want it does crawls through all filesystem?Your web app process, eg. PHP-FPM, then should:
chroot
Thus you can do:
test:test
test-www
test-www:test-www
chmod u=rwX,g=rX,o= /var/www/test/public
chmod u=rwX,g=rwXs,o= /var/www/test/public/upload
(thus the app will create new files as:test-www:test-www
- it will have test-www group because of setgid on the directory!)Thus, if the web app process would be bogus it would just read specific files which would have group read, and it would be able to write to
upload
dir only. I would strongly recommend to have thatupload
dir on a filesystem withnoexec,nodev,nosuid
mount
options and have constant monitoring for any new bizzare files in that directory, plus also monitor any new processes undertest-www
uid.On Linux one could use ACL to better tune permissions. If more than one human should be to upload web data, it would be better to split human account from the account used to upload web data files, ie. to create new account eg.
test-upload
, and test user would manage ssh keys to restrict which human could ssh/sftp there.sshd_config
knowsExposeAuthInfo
options thus it can be configured to log which ssh key was used to upload the data.I really doubt most webhosting services care about privileges separation, when they write 'secure' without any info what you get, I would say they lie.