FreeRadius Idle-Timeout not honored by pfSense radius client
-
I'm setting pfSense as a hotspot with an external captive portal (I added a custom HTML page that redirects to my external portal, then I complete the radius auth with a POST request on $PORTAL_ACTION$). I'm using an external radius server, and I send "Idle-Timeout" in my "Access-Accept" but the user sessions don't get removed once they exceed the time specified.
I'm aware of the Idle timeout (Minutes) and Hard timeout (Minutes) features but that's not what I want, because I configure my radius server externally and want to be able to make changes without having to change the captive portal's config on pfSense.
Is there any way to get pfSense handle the "Idle-Timeout" attribute correctly or is it just not supported?
-
This works :
as now the Radius server replies with a "Idle-Timeout" set to 5 (minutes).
The radius client (the captive portal) will use this value instead of what you've set on the main portal config page.
I've test : I was thrown of the portal after 5 minutes.But I get it : this is not what you want.
You want to edit with a tool like phpmyadmin, or some other databse/mysql access tool to edit/modify users and settings in the database, and have Freeradius running on pfSense acting upon what it found in the database.The thing is : pfSense freeradius doesn't use the database (I use a MySQL) for the user credentials and parameters. It uses a file, stored on the pfSense disk. Here it is :
or here : /usr/local/etc/raddb/mods-enabled/files which drills down to /usr/local/etc/raddb/mods-config/files/authorize - which is exactly the "users" what I've shown above.
What you want, I suppose : not entering users credentials and other stuff in the pfSene GUI, but use the database for this.
That's not possible. The main radius config file is hard coded to use the 'files' option. See /usr/local/etc/raddb/sites-enabled/default ( and /usr/local/etc/raddb/sites-available/README)Also check/look at the 2 files /usr/local/etc/raddb/sites-enabled/inter-tunnel-*****
pfSense is pfSense : that's the place where everything is centralized. There is no such options as : let FreeRadius use the MySQL database for users, passwords etc.
What need to be done to correct this : modify /usr/local/pkg/freeradius.inc as that is the place where the freeradius config files are created, from the pfSense GUI settings.
Ditch the 'files' option (several places) and activate 'sql'.See for example here.
I've tested this one, just for fun, it worked .
@nourgaser said in FreeRadius Idle-Timeout not honored by pfSense radius client:
or is it just not supported?
Supported like accepted or not accepted ?
My opinion : It's your copy of pfSense. Do with it whatever you want.
Netgate support their scripts, code whatever.
You support yours.
Don't tell me you don't support yourself
IMHO : go for it -
@Gertjan first of all, thank you genuinely for the effort you put into your reply to me, I really appreciate it. Sadly you misunderstood me, maybe it's my bad not being clear enough.
I'm not using the FreeRadius server pfSense package; I have my own FreeRadius server configured like you mentioned, it connects to a MySQL db and uses that for the users, the limits, and everything else; and I have a web app that controls that database. I add pfSense as a client on my FreeRadius server, and when a user uses my external captive portal, I create a user for them in my DB, and make a POST request to the pfSense captive portal to try and authenticate the user with its radius client client, using the credentials I just created and forwarded to it (
POST @ {ip_of_pfSense}:8002/index.php?zone={zone_name}
).Then my radius server sends the
Access-Accept
response like this:Sent Access-Accept Id {some_id} from {ip_of_freeradius_server}:1812 to {ip_of_freeradius_client}:{some_random_port_chosen_by_the_client} length {some_length} Idle-Timeout = {idle_timeout_from_my_db_in_seconds} Session-Timeout = {session_timeout_from_my_db_in_seconds} WISPr-Bandwidth-Max-Down = {max_down_bandwidth_from_my_db_in_kbps} WISPr-Bandwidth-Max-Up = {max_up_bandwidth_from_my_db_in_kbps} ...rest of the attributes...
The session time limit and bandwidth (and even quota) limits work and if my user exceeds them pfSense deletes their session. But the
Idle-Timeout
is ignored.Hope the clears up my issue a bit.
-
@nourgaser said in FreeRadius Idle-Timeout not honored by pfSense radius client:
Hope the clears up my issue a bit.
A lot.
I'll get back to you soon.Here : a tool I use to inspect the captive portal 'internal, SQLITE3 "database :
#!/usr/local/bin/php -q <?php require_once("/etc/inc/util.inc"); require_once("/etc/inc/functions.inc"); require_once("/etc/inc/captiveportal.inc"); /* Read in captive portal db */ /* Determine number of logged in users for all zones */ $count_cpusers = 0; /* Is portal activated ? */ if (is_array($config['captiveportal'])) /* For every zone, do */ foreach ($config['captiveportal'] as $cpkey => $cp) /* Sanity check */ if (is_array($config['captiveportal'][$cpkey])) /* Is zone enabled ? */ if (array_key_exists('enable', $config['captiveportal'][$cpkey])) { $cpzone = $cpkey; /* Zone selected -> count users and add */ $cpdb = captiveportal_read_db(); foreach ($cpdb as $cpent) { print_r($cpent); echo date("m/d/Y H:i:s\n", $cpent[0]); echo "---------------\n"; } } ?>
If an "Idle_Timeout" comes back from the radius server, like this (your example) :
... Idle-Timeout = {idle_timeout_from_my_db_in_seconds} ....
it's stored in the record of the connected portal user :
[8] => [idle_timeout] =>
I saw it when I was testing - see above.
The portal prune process (every 60 seconds) will use this value to throw of the client when [idle_timeout] is exceeded.
That is : it should work like that. I saw an IDLE DISCONNECT in the portal log when testing this morning.edit :
If you called the file /root/cap.php :
Use the 'tool' like this :
SSH (or console), option 8.php -q cap.php
When I log into the captive portal with my 'test user account', where I've set
I see this :
.... Array ( [0] => 1701419243 [allow_time] => 1701419243 [1] => 2014 [pipeno] => 2014 [2] => 192.168.2.6 [ip] => 192.168.2.6 [3] => e0:92:5c:d9:6c:fe [mac] => e0:92:5c:d9:6c:fe [4] => x [username] => x [5] => b70ed7483d25b0c9 [sessionid] => b70ed7483d25b0c9 [6] => eA== [bpassword] => eA== [7] => [session_timeout] => [8] => 5 [idle_timeout] => 5 [9] => [session_terminate_time] => [10] => 600 [interim_interval] => 600 [11] => [traffic_quota] => [12] => 1000 [bw_up] => 1000 [13] => 2000 [bw_down] => 2000 [14] => radius [authmethod] => radius [15] => first [context] => first )
Your looking at the dump of the pfSense captive portal logged in users.
It's a small PHP SQLITE database. For every logged in user, all variables are dumped.For example : "[idle_timeout] => 5" has been set accrding to what came back from the Radius server.
While typing here, 5 minutes are passed, so :
-
@Gertjan sorry for the late reply. It works now! I tried your php script you're right the idle_timeout is there, so it's weird it's not working. Then I found this thread, and figured the cron job was running fine, so I checked
captiveportal_prune_old
atcaptiveportal.inc
, and turns out I need to uncheck "Use RADIUS Session-Timeout attributes" for it to work, even though that's kind of unintuitive.Thanks for the great effort!
-
Uncheck ?
I've set it :as this check box does this :
/etc/inc/captiveportal.inc :
which means "$cpentry[7]" gets used, and that's the value obtained from Radius.
Note : "$cpentry[7]" == "/* hard timeout or session_timeout from radius if enabled */"
Not setting this checkbox it means it will use the captive portal 'master' hard timeout value :IMHO : "$cpentry[7]" == is the radius equivalent of a hard (seesion) time out.
"$cpentry[8]" is the soft (idle) timeout.