Páginas

quarta-feira, 24 de junho de 2009

Usando HTTP autenticado no Apache

Fala galera! Depois de tanto tempo!! Eis que surge uma nova dica pra vocês (espero não demorar tanto na próxima vez hehehe)....

Este tutorial requer que já se tenha em mãos um WebServer Apache configurado e funcionando!


Você já teve momentos em que desejou que algum usuário não autorizado fuçasse determinada pasta em seu servidor web?
Eis aqui a solução para seus problemas!!

Vamos imaginar um cenário real onde tenho um diretório chamado admin dentro do meu Web Space (local do meu servidor web onde ficam os arquivos acessíveis ao público) do Apache já instalado, no Debian Lenny o diretório do Web Space do Apache fica em:

/var/www/

No caso do nosso cenário do exemplo, teria uma pasta admin dentro deste diretório, ficando assim:

/var/www/admin

Imaginem que esta pasta armazena coisas muito importantes e você não quer que nenhum abelhudo vá lá xeretar sem autorização, aí aplicamos autenticação neste diretório. Pra quem não sabe autenticação nada mais é do que um serviço que pedirá usuário mais senha para liberar seu conteúdo ou seja, logar! Portando somente um ou alguns usuários estarão liberados para ler os arquivos deste diretório (admin no caso do exemplo).

Um pouco de teoria do protocolo HTTP

No HTTP a autenticação funciona da seguinte forma (vamos exemplificar isso usando o programa para sniffar as mensagens trocadas entre um servidor e um cliente):

O cliente faz uma requisição de determinada página via mensagens, a mensagem de requisição inicial do nosso exemplo será:

GET /admin HTTP/1.1
Host: 172.16.213.128

Esta mensagem do cliente significa que estou requisitando os objetos do diretório /admin do servidor web de ip 172.16.231.128, quando o diretório exige autenticação, o servidor responderá da seguinte forma:

HTTP/1.1 401 Authorization Required
Date: Wed, 03 Jun 2009 11:54:31 GMT
Server: Apache
WWW-Authenticate: Basic realm="Digite seu usuário e senha"

Esta mensagem informa ao cliente que ele precisa de autenticação, isto é informado na linha de cabeçalho WWW-Authenticate, e o Basic Realm é apenas um comentário que aparecerá ao usuário pedindo a senha.

Daí novamente o cliente fará uma requisição para o servidor, mas desta vez acrescentará a senha em formato criptografado (*Base64) dentro de uma linha de cabeçalho chamada Authorization como mostrado abaixo:

GET /admin HTTP/1.1
Host: 172.16.213.128
Authorization: Basic cm9vdDoxMjM0

Se o usuário casar com a senha, o servidor apresentará o conteúdo do diretório na tela do browser do cliente, caso não, a resposta do servidor será novamente uma requisição de senha (enquanto o usuário não clicar em cancelar e digitar a senha errada o servidor pedirá uma nova senha, quando ele clicar em cancelar a resposta do servidor será HTTP UNAUTHORIZED).

Mão na massa

Bom expliquei um pouco de como funciona o HTTP Autenticado, agora é hora de mostrar como implementar um e discutir quando usar e quando não usar o HTTP Autenticado.

O arquivo .htaccess

Este aquivo é inserido dentro de um diretório ao qual desejamos restringir acesso, em nosso exemplo o colocaríamos dentro da pasta /var/www/admin.

A vantagem de se usar o arquivo .htaccess é que em um servidor (aqueles de hospedagem normalmente) ao qual você não tem acesso a configuração do Web Server e tem acesso (FTP normalmente) somente a alguma pasta no servidor.

