Apache partilhado, com VirtualHosts, com segurança

Neste artigo, pretendo partilhar convosco, como configurar o Apache num ambiente em que o Apache é partilhado por vários sites.

Quando o Apache, é partilhado entre vários sites, de vários utilizadores, ou clientes. É necessário ter em conta, pormenores de segurança. É importante proteger os ficheiros, de cada um dos clientes. Não faz sentido, que os clientes tenham acesso endivido, ao conteúdo dos outros utilizadores.

Normalmente, isto acontece em empresas que vendem serviços de alojamento, para alojar aplicações como o WordPress, Joomla, etc.

O Apache é hoje em dia o servidor líder na web. Claro, que a qualidade e a facilidade de uso, ajudam bastante para esta liderança.

Quando é instalado, está preparado para funcionar apenas com um utilizador. Quando pretendemos que ele tenha vários “VirtualHosts“, que serão administrados por empresas ou clientes distintos, é necessário ter em conta, alguns princípios de segurança.

O Apache, tem tudo o que é necessário, para que possamos implementar vários “VirtualHosts” com segurança. Apenas, temos que fazer umas configurações.

Neste artigo, vou exemplificar a configuração do Apache, para que funcione com segurança, com vários utilizadores distintos.

Vou utilizar, o Ubuntu 14.04 Server instalado de novo e atualizado, para testar e demonstrar esta solução. Claro, que para outras distribuições, poderá ser diferente algumas configurações, no entanto, os princípios básicos, são estes para o Apache, num ambiente Linux.

Com esta configuração, pretendo separar o conteúdo dos vários “VirtualHosts“, o conteúdo estático e dinâmico. O que permite, isolar o conteúdo de cada utilizador, até mesmo em tempo de execução. Não será possível, os utilizadores terem acesso indevido aos ficheiros de outros utilizadores, até mesmo com scriptsPHP. Isolando totalmente o conteúdo de todos os utilizadores.

Para que seja possível isolar todos os utilizadores, é necessário criarmos uma lógica de utilizadores, com permissões que permita isola-los.

Vamos lá então, configurar esta solução!

Neste exemplo vou criar três VirtualHosts:

  • site1 – Para o web site 1
  • site2 – Para o web site 2
  • site3 – Para o web site 3

Cada um deles irá necessitar de um utilizador e de um grupo próprio:

  • site1 – utilizador: us1 – grupo: gs1
  • site2 – utilizador: us2 – grupo: gs2
  • site3 – utilizador: us3 – grupo: gs3

Criar Utilizadores e Grupos

Para começar, irei criar os utilizadores e grupos necessários para esta solução.

Criar o grupo do site1:

$ sudo groupadd gs1

Criar o utilizador e indicar o grupo a que pertence, gs1:

$ sudo useradd -c "Utilizador do site1" -s /bin/false -m -d /home/us1 -g gs1 us1

Criar o grupo do site2:

$ sudo groupadd gs2

Criar o utilizador e indicar o grupo a que pertence, gs2:

$ sudo useradd -c "Utilizador do site2" -s /bin/false -m -d /home/us2 -g gs2 us2

Criar o grupo do site3:

$ sudo groupadd gs3

Criar o utilizador e indicar o grupo a que pertence, gs3:

$ sudo useradd -c "Utilizador do site3" -s /bin/false -m -d /home/us3 -g gs3 us3

Neste momento temos os utilizadores e grupos criados. Todos eles, foram criados com o seu diretório pessoal em /home.

Criar diretório para o conteúdo web

Para guardarmos de forma organizada, o conteúdo web de cada utilizador, separando de outro tipo de conteúdo, iremos criar um diretório especifico, para conteúdo web. Iremos criar o diretório “www” dentro do diretório pessoal de cada utilizador.

Para tal fazemos:

$ sudo mkdir /home/us1/www
$ sudo mkdir /home/us2/www
$ sudo mkdir /home/us3/www

Ajustar as permissões dos diretórios pessoais

Agora iremos ajustar as permissões do diretório pessoal, dos utilizadores, que por defeito são criadas dando a outros utilizadores permissões de leitura. E para que os utilizadores sejam completamente isolados iremos retirar a permissão aos outros utilizadores.

Para retirar as permissões aos outros utilizadores:

$ sudo chmod -R 770 /home/us1
$ sudo chmod -R 770 /home/us2
$ sudo chmod -R 770 /home/us3

Estabelecer o utilizador e grupo dos diretórios

$ sudo chown us1:gs1 -R /home/us1
$ sudo chown us2:gs2 -R /home/us2
$ sudo chown us3:gs3 -R /home/us3

Neste momento, temos todos os utilizadores e grupos, necessários para por a solução a funcionar, com segurança. Bem como, os diretórios, onde queremos alojar o conteúdo web, que cada utilizador irá partilhar na Internet.

Instalar software

