Hospedagem multi-site - vulnerabilidade importante perdida para proteger sites uns dos outros?

9

EDIT # 2 23 de julho de 2015: procurando uma nova resposta que identifique um item de segurança importante perdido na configuração abaixo ou que possa dar motivos para acreditar que tudo está coberto.

EDIT # 3 29 de julho de 2015: Estou especialmente procurando por um possível erro de configuração, como inadvertidamente permitir algo que possa ser explorado para contornar as restrições de segurança ou, pior ainda, deixar algo bem aberto.

Esta é uma configuração de hospedagem multi-site / compartilhada e queremos usar uma instância compartilhada do Apache (ou seja, executada sob uma conta de usuário), mas com PHP / CGI sendo executado como usuário de cada site para garantir que nenhum site possa acessar arquivos de outro site; queremos ter certeza de que nada está sendo perdido (por exemplo, se não soubermos sobre a prevenção de ataques de links simbólicos).

Aqui está o que eu tenho até agora:

  • Assegure-se de que os scripts PHP sejam executados como a conta e grupo de usuários do Linux do site e que estejam presos (como o uso do CageFS) ou pelo menos adequadamente restritos usando as permissões do sistema de arquivos do Linux.
  • Use o suexec para garantir que os scripts CGI não possam ser executados como o usuário do Apache.
  • Se precisar de suporte de inclusão do lado do servidor (como em arquivos shtml), use Options IncludesNOEXEC para evitar que o CGI possa ser executado quando você não o espera (embora isso não deva ser tão preocupação se usar o suexec).
  • Tenha a proteção de ataques de links simbólicos em ação para que um hacker não consiga enganar o Apache para que sirva os arquivos de outro site como texto simples e divulgue informações exploráveis como senhas de banco de dados.
  • Configure AllowOverride / AllowOverrideList para permitir apenas as diretivas que um hacker não conseguiu explorar. Acho que isso é menos preocupante se os itens acima forem feitos corretamente.

Eu iria com o MPM ITK se não fosse tão lento e não fosse executado como root, mas estamos especificamente querendo usar um Apache compartilhado, mas certifique-se de que ele seja feito de forma segura.

Encontrei o link , mas não foi abrangente sobre este tópico.

Se for útil saber, planejamos usar o CloudLinux com o CageFS e o mod_lsapi.

Existe mais alguma coisa para se fazer ou conhecer?

EDIT 20 de julho de 2015: As pessoas enviaram algumas boas soluções alternativas que são valiosas em geral, mas observe que essa questão é direcionada apenas para a segurança de uma configuração compartilhada do Apache. Especificamente há algo não coberto acima que poderia permitir que um site acessasse os arquivos de outro site ou comprometesse outros sites de alguma forma?

Obrigado!

    
por sa289 11.07.2015 / 06:03

8 respostas

9

Concordo completamente com os itens que você tem até agora.

Eu usei uma configuração multi-usuário há alguns anos e eu basicamente encontrei o mesmo trade-off: mod_php é rápido (parcialmente porque tudo roda dentro do mesmo processo) e suexec é lento mas seguro (porque todo pedido bifurca um novo processo). Eu fui com o suexec, porque o isolamento do usuário era necessário.

Atualmente, há uma terceira opção que você pode considerar: fornecer a cada usuário seu próprio daemon php-fpm. Se isso é viável depende do número de usuários, porque cada um deles precisa obter pelo menos um processo php-fpm usando sua conta de usuário (o daemon então usa um mecanismo tipo prefork para escalar as solicitações, portanto o número de processos e seu uso de memória pode ser um fator limitante). Você também precisará de alguma geração de configuração automatizada, mas isso deve ser feito com alguns scripts de shell.

Eu não usei esse método em grandes ambientes, mas IMHO é uma boa solução para fornecer um bom desempenho do site PHP enquanto isola usuários no nível do processo.

    
por 13.07.2015 / 22:20
4

Tudo o que você tem até agora parece bem pensado. A única coisa que pude ver como um problema é o fato de que a maioria das explorações busca obter acesso root de uma forma ou de outra. Então, mesmo que cada site e seus processos e scripts correspondentes sejam aprisionados corretamente e tudo tenha seu próprio usuário e permissões, um hacker com root não poderia se importar menos, eles apenas evitarão tudo que você configurou.

Minha sugestão seria usar algum tipo de software de VM (VMware, VirtualBox, Qemu, etc) para dar a cada site sua própria cadeia de sistema operacional. Isso permite que você, como administrador do sistema, não se preocupe com um único site comprometido. Se um hacker ganhar raiz explorando o php (ou qualquer outro software) na VM de um site, basta pausar a VM e dissecá-la depois, aplicar as correções ou reverter para um estado ininterrupto. Isso também permite que os administradores do site apliquem um software específico ou uma configuração de segurança ao seu ambiente de site específico (o que pode interromper outro site).

