Na segunda parte, demonstramos dicas e ajustes importantes para otimizar a capacidade do servidor em lidar com um volume de tráfego mais intenso. Hoje, veremos como configurar o servidor para negociar diferentes mecanismos de autenticação. Demonstraremos regras de acesso básicas, direcionadas apenas ao controle de sessões de usuários, pois o controle de navegação (permissões de acesso) será tratado na parte 4 (última).
No Squid, existem quatro esquemas (schemes) de autenticação, conhecidos como Basic, NTLM, Digest e Negotiate, e são apresentados aos clientes na ordem definida no arquivo de configuração (em squid.conf). Portanto, a ordem deve ser estabelecida em função do nível de segurança ou da “compatibilidade com o navegador ou aplicações“.
Neste artigo, não abordarei o esquema digest.
O Basic é o esquema mais simples e menos seguro (sem criptografia), com uma única codificação base64 (fácil ser quebrada). Logo, costuma ser a implementação mais simples e rápida, compatível com inúmeras aplicações ou navegadores. Apesar dos aspectos negativos, sua presença é importante para oferecer alternativas de autenticação para aplicações mais específicas. Em função do fraco nível de segurança, deve ser definido como último recurso disponível, para que esquemas mais seguros (como Negotiate ou NTLM) sejam testados antes. Normalmente, o “chaveamento” entre os esquemas é feito automaticamente pelos navegadores web.
Já o esquema NTLM oferece um nível de segurança mais elevado, centralizado (validando credenciais de contas de um “Domínio Windows”) e é baseado no protocolo NTLM – trata-se de um protocolo de autenticação de desafio-resposta, desenvolvido pela Microsoft. No entanto, apesar de oferecer um nível de segurança maior, o protocolo NTLMv1 (primeira versão) apresenta vulnerabilidade conhecida e deve ser mantido desabilitado (é padrão nas versões mais novas do Samba).
O Negotiate é, atualmente, o esquema que oferece o nível mais forte de criptografia e segurança, permitindo a autenticação baseada no protocolo Kerberos. É a opção preferencial para integração com o AD. Vale lembrar que os sistemas operacionais Windows Server, mais recentes, implementam o protocolo de autenticação Kerberos versão 5 e extensões para autenticação de chave pública, transporte de dados de autorização e delegação. Portanto, costuma ser o primeiro esquema oferecido aos clientes.
Para compreender detalhadamente as etapas de comunicação, confiram este guia (no final):
http://wiki.squid-cache.org/ConfigExamples/Authenticate/Kerberos
O suporte de autenticação nativo no Squid é modular e, por razões já explicadas, não é compatível com o modo transparente. Existem duas implementações extremamente simples, uma baseada no modulo ncsa_auth (base local, via htpasswd) e outra no pam_auth (contas de usuário do sistema, via integração PAM), ambas são baseadas no esquema Basic.
Liste o conteúdo do diretório /usr/lib/squid para saber quais módulos estão disponíveis:
root@proxysrv:~# ls /usr/lib/squid/ basic_db_auth basic_pop3_auth cert_valid.pl ext_wbinfo_group_acl ntlm_fake_auth basic_fake_auth basic_radius_auth diskd helper-mux.pl ntlm_smb_lm_auth basic_getpwnam_auth basic_smb_auth ext_delayer_acl log_db_daemon storeid_file_rewrite basic_msnt_auth basic_smb_auth.sh ext_file_userip_acl log_file_daemon unlinkd basic_msnt_multi_domain_auth basic_smb_lm_auth ext_kerberos_ldap_group_acl negotiate_kerberos_auth url_fake_rewrite basic_ncsa_auth cachemgr.cgi ext_sql_session_acl negotiate_kerberos_auth_test url_fake_rewrite.sh basic_nis_auth cert_tool ext_unix_group_acl negotiate_wrapper_auth
Para habilitar a autenticação de usuários, primeiro o administrador precisa escolher o tipo de autenticação desejada e, em seguida, os módulos envolvidos e políticas de acesso.
Como forma de padronização, visando facilitar o processo de administração, costumamos subdividir a configuração do Squid em arquivos separados (a partir de /etc/squid/acl), estabelecendo uma lógica de “configuração modular”. Ou seja, a base de configuração é feita em /etc/squid/squid.conf e os recursos adicionais e mais específicos, como autenticação e controles de acesso, são separados em arquivos que serão carregados através da opção “include“.
Por exemplo:
## Utilização do cache em memória cache_mem 512 MB maximum_object_size_in_memory 256 KB maximum_object_size 200 MB minimum_object_size 0 KB cache_swap_low 85 cache_swap_high 90 ... ## 1. Definição dos módulos de autenticação include /etc/squid/acl/buildauth/authmodule ## 2. Opções globais de autenticação include /etc/squid/acl/buildauth/options # Example rule allowing access from your local networks. # Adapt to list your (internal) IP networks from where browsing # should be allowed acl localnet dst 10.0.0.0/8 # RFC1918 possible internal network acl localnet dst 172.16.0.0/12 # RFC1918 possible internal network acl localnet dst 192.168.0.0/16 # RFC1918 possible internal network ... ## Lista negra http_access deny to_localhost http_access deny domain_blacklist ## 3. Políticas de acesso (usuários) include /etc/squid/acl/buildauth/authpolicy ...
Desta forma, a base de configuração será sempre a mesma. É possível mover a estrutura inteira para qualquer servidor e depois ajustar apenas os arquivos necessários. Se, por exemplo, a autenticação não for desejada em determinado servidor, basta esvaziar o conteúdo dos arquivos exibidos anteriormente (em negrito).
1. Módulos de autenticação (/etc/squid/acl/buildauth/authmodule)
A primeira configuração define o helper de autenticação utilizado (programas externos) e suas respectivas opções (para dimensionamento de carga, por exemplo).
– Opções globais
auth_param [esquema_de_autenticação] program [chamada_do_módulo] auth_param [esquema_de_autenticação] children [limite_máximo_de_filhos] startup=[filhos_disponíveis_ao_iniciar] idle=[filhos_ociosos] auth_param [esquema_de_autenticação] [opções_do_esquema]– Identificação do servidor no esquema Basic
auth_param basic realm [identificação_do_proxy]
A configuração para o helper basic_ncsa_auth pode ser feita da seguinte maneira:
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/acl/buildauth/.ncsa_passwd auth_param basic children 150 startup=10 idle=10 auth_param basic credentialsttl 2 hours auth_param basic casesensitive off auth_param basic realm "Squid Proxy"
Antes de demonstrar como os usuários serão cadastrados (via htpasswd), veremos a forma como os processos são alocados…
O número de processos que atenderá às solicitações dos usuários, simultaneamente, é definido pela opção children (filhos). Para realizar ajustes granulares, podemos modificar a alocação dos filhos através da opção startup (número de filhos instanciados imediatamente, quando o serviço iniciar) e idle (número de processos ociosos).
Não existe um cálculo exato para este dimensionamento. Por padrão, o Squid trabalha com um limite máximo de 5 filhos. Para redes de médio ou grande porte, este limite é pequeno e problemas de autenticação serão certos. Os desenvolvedores consideram que 20 é um limite interessante para demandas de acesso mais expressivas. Porém, a Internet vem oferecendo uma gama de opções que podem apresentar características de conexão irregular, deixando alguns filhos pendentes por um intervalo de tempo. Por esta razão, tenho adotado um limite máximo de 150 e ajusto a escala de alocação (startup e idle) até atingir este limite, que seria o pior caso.
Não abuse no valor de idle, pois ele também define a quantidade de filhos instanciados sob demanda. Se a demanda de acesso for superior a 10 filhos, o servidor alocará mais 10 (idle) – ou seja, depois da próxima alocação, serão 20 filhos (e assim sucessivamente). Isto pode ser custoso para o servidor. Por esta razão costumo configurar até 10.
Para verificar se o servidor está bem dimensionado, utilize os comandos:
squidclient -l 127.0.0.1 -p 8080 -m mgr:negotiateauthenticator | more squidclient -l 127.0.0.1 -p 8080 -m mgr:ntlmauthenticator | more squidclient -l 127.0.0.1 -p 8080 -m mgr:basicauthenticator | more
Por exemplo (helper negotiate_wrapper_auth):
squidclient -l 127.0.0.1 -p 8080 -m mgr:negotiateauthenticator
HTTP/1.1 200 OK Server: squid Mime-Version: 1.0 ... Connection: close by kid1 { Negotiate Authenticator Statistics: program: /usr/lib/squid/negotiate_wrapper_auth number active: 5 of 200 (1 shutting down) requests sent: 2468245 replies received: 2468245 queue length: 0 avg service time: 0 msec # FD PID # Requests # Replies Flags Time Offset Request 2 12 24561 221 221 RS 0.000 0 (none) 1 152 10250 15517 15517 0.003 0 (none) 2 167 10261 196 196 0.003 0 (none) 3 177 10267 11 11 0.004 0 (none) 4 185 10286 3 3 0.007 0 (none) 5 193 10299 0 0 0.000 0 (none) Flags key: B = BUSY C = CLOSING R = RESERVED S = SHUTDOWN PENDING P = PLACEHOLDER } by kid1
“Para validar esquema o basic (basic_ncsa_auth), altere mgr para mgr:basicauthenticator”
Ao optar pelo helper basic_ncsa_auth, trabalharemos com uma base local. De acordo com o exemplo anterior, as contas serão armazenadas no arquivo .ncsa_passwd (em /etc/squid/acl/buildauth) e gerenciadas via htpasswd.
Para instalar a ferramenta htpasswd, utilize o comando:
apt install apache2-utils
Para criar o arquivo, durante o cadastro da primeira conta, adicione a opção “-c”. No entanto, não informe esta opção para as demais.
htpasswd -c /etc/squid/acl/buildauth/.ncsa_passwd user1 htpasswd /etc/squid/acl/buildauth/.ncsa_passwd user2 htpasswd /etc/squid/acl/buildauth/.ncsa_passwd usern
Outros exemplos:
http://www.hardware.com.br/livros/servidores-linux/proxy-com-autenticacao.html
2. Opções globais (/etc/squid/acl/buildauth/options)
Neste arquivo, através das opções authenticate_ttl e authenticate_ip_ttl, determinamos o tempo de duração do cache das credenciais de usuário e o intervalo de tempo em que o Squid mantém o mapeamento de usuários por IP (utilizado em conjunto com uma ACL do tipo max_user_ip).
authenticate_ttl 2 hour authenticate_ip_ttl 900 seconds authenticate_cache_garbage_interval 1 hour acl UserInfoControlChar urllogin [[:cntrl:]] http_access deny UserInfoControlChar
A ACL UserInfoControlChar foi utilizada como prevenção contra um bug no MSIE:
http://www.squid-cache.org/Advisories/SQUID-2004_1.txt
3. Políticas de acesso (/etc/squid/acl/buildauth/authpolicy)
Em authpolicy, podemos evitar que as contas de usuários sejam compartilhadas, definindo max_user_ip como 1, e também forçar a autenticação para qualquer requisição de acesso.
## Política de acesso acl max_users max_user_ip -s 1 acl all_users proxy_auth REQUIRED acl shared_users proxy_auth -i "/etc/squid/acl/user_shared" http_access deny !all_users http_access deny max_users !shared_users all ## Lista negra e lista branca acl user_blacklist proxy_auth_regex -i "/etc/squid/acl/user_blacklist" http_access deny user_blacklist all acl user_whitelist proxy_auth_regex -i "/etc/squid/acl/user_whitelist" http_access allow user_whitelist
O controle de acesso é feito a partir de regras http_access. A primeira obriga a identificação do usuário e a segunda inibe o compartilhamento de contas. A opção all, no final das regras, é uma garantia de que o acesso será bloqueado sem que o proxy envie uma nova solicitação de autenticação. Em alguns casos, pode ser desejado impedir o acesso para o usuário corrente, porém possibilitando a validação de outra credencial. Os principais controles costumam ser feitos com a opção all para evitar que os usuários sejam incomodados, constantemente, com caixas de autenticação.
A ACL all_users (REQUIRED) foi definida para forçar a identificação prévia dos usuários, antes de submeter aos demais controles. Vale lembrar que cada ACL identifica uma condição de acesso, mas o controle efetivo é feito pelas regras http_access.
Já a ACL max_users foi utilizada para garantir que as contas de usuários não sejam compartilhadas, pois permitirá apenas 1 endereço IP por usuário simultâneamente. Caso o limite de max_user_ip seja excedido, ambos os endereços serão bloqueados pelo intervalo de tempo configurado no arquivo options (vide authenticate_ip_ttl). Ou seja, o bloqueio durará 15 minutos (900 segundos).
Integrando com o Active Directory
A lógica essencial e básica foi apresentada. Veremos agora um exemplo, mais avançado, de configuração com autenticação integrada ao AD. Trabalharemos com os três esquemas de autenticação (negotiate, ntlm e basic), oferecendo suporte à autenticação Kerberos e NTLM. Conforme exposto inicialmente, o navegador selecionará o método mais adequado.
Vale lembrar que, para ingressar o servidor corretamente ao domínio, os mapeamentos de DNS são fundamentais (na autenticação Kerberos são OBRIGATÓRIOS), sejam registros do tipo A como PTR (precisa do reverso também) – as referências ao servidor proxy, em configurações manuais ou WPAD, serão feitas pelo nome FQDN. É recomendável conferir o mapeamento local, com a identificação do servidor no arquivo /etc/hosts, também.
Comece ingressando o servidor ao domínio:
http://linuxfirewall.com.br/linuxwp/autenticacao-integrada-com-o-ms-active-directory-ad/
Observação: “Para evitar exposição e consumo de recursos desnecessários, basta instalar e executar apenas o serviço winbind (responsável pela identificação dos usuários). Neste cenário, os demais serviços do Samba não são necessários – caso sejam instalados, desabilite os serviços smbd e nmbd (a instalação das dependências samba-common e samba-common-bin são suficientes). Como o nosso objetivo é prover a autenticação no Squid, a integração com NSS também é opcional (não requer a configuração do arquivo nsswitch.conf), mas seria necessária se houvesse integração com o PAM“.
Siga os passos descritos no link anterior. A cada alteração, reinicie o serviço winbind. Não há mistério, porém prossiga com a configuração do Squid apenas quando os testes de integração retornarem mensagem de sucesso (comandos net ads testjoin e wbinfo -t, por exemplo).
Em seguida, certifique-se da existência dos seguintes módulos:
root@proxysrv:~# ls /usr/lib/squid/* /usr/bin/ntlm_auth | grep "\(wrapper\|ntlm_auth\|kerberos_auth\b\)" /usr/bin/ntlm_auth /usr/lib/squid/negotiate_kerberos_auth /usr/lib/squid/negotiate_wrapper_auth
Caso não encontre os dois últimos módulos exibidos em /usr/lib/squid, é provável que sua compilação não ofereça suporte ao Kerberos. Se este for o caso, instale as bibliotecas de desenvolvimento e recompile o Squid (vide parte 1). Para confirmar as opções de compilação, utilize o comando “squid -v“.
Se necessário (recompilação), instale as bibliotecas de desenvolvimento:
apt-get install krb5-user libkrb5-3 libkrb5-dev libsasl2-modules-gssapi-mit
Certifique-se também da existência do winbind. Não esqueça de ajustar a permissão do usuário proxy, incluindo no grupo winbindd_priv:
apt-get install winbind chgrp winbindd_priv /var/lib/samba/winbindd_privileged gpasswd -a proxy winbindd_priv
Neste caso, edite o arquivo de configuração e comente a opção cache_effective_group para evitar que o Squid fixe um único grupo como efetivo, ignorando o mapeamento de grupo alternativo. Do contrário, inviabilizará o mapeamento sugerido.
Com esta configuração, já é possível validar o módulo ntlm_auth sob os esquemas NTLM e Basic. Até este ponto é simples. Mas, a configuração do Kerberos tende ser um pouco mais trabalhosa e depende de uma atenção adicional. Volto a frisar, os mapeamentos de DNS são obrigatórios e devemos utilizar o nome FQDN do servidor na configuração dos navegadores.
Para incluir o suporte à autenticação Kerberos será necessária a inclusão de alguns registros LDAP, criação de um SPN para classe de serviço HTTP e geração do arquivo com a estrutura de chaves para HTTP/nome_fqdn_do_servidor (keytab).
O processo descrito acima pode ser feito, no servidor Linux, através da ferramenta msktutil.
1. Instalação da ferramenta msktutil
Opte, preferencialmente, pelo download no site oficial. Já encontrei dificuldade com o binário disponível nos repositórios do Ubuntu (algumas versões).
wget https://fuhm.net/software/msktutil/releases/msktutil_0.4-2_amd64.debou
apt-get install msktutil
2. Geração do keytab para HTTP/nome_fqdn_do_servidor
Neste exemplo, estou supondo que o nome FQDN do servidor é proxysrv.local e o SPN será HTTP/proxysrv.local. Em computer-name informe o nome netbios (até o limite de 15 caracteres) – é um nome específico apenas para este propósito (diferente do nome mapeado com net join).
“Antes de executar o comando msktutil, inicie uma sessão administrativa com kinit“.
kinit adminitrator@LOCAL msktutil -c -s HTTP/proxysrv.local -k /etc/squid/PROXY.keytab --computer-name k-proxy --upn HTTP/proxysrv.local --server dc001.local --verbose --enctypes 28 chown proxy.proxy /etc/squid/PROXY.keytab chmod 640 /etc/squid/PROXY.keytab
Altere o arquivo /etc/krb5.conf, incluindo a seguinte linha:
... ticket_lifetime = 24h default_keytab_name = /etc/squid/PROXY.keytab default_tkt_enctypes = rc4-hmac default_tgs_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5 permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5 ...
Em seguida, edite o script de inicialização do serviço (em /etc/init.d/squid, por exemplo) e inclua as seguintes linhas:
KRB5_KTNAME=/etc/squid/PROXY.keytab KRB5RCACHETYPE=none export KRB5_KTNAME export KRB5RCACHETYPE
“A variável KRB5RCACHETYPE deve ser definida como none caso o cache comprometa o consumo de CPU – infelizmente, na maioria das vezes, compromete“.
Podemos validar o keytab abrindo uma nova sessão a partir do SPN criado anteriormente:
– Domínio local e realm LOCAL
root@proxysrv:~# kdestroy root@proxysrv:~# klist -ek Keytab name: FILE:/etc/squid/PROXY.keytab KVNO Principal ---- -------------------------------------------------------------------------- ... 2 HTTP/proxysrv.local@LOCAL (arcfour-hmac) 2 HTTP/proxysrv.local@LOCAL (aes128-cts-hmac-sha1-96) 2 HTTP/proxysrv.local@LOCAL (aes256-cts-hmac-sha1-96) 2 host/proxysrv.local@LOCAL (arcfour-hmac) 2 host/proxysrv.local@LOCAL (aes128-cts-hmac-sha1-96) 2 host/proxysrv.local@LOCAL (aes256-cts-hmac-sha1-96) root@proxysrv:~# kinit -V -k -t /etc/squid/PROXY.keytab HTTP/proxysrv.local@LOCAL root@proxysrv:~# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: HTTP/proxysrv.local@LOCAL Valid starting Expires Service principal 04-06-2017 14:35:06 05-06-2017 00:35:06 krbtgt/LOCAL@LOCAL renew until 05-06-2017 14:35:06 root@proxysrv:~# kdestroy
3. Mantendo o keytab atualizado (em função da política de expiração de senhas): Agende uma tarefa diária no cron para executar o msktutil com a opção –auto-update.
– Inclua um novo agendamento, como root, com crontab -e
00 4 * * * msktutil --auto-update --verbose --computer-name k-proxy | logger -t msktutil
Para finalizar, basta alterar a configuração dos helpers (acl/buildauth/authmodule):
## Negotiate kerberos/NTLM module auth_param negotiate program /usr/lib/squid/negotiate_wrapper_auth --ntlm /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp --use-cached-creds --kerberos /usr/lib/squid/negotiate_kerberos_auth -s GSS_C_NO_NAME auth_param negotiate children 200 startup=15 idle=5 auth_param negotiate keep_alive on ## NTLM Auth auth_param ntlm program /usr/bin/ntlm_auth --use-cached-creds --helper-protocol=squid-2.5-ntlmssp auth_param ntlm children 110 startup=5 idle=5 auth_param ntlm keep_alive on ## Basic NTLM plugin Auth auth_param basic program /usr/bin/ntlm_auth --use-cached-creds --helper-protocol=squid-2.5-basic auth_param basic children 110 startup=5 idle=5 auth_param basic credentialsttl 2 hours auth_param basic casesensitive off auth_param basic realm "Squid Proxy"
Reinicie o serviço para recarregar a configuração:
service squid stop service squid startou
/etc/init.d/squid stop /etc/init.d/squid start
Mais uma vez, o assunto prolongou um pouco mais do que imaginei. Ficou extenso porque procurei detalhar cada fase. O processo, em si, depois de compreendido, é muito simples.
Procurei organizar o texto de uma forma que facilite na compreensão das opções de configuração e técnicas de depuração. Já passei por inúmeras dificuldades e estas dicas me ajudaram bastante. A configuração com balanceamento de carga é um pouco mais complexa (precisa prever os nós de balanceamento também) e será tema de outro artigo no futuro.
– Confiram algumas referências de pesquisa:
http://wiki.bitbinary.com/index.php/Active_Directory_Integrated_Squid_Proxy
https://wiki.gentoo.org/wiki/Kerberos_Windows_Interoperability
https://www.safesquid.com/content-filtering/integrating-linux-host-windows-ad-kerberos-sso-authentication
https://fuhm.net/software/msktutil/manpage.html
– Outro link interessante, onde fiz uma pequena participação (comentando):
https://www.mundotibrasil.com.br/integrando-squid-com-grupos-do-active-directory/
[…] pouco tempo, publicamos um artigo tratando a autenticação do Squid. As etapas descritas demonstraram o processo de configuração que adotamos em nosso […]
Olá, eu procuro um artigo sobre configuração do Kerberos no Squid para autenticação dos usuários no AD, porém sem usar NTLM. Creio que assim não seria necessário instalar o winbind, nem ingressar o servidor de proxy ao domínio. Pode me ajudar?
Parabéns pelo artigo.
Bom dia Danilo,
O processo para autenticação Kerberos, em NTLM, é praticamente o mesmo. Você precisa gerar o keytab com o SPN de HTTP/ e utilizar diretamente o módulo de autenticação squid_kerb_auth. De qualquer forma, é bom fazer a configuração para negotiate e basic também (nem todas aplicações funcionarão perfeitamente sob negotiate).
https://wiki.squid-cache.org/ConfigExamples/Authenticate/Kerberos
Quando voce cria inicialmente um novo servidor Ubuntu 16.04, existem alguns passos de configuracao que voce deve tomar no inicio como parte da configuracao basica. Isto aumentara a seguranca e a usabilidade do seu servidor e dara uma solida fundacao para as acoes subsequentes
Eu peguei um bug no msktutil versão 0.5.2 quando utilizado a opção –verbose é exibida a informação abaixo, para resolver esse problema é só não usar a opção –verbose.
Dois dias quebrando a cabeça.
Aliais ótimo tutorial do squid
========================
Erro com o verbose ativo
========================
*** stack smashing detected ***: msktutil terminated
Aborted (core dumped)
Bom dia Rogerio,
Já passei por isto também… na maioria das vezes, é incompatibilidade de biblioteca com o binário que você baixou.
Dependendo da distribuição (Ubuntu, por exemplo), não compensa pegar de repositório alternativo.
Em alguns casos você pode descobrir link quebrado ou incompatibilidade, usando o comando ldd:
ldd $(which msktutil)
Em versões mais atuais do Ubuntu, pode instalar pelo apt sem medo!
Acho que, no caso do CentOS, também.
Caso esteja com muita dificuldade, o jeito será compilar! 😉