Como bloquear user-agent pelo .htaccess

Na semana passada o site de um cliente foi atacado por spammers devido a uma falha de segurança do WordPress e ontem um amigo notificou que o Eu Compraria estava fora do ar por falha do banco de dados – demorei um pouco para identificar isto pois o servidor e o banco continuavam “de pé”, mas analizando o processamento do servidor vi que constantemente o MySQL estava estourando o processamento.

Achei estranho e fui verificar os logs do servidor e encontrei a causa do problema: um bot fazendo requisições constantes para o And After, para páginas de busca e tags (onde meu sistema de cache, confesso, não é muito eficiente).

O primeiro passo foi bloquear o bot pelo IP via .htaccess para sanar o problema.

Como bloquear um IP via .htaccess

Sem mistérios, nas regras de .htacces adicionei o seguinte:

Order Deny,Allow
Deny from 54.197.86.53

Problema resolvido temporariamente.

Mas claro que durou pouco, pois o bot tinha um tange de IP para trabalhar. Ao invés de ir bloquando IP por IP – ou bloquear o range de IPs, como este bot se identificava via user-agent, achei que seria uma solução mais elegante e duradoura.

Como bloquar user-agent via htaccess

O primeiro passo é identificar o user-agent que você quer bloquear, para isso basta ver os logs do apache.

tail -f /path_dos_logs_do_dominio/access.log

No meu caso o bot se identificava como BDBBot. Depois de identificar quem queremos bloquear vamos criar as regras no htacess, explicadas abaixo.

Na primeira linha vamos determinar uma “env” chamada bad_bot se o user-agent casar com BDCBot (usando o modsetenvif do Apache). Você pode repetir esta linha para todos os user-agents que deseja bloquear.

Com esta identificação de user-agent e com o env configurado quando “casar”, você só precisa escrever a regra para negar os acessos sempre que o env for bad_bot.

Para o meu caso adicionei o seguinte ao htaccess:

BrowserMatchNoCase BDCBot bad_bot
Order Deny,Allow
Deny from env=bad_bot

Agora sim, problema com este bot resolvido de uma forma um pouco menos temporária.

Ainda neste tópico li sobte uma abordagem curiosa e, ao meu ver, perigosa que é fazer o inverso: ao invés de bloquear os spammers, bloquear tudo e permitir apenas os bots / crawlers conhecidos.

Eu não arrisco, mas se você se interessar pode conferir o tópico sobre o assunto.

Tutorial – deploy com git no Ubuntu Server (AWS EC2)

Semana passada configurei um servidor novo para um cliente (GS Solutions) e optamos por usar AWS para este projeto (leia meu comparativo entre Locaweb e Amazon) e fiquei encarregado de configurar o servidor.

O servidor será exclusivo para um projeto e optei por fazer todos os deploys com git para manter o controle do código que vai para o ar e automatizar o deploy. 

Já fiz isso para o And After e para o Eu Compraria e lembro que foi um pouco complicado permitir o git pull através do apache (usuário www-data no Ubuntu Server).

Mas uma vez feito, não tem erro. este é um tutorial de 4 passos simples para configurar seu servidor e permitir deploy utilizando o Git.

O tutorial foi testado em servidor Linux (Ubuntu Server) e pode precisar de ajustes simples para outros servidores.

1. Instale o git no servidor

Sem nenhum mistério:

sudo apt-get install git

2. Crie uma chave para o user www-data

Aqui está o segredo de permitir o deploy diretamente por comandos do Apache, que utiliza o usuário www-data.

No meu caso o deploy é feito através de um ambiente fechado do sistema, onde através do PHP o git pull é executado. O repositório em questão será onde está configurado o domínio do serviço, então quando o pull é executado na branch master acontece o deploy.

Para criar uma chave ssh para o user www-data você vai precisar executar o ssh-keygen com este usuário, para isso execute no servidor:

sudo -u www-data ssh-keygen

E gere uma chave para este usuário, com ou sem senha. Na home deste usuáriuo (no Ubuntu Server a home do usuário www-data normalmente é /var/www/) você terá uma pasta .ssh onde ficarão as chaves.