A única limitação para isso é o seu hardware, mas com um servidor decente e as extensões de kernel corretas, isso é fácil de lidar. Eu corri com sucesso este tipo de configuração em um Linode, concedido tanto o Host e o Visitante eram muito muito escassos. Se você está confortável com a linha de comando que eu suponho que você é, você não deve ter nenhum problema.

Esse tipo de configuração reduz o número de vetores de ataque que você precisa monitorar e permite que você se concentre na segurança das máquinas host e lide com tudo o mais em cada site.

    
por 14.07.2015 / 19:19
4

Eu sugiro que cada site seja executado sob seu próprio daemon do Apache e fazendo o cromato do Apache. Toda a função php do sistema falhará, pois o ambiente chroot do Apache não terá acesso a / bin / sh. Isso também significa que a função mail () do php não funcionará, mas se você estiver usando um provedor de email externo para enviar e-mails do seu aplicativo de e-mail, isso não deve ser um problema para você.

    
por 14.07.2015 / 19:33
4

O SELinux pode ser útil com mod_selinux . Um howto rápido é apresentado aqui:

Como posso usar o SELinux para confinar scripts PHP?

Como as instruções estão um pouco desatualizadas, verifiquei se isso funciona no RHEL 7.1:

Eu usei Versão do Fedora 19 e compilado com mock no RHEL 7.1 + EPEL.

YMMV se você usar os navios de simulação de configuração epel com:

[mockbuild@fedora mod_selinux]$ mock -r rhel-7-x86_64 --rebuild \
    mod_selinux-2.4.3-2.fc19.src.rpm

Atualize seu sistema de destino primeiro para garantir que selinux-policy seja atual.

Instalar na caixa de destino (ou colocar no seu espelho local primeiro):

yum localinstall mod_selinux-2.4.3-2.el7.x86_64.rpm

Now, you must assign each virtual host in apache a category. This is done by adding a line such as in the example below called selinuxDomainVal.

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host1
    ServerName host1.virtual
    selinuxDomainVal *:s0:c0
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host2
    ServerName host2.virtual
    selinuxDomainVal *:s0:c1 
</VirtualHost>

Next, in the document root for each host, relabel their document roots to the same category as the ones labelled in the httpd config.

chcon -R -l s0:c0 /var/www/vhosts/host1
chcon -R -l s0:c1 /var/www/vhosts/host2

If you want to make the labelling get honoured if you do a system relabel, you'd better update the local policy too!

semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c0 '/var/www/vhosts/host1(/.*)?' 
semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c1 '/var/www/vhosts/host2(/.*)?'
    
por 17.07.2015 / 15:39
4

Existem muitas respostas técnicas já fornecidas (por favor, dê uma olhada aqui: link e < um href="https://serverfault.com/q/212269/118677"> Dicas para proteger um servidor LAMP ), mas eu ainda gostaria de mencionar aqui um ponto importante (a partir de outra perspectiva) sobre o segurança: segurança é um processo . Tenho certeza que você já considerou isso, mas eu ainda espero que possa ser útil (também para outros leitores), às vezes, repensá-lo.

Por exemplo, em sua pergunta, você se concentra principalmente nas medidas técnicas: "esta questão é direcionada apenas em relação à segurança de uma configuração compartilhada do Apache. Especificamente, existem algumas etapas de segurança que são importantes para serem executadas, mas estão ausentes da lista acima ao executar o Apache e PHP compartilhados."

