Como posso usar o SELinux para confinar os scripts PHP?

7

Eu quero compartimentar diferentes aplicativos PHP no meu servidor da web SL6.4 (reconstrução do RHEL 6.4) para que eles não possam acessar os dados uns dos outros. Parece que o SELinux pode fazer isso, mas não tenho certeza dos detalhes. Minha pergunta tem duas partes:

  1. Como o SElinux gerencia scripts PHP em execução no processo Apache com mod_php? O processo de alguma forma entra no contexto do script ao executar o script PHP, ou isso só funciona quando os scripts são executados fora de processo via CGI ou FastCGI? Se ele faz a transição para um contexto de script para executar o script PHP, o que impede que um bug do PHP acione uma transição de volta ao contexto principal do httpd? Se eu precisar de um método alternativo de implementação do PHP, seria bom saber.
  2. Como posso separar scripts / aplicativos para que, por exemplo, O TinyTinyRSS não pode acessar coisas de propriedade do OpenCloud? Parece que eu deveria ser capaz de fazer isso desativando httpd_unified e fornecendo conjuntos de contextos httpd_ttrss_* e httpd_opencloud_* separados, paralelamente a httpd_user_foo e httpd_sys_foo . Pode até ser suficiente para mim usar a distinção sys / user sem novos contextos, dado o número de aplicativos que eu posso usar. Mas não encontrei muita documentação sobre exatamente quais são as implicações de desativar httpd_unified ou como configurar diferentes contextos HTTP. Particularmente com scripts PHP executados via mod_php .

Eu estou bem com a criação de novos módulos de políticas do SELinux, mas gostaria de alguma documentação apontando para o que eu preciso fazer a nova política fazer e como fazer com que ela se integre bem com a política direcionada do SELinux.

Se é uma causa perdida tentar fazer essa separação apenas com o SELinux e eu precisar criar httpds separados em diferentes contextos, ou possivelmente até mesmo contêineres LXC, isso também seria uma resposta útil.

    
por Michael Ekstrand 17.04.2013 / 16:53

1 resposta

4

A melhor maneira de alcançar este nível de separação é não usar transições de tipo, mas sim transições de categoria / MCS. Isso funciona um pouco como a implementação svirt no material do KVM libvirt.

OK, a primeira coisa que você precisa fazer é baixar um módulo httpd chamado mod_selinux . Ele está flutuando no fedora repos há algum tempo, mas nunca chegou aos sistemas EL6, infelizmente.

Em qualquer caso, você pode reconstruir o pacote a partir de fontes fedora. Eu fiz isso em uma máquina fedora, mas você pode simplesmente baixar o mesmo pacote de um espelho. Eu usei o F16 como base, pois ele executa httpd-2.2 .

yumdownloader --source mod_selinux --releaserver=16
...
mod_selinux-2.2.2454-3.fc15.src.rpm                        |  23 kB   00:00

Então, quando baixado, reconstrua em sua caixa EL6.

rpmbuild --rebuild mod_selinux-2.2.2454-3.fc15.src.rpm
...
Wrote: /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

Por fim, instale o módulo.

rpm -i /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

O RPM instala um módulo para httpd , que você precisará e também uma política para httpd , que também é necessária para que isso seja executado.

O arquivo deste módulo está instalado em /etc/httpd/conf.d/mod_selinux.conf .

O primeiro estágio nesse processo é aumentar o número de categorias executadas pelo processo httpd principal, para que ele possa produzir encadeamentos filhos que abrangem o intervalo correto. Na alteração do arquivo:

selinuxServerDomain     *:s0

Para

selinuxServerDomain     *:s0-s0:c0.c1023

Agora, você deve atribuir a cada host virtual no apache uma categoria. Isso é feito adicionando uma linha como no exemplo abaixo chamado 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>

Em seguida, na raiz do documento para cada host, renomeie novamente suas raízes de documento para a categoria mesmo como as rotuladas na configuração httpd.

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

Se você quiser fazer com que a rotulagem seja honrada se você fizer uma reclassificação do sistema, é melhor atualizar a política local também!

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(/.*)?'

E é isso! É impossível deixar a raiz do documento e explorar os outros agora.

    
por 19.04.2013 / 20:48