Hemos estado trabajando con otros usuarios de Pfsense en un problema que para muchos como yo es importante en un software como pFsense, como controlar los usuarios inhalambricos atraves de un CaptivePortal.
Como sabran, Pfsense tiene su propio CaptivePortal(CP de aqui en adelante) y asu vez tiene en su paqueteria a FreeRadius tanto 1 como 2, pero nos vamos a enfocar en la versión 2(FR2 de aqui en adelante).
Uniendo estos 2 paquetes tenemos algo que encontramos en productos como Mikrotik, Ruckus, etc. Ya podemos controlar nuestros usuarios en base a tiempos de navegación, por ejemplo:
usr1 2 minutos
usr2 4 minutos
usr3 8 minutos
etc.
La logica dice que CP estara autenticando los usuarios cada 60 segundos y con esto FR2 validara si a el usuario aun le queda tiempo de navegacion atraves del modulo "Counter" que es parte de FR2 y el llevara a cabo la funcion de estar llevando los contadores de tiempo de cada usuario.
Asi podriamos tener un sistema de cobro por tiempo por ejemplo, un usuario llega y paga 1 hora por adelantado, le damos su usuario+contraseña y listo.
Esto es como deberia funcionar, pero CP tiene ciertos problemas los cuales un usuario que lo veran en este link da un parche para atacar el problema que les voy a explicar enseguida:
Parche CP.
Problema de CP.
Resulta ser que CP no esta enviando los paquetes de Start/Stop cada 60 segundos, algo que yo he notado en mis pruebas es que no importa el tiempo que se le asigne a el usuario, siempre lo saca a los 5 minutos, y este asunto otros tambien lo han notado.
No es problema de FR2 si no del codigo de CP, por ello aqui plasmo las indicaciones del parche que nos dan para este problema, quiero aclarar que ese parche es para versiones anteriores a la 2.0.2, ya que este ultima cambio algo no mucho pero si algo, no hay problema yo estoy con la ultima version(2.0.2) y aplique los cambios y al momento me esta funcionado.
Lo 1ro que vamos hacer es configurar FR2 en Pfsense, que es lo que sigue para probar, la instalacion no tiene ciencia ya que Pfsense se encarga de todo, asi que antes de seguir instalen el paquete FreeRadius2.
Caracteristicas de Instalacion:
Pfsense 2.0.2
3 NIC's:
- WAN
- Lan DHCP
- Wifi DHCP
La interface WiFi tiene conectado un access point Cisco WRT54G2 v1.5, no autentifica nada esta abierta, recuerden que todo lo controla CP asi que no hay problema ya que confio plenamente que aunque reciban IP los que no pertecen a mi red no podran navegar.
Configurando FreeRadius 2
|
Figura 1: Configuracion Incial de FR2. |
|
|
|
|
Figura 2: Configuracion de la interface y puertos necesarios. |
|
Figura 3: Configuracion de NAS/Clientes. |
|
Figura 4: Configuración de 1 usuario. |
|
|
Figura 5: Configuración de Captive Portal. |
Basados en la figura-4 pueden agregar mas usuarios solo modificando el parametro de "Amount of Time" para cada uno asi podran entender esta configuración.
Reglas de Firewall
Antes de seguir recordar que Pfsense por default la interface opt1 en adelante no tiene reglas asi que nada puede cruzar por ahi asi que yo solo deseo ofrecer lo siguiente:
|
Figura 6: Reglas de la red Inhalambrica. |
Por ultimo debemos aseguranos que ambos servicios esten operando
|
Figura 7: Servicios en linea. |
Aplicación de Parche
Si ya llegaron aqui es momento de llevar a cabo la aplicación del parche, aqui les recomiendo que abran su shell o consola via ssh ya que ahi que ensuciarse las manos con nuestro editor "ee", no soy hacker asi que no logre crear al parche y darselos, si alguien sabe de favor agreguenlo con los pasos necesarios para aplicarlo :-).
Vamos a editar el archivo que controla a CP este se localiza en:
/etc/inc/captiveportal.inc
Recomendacion: Antes de modificar el archivo saquen un respaldo del archivo y tengalo a la mano por si algo les falla.
Vamos a usar a nuestro amigo "diff" para que nos muestre nuestras diferencias y hacer la tarea mas sencilla:
diff /etc/inc/captiveportal.inc /root/captiveportal.inc
730,731c730
< $stop_time - 60,
< //$cpentry[0], // start time
---
> $cpentry[0], // start time
735,739c734,735
< //10); // NAS Request
< 10, // NAS Request
< false, //Not interim update
< $stop_time);
< exec("/sbin/ipfw table 1 entryzerostats {$cpentry[2]}");
---
> 10); // NAS Request
> exec("/sbin/ipfw table 1 entryzerostats {$cpentry[2]}");
741,742c737
< exec("sleep 1");
< RADIUS_ACCOUNTING_START($cpentry[1], // ruleno
---
> RADIUS_ACCOUNTING_START($cpentry[1], // ruleno
799d793
< $stop_time - 60,
872d865
< $stop_time = time();
878d870
< $stop_time - 60,
883,885c875
< //7); // Admin Reboot
< 7, // Admin Reboot
< false, $stop_time);
---
> 7); // Admin Reboot
Aproximadamente en la linea 730 nuestro codigo queda asi:
/* do periodic RADIUS reauthentication? */
if (!$timedout && !empty($radiusservers)) {
if (isset($config['captiveportal']['radacct_enable'])) {
if ($config['captiveportal']['reauthenticateacct'] == "stopstart") {
/* stop and restart accounting */
RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno
$cpentry[4], // username
$cpentry[5], // sessionid
$stop_time - 60,
//$cpentry[0], // start time
$radiusservers,
$cpentry[2], // clientip
$cpentry[3], // clientmac
//10); // NAS Request
10, // NAS Request
false, //Not interim update
$stop_time);
exec("/sbin/ipfw table 1 entryzerostats {$cpentry[2]}");
exec("/sbin/ipfw table 2 entryzerostats {$cpentry[2]}");
exec("sleep 1");
Luego nos brincamos a la linea 799 vamos a dejar asi el codigo:
function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_time = null) {
global $g, $config;
$stop_time = (empty($stop_time)) ? time() : $stop_time;
/* this client needs to be deleted - remove ipfw rules */
if (isset($config['captiveportal']['radacct_enable']) && !empty($radiusservers)) {
RADIUS_ACCOUNTING_STOP($dbent[1], // ruleno
$dbent[4], // username
$dbent[5], // sessionid
$stop_time - 60,
$dbent[0], // start time
$radiusservers,
$dbent[2], // clientip
$dbent[3], // clientmac
$term_cause, // Acct-Terminate-Cause
false,
$stop_time);
}
Y aproximadamente en la linea 872 dejamos asi el codigo:
/* send RADIUS acct stop for all current clients */
function captiveportal_radius_stop_all() {
global $config;
if (!isset($config['captiveportal']['radacct_enable']))
return;
$radiusservers = captiveportal_get_radius_servers();
if (!empty($radiusservers)) {
$stop_time = time();
$cpdb = captiveportal_read_db();
foreach ($cpdb as $cpentry) {
RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno
$cpentry[4], // username
$cpentry[5], // sessionid
$stop_time - 60,
$cpentry[0], // start time
$radiusservers,
$cpentry[2], // clientip
$cpentry[3], // clientmac
//7); // Admin Reboot
7, // Admin Reboot
false, $stop_time);
}
}
}
Revisen muy bien sus cambios, si creen que ya hicieron todo acorde, les recomiendo ampliamente reiniciar su equipo y revisar si no les marca algun error el archivo, lo van a ver en el GUI cuando le digan si a el boton de reboot.
Pruebas
Ya con su equipo en linea, sin errores y sobre todo ambos servicios operando, conecten su "access point" y prendan su PC, tableta o lo que tengan inhalambrico para empezar las pruebas, se conectan a su red y les debe aparecer la pagina de CP.
Metan su usuario de prueba y empiecen a navegar, se van a su pfsense y abran la pagina de Status-CaptivePortal y vean la hora que inicio su usuario:
|
Figura 8: Estatus de CP. |
Un detalle es que una vez que el usuario termina si sesión el GUI no muestra su historial, pero por ello entra en funcion el log atraves de la consola, abran su shell y vean como van evolucionando el usuario:
|
Figura 9: Log de fr2. |
Como podran ver cada cierto tiempo NAS esta enviando paquetes a FR2 y este asu vez los valida y si el usuario aun esta dentro del tiempo asignado le es permitido seguir navegando.
Cuando llega a su fin tenemos esto:
|
Figura 10: Usuario llego a su limite. |
El contador no es exacto, aun estan haciendo ajustes que estos dias voy a probar, si sacamos la diferencia el usuario navego:
|
Figura 11: Tiempo que duro usuario navegando. |
Pero aqui lo importante es que ya CP puede ser usado para controlar los tiempos de navegacion, ya podemos cobrar x tiempo, espero puedan llevar a cabo sus pruebas y regresen con sus resultados, mientras mas informacion de pruebas haya mejor, y si hay errores para informacion y seguir mejorando el codigo, saludos.
2013-01-30
Detalles
Sesion abierta y cambio de dia: Supongamos que el usuario8, tiene 1 hora diario ejemplo arranca su sesion el dia 30/01/2013, pero el entra a las 23:30PM, que pasa?
Bien CP le va a dar 2 horas de navegacion, por que?
CP/FR2 validan la duracion de la sesion pero no controlan estos cambios de dia, ya que ellos validan que durante el dia X el usuario haya consumido su tiempo asignado, y al brincarse a el dia Y es otro dia, por lo tanto reinicia el contador en 0, por ello el usuario tendra su hora del dia X+Y siempre y cuando en el dia X le quede menos de lo asignado cuando el inicio su navegacion.
Esto les puede pasar, entonces si tienen usuarios nocturnos y les reclaman por que ya no puede navegar en Y dia por la noche, digales que dice radius.log no miente sale, saludos!!!