Skip to content

Category Archives: apache

Configurando PHP5 sobre FastCGI no Apache

11-Dec-07

Eu trabalhei por mais de 3 anos como desenvolvedor PHP e durante todo esse tempo uma das coisas que sempre notei foi a facilidade em driblar a segurança de quase todos os servidores web por onde passei. Quase todas as empresas (sem citar nomes) se preocupam muito com a segurança externa de suas redes, mas a segurança interna de seus servidores (quando há) é extremamente falha.

O que pretendo mostrar nesse post, é um modelo de configuração para servidores Apache e PHP que trate todos os problemas de segurança com os quais EU já me deparei e comentar um pouquinho o porquê de cada coisa. Se você tiver alguma outra idéia, crítica ou sugestão que possa enriquecer o modelo proposto aqui, sinta-se à vontade para faze-lo. :)

Como eu geralmente utilizo distribuições Debian ou Ubuntu, os comandos apresentados abaixo estarão no formato padrão para essas duas distribuições, porém você conseguirá adequar facilmente o conteúdo deste post para qualquer outro “sabor” de Linux.

Por que utilizar o FastCGI?

Ok, então vamos começar explicando um pouco do porquê rodar o PHP sobre o FastCGI ao invés de utiliza-lo como um módulo normal do Apache.

O FastCGI é um módulo do Apache que, juntamente com o SuEXEC, permite especificar ao servidor qual usuário utilizar para executar os scripts CGI, ou seja, você consegue criar um usuário Unix para cada site rodando no seu servidor e forçar o apache a executar esses scripts sempre sob um mesmo usuário. Dessa forma, além da segurança tradicional proporcionada pelo Apache e PHP, você ainda tem a segurança do Unix restringindo as ações desse usuário dentro do sistema. Portanto a partir de agora esqueça os antigos usuários globais www-data, apache, etc.

Instalação dos pacotes

A primeira coisa a ser feita é instalar os pacotes necessários pelo servidor, que nesse caso são basicamente três: Apache, FastCGI e PHP5. Também é interessante instalar o pacote php5-suhosin que propociona algumas configurações de segurança adicionais ao PHP. Apesar do módulo suEXEC estar contido no pacote libapache2-mod-fcgid, ele não será habilitado no Apache e isso terá que ser feito manualmente, como segue abaixo:


$ aptitude install apache2 libapache2-mod-fcgid php5-cgi php5-suhosin
$ a2enmod suexec
$ /etc/init.d/apache2 reload

Configurando um novo site (Passo 1/3)

Como todos os sites terão seu próprio usuário Unix, o primeiro passo da configuração de um novo site consiste na criação deste usuário. Como a única função deste usuário será acessar o site e executar o PHP via CGI, podemos colocar os arquivos do site dentro do seu diretório home e ainda (por questões de segurança) remover o seu shell, assim como mostrado abaixo:

* Por motivos didáticos, irei utilizar como exemplo meu próprio site.


$ useradd --home /var/www/arthurfurlan.org --shell /bin/false --create-home arthurfurlan

Depois de criado o usuário arthurfurlan, precisamos criar os diretórios que serão utilizados pelo Apache e PHP, que são basicamente 4 diretórios:

  • o diretório html que armazenará o conteúdo do site.
  • o diretório session que armazenará os arquivos de sessão do site.
  • o diretório tmp que armazenará os arquivos temporários do site (uploads).
  • o diretório log que armazenará os arquivos de logs do site.

Segue abaixo o comando utilizado para a criação dos diretórios:


$ cd /var/www/arthurfurlan.org
$ mkdir -p html/www session tmp log
$ chown -R arthurfurlan: html/www session tmp log
$ cd -

A principal questão a ser levantada aqui é a separação do diretório de armazenamento sessões para cada site. Isso raramente é feito e possibilita que um usuário acesse os arquivos de sessão dos demais sites que estão na mesma máquina, dessa forma se torna fácil criar um script que procure por sessões contendo senhas de usuários, de administração, etc. dos outros sites. Essa separação (juntamente com outras configurações do php) previne esse tipo de ataque.

Configurando o PHP (Passo 2/3)

Outra funcionalidade legal do FastCGI é possibilidade de se utilizar um arquivo de configuração do PHP específico para cada site, o que proporciona um maior nível de segurança. EU, particularmente, gosto de renomear o arquivo php.ini para seguir o padrão do Linux de arquivos que configuração (.*rc), porém se preferir manter o nome padrão do arquivo php.ini, sinta-se á vontade.

Vamos copiar o arquivo de configuração default do PHP:


$ cp /etc/php5/cgi/php.ini /var/www/arthurfurlan.org/.php5rc

E aplicar as seguintes configurações:

  • safe_mode para on
  • safe_mode_include_dir para on
  • disable_functions para escapeshellarg, escapeshellcmd, exec, shell_exec, curl_exec, system, passthru, popen, proc_open, proc_close, dl, ini_alter, parse_ini_file, show_source, highlight_file
  • enable_dl para off
  • open_basedir para /var/www/arthurfurlan.org/html/www:/var/www/arthurfurlan.org/tmp:/var/www/arthurfurlan.org/session
  • upload_tmp_dir para /var/www/arthurfurlan.org/tmp
  • session.save_path para /var/www/arthurfurlan.org/session

* Eu não pretendo comentar o porquê de cada uma das configurações acima, senão o post vai acabar muito mais longo (e chato) do que já está! Caso você queira entender melhor alguma das delas, pergunte na sessão de comentários abaixo. :)

Devido à uma restrição do FastCGI, o arquivo que irá efetivamente executar o arquivo PHP através do CGI precisa pertencer ao mesmo usuário que está executando o CGI, no nosso caso, precisa pertencer ao usuário arthurfurlan. Esse arquivo precisar ser um shell script com permissão de execução, como mostrado abaixo:


