This solution employs a router/server computer with two network interfaces, one is a network uplink, the other connects to the wifi routers with their respective supplicants.
Users authenticate using a username and password, and verify the identity of the RADIUS server using a certificate presented by the server (see more information under supplicant configuration).
As mentioned in '@@@', the NASes available do not support sending RADIUS accounting packets, they are only able to authenticate users against the response from a RADIUS server. This solution uses 802.1X to authenticate users and let them into the wireless network, and then Shorewall to perform the logging/accounting work. FreeRADIUS logs the MAC address of all devices that connect along with the username they authenticated as, this information can be used to match information in Shorewall's logs to a user session. For improved security the firewall policy will be to disallow all connections except those originating from known IP addresses of known wifi clients. A script, shwl_add.sh, gets run by FreeRADIUS upon successful authentication of a supplicant, which runs an ARP scan to find the IP address of the device with the MAC address specified by FreeRADIUS, it then adds the IP address to shorewall's "whitelist", logs the event along with some useful information to a MySQL database and writes the current timestamp to a text file. In Access-Accept packets the Session-Timeout and Termination-Action attributes are sent, informing the NAS that after the specified amount of time the supplicant needs to repeat the authentication process or be disconnected. When the supplicant repeats authentication the mentioned script detects that the supplicant is already known and simply logs the event to MySQL and updates the timestamp in the text file. Another script, shwl_del.sh, is run by crontab at a regular interval, which goes through all the IP addresses present in shorewall's "whitelist" and checks the timestamp of the corresponding supplicant's last authentication to FreeRADIUS in the corresponding text file. If more than the specified amount of time has passed, this script assumes that the supplicant has disconnected from the wifi network and removes its IP from shorewall's "whitelist", logs the event to MySQL, and deletes the related text files.
A python script, script_launcher.py, serves as an intermediary that is launched by FreeRADIUS using its Rlm_python module and in turn launches shwl_add.sh.
The database backend containing user credentials for FreeRADIUS is MySQL. Adding/deleting users can be accomplished by SQL queries which can be included in site specific custom user management scripts or as hooks to the standard 'adduser' and 'deluser' utilities (out of the scope of this guide). Updating of passwords is accomplished by a script, pam_to_mysql_update.sh, that gets run by the libpam-script PAM module during PAM stack execution, and updates the password in the MySQL database according to the same password the user chose for their system user account. An entry with the username field already filled and matching the system user account username needs to be already present in the MySQL database. Commands that expire or disable a user's system user account without deleting it (such as passwd -l) will not cause the credentials in the MySQL database to be disabled, thus it is necessary to take care (perhaps with a site specific lock user script) to also invalidate the same.
Shorewall dynamic zones are used to achieve the dynamic change of firewall rules set for the IP addresses added/removed to the "whitelist". The rules for the normal zone concerning the network connecting to the '@@@' disallows all connections, except those needed for the RADIUS conversation between the NASes and FreeRADIUS. A dynamic zone is declared under the normal zone, whose rules allow network access, with logging. The 'shorewall add <dynamic_zone_name> <ip_address>' and 'shorewall delete <dynamic_zone_name> <ip_address>' commands can then be used by the shwl_*.sh scripts to change the rules applicable for the specified source IP address.
Sudo is installed and configured as it is required for some of the mentioned scripts to run commands as root or as a different user.
A package containing the mentiond scripts, as well as the empty MySQL schema for the database used by some of them, is attached to this wiki page.