3. Libere as chaves no seu repositório

Agora é só cadastrar as chaves no seu repositório para que seu www-data do servidor tenha acesso ao repositório, no terminal do servidor digite:

vi ~/var/www/.ssh/id_rsa.pub

Cadastre a chave pública no seu repositório e pronto, você está pronto para acessar seu repositório diretamente do seu servidor.

4. Clone o repositório

Agora no seu servidor você pode executar os comandos do git com o usuário www-data, por exemplo:

sudo -u www-data git clone meurepositorio.git

Lembre-se que para automatizar o seu deploy o domínio configurado no Apache (sites available) deve ser o seu próprio repositório.

Para fazer o deploy você pode escolher a forma que achar melhor. Eu executo os comandos com a ajuda do PHP em um ambiente fechado: assim o php (www-data) executa o git pull no repositório do seridor.

Não sei se existe (e qual é) o risco do user www-data ter uma chave pública cadastrada no repositório, mas o ideal é que este usuário tenha acesso apenas de leitura no seu repositório.

Leia também mais algumas dicas e utilidades para seu servidor:

Shellscript para configurar domínio no Apache

Quando você se torna freelancer ou empreendedor a automatização passa a ser um ponto ainda mais importante no seu dia a dia. Cada tarefa automatizada significa aumento de lucro a longo prazo, mais tempo para estudar ou descansar. 

Pensando em automatização, recomendo que você aprenda como usar o GruntJS neste ótimo artigo do Fernahhh.

Eu administro um servidor AWS para meus projetos e projeto de alguns clientes, é um Ubuntu Server com Apache. Configurar domínios, principalmente localmente no meu ambiente de desenvolvimento, se tornou uma tarefa comum e que levava alguns minutos.

A cada novo projeto que vou trabalhar (seja front-end ou back-end) eu aponto um novo domínio para meu servidor local (hosts) e crio um domínio no meu apache apontando para o repositório do projeto. 

Shellscript para automatizar a criação de domínios no Apache

Resolvi utilizar shellscript para automatizar a criação de domínios no Apache. Encontrei um script e adaptei para a minha necessidade.

Este script rece um parâmetro, que é o domínio que será criado.

Exemplo:

sh create-site andafter.org

As ações do script:

  1. Cria os diretórios para o domínio
    1. /var/www/$dominio
    2. /var/www/$dominio/public
    3. /var/www/$dominio/logs
  2. Cria um arquivo de configuração com o nome do comínio em /etc/apache2/sites-available
  3. Cria um link simbólico para ativar o domínio (sites-enabled)

create-site.sh

