Autenticação Squid com base em Tabelas MySql

Categoria: Ubuntu | Palavras-chave: , , , , , , , , ,

Um assunto muito recorrente, para quem trabalha com administração de proxy’s, é a necessidade de se fazer autenticação dos usuários com base em uma determinada lista de acesso. Geralmente, é questão apenas de fazer a configuração correta do Squid, definir alguns arquivos texto com as informações e pronto. Porém, no caso de empresas grandes, é desejável que esta informação seja reutilizada a partir de alguma já existente, geralmente em forma de dados em tabelas de um banco de dados qualquer.

Utilizo em algumas empresas um script bem simples, que eu mesmo desenvolvi, para esta tarefa. Qual não foi minha surpresa, ao saber que fazer isto é uma dúvida bastante buscada na Internet por outras pessoas e, quase sempre, não resolvida. A maioria utiliza alguns projetos complicados, outros já recomendam partir para alguma solução mais rebuscada (e, talvez, até mais correta) como LDAP e outros.

Porém, basta um script e uma ou outra configuração e a questão está resolvida. Decidi então compartilhar, aqui, o script que instalo nas máquinas que administro. Seu uso é bem simples. Na verdade, se você pegar e simplesmente seguir os passos aqui descritos, verás que é algo trivial. Porém, para manter a qualidade dos artigos aqui publicados, este serve também como um tutorial para que você entenda um pouco mais do funcionamento dos mecanismos de autenticação do Squid.

Sobre este tutorial:

  • Baseado na distribuição Ubuntu 7.10 Server
  • Dificuldade de execução: Fácil
  • Nivel de conhecimento: Avançado

Pré-requisitos

  • Conhecimentos básicos sobre o proxy Squid
  • Conhecimentos básicos sobre o banco de dados MySql
  • Entendimento prévio do que se pretende fazer
  • Servidor Linux já instalado e configurado
  • Banco de dados MySql e Squid já instalados e configurados

Para os apressados
Se você não quer “perder tempo” com conceitos, ou só quer uma “receita de bolo”, aqui estão os procedimentos, considerando a instalação do pacote php5-cli (desconsidere se já instalado):

$ sudo su -
Password: sua_senha
# cat << EOF > CriaBanco_AutenticaSquid.sql
CREATE DATABASE AutenticaSquid;
USE AutenticaSquid;
CREATE TABLE Usuarios (
nome varchar(255) NOT NULL,
senha varchar(255) NOT NULL,
ativo tinyint(1) NOT NULL default '1',
PRIMARY KEY (nome),
KEY nome (nome)
) COMMENT = 'AutenticaSquid - Usuarios';
INSERT INTO Usuarios VALUES ('usuario1', encrypt('senha1'), 1);
INSERT INTO Usuarios VALUES ('usuario2', encrypt(''), 0);
EOF
# mysql -u usuario_do_banco -p < CriaBanco_AutenticaSquid.sql
Password: senha_do_banco
# apt-get install php5-cli
# cd /usr/lib/squid


# cat << EOF > mysqlt_auth

#!/usr/bin/php
<?
        $link = mysqli_connect("localhost", "usuario_do_banco", "senha_do_banco");
        if (!$link) {
                printf("Erro ao conectar com o banco de dados: %s\n", mysqli_connect_error());
                die();
        }
        $selectdb = mysqli_select_db($link, "AutenticaSquid");
        if (!$selectdb) {
                printf("Erro ao abrir o banco de dados: %s\n", mysqli_error($link));
                die();
        }
        while ( fscanf(STDIN, "%s %s", $nome, $senha) ) {
                $select = "SELECT nome, senha FROM Usuarios WHERE nome = '".$nome."' AND ativo = 1";
                $Query = mysqli_query($link, $select);
                $nrRegistros = mysqli_num_rows($Query);
                $erro = true;
                while ( $Registro = mysqli_fetch_array($Query) ) {
                        $erro = false;
                        if ( crypt($senha, $Registro[senha]) == $Registro[senha] ) printf("OK\n");
                        else printf("ERR\n");
                }
                if ($erro) printf("ERR\n");
        }