Quase todas as respostas aqui e em outras duas perguntas que mencionei também parecem ser puramente técnicas (exceto a recomendação de permanecer atualizado). E, do meu ponto de vista, isso poderia deixar alguns leitores com uma impressão enganosa de que, se você configurar seu servidor de acordo com a melhor prática, você ficará seguro para sempre. Então, por favor, não se esqueça dos pontos que sinto falta nas respostas:

  1. Em primeiro lugar, não se esqueça de que segurança é um processo e, em particular, sobre o ciclo "Planejar-Fazer-Verificar-Agir", conforme recomendado por muitos padrões, incluindo ISO 27001 ( link ). Basicamente, isso significa que você precisa revisar regularmente suas medidas de segurança, atualizá-las e testá-las .

  2. Atualize regularmente seu sistema. Isso não ajudará em ataques direcionados usando vulnerabilidades de dia zero, mas ajudará em quase todos os ataques automatizados.

  3. Monitore seu sistema. Eu realmente sinto falta desse ponto nas respostas. Do meu ponto de vista, é extremamente importante ser notificado o mais cedo possível sobre algum problema com o seu sistema.

    Isso é o que as estatísticas dizem sobre isso: "O tempo médio entre a infiltração e a descoberta é de 173,5 dias" ( link ), "205 mediana do número de dias antes da detecção" ( link ). E espero que esses números não sejam o que todos nós queremos ter.

    Existem muitas soluções (inclusive gratuitas) não apenas para monitorar o estado do serviço (como o Nagios), mas também sistemas de detecção de intrusão (OSSEC, Snort) e sistemas SIEM (OSSIM, Splunk). Se se tornar muito complicado, você poderia pelo menos habilitar algo como 'fail2ban' e / ou encaminhar seus logs para o servidor syslog separado e ter notificações de e-mail sobre os eventos importantes.

    Mais uma vez, o ponto mais importante aqui não é qual sistema de monitoramento você escolhe, o mais importante é que você tenha algum monitoramento e revise-o regularmente de acordo com seu ciclo "Planejar-Fazer-Verificar-Agir" .

  4. Esteja ciente das vulnerabilidades. O mesmo que monitorando. Basta se inscrever em uma lista de vulnerabilidades para ser notificado, quando alguma vulnerabilidade crítica for descoberta para o Apache ou outro serviço importante para sua configuração. O objetivo é ser notificado sobre as coisas mais importantes que aparecem antes da sua próxima atualização planejada.

  5. Tenha um plano sobre o que fazer no caso de um incidente (e atualize e revise regularmente de acordo com o seu ciclo "Planejar-Fazer-Verificar-Agir"). Se você fizer perguntas sobre configuração segura, isso significa que a segurança do seu sistema se torna importante para você. No entanto, o que você deve fazer no caso se o sistema foi invadido, apesar de todas as medidas de segurança? Mais uma vez, não quero dizer apenas medidas técnicas aqui como "reinstalar o sistema operacional": onde você deve relatar um acidente de acordo com a lei aplicável? Você tem permissão para desligar / desconectar seu servidor imediatamente (quanto custa para sua empresa)? Quem deve ser contatado se a pessoa responsável principal estiver de férias / doente?

  6. Tenha um servidor de backup, arquivamento e / ou substituição / replicação. Segurança também significa disponibilidade do seu serviço. Verifique seu backup / archive / replicação regularmente e também teste os procedimentos de restauração regularmente.

  7. Teste de penetração? (novamente, consulte o ciclo "Planejar-Fazer-Verificar-Agir" :) Se parecer muito, você pode pelo menos experimentar algumas ferramentas on-line gratuitas que examinam seus serviços da Web em busca de malware e problemas de segurança.

por 21.07.2015 / 12:32
3

Seu caso de uso é ideal para contêineres docker.

Cada contêiner pode representar um cliente ou cliente, com IDs de usuário exclusivos atribuídos a cada grupo de contêineres do Apache como segurança adicional. A chave seria descartar privilégios de root no início do contêiner, antes de iniciar sua pilha de apache. Cada cliente recebe seu próprio serviço de banco de dados com suas próprias senhas exclusivas, sem a dor de cabeça de ficar em pé em dezenas de máquinas virtuais, cada uma exigindo seus próprios núcleos de flocos de neve especiais e outras despesas gerais. Afinal, no coração do docker está o chroot. Devidamente administrado, eu levaria isso para um cluster virtual típico qualquer dia.

    
por 18.07.2015 / 00:13
2

Muitas boas sugestões já estão aqui. Há coisas que foram perdidas na discussão até agora.

Preste atenção aos processos fora deles executados como parte do serviço de páginas da web. ou seja, certifique-se de que todos os seus trabalhos agendados que tocam dados não confiáveis estejam sendo executados como o usuário apropriado e na cadeia apropriada, sejam esses trabalhos definidos pelo usuário ou não.

Na minha experiência, coisas como a análise de logs, quando fornecidas pelo serviço de hospedagem, são executadas como root quase sempre, e o software de análise de logs não recebe tantas auditorias de segurança quanto gostaríamos. Fazer isso bem é um pouco complicado e dependente da configuração. Por um lado, você não quer que o seu processo apache de propriedade da raiz (ou seja, o processo pai) seja gravado em qualquer diretório que o usuário possa comprometer. Isso provavelmente significa não escrever diretamente na prisão. Por outro lado, você precisa disponibilizar esses arquivos para processos na cadeia para análise, e você gostaria que isso fosse o mais próximo possível do tempo real. Se você puder dar aos seus jaulas acesso a uma montagem somente leitura de um sistema de arquivos com os logs, isso deve ser bom.

