Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    PfSense 2.3.2: Captive Portal + Non Transparent Squid3

    Scheduled Pinned Locked Moved Captive Portal
    3 Posts 2 Posters 3.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N
      naugul
      last edited by

      Hi!

      I'll start by apologizing, i know this is a know problem, treated in other topics, like this one, https://forum.pfsense.org/index.php?topic=111670.0

      First, i'm working in a 2.3.2 (64bit) version of pfSense.

      Now, according to that topic, it is possible to have a working environment with Captive Portal + Squid3 + SquidGuard AND WPAD. I mean, without using the transparent option of squid. The fact is, i can't make it work, i don't know if i'm missing something in the translation from Portuguese or what,  but it simply won't work.

      I've tried all modifications i could find of the

      /usr/local/bin/check_ip.php

      file, most of which make it impossible for the Squid service to start.

      This one, for example:

      
      #!/usr/local/bin/php-cgi -q
      
      require_once("config.inc");
      require_once("globals.inc");
      error_reporting(0);
      global $g;
      // stdin loop
      if (!defined(STDIN)) {
      	define("STDIN", fopen("php://stdin", "r"));
      }
      if (!defined(STDOUT)) {
      	define("STDOUT", fopen('php://stdout', 'w'));
      }
      while (!feof(STDIN)) {
      	$line = trim(fgets(STDIN));
      	$files = glob("{$g['vardb_path']}/captiveportal*.db");
      	$answer="ERR";
      	foreach ($files as $file) {
      		$result = squid_cp_read_db($file);
      		//1419045939,1419045939,2000,2000,192.168.10.11,192.168.10.11,08:00:27:5c:e1:ee,08:00:27:5c:e1:ee,marcello,marcello,605a1f46e2d64556,605a1f46e2d64556,,,,,,,,,,,first,first
      		foreach ($result as $row) {
      			if ($row[2] != "" && $row[2] == $line) {
      				$answer = "OK user={$row[4]}";
      				break 2;
      			}
      	$check_ip = trim(fgets(STDIN));
      	$dbs = glob("{$g['vardb_path']}/captiveportal*.db");
      
      	foreach ($dbs as $db) {
      		if(!strpos($db, "_radius")) {
      			$status = squid_check_ip($db, $check_ip);
      			break;
      	}
      }
      	fwrite(STDOUT, "{$answer}\n");
      	if (isset($status)) {
      		fwrite(STDOUT, "OK user={$status}\n");
      	} else {
      		fwrite(STDOUT, "ERR\n");
      	}
      }
      /* read captive portal DB into array */
      function squid_cp_read_db($file) {
      	$cpdb = array();
      	$DB = new SQLite3($file);
      	if ($DB) {
      		$response = $DB->query("SELECT * FROM captiveportal");
      		if ($response != FALSE) {
      			while ($row = $response->fetchArray()) {
      				$cpdb[] = $row;
      			}
      		}
      		$DB->close();
      
      function squid_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];
      }
      	return $cpdb;
      }
      
      ?>
      
      

      Makes this happen:

      cache.log ->

      Error in argument 1, char 3: option not found
      Error in argument 1, char 3: option not found
      WARNING: check_cp #Hlpr9 exited
      FATAL: The check_cp helpers are crashing too rapidly, need help!

      Any help would be appreciated.

      Thanks!
      Diego.

      PF: I'm not using RADIUS, the idea is just to use one instance of Captive Portal, with users from the pfSense User Manager.

      1 Reply Last reply Reply Quote 0
      • N
        naugul
        last edited by

        Ok.

        It's working. I don't know if that file has anything to do… But here is my current config...

        check_ip.php looks like this:

        
        #!/usr/local/bin/php-cgi -q
        require_once("config.inc");
        require_once("globals.inc");
        if (!extension_loaded('sqlite3')) {
        dl("sqlite3.so");
        }
        error_reporting(0);
        global $g;
        // stdin loop
        if (!defined(STDIN)) {
        	define("STDIN", fopen("php://stdin", "r"));
        }
        if (!defined(STDOUT)) {
        	define("STDOUT", fopen('php://stdout', 'w'));
        }
        while (!feof(STDIN)) {
        	$line = trim(fgets(STDIN));
        	$files = glob("{$g['vardb_path']}/captive*.db");
        	$answer = "ERR";
        	foreach ($files as $file) {
        		$result = squid_cp_read_db($file);
        		foreach ($result as $row) {
        //Database contains 5 fields: 1461302438 - 2006 - 192.168.4.100 - fc:aa:14:7d:e6:de - admin - 80b7d55a1bacb9c6
        			if ($row[2] != "" && $row[2] == $line) {
        				$answer = "OK user={$row[4]}";
        				break 2;
        			}
        		}
        	}
        	fwrite(STDOUT, "{$answer}\n");
        }
        /* read captive portal DB into array */
        function squid_cp_read_db($file) {
        	$cpdb = array();
        	$DB = new SQLite3($file);
        	if ($DB) {
        		$response = $DB->query("SELECT * FROM captiveportal");
        		if ($response != FALSE) {
        			while ($row = $response->fetchArray()) {
        				$cpdb[] = $row;
        			}
        		}
        		$DB->close();
        	}
        	return $cpdb;
        }
        
        ?>
        
        

        proxy.pac file looks like this:

        
        function FindProxyForURL(url, host) {
         //proxy  pfSense-IP:3128;
         var wpad = "PROXY wpad.localdomain.local:3128";
         host = host.toLowerCase();
         var hostIP = dnsResolve(host);
         if (hostIP == 0) return wpad;
         if (isPlainHostName(host)) return "DIRECT";
         if (shExpMatch(host, ".local")) return "DIRECT";
         //mi dominio localdomain.local;
         if (shExpMatch(host, ".localdomain.local")) return "DIRECT";
         //redes privadas;
         if (isInNet(dnsResolve(host), "127.0.0.0", "255.0.0.0")) return "DIRECT";
         if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")) return "DIRECT";
         if (isInNet(dnsResolve(host), "10.0.0.0", "255.255.0.0")) return "DIRECT";
         if (isInNet(dnsResolve(host), "10.0.0.0", "255.255.255.0")) return "DIRECT";
         //PrivateNet;
         if (isInNet(dnsResolve(host), "192.168.20.0", "255.255.255.0")) return "DIRECT";
         //end;
         if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")) return "DIRECT";
         if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.255.0")) return "DIRECT";
         if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")) return "DIRECT";
         if (shExpMatch(host, "fe80::*")) return "DIRECT";
         if (shExpMatch(url, "http:*")) return "DIRECT";
         if (shExpMatch(url, "https:*")) return wpad;
         return wpad;
        }
        
        

        Squid is set up with ONLY HTTP Transparent and Cautive Portal Authentication.

        This way, client pcs obtain proxy config from wpad, which forces all traffic BUT HTTP traffic to squid, and the HTTP traffic is routed using the transparent option of the Squid config, this causes the Cautive Portal to kick in and ask for user and password.

        I hope that this would be of use to someone else…

        1 Reply Last reply Reply Quote 0
        • K
          klmiciano
          last edited by

          Can you send the configs you made to make this setup work? I've been figuring this setup for weeks now.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.