?>
EOF



# vi /etc/squid/squid.conf
(...)
auth_param basic children 5
auth_param basic realm Descrição do seu servidor
auth_param basic credentialsttl 2 hour
auth_param basic program /usr/lib/squid/mysqlt_auth
(...)
acl usuarios proxy_auth "/etc/squid/usuarios"
http_access allow usuarios
http_access deny all
(...)
# cat << EOF > /etc/squid/usuarios
usuario1
usuario2
EOF
# /etc/init.d/squid restart

Com os comandos e procedimentos acima, você já deve ter a configuração pronta e totalmente funcional em seu servidor. Aogra vamos saber o porquê de cada comando e procedimento, e aprofundarmos um pouco mais no assunto.

Preparando o ambiente

Para iniciar os trabalhos, vamos logo entrando como usuário “root”:

$ sudo su -
Password: sua_senha
#

O comando sudo é velho conhecido, serve para rodar comandos com permissões administrativas. O comando “su -” indica que queremos nos tornar root (e permanecer assim), carregando o seu profile como se fosse um novo login.

Não será objeto deste tutorial a instalação do Squid e do MySql, pois estamos partindo do pressuposto que estes já estão rodando, conforme os pré-requisitos citados anteriormente. Em artigos futuros, talvez este assunto seja abordado. Portando, cheque se o seu proxy Squid já funciona adequadamente, se os usuários conseguem navegar por ele, se você já tem um banco de dados MySql rodando, se a as tabelas estão criadas, enfim… faça uma checagem geral.

Caso você não as tenha, segue um script de exemplo para criação do banco em MySql, já com a tabela e dois usuários de teste, sendo um desabilitado.


# cat << EOF > CriaBanco_AutenticaSquid.sql
CREATE DATABASE AutenticaSquid;
USE AutenticaSquid;
CREATE TABLE Usuarios (
nome varchar(255) NOT NULL,
senha varchar(255) NOT NULL,
ativo tinyint(1) NOT NULL default '1',
PRIMARY KEY (nome),
KEY nome (nome)
) COMMENT = 'AutenticaSquid - Usuarios';
INSERT INTO Usuarios VALUES ('usuario1', encrypt('senha1'), 1);
INSERT INTO Usuarios VALUES ('usuario2', encrypt(''), 0);
EOF
# mysql -u usuario_do_banco -p < CriaBanco_AutenticaSquid.sql
Password: senha_do_banco

Obtendo e Instalando

O script é escrito em PHP, então necessitamos a instalação dos pacotes referentes ao interpretador por linha de comando desta linguagem de script, que pode ser feita da seguinte forma:


# apt-get install php5-cli

Feita a instalação, entramos no diretório referente aos mecanismos de autenticação do Squid (no Ubuntu Server, “/usr/lib/squid”):


# cd /usr/lib/squid

Neste diretório, há um programa e/ou script para cada mecanismo de autenticação instalado. O funcionamento é simples, o Squid chama o executável deste diretório, passa através da entrada padrão o nome e a senha que o usuário digitou, recebendo de volta “OK” ou “ERR” conforme o caso.

Iremos criar um novo arquivo, definindo o seu conteúdo, chamado “mysqlt_auth” (será o nome de nosso programa de autenticação). Pode copiar e colar o código abaixo, alterando os valores necessários para se adaptar ao seu banco de dados:


# cat << EOF > mysqlt_auth

#!/usr/bin/php
<?
        $link = mysqli_connect("localhost", "usuario_do_banco", "senha_do_banco");
        if (!$link) {
                printf("Erro ao conectar com o banco de dados: %s\n", mysqli_connect_error());
                die();
        }
        $selectdb = mysqli_select_db($link, "AutenticaSquid");
        if (!$selectdb) {
                printf("Erro ao abrir o banco de dados: %s\n", mysqli_error($link));
                die();
        }
        while ( fscanf(STDIN, "%s %s", $nome, $senha) ) {
                $select = "SELECT nome, senha FROM Usuarios WHERE nome = '".$nome."' AND ativo = 1";
                $Query = mysqli_query($link, $select);
                $nrRegistros = mysqli_num_rows($Query);
                $erro = true;
                while ( $Registro = mysqli_fetch_array($Query) ) {
                        $erro = false;
                        if ( crypt($senha, $Registro[senha]) == $Registro[senha] ) printf("OK\n");
                        else printf("ERR\n");
                }
                if ($erro) printf("ERR\n");
        }
