- 24 Sep 2023
- quanticc software
Disclaimer! This is important!
Every Network is different , so one solution cannot be applied to all. Therefore try to understand logics & create or modify the solutions as per your network scenario. Never follow copy paste blindly, [unfortunately this has become our national culture]
My humble request is that kindly donot consider me as an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.
So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and try to help others
Regard's
Syed Jahanzaib~
This is another post about installation & configuration of ISP related billing system called Freeradius version 3.0.19. My aim is to let people know that creating your own Radius Billing system is not a ROCKET SCIENCE.
The only thing required is your ultimate passion to achieve the goal & with the right search, reading, understanding logic’s, you can do all on your own. I strongly encourage all to read the FR mailing list and Google search
For older version of Freeradius ver 2.x series, you may read below
https://aacable.wordpress.com/2016/03/11/mikrotik-with-freeradiusmysql-part-1/
Every Network is different , so one solution cannot be applied to all. Therefore try to understand logics & create or modify the solutions as per your network scenario. Never follow copy paste blindly, [unfortunately this has become our national culture]
My humble request is that kindly donot consider me as an expert on this stuff, I am NOT certified in anything Mikrotik/Cisco/Linux or Windows. However I have worked with some core networks and I read , research & try stuff all of the time. So I am not speaking/posting about stuff I am formerly trained in, I pretty much go with experience and what I have learned on my own. And , If I don’t know something then I read & learn all about it.
So , please don’t hold me/my-postings to be always 100 percent correct. I make mistakes just like everybody else. However – I do my best, learn from my mistakes and try to help others
Regard's Syed Jahanzaib~
This is another post about installation & configuration of ISP related billing system called Freeradius version 3.0.19. My aim is to let people know that creating your own Radius Billing system is not a ROCKET SCIENCE.
The only thing required is your ultimate passion to achieve the goal & with the right search, reading, understanding logic’s, you can do all on your own. I strongly encourage all to read the FR mailing list and Google search
For older version of Freeradius ver 2.x series, you may read below
https://aacable.wordpress.com/2016/03/11/mikrotik-with-freeradiusmysql-part-1/
Make your own Billing system in Linux with Latest version of Freeradius 3.0.19 / MySQL 5.7.27
by Syed Jahanzaib / aacable[at]hotmail[dot]com
[This Guide will be updated with many further supporting posts)
The aim of writing this post was that there are number of radius products available on the internet with lots of features, each have some unique features. But this is also true that none of them is 100% perfect for every type of ISP. The reason is that every ISP/Network have different sort of local requirements and billing mode. If you have searched on google you will find that there are tons of guides for freeradius implementation, but most of them have either incomplete data , or difficult explanation, or does not meet the practical requirements of Desi ISP. That’s why I started this guide so that info that is not common on the net can be shared here. plus most important you can learn on your own using this baby step.
In this post I have made some quick guide to install a very basic level of billing system by using Freeradius/mysql on UBUNTU 18.4 [64bit]. Mikrotik routerboard with firmware version 6.45.7 is being used as NAS to connect user and freeradius will be used for authentication/accounting billing system.
Let’s Rock …
by Syed Jahanzaib / aacable[at]hotmail[dot]com
[This Guide will be updated with many further supporting posts)
The aim of writing this post was that there are number of radius products available on the internet with lots of features, each have some unique features. But this is also true that none of them is 100% perfect for every type of ISP. The reason is that every ISP/Network have different sort of local requirements and billing mode. If you have searched on google you will find that there are tons of guides for freeradius implementation, but most of them have either incomplete data , or difficult explanation, or does not meet the practical requirements of Desi ISP. That’s why I started this guide so that info that is not common on the net can be shared here. plus most important you can learn on your own using this baby step.
In this post I have made some quick guide to install a very basic level of billing system by using Freeradius/mysql on UBUNTU 18.4 [64bit]. Mikrotik routerboard with firmware version 6.45.7 is being used as NAS to connect user and freeradius will be used for authentication/accounting billing system.
Let’s Rock …
Hardware Software components used in this post
Hardware:
- Xeon 2Ghz CPU x 2
- 64 GB RAM
- 480GB SSD x 8 disks in RAID-10
- Vmware ESXI 6.5 installed on bare metal hardware
- VM guest created for Radius role with following config
40 GB RAM / 12 CORES VCPU / 300 GB Disk Space
Software:
- OS: Ubuntu 18.04.3 LTS Server Edition [Click here for Download Link]
- FreeRADIUS: Version 3.0.19 [using apt-get with custom repository]
- Mysql Version: mysql Ver 14.14 Distrib 5.7.27, for Linux (x86_64) using EditLine wrapper [using apt-get]
- IP scheme
Radius IP = 101.11.11.254
Mikrotik IP = 101.11.11.255
Hardware:
- Xeon 2Ghz CPU x 2
- 64 GB RAM
- 480GB SSD x 8 disks in RAID-10
- Vmware ESXI 6.5 installed on bare metal hardware
- VM guest created for Radius role with following config
40 GB RAM / 12 CORES VCPU / 300 GB Disk Space
Software:
- OS: Ubuntu 18.04.3 LTS Server Edition [Click here for Download Link]
- FreeRADIUS: Version 3.0.19 [using apt-get with custom repository]
- Mysql Version: mysql Ver 14.14 Distrib 5.7.27, for Linux (x86_64) using EditLine wrapper [using apt-get]
- IP scheme
Radius IP = 101.11.11.254
Mikrotik IP = 101.11.11.255
Quick Tips for Ubuntu OS before rolling out FR
Network address configuration
In Ubuntu 18, network addresses are configured slightly differently as compared to earlier version of ubuntu series. To add / modify IP addresses, edit 50-cloud-init.yaml file
1 nano /etc/netplan/50-cloud-init.yaml
A working configuration file is attached as below. Make sure to follow syntaxes as defined. U18 is quite sensitive regarding this section.
123456789101112131415 # Ubuntu 18 Network Config file # Syed Jahanzaib
network:
ethernets:
# Interface Name
ens33:
# Interface IP Address
addresses:
- 101.11.11.254/24
gateway4: 101.11.11.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8
version: 2
<span style="color: var(--color-text);">
In Ubuntu 18, network addresses are configured slightly differently as compared to earlier version of ubuntu series. To add / modify IP addresses, edit 50-cloud-init.yaml file
1 | nano /etc/netplan/50-cloud-init.yaml |
A working configuration file is attached as below. Make sure to follow syntaxes as defined. U18 is quite sensitive regarding this section.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Ubuntu 18 Network Config file # Syed Jahanzaib network: ethernets: # Interface Name ens33: # Interface IP Address addresses: - 101.11.11.254/24 gateway4: 101.11.11.1 nameservers: addresses: - 1.1.1.1 - 8.8.8.8 version: 2 <span style="color: var(--color-text);"> |
ROOT Login Access on local machine is not Allowed by Default on Fresh installation of Ubuntu 18
After fresh installation of Ubuntu 18 server edition, you cannot login with root ID by default. & to perform various functions, you may need ROOT access.
Therefore using your normal user account , issue below cmd’s to change root password in order to enable root login access
1 sudo passwd root
it will ask you to enter current user password, then it will ask to enter new root password two times. Do so and then you can change to use root user by using
1 # su
and it will ask you to enter root password, Enter the password that you setup in above steps. and you will be switched to ROOT.
After fresh installation of Ubuntu 18 server edition, you cannot login with root ID by default. & to perform various functions, you may need ROOT access.
Therefore using your normal user account , issue below cmd’s to change root password in order to enable root login access
1 | sudo passwd root |
it will ask you to enter current user password, then it will ask to enter new root password two times. Do so and then you can change to use root user by using
1 | # su |
and it will ask you to enter root password, Enter the password that you setup in above steps. and you will be switched to ROOT.
Allow SSH Login for remote access using PUTTY or any other tool
By default, Ubuntu 18 will not allow you to remotely login via SSH.
Edit file
1 nano /etc/ssh/sshd_config
now search for
1 PermitRootLogin prohibit-password
Change it to
1 PermitRootLogin yes
Save & Exit , Restart ssh service
1 service ssh restart
Another quick copy paste method to enable root ssh access
12 sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
service ssh restart
By default, Ubuntu 18 will not allow you to remotely login via SSH.
Edit file
1 | nano /etc/ssh/sshd_config |
now search for
1 | PermitRootLogin prohibit-password |
Change it to
1 | PermitRootLogin yes |
Save & Exit , Restart ssh service
1 | service ssh restart |
Another quick copy paste method to enable root ssh access
1 2 | sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config service ssh restart |
NTP configuration for timezone configuration &
Automatic time update from the internet [for KHI/PK]
123 apt-get -y install ntp ntpdate
cp /usr/share/zoneinfo/Asia/Karachi /etc/localtime
sudo /etc/init.d/ntp restart
1 2 3 | apt-get -y install ntp ntpdate cp /usr/share/zoneinfo/Asia/Karachi /etc/localtime sudo /etc/init.d/ntp restart |
Disable iPV6
if ipv6 not required, its a good idea to disable it from beginning.
Use below CMD
123 echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6=1" /etc/sysctl.conf
sysctl -p
for further ensurity, now edit
1 nano /etc/default/grub
& change
123456 FROM:
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""
TO:
GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1"
GRUB_CMDLINE_LINUX="ipv6.disable=1"
Save & exit & run below cmd to update GRUB
1 sudo update-grub
if ipv6 not required, its a good idea to disable it from beginning.
Use below CMD
1 2 3 | echo "net.ipv6.conf.all.disable_ipv6=1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6=1" /etc/sysctl.conf sysctl -p |
for further ensurity, now edit
1 | nano /etc/default/grub |
& change
1 2 3 4 5 6 | FROM: GRUB_CMDLINE_LINUX_DEFAULT="" GRUB_CMDLINE_LINUX="" TO: GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1" GRUB_CMDLINE_LINUX="ipv6.disable=1" |
Save & exit & run below cmd to update GRUB
1 | sudo update-grub |
Installing components required for general operations including MYSQL as well
Install supporting tools like mysql / phpmyadmin etc [make sure you enter mysql password when it asks ]
#During installation, it will ask you to enter PASSWORD, dont let it skip, be vigilant
12 apt-get -y install apache2 mc wget make gcc mysql-server mysql-client curl
apt-get -y install phpmyadmin
Install supporting tools like mysql / phpmyadmin etc [make sure you enter mysql password when it asks ]
#During installation, it will ask you to enter PASSWORD, dont let it skip, be vigilant
1 2 | apt-get -y install apache2 mc wget make gcc mysql-server mysql-client curl apt-get -y install phpmyadmin |
NOTE# mySQL Empty Root Password
Try to login to mysql with your defined password. In case if mysql is letting you in with any random or empty password, use this CMD to change mysql root password
Use these steps only if you have mysql login issue with empty/any password
123456 mysql -uroot -pANYPASS
UPDATE mysql.user SET authentication_string= '' WHERE User='root';
UPDATE mysql.user SET plugin = '' WHERE user = 'root';
UPDATE mysql.user SET authentication_string=PASSWORD('zaib1234') WHERE User='root';
UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = 'root';
exit
Don’t forget to restart mySQL service, this part wasted some time of mine
1 service mysql restart
Try to login to mysql with your defined password. In case if mysql is letting you in with any random or empty password, use this CMD to change mysql root password
Use these steps only if you have mysql login issue with empty/any password
1 2 3 4 5 6 | mysql -uroot -pANYPASS UPDATE mysql.user SET authentication_string= '' WHERE User='root'; UPDATE mysql.user SET plugin = '' WHERE user = 'root'; UPDATE mysql.user SET authentication_string=PASSWORD('zaib1234') WHERE User='root'; UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = 'root'; exit |
Don’t forget to restart mySQL service, this part wasted some time of mine
1 | service mysql restart |
~ Installation & Configuration part ~
~ Freeradius version 3.0.19 ~
To install freeradius 3.0.19 via apt-get on ubuntu 18.4 server, first update the repository by using following
1 echo "deb http://packages.networkradius.com/releases/ubuntu-bionic bionic main" >> /etc/apt/sources.list
Save and exit, and issue below cmd
12 sudo apt-key adv --keyserver keys.gnupg.net --recv-key 0x41382202
sudo apt-get update
~
Now using apt-get install method , we will install FR ver 3.0.19
1 apt-get -y install freeradius freeradius-mysql freeradius-utils
Once installed, check the FR version, & it should be similar to this
12345678910 freeradius -v
radiusd: FreeRADIUS Version 3.0.19 (git #ab4c76709), for host x86_64-pc-linux-gnu
FreeRADIUS Version 3.0.19
Copyright (C) 1999-2019 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License
For more information about these matters, see the file named COPYRIGHT
To install freeradius 3.0.19 via apt-get on ubuntu 18.4 server, first update the repository by using following
1 | echo "deb http://packages.networkradius.com/releases/ubuntu-bionic bionic main" >> /etc/apt/sources.list |
Save and exit, and issue below cmd
1 2 | sudo apt-key adv --keyserver keys.gnupg.net --recv-key 0x41382202 sudo apt-get update |
~
Now using apt-get install method , we will install FR ver 3.0.19
1 | apt-get -y install freeradius freeradius-mysql freeradius-utils |
Once installed, check the FR version, & it should be similar to this
1 2 3 4 5 6 7 8 9 10 | freeradius -v radiusd: FreeRADIUS Version 3.0.19 (git #ab4c76709), for host x86_64-pc-linux-gnu FreeRADIUS Version 3.0.19 Copyright (C) 1999-2019 The FreeRADIUS server project and contributors There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE You may redistribute copies of FreeRADIUS under the terms of the GNU General Public License For more information about these matters, see the file named COPYRIGHT |
SQL Section:
Create DB in mysql
# Make sure to change password which you setup while installing mySQL
1234 mysql -uroot -pzaib1234
create database radius;
grant all on radius.* to radius@localhost identified by "zaib1234";
exit
Now import sql schema file into the mysql
1 mysql -u root -pzaib1234 radius < /etc/freeradius/mods-config/sql/main/mysql/schema.sql
Now create SQL link
1 ln -s /etc/freeradius/mods-available/sql /etc/freeradius/mods-enabled/
Create DB in mysql
# Make sure to change password which you setup while installing mySQL
1 2 3 4 | mysql -uroot -pzaib1234 create database radius; grant all on radius.* to radius@localhost identified by "zaib1234"; exit |
Now import sql schema file into the mysql
1 | mysql -u root -pzaib1234 radius < /etc/freeradius/mods-config/sql/main/mysql/schema.sql |
Now create SQL link
1 | ln -s /etc/freeradius/mods-available/sql /etc/freeradius/mods-enabled/ |
FREERADIUS CONFIG Section
now edit /etc/freeradius/mods-enabled/sql
1 nano /etc/freeradius/mods-enabled/sql
& make modification like in SQL { section
change to below
12345678910111213141516 sql {
dialect = "mysql"
driver = "rlm_sql_${dialect}"
mysql {
# there are few lines related to certs, delete them as we donot require them
warnings = auto
}
# Connection info:
server = "localhost"
port = 3306
login = "radius"
password = "zaib1234"
# Change password as you configured in initial steps/zaib
# Database table configuration for everything except Oracle
radius_db = "radius"
Save & exit.
now edit /etc/freeradius/mods-enabled/sql
1 | nano /etc/freeradius/mods-enabled/sql |
& make modification like in SQL { section
change to below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | sql { dialect = "mysql" driver = "rlm_sql_${dialect}" mysql { # there are few lines related to certs, delete them as we donot require them warnings = auto } # Connection info: server = "localhost" port = 3306 login = "radius" password = "zaib1234" # Change password as you configured in initial steps/zaib # Database table configuration for everything except Oracle radius_db = "radius" |
Save & exit.
Adding your NAS in mysql NAS table
TIP: Quick CMD to add NAS in table,
1 mysql -uroot -pzaib1234 -e "use radius; INSERT INTO nas (id, nasname, shortname, type, ports, secret, server, community, description) VALUES (NULL, '101.11.11.255', NULL, 'other', NULL, '123456', NULL, NULL, 'RADIUS Client');"
OUTPUT:
1234567 mysql> select * from nas;
+----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+
| id | nasname | shortname | type | ports | secret | server | community | description |
+----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+
| 1 | 101.11.11.255 | NULL | other | 3799 | 123456 | | NULL | RADIUS Client |
+----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+
1 row in set (0.00 sec)
TIP: Quick CMD to add NAS in table,
1 | mysql -uroot -pzaib1234 -e "use radius; INSERT INTO nas (id, nasname, shortname, type, ports, secret, server, community, description) VALUES (NULL, '101.11.11.255', NULL, 'other', NULL, '123456', NULL, NULL, 'RADIUS Client');" |
OUTPUT:
1 2 3 4 5 6 7 | mysql> select * from nas; +----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+ | id | nasname | shortname | type | ports | secret | server | community | description | +----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+ | 1 | 101.11.11.255 | NULL | other | 3799 | 123456 | | NULL | RADIUS Client | +----+---------------+-----------------+-------+-------+--------+--------+-----------+---------------+ 1 row in set (0.00 sec) |
Create TEST USER for validating freeradius & mysql installation
We will now create a simple Test USER in mySQL RADIUS DB for verification / test purposes. It will have
- Username Password
- Mikrotik Rate Limit for Bandwidth Limitation, example 1mb/1mb
- Expiration date time
- Simultaneous Use set to 1 , to prevent Multiple login of same ID (it requires further modifications in DEFAULT section of sites enabled)
1234567 mysql -uroot -pzaib1234
use radius;
INSERT INTO radcheck ( id , UserName , Attribute , op , Value ) VALUES ( NULL , 'zaib', 'Cleartext-Password', ':=', 'zaib');
INSERT INTO radreply (username, attribute, op, value) VALUES ('zaib', 'Mikrotik-Rate-Limit', '==', '1024k/1024k');
INSERT INTO radcheck ( id , UserName , Attribute , op , Value ) VALUES (NULL , 'zaib', 'Expiration', ':=', '13 Jan 2029 11:00');
INSERT INTO radcheck (username,attribute,op,value) VALUES ('zaib', 'Simultaneous-Use', ':=', '1');
exit
We will now create a simple Test USER in mySQL RADIUS DB for verification / test purposes. It will have
- Username Password
- Mikrotik Rate Limit for Bandwidth Limitation, example 1mb/1mb
- Expiration date time
- Simultaneous Use set to 1 , to prevent Multiple login of same ID (it requires further modifications in DEFAULT section of sites enabled)
1 2 3 4 5 6 7 | mysql -uroot -pzaib1234 use radius; INSERT INTO radcheck ( id , UserName , Attribute , op , Value ) VALUES ( NULL , 'zaib', 'Cleartext-Password', ':=', 'zaib'); INSERT INTO radreply (username, attribute, op, value) VALUES ('zaib', 'Mikrotik-Rate-Limit', '==', '1024k/1024k'); INSERT INTO radcheck ( id , UserName , Attribute , op , Value ) VALUES (NULL , 'zaib', 'Expiration', ':=', '13 Jan 2029 11:00'); INSERT INTO radcheck (username,attribute,op,value) VALUES ('zaib', 'Simultaneous-Use', ':=', '1'); exit |
Testing FREERADIUS connection using FR built-in tools
It’s time that we should test freeradius connectivity. in first Terminal, issue below cmd to start freeradius in DEBUG mode
12 service freeradius stop
freeradius -X
If FR configurall are configured correctly, then you will see something like below
12345678 Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on auth address * port 1812 bound to server default
Listening on acct address * port 1813 bound to server default
Listening on auth address :: port 1812 bound to server default
Listening on acct address :: port 1813 bound to server default
Listening on proxy address * port 48178
Listening on proxy address :: port 38713
Ready to process requests
If you see Ready to process requests
, than all good to Go, Else it will show you the particular errors and lines that you must FIX in order to proceed further.
Moving forward, Open second Terminal window, & try below cmd’s to test the user credentials/authentication
It’s time that we should test freeradius connectivity. in first Terminal, issue below cmd to start freeradius in DEBUG mode
1 2 | service freeradius stop freeradius -X |
If FR configurall are configured correctly, then you will see something like below
1 2 3 4 5 6 7 8 | Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel Listening on auth address * port 1812 bound to server default Listening on acct address * port 1813 bound to server default Listening on auth address :: port 1812 bound to server default Listening on acct address :: port 1813 bound to server default Listening on proxy address * port 48178 Listening on proxy address :: port 38713 Ready to process requests |
If you see Ready to process requests
, than all good to Go, Else it will show you the particular errors and lines that you must FIX in order to proceed further.
Moving forward, Open second Terminal window, & try below cmd’s to test the user credentials/authentication
Test#1 using RADCLIENT tool with particular calling MAC address
1 echo "User-Name=zaib,User-Password=zaib,Calling-Station-Id=00:0C:29:71:60:DA" | radclient -s localhost:1812 auth testing123
Result:
12345678 Sent Access-Request Id 38 from 0.0.0.0:37282 to 127.0.0.1:1812 length 63
Received Access-Accept Id 38 from 127.0.0.1:1812 to 127.0.0.1:37282 length 26
Packet summary:
Accepted : 1
Rejected : 0
Lost : 0
Passed filter : 1
Failed filter : 0
1 | echo "User-Name=zaib,User-Password=zaib,Calling-Station-Id=00:0C:29:71:60:DA" | radclient -s localhost:1812 auth testing123 |
Result:
1 2 3 4 5 6 7 8 | Sent Access-Request Id 38 from 0.0.0.0:37282 to 127.0.0.1:1812 length 63 Received Access-Accept Id 38 from 127.0.0.1:1812 to 127.0.0.1:37282 length 26 Packet summary: Accepted : 1 Rejected : 0 Lost : 0 Passed filter : 1 Failed filter : 0 |
Test#2 using RADTEST tool
1 radtest zaib zaib localhost 1812 testing123
Result:
123456789 Sent Access-Request Id 26 from 0.0.0.0:53486 to 127.0.0.1:1812 length 74
User-Name = "zaib"
User-Password = "zaib"
NAS-IP-Address = 101.11.11.254
NAS-Port = 1812
Message-Authenticator = 0x00
Cleartext-Password = "zaib"
Received Access-Accept Id 26 from 127.0.0.1:1812 to 127.0.0.1:53486 length 26
Session-Timeout = 289854175
Freeradius Debug Window:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 Ready to process requests
(0) Received Access-Request Id 57 from 127.0.0.1:56913 to 127.0.0.1:1812 length 63
(0) User-Name = "zaib"
(0) User-Password = "zaib"
(0) Calling-Station-Id = "00:0C:29:71:60:DA"
(0) # Executing section authorize from file /etc/freeradius/sites-enabled/default
(0) authorize {
(0) [preprocess] = ok
(0) [chap] = noop
(0) [mschap] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: No '@' in User-Name = "zaib", looking up realm NULL
(0) suffix: No such realm "NULL"
(0) [suffix] = noop
(0) [files] = noop
(0) sql: EXPAND %{User-Name}
(0) sql: --> zaib
(0) sql: SQL-User-Name set to 'zaib'
rlm_sql (sql): Reserved connection (1)
(0) sql: EXPAND SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id
(0) sql: --> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'zaib' ORDER BY id
(0) sql: Executing select query: SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'zaib' ORDER BY id
(0) sql: User found in radcheck table
(0) sql: Conditional check items matched, merging assignment check items
(0) sql: Cleartext-Password := "zaib"
(0) sql: Expiration := "Jan 13 2029 11:00:00 PKT"
(0) sql: Simultaneous-Use := 1
(0) sql: Calling-Station-Id := "00:0C:29:71:60:DA"
(0) sql: EXPAND SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id
(0) sql: --> SELECT id, username, attribute, value, op FROM radreply WHERE username = 'zaib' ORDER BY id
(0) sql: Executing select query: SELECT id, username, attribute, value, op FROM radreply WHERE username = 'zaib' ORDER BY id
(0) sql: User found in radreply table, merging reply items
(0) sql: Mikrotik-Rate-Limit == "1024k/1024k"
rlm_sql (sql): Reserved connection (2)
rlm_sql (sql): Released connection (2)
Need 5 more connections to reach 10 spares
rlm_sql (sql): Opening additional connection (6), 1 of 26 pending slots used
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.27-0ubuntu0.18.04.1, protocol version 10
(0) sql: EXPAND SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority
(0) sql: --> SELECT groupname FROM radusergroup WHERE username = 'zaib' ORDER BY priority
(0) sql: Executing select query: SELECT groupname FROM radusergroup WHERE username = 'zaib' ORDER BY priority
(0) sql: User not found in any groups
rlm_sql (sql): Released connection (1)
(0) [sql] = ok
(0) if (notfound){
(0) if (notfound) -> FALSE
(0) expiration: Account will expire at 'Jan 13 2029 11:00:00 PKT'
(0) [expiration] = ok
(0) if (userlock){
(0) if (userlock) -> FALSE
(0) [pap] = updated
(0) if (&request:Calling-Station-Id != &control:Calling-Station-Id) {
(0) if (&request:Calling-Station-Id != &control:Calling-Station-Id) -> FALSE
(0) } # authorize = updated
(0) Found Auth-Type = PAP
(0) # Executing group from file /etc/freeradius/sites-enabled/default
(0) Auth-Type PAP {
(0) pap: Login attempt with password
(0) pap: Comparing with "known good" Cleartext-Password
(0) pap: User authenticated successfully
(0) [pap] = ok
(0) } # Auth-Type PAP = ok
(0) # Executing section session from file /etc/freeradius/sites-enabled/default
(0) session {
(0) sql: EXPAND %{User-Name}
(0) sql: --> zaib
(0) sql: SQL-User-Name set to 'zaib'
rlm_sql (sql): Reserved connection (3)
(0) sql: EXPAND SELECT COUNT(*) FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL
(0) sql: --> SELECT COUNT(*) FROM radacct WHERE username = 'zaib' AND acctstoptime IS NULL
(0) sql: Executing select query: SELECT COUNT(*) FROM radacct WHERE username = 'zaib' AND acctstoptime IS NULL
rlm_sql (sql): Released connection (3)
(0) [sql] = ok
(0) } # session = ok
(0) # Executing section post-auth from file /etc/freeradius/sites-enabled/default
(0) post-auth {
(0) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) {
(0) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) -> FALSE
(0) update {
(0) No attributes updated for RHS &session-state:
(0) } # update = noop
(0) sql: EXPAND .query
(0) sql: --> .query
(0) sql: Using query template 'query'
rlm_sql (sql): Reserved connection (4)
(0) sql: EXPAND %{User-Name}
(0) sql: --> zaib
(0) sql: SQL-User-Name set to 'zaib'
(0) sql: EXPAND INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( '%{SQL-User-Name}', '%{%{User-Password}:-%{Chap-Password}}', '%{reply:Packet-Type}', '%{reply:Reply-Message}', '%S', '%{NAS-IP-Address}', '%{Calling-Station-Id}')
(0) sql: --> INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( 'zaib', 'zaib', 'Access-Accept', '', '2019-11-07 15:58:05', '127.0.0.1', '00:0C:29:71:60:DA')
(0) sql: Executing query: INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( 'zaib', 'zaib', 'Access-Accept', '', '2019-11-07 15:58:05', '127.0.0.1', '00:0C:29:71:60:DA')
(0) sql: SQL query returned: success
(0) sql: 1 record(s) updated
rlm_sql (sql): Released connection (4)
(0) [sql] = ok
(0) [exec] = noop
(0) } # post-auth = ok
(0) Sent Access-Accept Id 57 from 127.0.0.1:1812 to 127.0.0.1:56913 length 0
(0) Session-Timeout = 289854115
(0) Finished request
Waking up in 4.9 seconds.
(0) Cleaning up request packet ID 57 with timestamp +2
Ready to process requests
Above output shows OK status. You can inspect any errors in the freeradius config or with the user credentials here like, invalid mac, expiratione etc
1 | radtest zaib zaib localhost 1812 testing123 |
Result:
1 2 3 4 5 6 7 8 9 | Sent Access-Request Id 26 from 0.0.0.0:53486 to 127.0.0.1:1812 length 74 User-Name = "zaib" User-Password = "zaib" NAS-IP-Address = 101.11.11.254 NAS-Port = 1812 Message-Authenticator = 0x00 Cleartext-Password = "zaib" Received Access-Accept Id 26 from 127.0.0.1:1812 to 127.0.0.1:53486 length 26 Session-Timeout = 289854175 |
Freeradius Debug Window:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | Ready to process requests (0) Received Access-Request Id 57 from 127.0.0.1:56913 to 127.0.0.1:1812 length 63 (0) User-Name = "zaib" (0) User-Password = "zaib" (0) Calling-Station-Id = "00:0C:29:71:60:DA" (0) # Executing section authorize from file /etc/freeradius/sites-enabled/default (0) authorize { (0) [preprocess] = ok (0) [chap] = noop (0) [mschap] = noop (0) suffix: Checking for suffix after "@" (0) suffix: No '@' in User-Name = "zaib", looking up realm NULL (0) suffix: No such realm "NULL" (0) [suffix] = noop (0) [files] = noop (0) sql: EXPAND %{User-Name} (0) sql: --> zaib (0) sql: SQL-User-Name set to 'zaib' rlm_sql (sql): Reserved connection (1) (0) sql: EXPAND SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id (0) sql: --> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'zaib' ORDER BY id (0) sql: Executing select query: SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'zaib' ORDER BY id (0) sql: User found in radcheck table (0) sql: Conditional check items matched, merging assignment check items (0) sql: Cleartext-Password := "zaib" (0) sql: Expiration := "Jan 13 2029 11:00:00 PKT" (0) sql: Simultaneous-Use := 1 (0) sql: Calling-Station-Id := "00:0C:29:71:60:DA" (0) sql: EXPAND SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id (0) sql: --> SELECT id, username, attribute, value, op FROM radreply WHERE username = 'zaib' ORDER BY id (0) sql: Executing select query: SELECT id, username, attribute, value, op FROM radreply WHERE username = 'zaib' ORDER BY id (0) sql: User found in radreply table, merging reply items (0) sql: Mikrotik-Rate-Limit == "1024k/1024k" rlm_sql (sql): Reserved connection (2) rlm_sql (sql): Released connection (2) Need 5 more connections to reach 10 spares rlm_sql (sql): Opening additional connection (6), 1 of 26 pending slots used rlm_sql_mysql: Starting connect to MySQL server rlm_sql_mysql: Connected to database 'radius' on Localhost via UNIX socket, server version 5.7.27-0ubuntu0.18.04.1, protocol version 10 (0) sql: EXPAND SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority (0) sql: --> SELECT groupname FROM radusergroup WHERE username = 'zaib' ORDER BY priority (0) sql: Executing select query: SELECT groupname FROM radusergroup WHERE username = 'zaib' ORDER BY priority (0) sql: User not found in any groups rlm_sql (sql): Released connection (1) (0) [sql] = ok (0) if (notfound){ (0) if (notfound) -> FALSE (0) expiration: Account will expire at 'Jan 13 2029 11:00:00 PKT' (0) [expiration] = ok (0) if (userlock){ (0) if (userlock) -> FALSE (0) [pap] = updated (0) if (&request:Calling-Station-Id != &control:Calling-Station-Id) { (0) if (&request:Calling-Station-Id != &control:Calling-Station-Id) -> FALSE (0) } # authorize = updated (0) Found Auth-Type = PAP (0) # Executing group from file /etc/freeradius/sites-enabled/default (0) Auth-Type PAP { (0) pap: Login attempt with password (0) pap: Comparing with "known good" Cleartext-Password (0) pap: User authenticated successfully (0) [pap] = ok (0) } # Auth-Type PAP = ok (0) # Executing section session from file /etc/freeradius/sites-enabled/default (0) session { (0) sql: EXPAND %{User-Name} (0) sql: --> zaib (0) sql: SQL-User-Name set to 'zaib' rlm_sql (sql): Reserved connection (3) (0) sql: EXPAND SELECT COUNT(*) FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL (0) sql: --> SELECT COUNT(*) FROM radacct WHERE username = 'zaib' AND acctstoptime IS NULL (0) sql: Executing select query: SELECT COUNT(*) FROM radacct WHERE username = 'zaib' AND acctstoptime IS NULL rlm_sql (sql): Released connection (3) (0) [sql] = ok (0) } # session = ok (0) # Executing section post-auth from file /etc/freeradius/sites-enabled/default (0) post-auth { (0) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { (0) if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) -> FALSE (0) update { (0) No attributes updated for RHS &session-state: (0) } # update = noop (0) sql: EXPAND .query (0) sql: --> .query (0) sql: Using query template 'query' rlm_sql (sql): Reserved connection (4) (0) sql: EXPAND %{User-Name} (0) sql: --> zaib (0) sql: SQL-User-Name set to 'zaib' (0) sql: EXPAND INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( '%{SQL-User-Name}', '%{%{User-Password}:-%{Chap-Password}}', '%{reply:Packet-Type}', '%{reply:Reply-Message}', '%S', '%{NAS-IP-Address}', '%{Calling-Station-Id}') (0) sql: --> INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( 'zaib', 'zaib', 'Access-Accept', '', '2019-11-07 15:58:05', '127.0.0.1', '00:0C:29:71:60:DA') (0) sql: Executing query: INSERT INTO radpostauth (username, pass, reply, reply_msg, authdate, nasipaddress, mac) VALUES ( 'zaib', 'zaib', 'Access-Accept', '', '2019-11-07 15:58:05', '127.0.0.1', '00:0C:29:71:60:DA') (0) sql: SQL query returned: success (0) sql: 1 record(s) updated rlm_sql (sql): Released connection (4) (0) [sql] = ok (0) [exec] = noop (0) } # post-auth = ok (0) Sent Access-Accept Id 57 from 127.0.0.1:1812 to 127.0.0.1:56913 length 0 (0) Session-Timeout = 289854115 (0) Finished request Waking up in 4.9 seconds. (0) Cleaning up request packet ID 57 with timestamp +2 Ready to process requests |
Above output shows OK status. You can inspect any errors in the freeradius config or with the user credentials here like, invalid mac, expiratione etc
Workaround to open existing session in RADACCT
When there is an disconnection between NAS & RADIUS, following situation will be observed
When there is an disconnection between NAS & RADIUS, following situation will be observed
NAS:
User session will be online on NAS, but NAS will not send interim updates to the Radius because communication between NAS/Radius is lost
User session will be online on NAS, but NAS will not send interim updates to the Radius because communication between NAS/Radius is lost
RADIUS:
Radius will not receive any interim updates from the NAS & his session will keep alive (acctstoptime IS NULL), But for some local requirements we scheduled a bash script which checks stale session checking last acct update time . Example if the radius doesn’t receives interim update for 10 minutes, it will close this user session in radacct table by setting acctstoptime to current date/time.
Now when the connectivity restore between the NAS & Radius, and since NAS has this user online, it will send Interim Update to the radius, BUT our radius have closed this session already earlier (via bash script), therefore this update packet will only update the old entry using unique acct ID, but acctstoptime will not be set to NULL.
This will create confusion for frontend, because when you will search online users by searching entries whose acctstoptime is NULL. this session will not appear which will create FALSE assumption on your frontend that this user is offline whereas this user is actually online in NAS.
To settle this , I made some dirty workaround by poking in freeradius SQL queries.conf file. I am not aware if this trick is is already being used or not,but its working fine on my end.
Add below code
1 acctstoptime = NULL, \
in queries.conf
Edit file by
1 nano /etc/freeradius/mods-config/sql/main/mysql/queries.conf
1234567891011121314151617181920212223242526 interim-update {
#
# Update an existing session and calculate the interval
# between the last data we received for the session and this
# update. This can be used to find stale sessions.
#
query = "\
UPDATE ${....acct_table1} \
SET \
acctupdatetime = (@acctupdatetime_old:=acctupdatetime), \
acctupdatetime = FROM_UNIXTIME(\
%{integer:Event-Timestamp}), \
acctinterval = %{integer:Event-Timestamp} - \
UNIX_TIMESTAMP(@acctupdatetime_old), \
acctstoptime = NULL, \
framedipaddress = '%{Framed-IP-Address}', \
framedipv6address = '%{Framed-IPv6-Address}', \
framedipv6prefix = '%{Framed-IPv6-Prefix}', \
framedinterfaceid = '%{Framed-Interface-Id}', \
delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \
acctsessiontime = %{%{Acct-Session-Time}:-NULL}, \
acctinputoctets = '%{%{Acct-Input-Gigawords}:-0}' \
<< 32 | '%{%{Acct-Input-Octets}:-0}', \
acctoutputoctets = '%{%{Acct-Output-Gigawords}:-0}' \
<< 32 | '%{%{Acct-Output-Octets}:-0}' \
WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'"
& as always reload freeradius
1 service freeradius reload
Radius will not receive any interim updates from the NAS & his session will keep alive (acctstoptime IS NULL), But for some local requirements we scheduled a bash script which checks stale session checking last acct update time . Example if the radius doesn’t receives interim update for 10 minutes, it will close this user session in radacct table by setting acctstoptime to current date/time.
Now when the connectivity restore between the NAS & Radius, and since NAS has this user online, it will send Interim Update to the radius, BUT our radius have closed this session already earlier (via bash script), therefore this update packet will only update the old entry using unique acct ID, but acctstoptime will not be set to NULL.
This will create confusion for frontend, because when you will search online users by searching entries whose acctstoptime is NULL. this session will not appear which will create FALSE assumption on your frontend that this user is offline whereas this user is actually online in NAS.
To settle this , I made some dirty workaround by poking in freeradius SQL queries.conf file. I am not aware if this trick is is already being used or not,but its working fine on my end.
Add below code
1 | acctstoptime = NULL, \ |
in queries.conf
Edit file by
1 | nano /etc/freeradius/mods-config/sql/main/mysql/queries.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | interim-update { # # Update an existing session and calculate the interval # between the last data we received for the session and this # update. This can be used to find stale sessions. # query = "\ UPDATE ${....acct_table1} \ SET \ acctupdatetime = (@acctupdatetime_old:=acctupdatetime), \ acctupdatetime = FROM_UNIXTIME(\ %{integer:Event-Timestamp}), \ acctinterval = %{integer:Event-Timestamp} - \ UNIX_TIMESTAMP(@acctupdatetime_old), \ acctstoptime = NULL, \ framedipaddress = '%{Framed-IP-Address}', \ framedipv6address = '%{Framed-IPv6-Address}', \ framedipv6prefix = '%{Framed-IPv6-Prefix}', \ framedinterfaceid = '%{Framed-Interface-Id}', \ delegatedipv6prefix = '%{Delegated-IPv6-Prefix}', \ acctsessiontime = %{%{Acct-Session-Time}:-NULL}, \ acctinputoctets = '%{%{Acct-Input-Gigawords}:-0}' \ << 32 | '%{%{Acct-Input-Octets}:-0}', \ acctoutputoctets = '%{%{Acct-Output-Gigawords}:-0}' \ << 32 | '%{%{Acct-Output-Octets}:-0}' \ WHERE AcctUniqueId = '%{Acct-Unique-Session-Id}'" |
& as always reload freeradius
1 | service freeradius reload |
Prevent Multiple User login [ Simultaneous Login :=1 ]
To prevent multiple login for same user , we have to first enable SQL base session logging , so that our control can check the session details for already logged in user
Edit file
1 nano /etc/freeradius/sites-enabled/default
& then uncomment sql under session { section
12345 # Session database, used for checking Simultaneous-Use. Either the radutmp
# or rlm_sql module can handle this.
# The rlm_sql module is *much* faster
session {
sql
To prevent multiple login for same user , we have to first enable SQL base session logging , so that our control can check the session details for already logged in user
Edit file
1 | nano /etc/freeradius/sites-enabled/default |
& then uncomment sql under session { section
1 2 3 4 5 | # Session database, used for checking Simultaneous-Use. Either the radutmp # or rlm_sql module can handle this. # The rlm_sql module is *much* faster session { sql |
MAC binding for particular user
In FR 3, chdckval module have been removed (which was used in Fr2 for mac control).
First add the Calling-Station-Id in RADCHECK table for that user.
Now we need to add UNLAG query in FR sites-enabled DEFAULT config to trigger MAC address control upon receivng authentication request (if control for that user is defined in RADCHECK table)
edit file
1 nano /etc/freeradius/sites-enabled/default
Under authorize { section, add below code
123456 if (&request:Calling-Station-Id != &control:Calling-Station-Id) {
update reply {
Reply-Message := "Incorrect Mac"
}
reject
}
After every change in config files, reload freeradius by
1 service freeradius reload
Now you can simulate test using below CMD
In FR 3, chdckval module have been removed (which was used in Fr2 for mac control).
First add the Calling-Station-Id in RADCHECK table for that user.
Now we need to add UNLAG query in FR sites-enabled DEFAULT config to trigger MAC address control upon receivng authentication request (if control for that user is defined in RADCHECK table)
edit file
1 | nano /etc/freeradius/sites-enabled/default |
Under authorize { section, add below code
1 2 3 4 5 6 | if (&request:Calling-Station-Id != &control:Calling-Station-Id) { update reply { Reply-Message := "Incorrect Mac" } reject } |
After every change in config files, reload freeradius by
1 | service freeradius reload |
Now you can simulate test using below CMD
RADCLIENT test with particular calling MAC address
1234 # example with Password attribute, you can also try User-Password
echo "User-Name = user01, Password = pass01, Calling-Station-Id = 98-4B-4A-F5-BF-40" | radclient -s localhost:1812 auth testing123
#Another example with cleartext-password attribute
echo "User-Name = user01, ClearText-Password = passwd, Calling-Station-Id = 00:50:56:91:D5:16" | radclient -s localhost:1812 auth testing123
Note: If there is no Calling-Station-ID defined in RADCHECK , test will success and in FREERADIUS Debug log, you will see line that failed to evaluate control. but user will be able to connect if no mac defined in radcheck.
1 2 3 4 | # example with Password attribute, you can also try User-Password echo "User-Name = user01, Password = pass01, Calling-Station-Id = 98-4B-4A-F5-BF-40" | radclient -s localhost:1812 auth testing123 #Another example with cleartext-password attribute echo "User-Name = user01, ClearText-Password = passwd, Calling-Station-Id = 00:50:56:91:D5:16" | radclient -s localhost:1812 auth testing123 |
Note: If there is no Calling-Station-ID defined in RADCHECK , test will success and in FREERADIUS Debug log, you will see line that failed to evaluate control. but user will be able to connect if no mac defined in radcheck.
Modifying RADPOSTAUTH section for recording user login attempts in sql table
To record all users login attempts with our customized RADPOSTAUTH table, we can following
First edit queries.conf in /etc/freeradius/mods-config/sql/main/mysql
1 nano /etc/freeradius/mods-config/sql/main/mysql/queries.conf
Goto End & search for section (usually its in the last)
12345 #######################################################################
# Authentication Logging Queries
#######################################################################
# postauth_query - Insert some info after authentication
#######################################################################
Delete existing query & use this one
123456789101112 query = "\
INSERT INTO ${..postauth_table} \
(username, pass, reply, reply_msg, authdate, nasipaddress, mac) \
VALUES ( \
'%{SQL-User-Name}', \
'%{%{User-Password}:-%{Chap-Password}}', \
'%{reply:Packet-Type}', \
'%{reply:Reply-Message}', \
'%S', \
'%{NAS-IP-Address}', \
'%{Calling-Station-Id}')"
}
Save and Exit.
Modify RADPOSTAUTH table
Now modify the RADPOSTAUTH table in radius DB so that reply messages can be stored here in the way want it to be
12345678 mysql -uroot -pzaib1234
use radius;
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
DROP TABLE IF EXISTS `radpostauth`;
CREATE TABLE `radpostauth` ( `id` int(11) NOT NULL, `username` varchar(64) NOT NULL DEFAULT '', `pass` varchar(64) NOT NULL DEFAULT '', `reply` varchar(256) NOT NULL DEFAULT '', `reply_msg` varchar(256) DEFAULT NULL, `authdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `nasipaddress` varchar(100) DEFAULT NULL, `mac` text ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `radpostauth` ADD PRIMARY KEY (`id`), ADD KEY `username` (`username`(32));
ALTER TABLE `radpostauth` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;
exit
As always reload freeradius service after any modification in the configuration files using
1 service freeradius reload
Try to auth any user and then look into RADPOSTAUTH table & you will see entries like
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 mysql> select * from radpostauth;
+----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+
| id | username | pass | reply | reply_msg | authdate | nasipaddress | mac |
+----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+
| 14 | zaib | zaib | Access-Accept | | 2019-11-05 19:21:37 | 127.0.0.1 | 00:0C:29:35:F8:2F |
| 15 | zaib | zaib | Access-Accept | | 2019-11-05 19:21:50 | 127.0.0.1 | 00:0C:29:35:F8:21 |
| 16 | zaib | zaib | Access-Reject | | 2019-11-05 19:22:12 | 127.0.0.1 | 00:0C:29:35:F8:21 |
| 17 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:23:51 | 127.0.0.1 | 00:0C:29:35:F8:21 |
| 18 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:23:57 | 127.0.0.1 | 00:0C:29:35:F8:2F |
| 19 | zaib | zaib | Access-Accept | | 2019-11-05 19:24:14 | 127.0.0.1 | 11:11:11:11:11:11 |
| 20 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:24:21 | 127.0.0.1 | 00:0C:29:35:F8:2F |
| 21 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:25:23 | 127.0.0.1 | 00:0C:29:35:F8:2F |
| 22 | zaib | zaib | Access-Accept | | 2019-11-05 19:25:29 | 127.0.0.1 | 11:11:11:11:11:11 |
| 23 | zaib | zaib | Access-Reject | Your account has expired=2C zaib | 2019-11-05 19:25:44 | 127.0.0.1 | 11:11:11:11:11:11 |
| 24 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:26:16 | 127.0.0.1 | 11:11:11:11:11:11 |
| 25 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:26:25 | 101.11.11.254 | |
| 26 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:27:22 | 101.11.11.254 | |
| 27 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:27:41 | 101.11.11.254 | |
| 28 | zaib1 | zaib | Access-Reject | | 2019-11-05 19:27:55 | 101.11.11.254 | |
| 29 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:29:04 | 101.11.11.254 | |
| 30 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:29:12 | 101.11.11.254 | |
| 31 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:30:28 | 101.11.11.254 | |
| 32 | zaib | zaib1 | Access-Reject | Wrong Password | 2019-11-05 19:30:46 | 101.11.11.254 | |
| 33 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:30:54 | 101.11.11.254 | |
| 34 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:32:45 | 101.11.11.254 | |
| 35 | zaib | zaib | Access-Accept | | 2019-11-05 19:32:51 | 101.11.11.254 | |
| 36 | zaib | zaib | Access-Accept | | 2019-11-05 19:33:01 | 101.11.11.254 | |
| 37 | zaib | zaib | Access-Reject | You are already logged in - access denied | 2019-11-05 19:33:57 | 101.11.11.254 | |
| 38 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:21 | 101.11.11.254 | |
| 39 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:28 | 127.0.0.1 | 11:11:11:11:11:11 |
| 40 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:51 | 127.0.0.1 | |
| 41 | zaib | | Access-Reject | Incorrect Mac | 2019-11-05 19:37:23 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 42 | zaib | | Access-Accept | | 2019-11-05 19:37:38 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 43 | zaib | | Access-Reject | Incorrect Mac | 2019-11-05 19:39:13 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 44 | zaib | zaib | Access-Reject | You are already logged in - access denied | 2019-11-06 08:37:04 | 101.11.11.254 | |
| 45 | zaib | zaib | Access-Accept | | 2019-11-06 08:37:24 | 101.11.11.254 | |
| 46 | zaib | | Access-Reject | Incorrect Mac | 2019-11-07 07:56:07 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 47 | zaib | | Access-Reject | You are already logged in - access denied | 2019-11-07 07:57:03 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 48 | zaib | | Access-Accept | | 2019-11-07 07:57:18 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 49 | zaib@zaib | | Access-Reject | Wrong Password | 2019-11-07 07:57:23 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 50 | zaib@zaib | | Access-Accept | | 2019-11-07 08:00:37 | 101.11.11.255 | 00:0C:29:71:60:DA |
| 51 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-07 15:54:53 | 127.0.0.1 | 11:11:11:11:11:11 |
| 52 | zaib | zaib | Access-Accept | | 2019-11-07 15:56:12 | 127.0.0.1 | 00:0C:29:71:60:DA |
| 53 | zaib | zaib | Access-Accept | | 2019-11-07 15:57:05 | 101.11.11.254 | |
| 54 | zaib | zaib | Access-Accept | | 2019-11-07 15:58:05 | 127.0.0.1 | 00:0C:29:71:60:DA |
+----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+
To record all users login attempts with our customized RADPOSTAUTH table, we can following
First edit queries.conf in /etc/freeradius/mods-config/sql/main/mysql
1 | nano /etc/freeradius/mods-config/sql/main/mysql/queries.conf |
Goto End & search for section (usually its in the last)
1 2 3 4 5 | ####################################################################### # Authentication Logging Queries ####################################################################### # postauth_query - Insert some info after authentication ####################################################################### |
Delete existing query & use this one
1 2 3 4 5 6 7 8 9 10 11 12 | query = "\ INSERT INTO ${..postauth_table} \ (username, pass, reply, reply_msg, authdate, nasipaddress, mac) \ VALUES ( \ '%{SQL-User-Name}', \ '%{%{User-Password}:-%{Chap-Password}}', \ '%{reply:Packet-Type}', \ '%{reply:Reply-Message}', \ '%S', \ '%{NAS-IP-Address}', \ '%{Calling-Station-Id}')" } |
Save and Exit.
Modify RADPOSTAUTH table
Now modify the RADPOSTAUTH table in radius DB so that reply messages can be stored here in the way want it to be
1 2 3 4 5 6 7 8 | mysql -uroot -pzaib1234 use radius; SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; DROP TABLE IF EXISTS `radpostauth`; CREATE TABLE `radpostauth` ( `id` int(11) NOT NULL, `username` varchar(64) NOT NULL DEFAULT '', `pass` varchar(64) NOT NULL DEFAULT '', `reply` varchar(256) NOT NULL DEFAULT '', `reply_msg` varchar(256) DEFAULT NULL, `authdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `nasipaddress` varchar(100) DEFAULT NULL, `mac` text ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `radpostauth` ADD PRIMARY KEY (`id`), ADD KEY `username` (`username`(32)); ALTER TABLE `radpostauth` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12; exit |
As always reload freeradius service after any modification in the configuration files using
1 | service freeradius reload |
Try to auth any user and then look into RADPOSTAUTH table & you will see entries like
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | mysql> select * from radpostauth; +----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+ | id | username | pass | reply | reply_msg | authdate | nasipaddress | mac | +----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+ | 14 | zaib | zaib | Access-Accept | | 2019-11-05 19:21:37 | 127.0.0.1 | 00:0C:29:35:F8:2F | | 15 | zaib | zaib | Access-Accept | | 2019-11-05 19:21:50 | 127.0.0.1 | 00:0C:29:35:F8:21 | | 16 | zaib | zaib | Access-Reject | | 2019-11-05 19:22:12 | 127.0.0.1 | 00:0C:29:35:F8:21 | | 17 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:23:51 | 127.0.0.1 | 00:0C:29:35:F8:21 | | 18 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:23:57 | 127.0.0.1 | 00:0C:29:35:F8:2F | | 19 | zaib | zaib | Access-Accept | | 2019-11-05 19:24:14 | 127.0.0.1 | 11:11:11:11:11:11 | | 20 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:24:21 | 127.0.0.1 | 00:0C:29:35:F8:2F | | 21 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-05 19:25:23 | 127.0.0.1 | 00:0C:29:35:F8:2F | | 22 | zaib | zaib | Access-Accept | | 2019-11-05 19:25:29 | 127.0.0.1 | 11:11:11:11:11:11 | | 23 | zaib | zaib | Access-Reject | Your account has expired=2C zaib | 2019-11-05 19:25:44 | 127.0.0.1 | 11:11:11:11:11:11 | | 24 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:26:16 | 127.0.0.1 | 11:11:11:11:11:11 | | 25 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:26:25 | 101.11.11.254 | | | 26 | zaib | zaib | Access-Accept | Account Expired | 2019-11-05 19:27:22 | 101.11.11.254 | | | 27 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:27:41 | 101.11.11.254 | | | 28 | zaib1 | zaib | Access-Reject | | 2019-11-05 19:27:55 | 101.11.11.254 | | | 29 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:29:04 | 101.11.11.254 | | | 30 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:29:12 | 101.11.11.254 | | | 31 | zaib | zaib1 | Access-Reject | Account Expired | 2019-11-05 19:30:28 | 101.11.11.254 | | | 32 | zaib | zaib1 | Access-Reject | Wrong Password | 2019-11-05 19:30:46 | 101.11.11.254 | | | 33 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:30:54 | 101.11.11.254 | | | 34 | zaib1 | zaib | Access-Reject | Username not found | 2019-11-05 19:32:45 | 101.11.11.254 | | | 35 | zaib | zaib | Access-Accept | | 2019-11-05 19:32:51 | 101.11.11.254 | | | 36 | zaib | zaib | Access-Accept | | 2019-11-05 19:33:01 | 101.11.11.254 | | | 37 | zaib | zaib | Access-Reject | You are already logged in - access denied | 2019-11-05 19:33:57 | 101.11.11.254 | | | 38 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:21 | 101.11.11.254 | | | 39 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:28 | 127.0.0.1 | 11:11:11:11:11:11 | | 40 | zaib | zaib | Access-Accept | | 2019-11-05 19:35:51 | 127.0.0.1 | | | 41 | zaib | | Access-Reject | Incorrect Mac | 2019-11-05 19:37:23 | 101.11.11.255 | 00:0C:29:71:60:DA | | 42 | zaib | | Access-Accept | | 2019-11-05 19:37:38 | 101.11.11.255 | 00:0C:29:71:60:DA | | 43 | zaib | | Access-Reject | Incorrect Mac | 2019-11-05 19:39:13 | 101.11.11.255 | 00:0C:29:71:60:DA | | 44 | zaib | zaib | Access-Reject | You are already logged in - access denied | 2019-11-06 08:37:04 | 101.11.11.254 | | | 45 | zaib | zaib | Access-Accept | | 2019-11-06 08:37:24 | 101.11.11.254 | | | 46 | zaib | | Access-Reject | Incorrect Mac | 2019-11-07 07:56:07 | 101.11.11.255 | 00:0C:29:71:60:DA | | 47 | zaib | | Access-Reject | You are already logged in - access denied | 2019-11-07 07:57:03 | 101.11.11.255 | 00:0C:29:71:60:DA | | 48 | zaib | | Access-Accept | | 2019-11-07 07:57:18 | 101.11.11.255 | 00:0C:29:71:60:DA | | 49 | zaib@zaib | | Access-Reject | Wrong Password | 2019-11-07 07:57:23 | 101.11.11.255 | 00:0C:29:71:60:DA | | 50 | zaib@zaib | | Access-Accept | | 2019-11-07 08:00:37 | 101.11.11.255 | 00:0C:29:71:60:DA | | 51 | zaib | zaib | Access-Reject | Incorrect Mac | 2019-11-07 15:54:53 | 127.0.0.1 | 11:11:11:11:11:11 | | 52 | zaib | zaib | Access-Accept | | 2019-11-07 15:56:12 | 127.0.0.1 | 00:0C:29:71:60:DA | | 53 | zaib | zaib | Access-Accept | | 2019-11-07 15:57:05 | 101.11.11.254 | | | 54 | zaib | zaib | Access-Accept | | 2019-11-07 15:58:05 | 127.0.0.1 | 00:0C:29:71:60:DA | +----+-----------+-------+---------------+-------------------------------------------+---------------------+---------------+-------------------+ |
Unable to login with username like zaib@zaib
If you are unable to login with username like z@ib@zaib , then disable the filter_username module under authorize { section
edit file
1 nano /etc/freeradius/sites-enabled/default
Navigate to authorize { section, & comment the filter_username
12345678 authorize {
#
# Take a User-Name, and perform some checks on it, for spaces and other
# invalid characters. If the User-Name appears invalid, reject the
# request.
# See policy.d/filter for the definition of the filter_username policy.
# filter_username
If you are unable to login with username like z@ib@zaib , then disable the filter_username module under authorize { section
edit file
1 | nano /etc/freeradius/sites-enabled/default |
Navigate to authorize { section, & comment the filter_username
1 2 3 4 5 6 7 8 | authorize { # # Take a User-Name, and perform some checks on it, for spaces and other # invalid characters. If the User-Name appears invalid, reject the # request. # See policy.d/filter for the definition of the filter_username policy. # filter_username |
Mikrotik-Rate-Limit not working with FR 3
(Updated on 9-NOV-2019)
Today I encountered issue at local network, where radius was not sending the Mikrotik-Rate-Limit
syntax to the NAS. After doing some troubleshooting it came to my knowledge that you have to change op
value from ==
to :=
, Example
Mikrotik-Rate-Limit := 1024k/1024k
Today I encountered issue at local network, where radius was not sending the Mikrotik-Rate-Limit
syntax to the NAS. After doing some troubleshooting it came to my knowledge that you have to change op
value from ==
to :=
, Example
Mikrotik-Rate-Limit := 1024k/1024k
Trimming RADACCT table to make it SLIM & blazing Responsive
Over the period of time, radacct table will grow enormously. This can slow down many queries , therefore its a good idea to move all closed session entries (NOT NULL) to another table like radacct_archive. I created following bash script which helped me to sort many issues.
Note: Make sure to change credentials section
1234 mkdir /temp
touch /temp/radacct_trim.sh
chmod +x /temp/radacct_trim.sh
nano /temp/radacct_trim.sh
& copy paste following
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 #!/usr/bin/env bash
####!/bin/sh
#set -x
#MYSQL DETAILS
DATE=`date`
logger radacct_trim script started $DATE
SQLUSER="root"
SQLPASS="YOUR_PASSWORD"
DB="radius"
TBL_ARCH="radacct_archive"
TBL_ARCH_EXISTS=$(printf 'SHOW TABLES LIKE "%s"' "$TBL_ARCH")
MONTHS="12"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLUSER --skip-column-names -s -e"
# This is one time step.
echo "
Script Started @ $DATE
"
echo "- Step 1 : Checking for DB: $DB / TABLE: $TBL_ARCH ..."
DBCHK=`mysqlshow --user=$SQLUSER $DB | grep -v Wildcard | grep -o $DB`
if [ "$DBCHK" == "$DB" ]; then
echo " > $DB DB found"
else
echo " > $DB not found. Creating now ..."
$CMD "create database if not exists $DB;"
fi
if [[ $(mysql -u$SQLUSER -e "$TBL_ARCH_EXISTS" $DB) ]]
then
echo " > $TBL_ARCH TABLE found IN DB: $DB"
else
echo " > $TBL_ARCH TABLE not found IN DB: $DB / Creating now ..."
$CMD "use $DB; create table if not exists $TBL_ARCH LIKE radacct;"
fi
# Start Action: copy data from radacct to new db/archive table
NOTULL_COUNT=`$CMD "use $DB; select count(*) from radacct WHERE acctstoptime is not null;"`
echo "- Step 2 : Found $NOTULL_COUNT records in radacct table , Now copying $NOTULL_COUNT records to $TBL_ARCH table ..."
$CMD "use $DB; INSERT IGNORE INTO $TBL_ARCH SELECT * FROM radacct WHERE acctstoptime is not null;"
echo "- Step 3 : Deleting $NOTULL_COUNT records old data from radacct table (which have acctstoptime NOT NULL) ..."
# --- Now Delete data from CURRENT RADACCT table so that it should remain fit and smart ins size
$CMD "use $DB; DELETE FROM radacct WHERE acctstoptime is not null;"
echo "- Step 4 : Copying old data from $TBL_ARCH older then $MONTHS months ..."
# --- Now Delete data from RADACCT_ARCHIVE table so that it should not grow either more than we required i.e 1 Year - one year archived data is enough IMO
$CMD "use $DB; DELETE FROM $TBL_ARCH WHERE date(acctstarttime) < (CURDATE() - INTERVAL $MONTHS MONTH);"
DATE=`date`
logger radacct_trim script ended with $NOTULL_COUNT records processed for trimming @ $DATE
echo "
radacct_trim script ended with $NOTULL_COUNT records processed for trimming @ $DATE"
Schedule this BASH script to run every minute (or as per required)
1 1 * * * * /temp/radacct_trim.sh
Over the period of time, radacct table will grow enormously. This can slow down many queries , therefore its a good idea to move all closed session entries (NOT NULL) to another table like radacct_archive. I created following bash script which helped me to sort many issues.
Note: Make sure to change credentials section
1 2 3 4 | mkdir /temp touch /temp/radacct_trim.sh chmod +x /temp/radacct_trim.sh nano /temp/radacct_trim.sh |
& copy paste following
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #!/usr/bin/env bash ####!/bin/sh #set -x #MYSQL DETAILS DATE=`date` logger radacct_trim script started $DATE SQLUSER="root" SQLPASS="YOUR_PASSWORD" DB="radius" TBL_ARCH="radacct_archive" TBL_ARCH_EXISTS=$(printf 'SHOW TABLES LIKE "%s"' "$TBL_ARCH") MONTHS="12" export MYSQL_PWD=$SQLPASS CMD="mysql -u$SQLUSER --skip-column-names -s -e" # This is one time step. echo " Script Started @ $DATE " echo "- Step 1 : Checking for DB: $DB / TABLE: $TBL_ARCH ..." DBCHK=`mysqlshow --user=$SQLUSER $DB | grep -v Wildcard | grep -o $DB` if [ "$DBCHK" == "$DB" ]; then echo " > $DB DB found" else echo " > $DB not found. Creating now ..." $CMD "create database if not exists $DB;" fi if [[ $(mysql -u$SQLUSER -e "$TBL_ARCH_EXISTS" $DB) ]] then echo " > $TBL_ARCH TABLE found IN DB: $DB" else echo " > $TBL_ARCH TABLE not found IN DB: $DB / Creating now ..." $CMD "use $DB; create table if not exists $TBL_ARCH LIKE radacct;" fi # Start Action: copy data from radacct to new db/archive table NOTULL_COUNT=`$CMD "use $DB; select count(*) from radacct WHERE acctstoptime is not null;"` echo "- Step 2 : Found $NOTULL_COUNT records in radacct table , Now copying $NOTULL_COUNT records to $TBL_ARCH table ..." $CMD "use $DB; INSERT IGNORE INTO $TBL_ARCH SELECT * FROM radacct WHERE acctstoptime is not null;" echo "- Step 3 : Deleting $NOTULL_COUNT records old data from radacct table (which have acctstoptime NOT NULL) ..." # --- Now Delete data from CURRENT RADACCT table so that it should remain fit and smart ins size $CMD "use $DB; DELETE FROM radacct WHERE acctstoptime is not null;" echo "- Step 4 : Copying old data from $TBL_ARCH older then $MONTHS months ..." # --- Now Delete data from RADACCT_ARCHIVE table so that it should not grow either more than we required i.e 1 Year - one year archived data is enough IMO $CMD "use $DB; DELETE FROM $TBL_ARCH WHERE date(acctstarttime) < (CURDATE() - INTERVAL $MONTHS MONTH);" DATE=`date` logger radacct_trim script ended with $NOTULL_COUNT records processed for trimming @ $DATE echo " radacct_trim script ended with $NOTULL_COUNT records processed for trimming @ $DATE" |
Schedule this BASH script to run every minute (or as per required)
1 | 1 * * * * /temp/radacct_trim.sh |
Check for STALE Sessions in RADACCT [for FR ver3 in particular]
This bash script will close sessions in RADACCT whose interim updates have not received in last XX minutes. You can schedule it to run every minute or as required
123456789101112131415161718192021222324252627282930313233343536373839404142 #!/usr/bin/env bash
###!/bin/sh
#set -x
#trap "set +x; set -x" DEBUG
# BASH base script to close STALE sessions from freeradius, whose accounting is not updated in last X minutes in RADACCT table
# By Syed Jahanzaib
# CREATED on : 25-July-2018
# Local Variables
# Mysql credentials
SQLID="root"
SQLPASS="YOUR_PASSWORD"
export MYSQL_PWD=$SQLPASS
CMD="mysql -u$SQLID --skip-column-names -s -e"
DB="radius"
INTERVAL="11"
DB="radius"
#Table which contain main users information
TBL="users"
#Rad user group in which we will update user profile like from 1mb to expired or likewise
TBL_LOG="log"
STALE_USR_LIST="/tmp/stale_sessions.txt"
# Date Time Variables
DATE=$(date +%d-%m-%Y)
DT_HMS=$(date +'%H:%M:%S')
FULL_DATE=`date`
CURR_HOUR=$(date +%H)
TODAY=$(date +"%Y-%m-%d")
WEEK=`date -d "-1000 days" '+%Y-%m-%d'`
BEGIN="1970-01-01"
H=$(date +'%-H')
#Check and close session for staleness
$CMD "use $DB; select username,radacctid,nasipaddress from radacct WHERE acctstoptime IS NULL AND acctupdatetime $STALE_USR_LIST
# IF no user found , show error and exit - zaib
CHK=`wc -m $STALE_USR_LIST | awk {'print $1}'`
if [ "$CHK" -eq 0 ]
then
echo "No stall sesion found (which accounting session have not updated in last $INTERVAL minutes) , exiting ..."
exit 1
fi
$CMD "use $DB; UPDATE radacct SET acctstoptime = NOW(), acctterminatecause = 'Clear-Stale-Session' WHERE acctstoptime IS NULL AND acctupdatetime /dev/null 2>&1
WordPress is not letting pasting of code. look for this line
This bash script will close sessions in RADACCT whose interim updates have not received in last XX minutes. You can schedule it to run every minute or as required
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #!/usr/bin/env bash ###!/bin/sh #set -x #trap "set +x; set -x" DEBUG # BASH base script to close STALE sessions from freeradius, whose accounting is not updated in last X minutes in RADACCT table # By Syed Jahanzaib # CREATED on : 25-July-2018 # Local Variables # Mysql credentials SQLID="root" SQLPASS="YOUR_PASSWORD" export MYSQL_PWD=$SQLPASS CMD="mysql -u$SQLID --skip-column-names -s -e" DB="radius" INTERVAL="11" DB="radius" #Table which contain main users information TBL="users" #Rad user group in which we will update user profile like from 1mb to expired or likewise TBL_LOG="log" STALE_USR_LIST="/tmp/stale_sessions.txt" # Date Time Variables DATE=$(date +%d-%m-%Y) DT_HMS=$(date +'%H:%M:%S') FULL_DATE=`date` CURR_HOUR=$(date +%H) TODAY=$(date +"%Y-%m-%d") WEEK=`date -d "-1000 days" '+%Y-%m-%d'` BEGIN="1970-01-01" H=$(date +'%-H') #Check and close session for staleness $CMD "use $DB; select username,radacctid,nasipaddress from radacct WHERE acctstoptime IS NULL AND acctupdatetime $STALE_USR_LIST # IF no user found , show error and exit - zaib CHK=`wc -m $STALE_USR_LIST | awk {'print $1}'` if [ "$CHK" -eq 0 ] then echo "No stall sesion found (which accounting session have not updated in last $INTERVAL minutes) , exiting ..." exit 1 fi $CMD "use $DB; UPDATE radacct SET acctstoptime = NOW(), acctterminatecause = 'Clear-Stale-Session' WHERE acctstoptime IS NULL AND acctupdatetime /dev/null 2>&1 |
WordPress is not letting pasting of code. look for this line
TIPS for MYSQL:
following are some mySQL tuning made according to the hardware. These are just my assumptions that this setting will work fine. However you may tune your setup according to your hardware. Install & run MYSQLTUNER tool which will better guide you as per the actual hardware/software scneario.
1 /etc/mysql/mysql.conf.d/mysqld.cnf
123456789101112131415161718192021222324252627282930 [mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address = 127.0.0.1
skip_name_resolve
key_buffer_size = 4G
thread_stack = 192K
thread_cache_size = 8
myisam-recover-options = BACKUP
max_connections = 2000
table_open_cache = 15000
query_cache_limit = 200M
query_cache_size = 0
query_cache_type = 0
#log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 100M
innodb_buffer_pool_size = 22G
innodb_log_file_size = 11G
innodb_buffer_pool_instances = 22
following are some mySQL tuning made according to the hardware. These are just my assumptions that this setting will work fine. However you may tune your setup according to your hardware. Install & run MYSQLTUNER tool which will better guide you as per the actual hardware/software scneario.
1 | /etc/mysql/mysql.conf.d/mysqld.cnf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp lc-messages-dir = /usr/share/mysql skip-external-locking bind-address = 127.0.0.1 skip_name_resolve key_buffer_size = 4G thread_stack = 192K thread_cache_size = 8 myisam-recover-options = BACKUP max_connections = 2000 table_open_cache = 15000 query_cache_limit = 200M query_cache_size = 0 query_cache_type = 0 #log_error = /var/log/mysql/error.log expire_logs_days = 10 max_binlog_size = 100M innodb_buffer_pool_size = 22G innodb_log_file_size = 11G innodb_buffer_pool_instances = 22 |
MYSQLTUNER to see mySQL performance
It is good idea to install mysqltuner
1 apt-get install mysqltuner
Let your mysql Run for 1-2 days, then run this tool
1 mysqltuner
It is good idea to install mysqltuner
1 | apt-get install mysqltuner |
Let your mysql Run for 1-2 days, then run this tool
1 | mysqltuner |
MYSQL FIND ENGINE TYPE FOR DB
123 mysql -uroot -pzaib1234
use radius;
SHOW TABLE STATUS\G
1 2 3 | mysql -uroot -pzaib1234 use radius; SHOW TABLE STATUS\G |
OUTPUT:
1234567891011121314151617181920 mysql> SHOW TABLE STATUS\G
*************************** 2. row ***************************
Name: radacct
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 1
Avg_row_length: 16384
Data_length: 16384
Max_data_length: 0
Index_length: 212992
Data_free: 0
Auto_increment: 2323234
Create_time: 2019-11-05 19:06:21
Update_time: 2019-11-07 10:27:08
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
In above OUTPUT, You can see the type, with 5.5+ its generally innodb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | mysql> SHOW TABLE STATUS\G *************************** 2. row *************************** Name: radacct Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 1 Avg_row_length: 16384 Data_length: 16384 Max_data_length: 0 Index_length: 212992 Data_free: 0 Auto_increment: 2323234 Create_time: 2019-11-05 19:06:21 Update_time: 2019-11-07 10:27:08 Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: |
In above OUTPUT, You can see the type, with 5.5+ its generally innodb
Monitor Disk Read Write
To monitor all disks read/write speed install this tool
1 apt-get install -y iotop
Run it using below cmd
1 iotop -o
To monitor all disks read/write speed install this tool
1 | apt-get install -y iotop |
Run it using below cmd
1 | iotop -o |
HTOP – Monitor ALL Processes / CPU Cores Usage Monitor
install this
1 apt-get install -y htop
1 htop
install this
1 | apt-get install -y htop |
1 | htop |
Additional:
Doing Stress Test on Radius using BASH scripts
Doing Stress Test on Radius using BASH scripts
TIP:
Installing Freeradius latest version 3.xx.xx on Ubuntu 16.4 Server
123456 echo "deb http://packages.networkradius.com/releases/ubuntu-xenial xenial
main" >> /etc/apt/sources.list
apt-get update
sudo apt-key adv --keyserver keys.gnupg.net --recv-key 0x41382202
sudo apt-get update
apt-get -y install freeradius freeradius-mysql freeradius-utils
1 2 3 4 5 6 | echo "deb http://packages.networkradius.com/releases/ubuntu-xenial xenial main" >> /etc/apt/sources.list apt-get update sudo apt-key adv --keyserver keys.gnupg.net --recv-key 0x41382202 sudo apt-get update apt-get -y install freeradius freeradius-mysql freeradius-utils |
Adding DICTIONARY in Freeradius (vBNG)
To add additional/3rd party dictionaries in freeradius, first copy the dictionary file in /usr/share/freeradius folder.
then edit the file DICTIONARY file in /usr/share/freeradius/dictionary
1 nano /usr/share/freeradius/dictionary
& add the dictionary file location in the end of this file
Example File:
123 ZAIB #### 15-FEB-2021
#### Add VBNG NETELASTIC support in Freeradius as well
$INCLUDE dictionary.netelastic-2019q3
& reload the freeradius service
123 service freeradius reload
OR
service freeradius restart
To add additional/3rd party dictionaries in freeradius, first copy the dictionary file in /usr/share/freeradius folder.
then edit the file DICTIONARY file in /usr/share/freeradius/dictionary
1 | nano /usr/share/freeradius/dictionary |
& add the dictionary file location in the end of this file
Example File:
1 2 3 | ZAIB #### 15-FEB-2021 #### Add VBNG NETELASTIC support in Freeradius as well $INCLUDE dictionary.netelastic-2019q3 |
& reload the freeradius service
1 2 3 | service freeradius reload OR service freeradius restart |