!/bin/bash
################
# Script for creating Virtual Servers On Apache
# Check for the correct parameters
if [ $# -eq 0 ]; then
        echo 'Você precisa passar o domínio a ser criado como parâmetro'
        echo 'Uso: create-site gssolutions.com.br'
        exit 0
fi
# Assign Variables
SITE=$1
# Create the Directory which will contain your Virtual Site
if [ ! -d /var/www/$SITE ]; then
        mkdir /var/www/$SITE
        mkdir /var/www/$SITE/public
        mkdir /var/www/$SITE/logs
fi
# Create the Config file for your virtual site
echo "<virtualhost *:80="">"> /etc/apache2/sites-available/$SITE
echo    "# Admin email, Server Name (domain name) and any aliases"  >> /etc/apache2/sites-available/$SITE
echo    "  ServerAdmin [email protected]" >> /etc/apache2/sites-available/$SITE
echo    "  ServerName $SITE" >> /etc/apache2/sites-available/$SITE
echo    "  ServerAlias www.$SITE" >> /etc/apache2/sites-available/$SITE
echo    " ">>/etc/apache2/sites-available/$SITE
echo    "  # Index file and Document Root (where the public files are located)" >> /etc/apache2/sites-available/$SITE
echo    "  DirectoryIndex index.html" >> /etc/apache2/sites-available/$SITE
echo    "  DocumentRoot /var/www/$SITE/public" >> /etc/apache2/sites-available/$SITE
echo    "  LogLevel warn" >> /etc/apache2/sites-available/$SITE
echo    "  ErrorLog  /var/www/$SITE/logs/error.log" >> /etc/apache2/sites-available/$SITE
echo    "  CustomLog /var/www/$SITE/logs/access.log combined" >> /etc/apache2/sites-available/$SITE
echo "</virtualhost>" >> /etc/apache2/sites-available/$SITE
echo    "<directory \"="" var="" www="" $site="" public\"="">" >> /etc/apache2/sites-available/$SITE
echo    "   Options Indexes FollowSymLinks" >> /etc/apache2/sites-available/$SITE
echo    "   AllowOverride All" >> /etc/apache2/sites-available/$SITE
echo    "   Order allow,deny" >> /etc/apache2/sites-available/$SITE
echo    "   Allow from all" >> /etc/apache2/sites-available/$SITE
echo    "</directory>" >> /etc/apache2/sites-available/$SITE
# Create the Sym Link to enable your Virtual Site
if [ ! -L /etc/apache2/sites-enabled/$SITE ]; then
        ln -s /etc/apache2/sites-available/$SITE /etc/apache2/sites-enabled/
fi

Se você quiser pode adicionar ao final do script o comando para dar reload nas configurações do Apache.

Ilustra do “apache” é do ~pitx

Como encontrar o PHP.ini?

Já tive problemas para encontrar o PHP.ini no MacOS, eu alterava as configurações do meu arquivo php.ini, reiniciava o meu apache e as mudanças não eram aplicadas.

Já imaginava que era isso, então descobri que eu estava alterando um php.ini que não estava sendo carregado pelo PHP na minha máquina.

Como descobrir onde está o PHP.ini?

Você pode criar uma página que exiba toda a configuração do PHP e exiba em seu navegador, para isso crie um arquivo com o seguinte:

<?
phpinfo();
?>

Coloque o arquivo em uma pasta acessível pelo seu Apache e abra ela no navegador, esta página exibe todas as configurações do seu PHP.

Procure por “configuration file” e lá estará o caminho (path) do arquivo de configuração carregado pelo PHP.

Descobrindo o php.ini no terminal

Se você tem acesso a um terminal pode exibir todas as informações do php.ini direto no terminal, para isso digite:

php -i

E para facilitar a identificação do caminho completo do seu arquivo de configuração do PHP (php.ini) execute o seguinte comando no terminal:

php -i | grep 'Configuration File'<br>

Espero ter te ajudado a encontrar o caminho do php.ini.


Graças ao google os artigos mais acessados do O Desenvolvedor são os que responsem dúvidas simples com respostas rápidas, quer saber mais sobre PHP? Leia também:

PHP short_open_tag

Uma vez um colega me disse que os erros bobos são os mais difíceis de serem detectados, e é onde acabamos perdendo mais tempo – por isso eu acho pair programming uma ótima idéia.

Resolvi escrever este post para que os leitores, quando se depararem com situação parecida, economizem o precisoso tempo indo direto a solução e não fazendo os testes como eu fiz. O problema: meu apache parou de executar algumas tags do PHP, imprimindo o código PHP na tela.

 

No Mac OS configurei o Apache, PHP, NodeJS e o MongoDB. Tesstei e todos estavam funcionando, porém vários dos meus projetos, como o And After e o Eu Compraria deixaram de funcionar corretamente. As páginas abriam, algumas sem CSS, tudo estranho! Fui verificar o código e o PHP não estava interpretando nada dentro do e estava imprimindo o código no HTML.

Com alguns testes descobri que <?php funcionava e <? não, com mais um pouco de pesquisa descobri uma configuração que nunca dei importância no PHP, a short_open_tag.

 

PHP short_open_tag

short_open_tag é a configuração que permite o atalho de sintaxe <? ser interpretado da mesma forma que <?php.

Como habilitar ou desabilitar a short_open_tag?

Esta configuração está no php.ini, portanto abra ele no seu editor de texto e faça uma busca por "short_open_tag", encontre a linha e altere o valor da configuração.

 

Não sei o motivo, mas no Mac OS o padrão (pelo menos da minha instalação) foi a short_open_tag desabilitada. Quer saber mais sobre o assunto? Documentação do PHP.