?>
EOF


O funcionamento do script é simples:

  • Conecta ao MySql
  • Seleciona o banco de dados criado
  • Lê da entrada padrão o nome e senha do usuário
  • Pesquisa na tabela Usuarios por usuarios ativos (ativo=1) que contenham aquele nome
  • Assume que houve erro.
  • Se foi encontrado um registro, assume que não houve erro.
  • Compara a encriptação da senha digitada se confere com a senha criptografada armazenada.
  • Caso sejam iguais, mostra OK.
  • Caso sejam diferentes, mostra ERR.
  • Caso tenha havido erro, mostra ERR.
  • Recomeça a leitura da entrada padrão.

Configurando o Serviço

Para que o Squid “enxergue” o novo esquema de autenticação, é necessário que façamos a devida alteração em seu arquivo de configuração. Edite o arquivo /etc/squid/squid.conf e verifique que há uma diretiva que “aponta” para o programa de autenticação, bastando então alterá-lo:


# vi /etc/squid/squid.conf
(...)
auth_param basic children 5
auth_param basic realm Descrição do seu servidor
auth_param basic credentialsttl 2 hour
auth_param basic program /usr/lib/squid/mysqlt_auth
(...)

Para cofigurar as ACL’s, você faz da mesma forma como faria a autenticação da forma “normal”. Para fins de exemplo, aqui está um conjunto de ACL’s que deixa um usuário navegar e barra todos os outros acessos:


# vi /etc/squid/squid.conf
(...)
acl usuarios proxy_auth "/etc/squid/usuarios"
http_access allow usuarios
http_access deny all
(...)
# cat << EOF > /etc/squid/usuarios
usuario1
usuario2
EOF
#

Veja que, devido à simplicidade de nosso script, ainda precisamos de um arquivo auxiliar ( no caso, /etc/squid/usuarios ) contendo o nome de todos os usuários cadastrados. Desta forma, ele irá buscar a senha e se está ativo ou não no MySql, mas ainda é necessário inserir aqui o seu nome.

Terminada a configuração do Squid, devemos reinicializar o Squid:


# /etc/init.d/squid restart

Outras ACL’s e configurações podem ser feitas, em conjunto com as aqui mostradas, bastando você alterar o arquivo de configuração conforme desejado.

Testando e Utilizando

Para verificar se o Squid carregou o script corretamente, use o seguinte comando para visualizar se ele está rodando:

# ps aux | grep mysqlt_auth
proxy 5821 0.0 0.9 22408 4708 ? Ss 06:37 0:00 /usr/bin/php /usr/lib/squid/mysqlt_auth
proxy 5822 0.0 0.9 22412 4704 ? Ss 06:37 0:00 /usr/bin/php /usr/lib/squid/mysqlt_auth
proxy 5823 0.0 0.8 22408 4540 ? Ss 06:37 0:00 /usr/bin/php /usr/lib/squid/mysqlt_auth
proxy 5824 0.0 0.8 22408 4540 ? Ss 06:37 0:00 /usr/bin/php /usr/lib/squid/mysqlt_auth
proxy 5825 0.0 0.8 22408 4540 ? Ss 06:37 0:00 /usr/bin/php /usr/lib/squid/mysqlt_auth
root 30390 0.0 0.1 2972 748 pts/0 R+ 20:35 0:00 grep mysqlt_auth
#

Veja que há 5 instâncias do Script servindo ao Squid.
Se não houver nenhuma instância, basta checar o arquivo /var/log/squid/cache.log atrás de mensagens de erro. Em uma situação normal, ele deve mostrar o seguinte:


# cat /var/log/squid/cache.log | grep helperOpenServers
2008/12/31 23:37:09| helperOpenServers: Starting 5 'mysqlt_auth' processes

Para verificar a autenticação dos usuários em si, rode o script manualmente:


# /usr/lib/squid/mysqlt_auth
usuario1 senha1
OK
usuario2 senha2
ERR
<ctrl+d>
#

Como se vê, executando o comando e digitando o usuário e a senha a cada linha, separados por espaço, ele informa se tem acesso ou não. O CTRL+D indica fim de arquivo, e o comando é encerrado.

Dicas finais

  • Os caminhos, comandos e procedimentos aqui indicados, tomam como base o Ubuntu 7.10 Server. Porém, pode ser utilizado com pequenas adaptações para Ubuntu 6.06 LTS Server, outras versões, e até mesmo outras distribuições.
  • Você pode escrever uma página Web, em PHP ou outra linguagem dinâmica, que consulta as informações do banco, e gerencia os usuários, com troca de senhas, etc. Inclusive, utilizo uma solução assim que eu mesmo desenvolvi.
  • Lembre-se que aqui foi mostrado como fazer autenticação com informações de tabelas no Squid. Você deve saber trabalhar com proxy’s, autenticação, e todas as suas complicações (não funcionar com proxy transparente, configuração no browser, etc).

Publicado em 27 de Março de 2008 | 19 Comentários

Marcos André Lucas

Marcos André Lucas

Analista de Sistemas, Consultor de TI, Professor Universitário de Redes e Servidores, Pai do Vinícius e gordinho boa pinta nas horas vagas ;)

Mais posts do autor (4)