Os aplicativos PHP normalmente não atendem aos seus próprios arquivos estáticos e, se você tiver um processo apache compartilhado, acredito que o processo do apache esteja lendo as coisas diretamente das prisões do ambiente host? Se assim for, então isso abre uma série de preocupações.

.htaccess arquivos são óbvios, onde você precisa ter muito cuidado com o que você permite. Muitos, se não, os aplicativos php mais substanciais são muito dependentes dos arranjos de arquivos .htaccess que você provavelmente não pode permitir sem subverter seu esquema planejado.

Menos óbvio é como o apache decide o que é um arquivo estático de qualquer maneira. por exemplo. O que faz com um arquivo *.php.gif ou *.php.en ? Se esse mecanismo ou outro engana a discriminação sobre o que é um arquivo estático, é possível que o apache execute o PHP de fora da cadeia? Eu configurei um servidor web leve e separado para conteúdo estático, que não é configurado com nenhum módulo para executar conteúdo dinâmico, e tenho um balanceador de carga decidindo quais solicitações enviar para o servidor estático e qual para o dinâmico.

Em relação à sugestão do Stefan Docker, é possível ter um único servidor web que fique fora do contêiner e que converse com daemons do php em cada contêiner para o conteúdo dinâmico, além de ter um segundo servidor web, que fica em uma janela de encaixe contêiner, e que compartilha os volumes que cada um usa para seu conteúdo, e é, portanto, capaz de servir o conteúdo estático, que é muito semelhante ao do parágrafo anterior. Eu recomendo o docker entre as várias abordagens do tipo cadeia, mas com essa ou outras abordagens do tipo cadeia, você terá várias outras questões para resolver. Como funciona o upload de arquivos? Você coloca daemons de transferência de arquivos em cada contêiner? Você adota uma abordagem baseada no estilo PAAS git? Como você torna os logs gerados dentro do contêiner acessíveis e os transfere? Como você gerencia e executa tarefas cron? Você dará aos usuários qualquer tipo de acesso ao shell e, em caso afirmativo, esse outro daemon dentro do contêiner? etc, etc.

    
por 29.07.2015 / 10:32
1

A primeira coisa que não vejo é o gerenciamento de processos, portanto, um processo não pode passar fome por outro processo de CPU ou RAM (ou E / S, embora seu sistema de arquivos possa ser arquitetado para evitar isso). Uma grande vantagem de uma abordagem de "contêineres" às suas instâncias do PHP, em vez de tentar executá-las todas em uma imagem "OS", é que você pode restringir melhor a utilização de recursos dessa maneira. Eu sei que não é o seu design, mas isso é algo a considerar.

De qualquer forma, voltemos ao caso de uso do PHP rodando atrás do Apache, basicamente funcionando como um proxy. O suexec não não impede que algo seja executado como o usuário do apache - ele fornece a capacidade para ser executado como outro usuário. Portanto, uma preocupação é garantir que tudo seja feito corretamente - a página do documento chama a atenção para esse possível perigo: link . Então, você sabe, grão de sal e tudo isso.

Do ponto de vista de segurança, pode ser útil ter um conjunto restrito de binários de usuário para trabalhar (que a cagefs fornece), especialmente se forem compilados de forma diferente ou contra uma biblioteca diferente (por exemplo, um que não inclua recursos indesejados). ) mas o perigo é que nesse ponto você não está mais seguindo uma distribuição conhecida por atualizações, você está seguindo uma distribuição diferente (cagefs) para suas instalações PHP (pelo menos no que diz respeito às ferramentas de espaço do usuário) . Embora você provavelmente já esteja seguindo uma distribuição específica com o cloudlinux, esse é um risco incremental, não necessariamente interessante por si só.

Eu deixaria o AllowOverride onde você poderia ter desejado. A idéia central por trás da defesa em profundidade é não confiar em uma única camada para proteger toda a sua pilha. Sempre assuma que algo pode dar errado. Mitigar quando isso acontece. Repita até que você tenha atenuado, assim como você pode, mesmo se você tiver apenas uma cerca na frente de seus sites.

O gerenciamento de logs será fundamental. Com vários serviços sendo executados em sistemas de arquivos isolados, a integração de atividades para correlacionar quando há um problema pode ser um problema menor se você não tiver configurado isso desde o início.

Esse é o meu cérebro. Espero que haja algo vagamente útil lá. :)

    
por 28.07.2015 / 02:54