Neste momento podemos começar a instalar o software necessário para o Apache. Necessitamos de instalar os seguintes pacotes:

  • apache2-mpm-itk: Este modulo permite, ao apache, correr cada VirtualHost e seus processos com um utilizador independente. O que nos permite o isolamento necessário para esta solução.
  • libapache2-mod-php5: Permite termos o php5 a correr no nosso servidor. O php é muito utilizado para aplicações web, é uma linguagem indispensável. E neste caso os scripts serão executados com as permissões de cada utilizador.

Para podermos instalar este software, corremos o seguinte comando:

$ sudo apt-get install apache2-mpm-itk libapache2-mpm-itk libapache2-mod-php5

Ao instalarmos, estes pacotes de software, iram ser instaladas outras dependências, inclusive, o próprio Apache.

Neste momento, temos o software necessário instalado, podemos continuar a configurar esta solução.

Configurar o Apache

Visto que optei, por criar o diretório pessoal de cada utilizador, em /home, temos que informar ao apache, para permitir servir conteúdo a partir do mesmo.

Para tal, editamos o ficheiro “/etc/apache2/apache2.conf” e adicionamos as seguintes linhas de texto. Após, as outras configurações de diretórios, para fins de organização ou no final do ficheiro.

<Directory /home/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

Editar o ficheiro:

$ sudo nano /etc/apache2/apache2.conf

Neste momento, o Apache está pronto para disponibilizar conteúdo web, de cada um dos nossos utilizadores, a partir do diretório /home.

Criar os “VirtualHosts

Agora, temos que criar os “VirtualHosts“, para cada um dos utilizadores e configura-los. Para tal, iremos criar os ficheiros em “/etc/apache2/sites-available/”. Este diretório, guarda todos os ficheiros com as configurações, dos “VirtualHosts“.

Para criar o “VirtualHost” do “site1“, editamos o ficheiro “/etc/apache2/sites-available/site1.conf” e colocamos o seguinte conteúdo:

<VirtualHost *:80>
    ServerAdmin root@site1
    ServerName site1
    DocumentRoot /home/us1/www
    DirectoryIndex index.php index.html index.htm
    ErrorLog /home/us1/error.log
    LogLevel warn
        CustomLog /home/us1/access.log combined

    <IfModule mpm_itk_module>
        AssignUserId us1 gs1
    </IfModule>
</VirtualHost>

Editar o ficheiro:

$ sudo nano /etc/apache2/sites-available/site1.conf

Para criar o “VirtualHost” do “site2“, editamos o ficheiro “/etc/apache2/sites-available/site2.conf” e colocamos o seguinte conteúdo:

<VirtualHost *:80>
    ServerAdmin root@site2
    ServerName site2
    DocumentRoot /home/us2/www
    DirectoryIndex index.php index.html index.htm
    ErrorLog /home/us2/error.log
    LogLevel warn
        CustomLog /home/us2/access.log combined

    <IfModule mpm_itk_module>
        AssignUserId us2 gs2
    </IfModule>
</VirtualHost>

Editar o ficheiro:

$ sudo nano /etc/apache2/sites-available/site2.conf

Para criar o “VirtualHost” do “site3“, editamos o ficheiro “/etc/apache2/sites-available/site3.conf” e colocamos o seguinte conteúdo:

<VirtualHost *:80>
    ServerAdmin root@site3
    ServerName site3
    DocumentRoot /home/us3/www
    DirectoryIndex index.php index.html index.htm
    ErrorLog /home/us3/error.log
    LogLevel warn
        CustomLog /home/us3/access.log combined

    <IfModule mpm_itk_module>
        AssignUserId us3 gs3
    </IfModule>
</VirtualHost>

Editar o ficheiro:

$ sudo nano /etc/apache2/sites-available/site3.conf

Ativar os “VirtualHosts

Agora, que temos os “VirtualHosts” criados, para os nossos três sites, temos de ativá-los, para que o Apache possa disponibilizar o conteúdo de cada um deles.

Para ativar um “VirtualHost“, usamos o comando “a2ensite“, este comando permite ativar um “VirtualHost“.

Ativamos os nossos três desta forma:

$ sudo a2ensite site1
$ sudo a2ensite site2
$ sudo a2ensite site3

Recarregar configurações

Para que o apache, carregue os novos “VirtualHosts“, é necessário manda-lo recarregar as configurações. Da seguinte forma:

$ sudo service apache2 reload

Modificar os permissões dos ficheiros LOG

Os ficheiros error.log e access.log de cada utilizador, são criados neste caso na raiz de cada diretório pessoal. Como estes logs são criados pelo root, as permissões têm de ser modificadas, para dar acesso apenas ao dono e ao grupo. Para isso:

$ sudo chmod 660 /home/us1/*.log
$ sudo chmod 660 /home/us2/*.log
$ sudo chmod 660 /home/us3/*.log

Estabelecer o utilizador e grupo dos ficheiros de LOG

$ sudo chown us1:gs1 /home/us1/*.log
$ sudo chown us2:gs2 /home/us2/*.log
$ sudo chown us3:gs3 /home/us3/*.log

Conteúdo de teste

Neste momento, temos o nosso Apache e seus “VirtualHosts” configurados. Para que possamos verificar que esta solução funciona, temos que ter uma forma de testar, que cada utilizador só tem acesso ao seu conteúdo. Para isso, iremos adicionar um pequeno script, que irá testar e mostrar o “id” de execução, em cada requisição feita a cada um dos sites. Bem como, testar o acesso aos ficheiros dos outros utilizadores, a fim de comprovar, que não é possível ler o conteúdo dos outros “VirtualHosts“.

Iremos criar o scriptindex.php“, dentro do diretório “www” de cada utilizador. Este fará o trabalho por nós. Colocamos o seguinte texto em cada ficheiro:

<!DOCTYPE html>
<html lang="pt">
    <head>
        <meta charset="utf-8">
        <title>Teste de permissões</title>
    </head>
    <body>
<?php
// Listar o "id" do utilizador e o nome com qual o script é executado
// bem como o "gid" do utilizador
echo "<p><b>Com que utilizador está a correr este script</b></br>";
echo system("/usr/bin/id");
echo "</p>";
//Testar se tem acesso ao ficheiro 'index.php' de cada "VirtualHost"
for($x=1; $x < 4; $x++){
    echo "<p><b>Acesso ao site$x</b></br>";
    $ficheiro="/home/us$x/www/index.php";
    if (file_exists($ficheiro)) {
        echo "Tem permissão de acesso ao ficheiro '$ficheiro'.</br>";
    }else{
        echo "Não tem permissão para aceder o ficheiro '$ficheiro'.</br>";
    }
}
echo "</p>";

//Testar se tem acesso de leitura no ficheiro 'index.php' de cada "VirtualHost"
for($x=1; $x < 4; $x++){
    echo "<p><b>Acesso de leitura ao site$x</b></br>";
    $ficheiro="/home/us$x/www/index.php";
    if (is_readable($ficheiro)) {
        echo "Tem permissão de leitura no ficheiro '$ficheiro'.";
    } else {
        echo "Não tem permissão de leitura no ficheiro '$ficheiro'.";
    }
}
echo "</p>";

//Testar se tem acesso de escrita no ficheiro 'index.php' de cada "VirtualHost"
for($x=1; $x < 4; $x++){
    echo "<p><b>Acesso de escrita ao site$x</b></br>";
    $ficheiro="/home/us$x/www/index.php";
    if (is_writable($ficheiro)) {
        echo "Tem permissão de escrita no ficheiro '$ficheiro'.";
    } else {
        echo "Não tem permissão de escrita no ficheiro '$ficheiro'.";
    }
}
echo "</p>";

?>
    </body>
</html>

Editar os ficheiros “index.php”:

$ sudo nano /home/us1/www/index.php
$ sudo nano /home/us2/www/index.php
$ sudo nano /home/us3/www/index.php

Modificar os permissões do scriptindex.php

O script index.php, de cada utilizador, foram criados como root, para evitar iniciar sessão, com cada um dos utilizadores. As permissões têm de ser modificadas, para dar permissão apenas ao utilizador e grupo. Para isso:

$ sudo chmod 660 /home/us1/www/index.php
$ sudo chmod 660 /home/us2/www/index.php
$ sudo chmod 660 /home/us3/www/index.php

Estabelecer o utilizador e grupo do script index.php

$ sudo chown us1:gs1 /home/us1/www/index.php
$ sudo chown us2:gs2 /home/us2/www/index.php
$ sudo chown us3:gs3 /home/us3/www/index.php

Com este tipo de configuração, é possível partilhar um servidor físico por vários sites, de forma segura e estável. Desta forma, os utilizadores só poderão trabalhar dentro do seu diretório pessoal. Evitando assim, problemas de segurança, que surgem entre sites. Bem como, acidentes esporádicos que podem acontecer, devido a anomalias inesperadas em scripts mal concebidos.

Teste

Para que possamos correr o script de teste, é necessário editar o ficheiro “/etc/hosts” de um Desktop qualquer, com Linux de preferência. Nele temos de adicionar a seguinte linha, para que possa ser possível aceder os “VirtualHosts” por um hostname. Temos de substituir o IP na linha, pelo IP real do servidor. Assim:

192.168.1.49 site1 site2 site3

Editar o ficheiro “/etc/hosts” no Linux:

$ sudo nano /etc/hosts

Neste momento está tudo configurado e pronto a ser testado, para isso utilizamos o nosso Browser preferido, o FireFox claro! Para aceder aos seguintes endereços:

http://site1
http://site2
http://site3

Se tudo correr como previsto, podemos comprovar que cada utilizador só tem permissão para aceder ao seu próprio conteúdo.

Comentem, partilhem e experimentem!

    Deixe uma resposta