19 Comentários

  1. Jean disse:

    Muito bom o post cara!
    Parabéns Marcos!
    Show de bola!
    Abraço

  2. […] por Marcos André Lucas (mlucas82Θgmail·com) – referência […]

  3. Edson disse:

    Funciona com proxy transparente ?

  4. Marcos André Lucas disse:

    Edson,

    Não, não funciona. Conforme dito no final do artigo: “Você deve saber trabalhar com proxy’s, autenticação, e todas as suas complicações (não funcionar com proxy transparente, configuração no browser, etc).”

    Qualquer tipo de autenticação do Squid, seja ela com tabelas MySql, seja com usuários do SO, enfim, qualquer tipo, o esquema de autenticação utilizado pelo proxy não funciona com proxy transparente. Pode usar os dois ao mesmo tempo, no mesmo serviço e servidor, mas um usuário que esteja navegando e seja redirecionado de forma transparente para este proxy, não poderá fazer autenticação.

    Isto ocorre da forma como o protocolo de autenticação funciona. Ele responde com Headers HTTP especiais para o navegador, que se encarrega de pedir ao usuário sua senha. Quando trabalhando em modo transparente, o navegador não entende estes cabeçalhos, e então ignora-os.

    Espero poder tê-lo ajudado.

  5. O único problema que eu vejo utilizando essa solução é que os dados da autenticação trafegam na rede em texto plano, apenas usando base64. Qualquer pessoa rodando sniffer na sua rede pode capturar as senhas digitadas pelos usuários, e se você usar as senhas para mais sistemas além de autenticação do squid, isso pode ser um grande problema. Para resolver isso recomendaria usar digest, porém pode ser que você tenha que guardar as senhas de modo diferente em sua base de dados. Dê uma pesquisada nisso. Abraço !

  6. Marcos André Lucas disse:

    Jeronimo,

    Realmente, elas trafegam usando texto plano. Se estivessem somente armazenadas em arquivos de texto, ou no Sistema Operacional (shadow), que é o que quase todo mundo usa, ainda assim trafegariam pela rede em texto plano. A idéia foi mostrar o esquema de autenticação pegando dados de outra fonte, no caso uma tabela no MySql.

    Mas a sua recomendação não apenas está correta, como irei escrever um novo artigo, desta vez usando outro esquema para tráfego das senhas na rede. Muito obrigado pela sua sugestão, e obrigado por visitar nosso site.

  7. Muito bom o texto!

    Já coloquei nos favoritos!

    Engenharia Ambiental

  8. Marco, muito legal esse teu trabalho, testei e funcionou direitinho, o meu sistema é um freebsd, será que voçê teria um squela parecido para acl e logs do squid no mysql também ? dai ficaria tuno no bd.

  9. Marcos André Lucas disse:

    Jean e Leonardo, obrigado.

    Steven, obrigado por ler e mais ainda por experimentar a solução na prática. Existem algumas implementações para colocar os log’s em MySql, irei precisar fazer algo parecido para um cliente em que surgiu somente agora esta necessidade. Assim que terminar, colocarei aqui os passos. Sobre ACL’s, não, não conheço forma de fazer ele ler do MySql, mas trabalho da seguinte forma: tenho uma página PHP que manipula as tabelas em banco, e, a cada inserção, atualização ou remoção, ele gera um evento para um script que atualiza os arquivos texto do Squid. É uma RTA – Recurso Técnico Alternativo (popular gambiarra), mas que funciona.

  10. Andre Almeida disse:

    Parabéns Marcos! =)

  11. Marcos,

    Excelente artigo, tem como disponibilizar o squid.conf para fazer comparações?

    Obrigado

  12. Marlon Cesar disse:

    Para ajudar os colegar, no exemplo abaixo estou utilizando MD5 nas senhas no banco de dados…

    —————- CORTE DAQUI PARA BAIXO :D ————————-

    #!/usr/bin/php

  13. dirley disse:

    Marlon Cesar
    Amigo, onde está a parte da utilização do MD5 ?

  14. […] O site ubuntutero publicou uma excelente dica que ensina fazer a autenticação dos usuários de uma rede local através de uma tabela do bando de dados mysql.Leia a dica aqui […]

  15. jonathan disse:

    Poxa vida, um otimo tutorial, estava terminando minha 4° semana de busca por proxy autenticado e ai achei esse, é uma pena que eu uso proxy transparente, vou pensar uma forma de autenticar os usuarios…
    trata-se de uma rede aberta, com proxy transparente (squid) com cache e relatorios (sarg), alguns bloqueios, diversos perfis , cada um com n usuarios e cada perfil com suas regras e velocidade de acesso… é a minha obra prima…
    quando terminar tudo vou postar aki

  16. Tiago disse:

    huahau to doido atraz disso mais com suporte a MD5, na minha tabela de usuários as senhas estão em MD5, não consigo fazer funcionar =s

  17. Andre Abade disse:

    Pessoal, bom dia…Faço algo parecido já faz algum tempo, porem utilizo o perl para fazer a autenticação em minha base de dados. De uma semana pra cá meu squid ta caindo direto com mensagens de WARNING:basicauthenticator #23 (FD 28) Exited. FATAL: The basicauthenticator helpers are crashing too rapidly, nedd help. Alguem sabe o que pode ser?

  18. Max Weber disse:

    Muito bom o tutorial amigo! Mas acho que tive problemas em implantar isso no meu proxy.

    ==== Esta linha é a minha linha padrão ===
    auth_param basic program /usr/bin/ncsa_auth /etc/squid/passwd

    ==== Depois troquei para esta linha do tutorial ===
    auth_param basic program /usr/bin/mysqlt_auth

    Lembrando que no tutorial o caminho do mysqlt é /usr/lib/squid, fiz dessa forma tb e não funcionou. então coloquei nesse diretório aí.

    Uma dúvida em relação a próxima linha
    acl autenticados proxy_auth REQUIRED (continua do jeito que está?)

    Aí o que ocorre? Quando reinicio o squid com essas configurações, e tento navegar, não pede autenticação e dá erro já de cara da página, como se não houvesse internet.

    Alguém pode me dar uma luz? Obrigado moçada.

  19. Célio Junior disse:

    Tem um tempinho que escreveu isso… Mas tem como fazer essa autenticaçao usando squid3?

Deixe seu comentário

Website