$ cd /var/www/arthurfurlan.org
$ touch .php5cgi
$ chmod 755 .php5cgi
$ chown arthurfurlan: .php5cgi
$ cd -

Contendo o sequinte conteúdo:


$ vim /var/www/arthurfurlan.org/.php5cgi
#!/bin/sh
export PHPRC=/var/www/arthurfurlan.org/.php5rc
exec /usr/bin/php5-cgi "$@"

* Se você nomeou o arquivo de configuração do PHP com outro nome, você deve alterá-lo na variável de ambiente PHPRC do script acima.

Agora toda a parte de configuração do PHP do novo site já está configurada, e fica faltando somente criar o VirtualHost e habilitá-lo.

Configurando o VirtualHost do Apache (Passo 3/3)

Eu irei instalar o site em localhost, sobre o IP de loopback normal 127.0.0.1 mas caso você esteja configurando um site com para acesso externo basta alterar os locais correspondentes para o IP que desejar.

Vamos criar o NameVirtualHost para o novo site.
Abra o arquivo /etc/apache2/sites-available/default e adicione a linha abaixo, caso ainda não exista:


NameVirtualHost 127.0.0.1

Se você está configurando um site para rodar em localhost, você precisará configurar a sua máquina para que ela saiba que ela deve responder pelo domínio seu novo domínio, e isso pode ser feito adicionando no arquivo /etc/hosts a seguinte linha:


127.0.0.1 arthurfurlan.org

Caso esteja utilizando um IP para acesso externo, você precisará configurar o seu servidor de DNS para que aponte o seu novo domínio para o seu host.
Agora criaremos o VirtualHost como mostrado abaixo:


$ vim /etc/apache2/sites-available/arthurfurlan.org
<Virtualhost 127.0.0.1>
    ServerName arthurfurlan.org
    ServerAlias www.arthurfurlan.org
    ServerAdmin webmaster@arthurfurlan.org

    PHP_Fix_Pathinfo_Enable 1
    DocumentRoot /var/www/arthurfurlan.org/html/www
    SuexecUserGroup arthurfurlan arthurfurlan

    <Directory /var/www/arthurfurlan.org/html/www>
        Options +ExecCGI
        AddHandler fcgid-script .php
        FCGIWrapper /var/www/arthurfurlan.org/.php5cgi .php
    </Directory>

    ErrorLog /var/www/arthurfurlan.org/log/error.log
    CustomLog /var/www/arthurfurlan.org/log/access.log combined
</Virtualhost>

E agora sim, tudo terminado! Basta habilitar o recém-criado VirtualHost como mostrado abaixo para ter o seu novo site rodando sob o seu próprio usuário. :)


$ a2ensite arthurfurlan.org
$ /etc/init.d/apache2 reload

Corrigindo warnings da configuração default do Apache no Ubuntu 7.10

08-Oct-07

UPDATE: Essa correção também se aplica a versão 8.04 do Ubuntu.

Esse final de semana eu decidi instalar a versão beta do Ubuntu Gutsy na minha máquina para ver como está ficando a nova versão LTS do Ubuntu. Com relação à distro, eu realmente fiquei impressionado… Tem algumas coisas bastante interessantes e alguns efeitos (eye-candy) que me lembraram um pouco do Mac! Realmente essa nova versão está muito bacana, mas nesse post eu não vou falar sobre isso e vou tratar de um assunto um pouquinho chato: um probleminha na configuração do apache dessa nova versão (e das anteriores).

Como todo bom freelancer, sempre que eu instalo um novo sistema no meu desktop eu configuro o servidor web para poder tocar meus projetos… E como geralmente eu estou envolvido com mais do que um sistema, eu costumo criar VirtualHost’s para cada um deles! Por isso é bastante comum eu restartar várias vezes o meu servidor apache sempre que altero alguma configuração, e desde a versão passada do Ubuntu que eu notei que a configuração default do Apache (na verdade não é configuração do apache) gera um monte de warnings estranhos, como segue abaixo:


$ sudo apt-get install apache2
...
$ sudo /etc/init.d/apache2 restart
 * Restarting web server apache2
apache2: apr_sockaddr_info_get() failed for isengard
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
apache2: apr_sockaddr_info_get() failed for isengard
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
[ OK ]

A princípio essas mensagens de warning não atrapalham a execução do servidor que é iniciado normalmente após exibi-las, porém é bastante chato que ter que ficar lendo esse monte de “erros” sempre que você for reiniciar o servidor… Essas mensagens são geradas porque os VirtualHost’s necessitam que a definição de seus hosts no /etc/hosts sigam uma sintaxe específica de host + domínio. Portanto, para corrigir o problema você precisa editar o arquivo /etc/hosts e alterar o formato dessas configurações para as previstas nas especificações.

Corrigir isso é extremamente simples e portanto eu vou usar o arquivo do meu próprio desktop para exemplificar as alterações… A minha máquina está configurada atualmente com o nome de isengard e o domínio residencial. Abaixo você pode ver como se encontra o meu arquivo /etc/hosts atualmente:


127.0.0.1 localhost
127.0.1.1 isengard.residencial

Para corrigir o problema, você precisará alterar as primeiras linhas do seu arquivo (mostrada acima) para o formato abaixo:


127.0.0.1 localhost.localdomain localhost
127.0.1.1 isengard.residencial isengard

Caso você não possua um domínio configurado, você pode utilizar como domínio localdomain como no exemplo da linha do localhost do arquivo… E pronto! Agora você pode reiniciar o seu servidor apache tranquilamente sem receber nenhuma mensagem chata de warning :)

Simples não? Segue então um pouco mais do mesmo: CouldNotDetermineServerName