[SOLVED] Return Access-Accept/-Reject depending on other active sessions during post-authentication
Matthias Nagel
matthias.h.nagel at gmail.com
Tue Dec 18 18:20:44 CET 2012
Hello,
problem solved. I post this message for the sake of completeness and in case, if anyone will ever need to solve a similar problem. Of course, any comments on how my solution can be improved are welcomed.
1) At the SQL side I created a view (active_users) with three columns (nasipaddress, nasport and vlan) that always shows the active sessions. Basically it selects all entries from the accounting table (radacct) where the stop time is NULL and then the result is joined with the user attribute table (radreply) in order to append the vlan to each record. Of course, the join is done by the user name.
2) In the RADIUS config the following expression is added to the post-auth section of the default server.
# Prevent multiple untagged VLANs on the same port at the same time.
# Otherwise there would be short-curcuit fault between the affected VLANs
if ( "%{sql:SELECT COUNT(*) FROM active_users WHERE nasipaddress = '%{NAS-IP-Address}' AND nasport = %{NAS-Port} AND vlan <> '%{reply:Tunnel-Private-Group-ID}' }" != 0 ) {
reject
}
The SQL statement counts all (active) sessions on the same NAS on the same NAS port with a different VLAN assignment than the VLAN the current user is going to be assigned to. If the number does not equal zero, there is at least one session on the same port with a different VLAN. In that case the user is rejected.
3) Prevent stalled-session
Accouning-Stop messages can be lost. In that case a session will falsely remain active and thus likely block out any other user. I use an interim update intervall with five minutes. If three updates were missed, i.e. the last update time is less then the current system time minus 15 minutes, the session is considered to be stalled and the stop time is set to the last update time. This way a stalled session is closed 15 minutes after the last update.
Yours, Matthias
Am Sonntag 16 Dezember 2012, 17:07:53 schrieb Alan DeKok:
> Matthias Nagel wrote:
> > Now, I would like to write some kind of RADIUS policy to prevent this behaviour.
>
> (a) store information in a database
> (b) use "unlang" to query the database
>
> > This policy is supposed to do the following during the post-authentication phase:
> >
> > 1) If there is no active session on the NAS port, just return Access-Accept
>
> You may need to create a new table which stores active sessions.
> INSERT data into it on authentication / accounting start. DELETE data
> on accounting stop.
>
> > 2) If there is at least one active session on the NAS port and the 'Tunnel-Private-Group-ID' of that session equals the 'Tunnel-Private-Group-ID' of the new request, return Access-Accept.
>
> Store the Tunnel-Private-Group-ID of a session on INSERT. Query it on
> the next session authentication.
>
> > 3) If there is at least one active session on the NAS port and the 'Tunnel-Private-Group-ID' of that session DOES NOT equal the 'Tunnel-Private-Group-ID' of the new request, return Access-Reject.
>
> Query the DB. If it doesn't match, reject.
>
> > Is this possible to do? I have the accounting information in a SQL database, hence I know, if there are active sessions on some port. But I do not know, which would be the correct RADIUS configuration section and I do not know if "unlang" or some other configuration directive can perform such a check.
>
> "unlang" is just a way to write policies. It does NOT store data.
> SQL databases store data.
>
> The two together can solve this problem.
>
> Alan DeKok.
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
----------------------------------------------------------------------
Matthias Nagel
Willy-Andreas-Allee 1, Zimmer 506
76131 Karlsruhe
Telefon: +49-721-8695-1506
Mobil: +49-151-15998774
e-Mail: matthias.h.nagel at gmail.com
ICQ: 499797758
Skype: nagmat84
More information about the Freeradius-Users
mailing list