Agora de acordo com a página de documentação do próprio Apache, o .htaccess não é recomendado caso você tenha acesso ao arquivo de configuração do servidor. (veja mais detalhes em “Quando (não) usar arquivos .htaccess” em http://httpd.apache.org/docs/2.2/pt-br/howto/htaccess.html)

Tudo que especificamos dentro de .htaccess pode ser escrito em um bloco de diretiva < Directory > (quando temos acesso aos arquivos de configuração do servidor), na configuração de um site no Apache (como fazer isso será explicado mais pra frente neste mesmo tutorial).

Quando queremos usar arquivos .htaccess tem que existir uma linha especificando seu nome no arquivo de configuração do Apache, como estou usando Debian Lenny o arquivo de configuração é /etc/apache2/apache2.conf, mas independente disso a linha que define o nome do “arquivo de acesso” é:

AccessFileName < arquivo >

Onde normalmente em < arquivo > especificamos o nome .htaccess, agora mais uma coisa que temos que ter em mente são as permissões de acesso por usuário em cada diretório (diretiva < Directory >), dentro de uma diretiva Directory temos que especificar a linha:

AllowOverride < permissões >

Onde no nosso exemplo usaremos a permissão All, ou seja, depois que eu autenticar no diretório especificado tenho permissão de fazer tudo!

Agora vamos por em prática o que foi aprendido até aqui (depois de tanta teoria hehehe)....

Suponha que vou usar primeiramente o arquivo .htaccess para realizar a autenticação.

Autenticando via .htaccess

* Você terá de usar o root para realizar essas configurações

1.Abra o arquivo /etc/apache2/apache2.conf com o editor de texto da sua preferência, ou use meu exemplo:

# vim /etc/apache2/apache2.conf

2.Verifique se a linha AccessFileName está desta forma:

AccessFileName .htaccess

3.Agora vamos criar o arquivo .htaccess e jogá-lo dentro do diretório

Criar o diretório admin

# mkdir /var/www/admin

Criar arquivo .htaccess e acrescentar as linhas descritas (não digite o número das linhas, somente o conteúdo)

# vim /var/www/admin/.htaccess

1 AuthType Basic
2 AuthName "Digite usuário e senha"
3 AuthUserFile /etc/apache2/.htpasswd
4 Require valid-user
5 Satisfy Any

Explicando:

linha 1: Isso significa que vou usar o tipo Base64 de transferência (que não é criptografado e sim codificado e é facilmente decodificado, explicarei aspectos relacionados a segurança logo mais neste tutorial)

linha 2: Lembram da mensagem de resposta HTTP?

WWW-Authenticate: Basic realm="Digite seu usuário e senha"

Esta linha adiciona o rótulo da mensagem do Realm

linha 3: Digo que ele buscará a senha do arquivo de senhas
/etc/apache2/.htpasswd

linha 4: Requer que exista um usuário válido a ser autenticado

linha 5: Satisfy pode ter dois valores All ou Any,

o All diz que o usuário tem que passar na restrição de acesso (Required ou Allow, no nosso caso required) E entrar com um usuário e senha válidos para realizar a autenticação

o Any diz que o usuário tem que passar na restrição de acesso OU entrar com um usuário e senha válidos para realizar a autenticação

4.Agora como foi visto acima o arquivo de senhas /etc/apache2/.htpasswd tem que ser criado! Crio este arquivo facilmente com o comando htpasswd da seguinte forma:

# htpasswd -c /etc/apache2/.htpasswd root

onde:
-c = create new archive

Este comando pedirá senha para o usuário especificado, em nosso caso, root

5.Reinicie o Apache:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

ou

/etc/init.d/apache2 restart

6.Agora a autenticação já tem de estar funcionando! Tente entrar pelo browser no seu servidor apache no diretório admin, em uma máquina “normal”, a url ficaria assim no browser:

http://localhost/admin

Se ele pedir usuário e senha quando esta url for especificada, parabéns! Senão reveja novamente os passos deste tutorial, ou email-me :D

Agora vocês vão me perguntar “Mas meu você não falou que quando eu tenho acesso aos arquivos de configuração do Apache eu não devo criar arquivos .htaccess devido ao desempenho e mais a um monte de coisas?”, eis que lhe responderei “SIM”, agora explicarei como você faria se tivesse acesso aos arquivos de configuração do Apache.
Autenticando via arquivo de configuração do Apache

1.Abra o arquivo (em um editor de texto) de configuração do SITE que você usará, no meu caso
seria:

# vim /etc/apache2/sites-enabled/000-default

2.Agora adicione um container com uma diretiva Directory desta forma (sem adicionar os números das linhas):

1 < Directory /var/www/admin >
2 Deny from all
3 AuthType Basic
4 AuthName "Digite usuário e senha"
5 AuthUserFile /etc/apache2/.htpasswd
6 Require valid-user
7 Satisfy Any
8 < /Directory >

Explicando:

linha 1: Nesta linha abro o container da diretiva Directory e aponto o diretório /var/www/admin (o qual quero modificar permissões de acesso)

linha 2: Nesta linha nego privilégio a todo mundo para liberar nas linhas de baixo, porém nas linhas de baixo libero com as restrições de acesso igualmente as restrições que usei quando utilizei o arquivo .htaccess (lembrando que se eu adicionar as restrições no arquivo de configuração do site não preciso criar o arquivo .htaccess no diretório, por favor não confunda :D)

linhas 3,4,5,6,7: Já explicadas quando falei sobre o arquivo .htaccess

linha 8: Fecho o container da diretiva Directory

3.Agora salvo e saio do arquivo, daí o Apache tem um comando bem interessante que faz carregar o arquivo do site, que é a2ensite (Apache 2 enable site), use-o desta forma:

# a2ensite

Daí aparecerão os arquivos de site disponíveis a ser(em) carregado(s), daí você digita um dos nomes que aparece e tecla enter ele carregará o arquivo

4.Aí para terminar digite:

/etc/init.d/apache2 reload

Com isso você fará com que o Daemon do Apache releia as configurações, do arquivo de configuração do site que você acaba de modificar.
Ou se quiser ter mais certeza reinicie o Daemon usando:

/etc/init.d/apache2 stop
/etc/init.d/apache2 start

ou

/etc/init.d/apache2 restart

5.Agora a autenticação já deve estar funcionando corretamente, mas agora baseada em arquivo de configuração do Apache e não mais no .htaccess, faça os testes como no ítem 6 da explicação do .htaccess

Aspectos de segurança

Voltando a seção “Um pouco de teoria sobre o protocolo HTTP” vimos que quando uma requisição é enviada a um diretório que esteja funcionando autenticação o cliente têm que fazer uma nova requisição enviando seu usuário e senha, que no nosso exemplo é Basic, o que significa que não tem criptografia portanto quando temos um espião na rede esta senha e usuário podem ser facilmente descodificados (pois o Base64 não é criptografia mas sim um formato de codificação de mensagens)... veja o exemplo abaixo:

Suponha que eu estivesse farejando na rede (com um sniffer) e consegui pegar esta mensagem (a mesma do nosso exemplo):

GET /admin HTTP/1.1
Host: 172.16.213.128
Authorization: Basic cm9vdDoxMjM0

Agora suponha que eu use Linux (clarooooo !!! :D) e conheço um pouco sobre o openssl.... observem o que eu poderia fazer com a mensagem codificada (cm9vdDoxMjM0):

# echo "cm9vdDoxMjM0" | openssl enc -base64 -d
root:1234

Ou seja acabei de conseguir o usename e a senha válida para um usuário que tem permissão de se logar no diretório admin!

Conclusão: Se você quiser mais segurança não use o tipo de autenticação Basic, e além do mais configure seu Apache2 para usar HTTPS e não HTTP!

Terminando

Bom gente é isso ai! Acabou! Dúvidas por favor me enviem um e-mail um post um grito, um sms, ou qualquer outra coisa, porém não fiquem com elas :D!!

Espero que tenham gostado! Abraço a todos!

Referências

Apache

http://httpd.apache.org/docs/2.2/pt-br/howto/htaccess.html
http://httpd.apache.org/docs/2.2/pt-br/mod/core.html#allowoverride
http://httpd.apache.org/docs/1.3/misc/FAQ.html#user-authentication
http://httpd.apache.org/docs/1.3/mod/core.html#require
http://httpd.apache.org/docs/1.3/mod/mod_access.html#allow

Autenticação/Codificação

http://www.acunetix.com/websitesecurity/authentication.htm
http://en.wikipedia.org/wiki/Basic_access_authentication
http://pt.wikipedia.org/wiki/Base64
http://en.wikipedia.org/wiki/Digest_access_authentication
http://apache.active-venture.com/auth-digest.html

OpenSSL How-to

http://www.madboa.com/geek/openssl/

HTTPS

http://en.wikipedia.org/wiki/HTTP_Secure

Nenhum comentário: