Squid autenticado no Captive Portal pfSense 2.3



  • Olá pessoal,

    Há tempos estou buscando a solução para Squid (transparente) autenticado no Captive Portal em desde a versão 2.2.x. Nos debugs encontrei problemas com o script PHP que faziam o processo do Squid parar.

    A solução foi recriar o script em php. Para aplicar a correção basta trocar o conteúdo do arquivo /usr/local/bin/check_ip.php pelo o conteúdo abaixo e salvar as configurações do Squid e do Captive Portal:

    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
    define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
    define("STDOUT", fopen("php://stdout", "r"));
    }
    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    foreach($dbs as $db){
    $status = check_ip($db, $check_ip);
    break;
    }
    if(isset($status)){
    fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
    fwrite(STDOUT, "ERR\n");
    }

    function check_ip($db, $check_ip){
    exec("sqlite3 {$db} "SELECT ip FROM captiveportal WHERE ip='{$check_ip}'"", $ip);
    if($check_ip == $ip[0]){
    exec("sqlite3 {$db} "SELECT username FROM captiveportal WHERE ip='{$check_ip}'"", $user);
    return $user[0];
    }
    }
    ?>

    OBS: Não foi testado em outras versões anteriores a 2.3;

    OBS2: Deixar um site de redirecionamento após a autenticação (configuração After authentication Redirection URL do Captive Portal) ajuda a retornar a página mais rápido. Porém se a página estiver em cache também será rapido o login, se a página não estiver em cache o retorno pode demorar.

    Abs!

    Augusto



  • Legal!

    Essa funcionalidade realmente estava fazendo falta.
    Tomara que na próxima versão o pfSense já integre essa solução!

    Valeu, Augusto!



  • Grande Augusto!
    Ótima dica! Muito obrigado!



  • @joaoheytor:

    Grande Augusto!
    Ótima dica! Muito obrigado!

    Muito bom amigo!

    quando migrar para o pfsense 2.3 vou testar :)

    Abraços,

    Diego



  • Legal cara.. tava procurando isso também, porém ta dando esse erro aqui:

    Squid Cache (Version 3.5.16): Terminated abnormally.
    CPU Usage: 0.150 seconds = 0.047 user + 0.103 sys
    Maximum Resident Size: 88176 KB
    Page faults with physical i/o: 0
    Error: file is encrypted or is not a database
    Error: file is encrypted or is not a database
    2016/05/13 11:40:47 kid1| Starting Squid Cache version 3.5.16 for amd64-portbld-freebsd10.3…
    2016/05/13 11:40:47 kid1| Service Name: squid
    2016/05/13 11:40:47| pinger: Initialising ICMP pinger ...
    Error: file is encrypted or is not a database
    Error: file is encrypted or is not a database
    Error: file is encrypted or is not a database
    2016/05/13 11:41:47 kid1| WARNING: check_cp #Hlpr9 exited
    Error: file is encrypted or is not a database
    2016/05/13 11:41:47 kid1| WARNING: check_cp #Hlpr10 exited
    FATAL: The check_cp helpers are crashing too rapidly, need help!



  • Quantas instâncias do Captive Portal você tem?

    Pelo erro, tem alguma coisa de errado com o banco de dados do captive portal. O script deve ler mais de um banco pois cada instância cria um banco diferente.

    Um teste válido seria verificar se o script está fazendo sua função. Para isso:

    1º - Autentique com pelo menos um usuário em cada instância do Captive Portal;
    2º - logue via SSH no pfSense;
    3º - Execute o script de autenticação (check_ip.php) apenas com o comando /usr/local/bin/check_ip.php. Nesse momento o script ficará esperando sua ação, o que ele deseja nesse momento é que você insira um ip, ou seja, se esse ip inserido estiver autenticado ele retorna OK=usuario, senão deve retornar ERR.



  • Só uma instância. Mas acho q sei o motivo. Estou usando radius na autenticação do  CP. Não usuário local. Será q é isso?



  • Exatamente, fiz um teste utilizando Radius também e a verificação dos bancos das instâncias do captive que faço na linha 10 ("/var/db/captiveportal*.db") acaba incluindo o banco de dados do radius também. Nesse caso tem que fazer uma verificação para não incluir esses bancos. Vou dar uma revisada no script e posto novamente.

    Por hora para corrigir esse erro basta trocar o * pelo nome completo do seu banco de dados de sua instância do Captive.



  • Muito bom. Estou tentando implementar isso já faz uns 60 dias. Uso apenas Squid atualmente em minha rede. Vou testar e ver no que dá e posto aqui.

    Cordialmente;

    Claudir P. Santos



  • Realmente pra usuários locais funciona bem e ainda registra os usuários no access.log do squid. Muito bom…

    Pena que pra autenticação RADIUS ainda nao funciona.



  • Boa tarde,

    Segue o script corrigido para funcionar com Radius.

    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
    define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
    define("STDOUT", fopen("php://stdout", "r"));
    }

    while (!feof(STDIN)) {

    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");

    foreach($dbs as $db){
    if(!strpos($db, "_radius")){
    $status = check_ip($db, $check_ip);
    break;
    }
    }
    if(isset($status)){
    fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
    fwrite(STDOUT, "ERR\n");
    }

    } // end While

    function check_ip($db, $check_ip){
    exec("sqlite3 {$db} "SELECT ip FROM captiveportal WHERE ip='{$check_ip}'"", $ip);
    if($check_ip == $ip[0]){
    exec("sqlite3 {$db} "SELECT username FROM captiveportal WHERE ip='{$check_ip}'"", $user);
    return $user[0];
    }
    }

    ?>



  • Putz cara!! Valeu demais!! Funcionou 100%

    Vou adicionar essa solução aqui –> https://forum.pfsense.org/index.php?topic=103745.new;topicseen#new Tem algumas pessoas querendo essa solução também.

    abç



  • @augusto_pereira:

    Olá pessoal,

    Há tempos estou buscando a solução para Squid (transparente) autenticado no Captive Portal em desde a versão 2.2.x. Nos debugs encontrei problemas com o script PHP que faziam o processo do Squid parar.

    A solução foi recriar o script em php. Para aplicar a correção basta trocar o conteúdo do arquivo /usr/local/bin/check_ip.php pelo o conteúdo abaixo e salvar as configurações do Squid e do Captive Portal:

    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
    define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
    define("STDOUT", fopen("php://stdout", "r"));
    }
    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    foreach($dbs as $db){
    $status = check_ip($db, $check_ip);
    break;
    }
    if(isset($status)){
    fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
    fwrite(STDOUT, "ERR\n");
    }

    function check_ip($db, $check_ip){
    exec("sqlite3 {$db} "SELECT ip FROM captiveportal WHERE ip='{$check_ip}'"", $ip);
    if($check_ip == $ip[0]){
    exec("sqlite3 {$db} "SELECT username FROM captiveportal WHERE ip='{$check_ip}'"", $user);
    return $user[0];
    }
    }
    ?>

    OBS: Não foi testado em outras versões anteriores a 2.3;

    OBS2: Deixar um site de redirecionamento após a autenticação (configuração After authentication Redirection URL do Captive Portal) ajuda a retornar a página mais rápido. Porém se a página estiver em cache também será rapido o login, se a página não estiver em cache o retorno pode demorar.

    Abs!

    Augusto

    Thanks ,
    I put this code and set squid use captiveportal for Authentication , and reboot system , but nothing happen and light squid show me IP and show not username .
    I have radius too , do I need another code ?

    when I set authentication method captiveportal squid work but and I see captive portal login page , but after login user see error about access denied , and this error make by squid .



  • Usei o segundo script em um ambiente onde o portal captive pega as informações dos usuário em um servidor Radius com Windows Server 2012. Funcionou perfeitamente.
    Muito obrigado. Faz um tempo que estava tentando implementar isso para migrar do squid puro para o pfsense.

    Cordialmente;

    Claudir Pereira dos Santos



  • Dear mfaridi,

    use this code on check_ip.php

    Note: After replace code, edit captive portal and squid configuration. Click Save.

    
    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
       define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
       define("STDOUT", fopen("php://stdout", "r"));
    }
    
    while (!feof(STDIN)) {
    
    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    
    foreach($dbs as $db){
       if(!strpos($db, "_radius")){
          $status = check_ip($db, $check_ip);
          break;   
       }   
    }
    if(isset($status)){
       fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
       fwrite(STDOUT, "ERR\n");
    }
    
    } // end While
    
    function check_ip($db, $check_ip){
       exec("sqlite3 {$db} \"SELECT ip FROM captiveportal WHERE ip='{$check_ip}'\"", $ip);
       if($check_ip == $ip[0]){
          exec("sqlite3 {$db} \"SELECT username FROM captiveportal WHERE ip='{$check_ip}'\"", $user);
          return $user[0];
       }
    }
    
    ?>
    
    


  • @rlrobs:

    Dear mfaridi,

    use this code on check_ip.php

    Note: After replace code, edit captive portal and squid configuration. Click Save.

    
    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
       define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
       define("STDOUT", fopen("php://stdout", "r"));
    }
    
    while (!feof(STDIN)) {
    
    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    
    foreach($dbs as $db){
       if(!strpos($db, "_radius")){
          $status = check_ip($db, $check_ip);
          break;   
       }   
    }
    if(isset($status)){
       fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
       fwrite(STDOUT, "ERR\n");
    }
    
    } // end While
    
    function check_ip($db, $check_ip){
       exec("sqlite3 {$db} \"SELECT ip FROM captiveportal WHERE ip='{$check_ip}'\"", $ip);
       if($check_ip == $ip[0]){
          exec("sqlite3 {$db} \"SELECT username FROM captiveportal WHERE ip='{$check_ip}'\"", $user);
          return $user[0];
       }
    }
    
    ?>
    
    

    Thanks when I use that code and go to squid setting and choose Authentication Method Captive portal and save captive portal too and reset system , user see captive portal login page and they enter password and username , but after login they see error about access denied and they see this




  • mfaridi,

    follow print screen of my configurations.
    Note: pfsense 2.3












  • @rlrobs:

    mfaridi,

    follow print screen of my configurations.
    Note: pfsense 2.3

    Thanks , Thanks
    After your guide every thing work good , but I have these problems ;

    1- Captive portal sometimes need paas and some time no
    2- I think PFsense system is heavy and config with GUI take time , I have 2 GB of RAM and Dual core CPU
    3- lightsquid make report , I see IP too , light squid show username and some IPs



  • Muito interessante isso. Quando migrar para versão 2.3 vou implementar na rede aqui.
    Parabéns ao colega Augusto.

    ;D

    Denicio.



  • Augusto,

    abusando da sua boa vontade.. Fiz um teste aqui cadastrando dois captive portal com radius e um deles não funcionou. Fiz também com duas instâncias com usuŕios locais e o resultado foi o mesmo. Ele só funciona com uma das instancias.. Veja o print:




  • Boa tarde rlrobs,

    Realmente precisamos fazer uma mudança no script,tente com esse:

    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
      define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
      define("STDOUT", fopen("php://stdout", "r"));
    }

    while (!feof(STDIN)) {

    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    //print_r($dbs);

    foreach($dbs as $i => $db){
      if(!strpos($db, "_radius")){
          $status = check_ip($db, $check_ip);
    if(isset($status)){
      $return = "OK user={$status}\n";
    break;
    }
    else{
      $return = "ERR\n";
    }
      } 
    }
    fwrite(STDOUT, "{$return}");
    } // end While

    function check_ip($db, $check_ip){
      exec("sqlite3 {$db} "SELECT ip FROM captiveportal WHERE ip='{$check_ip}'"", $ip);
      if($check_ip == $ip[0]){
          exec("sqlite3 {$db} "SELECT username FROM captiveportal WHERE ip='{$check_ip}'"", $user);
          return $user[0];
      }
    }

    ?>



  • Estou com proxy ATIVO e o Captive portal ja esta autenticando POREM so autentica se desativar o proxy da estação, ai depois tenho que ativar para conseguir navegar… =/
    Alguem tem uma ideia do captive autenticar mesmo com o proxy ativo no cliente?



  • Captive portal so demonstra a tela de autenticação com Squid TRANSPARENTE.  :-\



  • @augusto_pereira:

    Olá pessoal,

    Há tempos estou buscando a solução para Squid (transparente) autenticado no Captive Portal em desde a versão 2.2.x. Nos debugs encontrei problemas com o script PHP que faziam o processo do Squid parar.

    A solução foi recriar o script em php. Para aplicar a correção basta trocar o conteúdo do arquivo /usr/local/bin/check_ip.php pelo o conteúdo abaixo e salvar as configurações do Squid e do Captive Portal:

    #!/usr/local/bin/php-cgi -q
    if(!defined(STDIN)){
    define("STDIN", fopen("php://stdin", "r"));
    }
    if(!defined(STDOUT)){
    define("STDOUT", fopen("php://stdout", "r"));
    }
    $check_ip = trim(fgets(STDIN));
    $dbs = glob("/var/db/captiveportal*.db");
    foreach($dbs as $db){
    $status = check_ip($db, $check_ip);
    break;
    }
    if(isset($status)){
    fwrite(STDOUT, "OK user={$status}\n");
    }
    else{
    fwrite(STDOUT, "ERR\n");
    }

    function check_ip($db, $check_ip){
    exec("sqlite3 {$db} "SELECT ip FROM captiveportal WHERE ip='{$check_ip}'"", $ip);
    if($check_ip == $ip[0]){
    exec("sqlite3 {$db} "SELECT username FROM captiveportal WHERE ip='{$check_ip}'"", $user);
    return $user[0];
    }
    }
    ?>

    OBS: Não foi testado em outras versões anteriores a 2.3;

    OBS2: Deixar um site de redirecionamento após a autenticação (configuração After authentication Redirection URL do Captive Portal) ajuda a retornar a página mais rápido. Porém se a página estiver em cache também será rapido o login, se a página não estiver em cache o retorno pode demorar.

    Abs!

    Augusto

    O meu deu tudo certo porem a pagina do captive não abre, da erro como se eu tivesse que autenticar pra abrir, coloquei uma pagina na Whitelist e apenas ela abre, como faço para que todas as paginas redirecionarem para autenticação do captive? :(



  • @derikdk:

    Captive portal so demonstra a tela de autenticação com Squid TRANSPARENTE.  :-\

    Quando o proxy está marcado, a pagina inicial do navegador precisa estar configurada para não passar pelo proxy no cliente.



  • @marcelloc:

    @derikdk:

    Captive portal so demonstra a tela de autenticação com Squid TRANSPARENTE.  :-\

    Quando o proxy está marcado, a pagina inicial do navegador precisa estar configurada para não passar pelo proxy no cliente.

    Meu proxy não esta marcado, esta como transparente, e mesmo asssim a pagina do CP não aparece nem mesmo forçando ela colocando a porta, ja configurarei as regras do firewall para passa fora do proxy mas mesmo assim nem sinal do CP abrir



  • Complementando a dica estava faltando "SOMENTE ISSO"  ;D

    @marcelloc:

    @derikdk:

    Captive portal so demonstra a tela de autenticação com Squid TRANSPARENTE.  :-\

    Quando o proxy está marcado, a pagina inicial do navegador precisa estar configurada para não passar pelo proxy no cliente.

    ![Sem título.jpg](/public/imported_attachments/1/Sem título.jpg)
    ![Sem título.jpg_thumb](/public/imported_attachments/1/Sem título.jpg_thumb)



  • @augusto_pereira:

    Boa tarde,

    Segue o script corrigido para funcionar com Radius.

    Utilizei seu script porém só recebo mensagem de acesso negado, ao retirar a autenticação do squid, autentico no captive e navego de boa.

    Utilizo o pfsense 2.3 e o pacote nativo do squid. o captive autentica em um Server 2008 R2

    Squid transparente.

    Depois que alterar o check_ip disse para alterar o squid e captive também, mas quais são essas alterações?



  • Refiz o esquema de alteração do cóigo para Radius e desta vez deu certo, obrigado a quem postou a alteração do código para Radius.

    @jrcferrari:

    @augusto_pereira:

    Boa tarde,

    Segue o script corrigido para funcionar com Radius.

    Utilizei seu script porém só recebo mensagem de acesso negado, ao retirar a autenticação do squid, autentico no captive e navego de boa.

    Utilizo o pfsense 2.3 e o pacote nativo do squid. o captive autentica em um Server 2008 R2

    Squid transparente.

    Depois que alterar o check_ip disse para alterar o squid e captive também, mas quais são essas alterações?



  • @derikdk:

    Complementando a dica estava faltando "SOMENTE ISSO"  ;D

    @marcelloc:

    @derikdk:

    Captive portal so demonstra a tela de autenticação com Squid TRANSPARENTE.  :-\

    Quando o proxy está marcado, a pagina inicial do navegador precisa estar configurada para não passar pelo proxy no cliente.

    Alem dessa configuração tenho que fazer mais alguma pra abri o CP com o proxy setado?

    Porque só com essa não abre não kk "Ela abre a pagina que eu liberei mas não redireciona pro CP"



  • VictorM,

    Captive Portal somente funciona com proxy transparente. Não há como fazer funcionar com proxy marcado.

    Att,

    Augusto



  • @augusto_pereira:

    VictorM,

    Captive Portal somente funciona com proxy transparente. Não há como fazer funcionar com proxy marcado.

    Att,

    Augusto

    Claro que tem, eu uso dessa forma.



  • @Tomas:

    @augusto_pereira:

    VictorM,

    Captive Portal somente funciona com proxy transparente. Não há como fazer funcionar com proxy marcado.

    Att,

    Augusto

    Claro que tem, eu uso dessa forma.

    Então compartilhe conosco como você faz, Tomas Waldow.



  • @jonathandalves:

    @Tomas:

    @augusto_pereira:

    VictorM,

    Captive Portal somente funciona com proxy transparente. Não há como fazer funcionar com proxy marcado.

    Att,

    Augusto

    Claro que tem, eu uso dessa forma.

    Então compartilhe conosco como você faz, Tomas Waldow.

    Porfavor compartilhe



  • Bom, eu uso WPAD, mas ideia é a mesma, então vamos lá;

    Primeiro precisa que um site seja liberado no firewall, pode ser o site a empresa, no meu caso é uma escola.
    Depois é preciso colocar esse site na exceção do proxy para que não seja feita a requisição na 3128 e sim na 80 para que o CP posso responder a pagina de autenticação.
    Se usar o proxy marcado precisa informar esse "site" nas configurações conforme imagem em anexo.

    Se usar WPAD ficaria dessa forma:

    function FindProxyForURL(url,host){
    
      // resolve o ip do host
      var host_ip=dnsResolve(host);
    
      // If the requested website is hosted within the internal network, send direct.
      if (isPlainHostName(host) ||
        isInNet(host_ip, "10.0.0.0", "255.0.0.0") ||
        isInNet(host_ip, "172.16.0.0",  "255.240.0.0") ||
        isInNet(host_ip, "192.168.0.0",  "255.255.0.0") ||
        isInNet(host_ip, "127.0.0.0", "255.255.255.0"))
      return "DIRECT";
    
      // Dominio sem proxy
      if (shExpMatch(host, "www.exemplo.com")) return "DIRECT";
    
      // Regra deafult com proxy 
      return "PROXY 192.168.1.1:3128";
    }
    

    Façam testes e informe se deu certo, posso ter esquecido alguma coisa!




  • Boa tarde,

    Seguindo esse topico fiz tudo o que foi dito aqui mas não consegui por a funcionar o proxy transparent + captive portal.

    Tenho o mesmo erro que o membro mfaridi (https://forum.pfsense.org/index.php?topic=111670.msg628122#msg628122) e segui as imagens do outro membro rlrobs mas continuo com o mesmo erro do membro mfaridi.

    Tenho o pfsense 2.3.2 em que só com o proxy transparent + squidguard funciona lindamente. Metendo no squid a atuthentication para captive portal deixo de ter acesso a qualquer pagina da internet e tenho o erro: "The following error wan encountered while tryin to retrieve the url: http://…..." (o memso do membro mfaridi).

    Uma pequena ajuda agradecia.
    Obrigado.



  • @ricain59:

    Boa tarde,

    Seguindo esse topico fiz tudo o que foi dito aqui mas não consegui por a funcionar o proxy transparent + captive portal.

    Tenho o mesmo erro que o membro mfaridi (https://forum.pfsense.org/index.php?topic=111670.msg628122#msg628122) e segui as imagens do outro membro rlrobs mas continuo com o mesmo erro do membro mfaridi.

    Tenho o pfsense 2.3.2 em que só com o proxy transparent + squidguard funciona lindamente. Metendo no squid a atuthentication para captive portal deixo de ter acesso a qualquer pagina da internet e tenho o erro: "The following error wan encountered while tryin to retrieve the url: http://…..." (o memso do membro mfaridi).

    Uma pequena ajuda agradecia.
    Obrigado.

    ricain59

    Poste com detalhes os passos que fez para podermos ajudá-lo.



  • @Tomas:

    Bom, eu uso WPAD, mas ideia é a mesma, então vamos lá;

    Primeiro precisa que um site seja liberado no firewall, pode ser o site a empresa, no meu caso é uma escola.
    Depois é preciso colocar esse site na exceção do proxy para que não seja feita a requisição na 3128 e sim na 80 para que o CP posso responder a pagina de autenticação.
    Se usar o proxy marcado precisa informar esse "site" nas configurações conforme imagem em anexo.

    Se usar WPAD ficaria dessa forma:

    function FindProxyForURL(url,host){
    
      // resolve o ip do host
      var host_ip=dnsResolve(host);
    
      // If the requested website is hosted within the internal network, send direct.
      if (isPlainHostName(host) ||
        isInNet(host_ip, "10.0.0.0", "255.0.0.0") ||
        isInNet(host_ip, "172.16.0.0",  "255.240.0.0") ||
        isInNet(host_ip, "192.168.0.0",  "255.255.0.0") ||
        isInNet(host_ip, "127.0.0.0", "255.255.255.0"))
      return "DIRECT";
    	
      // Dominio sem proxy
      if (shExpMatch(host, "www.exemplo.com")) return "DIRECT";
    
      // Regra deafult com proxy 
      return "PROXY 192.168.1.1:3128";
    }
    

    Façam testes e informe se deu certo, posso ter esquecido alguma coisa!

    Tomas Waldow,

    Fiz todos os passos como indicou porém não funcionou. A autenticação no Captive Portal ocorre porém uma vez logado no Captive nenhum tráfego é passado no Squid. Verifique se seu proxy transparente está desmarcado para fazer um teste com apenas o proxy marcado funcionando.



  • Não uso proxy transparente!



  • @augusto_pereira:

    ricain59

    Poste com detalhes os passos que fez para podermos ajudá-lo.

    Obrigado Augusto Pereira,

    Mas para não estar a "encher" este topico eu criei um com o meu problema. Se poder passar por la agradecia: https://forum.pfsense.org/index.php?topic=117308.0