Description:
This document describes the creation of a freeradius server with mysql back-end to be used for dot1x authentication from a Cisco WLC serving guest wireless access for a series of Cisco Aironets. We will walk through compilation of the latest stable opennsl (1.1.1a) and freeradius 3.0.17, test authentication and then configure a mysql back-end radius clients, authentication and accounting.
Compile and Install OpenSSL
- unpack openssl 1.1.1a source code in /tmp
- Create a directory for openssl and all it’s pieces to live:
ln -s /apps/openssl-1.1.1a /apps/openssl
- Go to the source directory for openssl and run their configure script
root@Wireless-Svr:/tmp/openssl-1.1.1a# ./config –prefix=/apps/openssl-1.1.1a
Operating system: x86_64-whatever-linux2
Configuring OpenSSL version 1.1.1a (0x1010101fL) for linux-x86_64
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile
**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm –dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** ‘Troubleshooting’ section in the INSTALL file first) ***
*** ***
**********************************************************************
- Compile (will take some minutes and quite a bit of gcc output will go to your terminal)
make install
- Now check /apps/openssl-1.1.1a and make sure you see proper include and binary directories
bin include lib share ssl
root@Wireless-Svr:/tmp/openssl-1.1.1a# ls /apps/openssl/lib/
engines-1.1 libcrypto.a libcrypto.so libcrypto.so.1.1 libssl.a libssl.so libssl.so.1.1 pkgconfig
root@Wireless-Svr:/tmp/openssl-1.1.1a# ls /apps/openssl/bin
root@Wireless-Svr:/tmp/openssl-1.1.1a# /apps/openssl/bin/openssl
OpenSSL>
- Now for ease of library searching create /etc/ld.so.conf.d/openssl-1.1.1a.conf with the following contents
- Again for ease of library searching, create /etc/profile.d/LIB_PATHS.sh with the following contents
- Finally, add openssl to the search path by creating /etc/profile.d/PATHS.sh with the following contents
- Reboot and log back into the system. We are now ready to begin the radius server install.
Compiling Freeradius-3.0.17
- Unpack freeradius-3.0.17 code in /tmp and create a nice directory for it to live:
ln -s /apps/freeradius-3.0.17 /apps/freeradius
- Enter the source directory and run configure like so:
- Once completed compile and install the binaries
make install
- Check to make sure freeradius installed properly
bin etc include lib sbin share var
- Edit /etc/profile.d/PATHS.sh and append the sbin and bin directories for freeradius, should look like so:
- Log out and back in. At this point can move onto configuration of the radius server.
FreeRadius 3.0.17 Configuration
- Before setting up the mysql back-end and all that fanciness, we test simple file authentication. First link the configuration to /etc/ for ease of use:
- Now edit /etc/freeradius/radiusd.conf and allow vulnerable SSL
allow_vulnerable_openssl = yes
}
- Now edit /etc/freeradius/etc/raddb/clients.conf and add the following entry for the WLC:
ipaddr = $ip
secret = $secret
shortname = $actual_hostname
}
- Now edit /etc/freeradius/etc/raddb/clients.conf and add the following entry for the WLC:
$username Cleartext-Password := $password
(Cisco Controller) >test aaa radius username $username password $password wlan-id 3Radius Test Request
Wlan-id…………………………………. 3
ApGroup Name…………………………….. none
Attributes Values
——-— ——
User-Name $username
Called-Station-Id 00-00-00-00-00-00:SGR_Guest
Calling-Station-Id 00-11-22-33-44-55
Nas-Port 0x00000005 (5)
Nas-Ip-Address $Cisco_WLC_IP
NAS-Identifier $WLC_Hostname
Airespace / WLAN-Identifier 0x00000003 (3)
User-Password $password
Service-Type 0x00000008 (8)
Framed-MTU 0x00000514 (1300)
Nas-Port-Type 0x00000013 (19)
Tunnel-Type 0x0000000d (13)
Tunnel-Medium-Type 0x00000006 (6)
Tunnel-Group-Id 0x00000ce3 (3299)
Cisco / Audit-Session-Id 0ac80119000003a35c3de9cc
Acct-Session-Id 5c3de9cc/00:11:22:33:44:55/959
test radius auth request successfully sent. Execute ‘test aaa show radius’ for response
root@Wireless-Svr:~# radiusd -X
…
port = 18120
}
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 auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on proxy address * port 56365
Listening on proxy address :: port 40764
Ready to process requests
- Login to the WLC and configure it for radius authentication on the guest wireless vlan(3). Configuration is pretty standard, for reference I suggest the first half of this article.
- Now, ssh to the WLC and run the following radius test command
(Cisco Controller) >test aaa radius username $username password $password wlan-id 3
Radius Test Request
Wlan-id…………………………………. 3
ApGroup Name…………………………….. none
Attributes Values
——-— ——
User-Name $username
Called-Station-Id 00-00-00-00-00-00:SGR_Guest
Calling-Station-Id 00-11-22-33-44-55
Nas-Port 0x00000005 (5)
Nas-Ip-Address $Cisco_WLC_IP
NAS-Identifier $WLC_Hostname
Airespace / WLAN-Identifier 0x00000003 (3)
User-Password $password
Service-Type 0x00000008 (8)
Framed-MTU 0x00000514 (1300)
Nas-Port-Type 0x00000013 (19)
Tunnel-Type 0x0000000d (13)
Tunnel-Medium-Type 0x00000006 (6)
Tunnel-Group-Id 0x00000ce3 (3299)
Cisco / Audit-Session-Id 0ac80119000003a35c3de9cc
Acct-Session-Id 5c3de9cc/00:11:22:33:44:55/959
test radius auth request successfully sent. Execute ‘test aaa show radius’ for response
- Now from your radius debugger you should see the following
(0) Received Access-Request Id 7 from $Cisco_WLC_IP:46462 to $FreeRadius_ServerIP:1812 length 253
(0) User-Name = “$username”
(0) Called-Station-Id = “00-00-00-00-00-00:SGR_Guest”
(0) Calling-Station-Id = “00-11-22-33-44-55”
(0) NAS-Port = 5
(0) NAS-IP-Address = $Cisco_WLC_IP
(0) NAS-Identifier = “$WLC_Hostname”
(0) Airespace-Wlan-Id = 3
(0) User-Password = “$password”
(0) Service-Type = Authenticate-Only
(0) Framed-MTU = 1300
(0) NAS-Port-Type = Wireless-802.11
(0) Tunnel-Type:0 = VLAN
(0) Tunnel-Medium-Type:0 = IEEE-802
(0) Tunnel-Private-Group-Id:0 = “3299”
(0) Cisco-AVPair = “audit-session-id=0ac80119000003a35c3de9cc”
(0) Acct-Session-Id = “5c3de9cc/00:11:22:33:44:55/959”
(0) # Executing section authorize from file /apps/freeradius-3.0.17/etc/raddb/sites-enabled/default
(0) authorize {
(0) policy filter_username {
(0) if (&User-Name) {
(0) if (&User-Name) -> TRUE
(0) if (&User-Name) {
(0) if (&User-Name =~ / /) {
(0) if (&User-Name =~ / /) -> FALSE
(0) if (&User-Name =~ /@[^@]*@/ ) {
(0) if (&User-Name =~ /@[^@]*@/ ) -> FALSE
(0) if (&User-Name =~ /\.\./ ) {
(0) if (&User-Name =~ /\.\./ ) -> FALSE
(0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) {
(0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) -> FALSE
(0) if (&User-Name =~ /\.$/) {
(0) if (&User-Name =~ /\.$/) -> FALSE
(0) if (&User-Name =~ /@\./) {
(0) if (&User-Name =~ /@\./) -> FALSE
(0) } # if (&User-Name) = notfound
(0) } # policy filter_username = notfound
(0) [preprocess] = ok
(0) [chap] = noop
(0) [mschap] = noop
(0) [digest] = noop
(0) suffix: Checking for suffix after “@”
(0) suffix: No ‘@’ in User-Name = “$username”, looking up realm NULL
(0) suffix: No such realm “NULL”
(0) [suffix] = noop
(0) eap: No EAP-Message, not doing EAP
(0) [eap] = noop
(0) files: users: Matched entry $username at line 221
(0) [files] = ok
(0) [expiration] = noop
(0) [logintime] = noop
(0) [pap] = updated
(0) } # authorize = updated
(0) Found Auth-Type = PAP
(0) # Executing group from file /apps/freeradius-3.0.17/etc/raddb/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 post-auth from file /apps/freeradius-3.0.17/etc/raddb/sites-enabled/default
(0) post-auth {
(0) update {
(0) No attributes updated
(0) } # update = noop
(0) [exec] = noop
(0) policy remove_reply_message_if_eap {
(0) if (&reply:EAP-Message && &reply:Reply-Message) {
(0) if (&reply:EAP-Message && &reply:Reply-Message) -> FALSE
(0) else {
(0) [noop] = noop
(0) } # else = noop
(0) } # policy remove_reply_message_if_eap = noop
(0) } # post-auth = noop
(0) Sent Access-Accept Id 7 from $FreeRadius_ServerIP:1812 to $Cisco_WLC_IP:46462 length 0
(0) Finished request
Waking up in 4.9 seconds.
(0) Cleaning up request packet ID 7 with timestamp +0
Ready to process requests
- Now from the WLC if you show the results you should see a success like the following
(Cisco Controller) >test aaa show radius
Radius Test Request
Wlan-id…………………………………. 3
ApGroup Name…………………………….. none
Radius Test Response
Radius Server Retry Status
———-— –— ——
$FreeRadius_ServerIP 6 Success
Authentication Response:
Result Code: Success
No AVPs in Response
- OK, now let’s take a packet-capture view of the request. I capture both ends by running the following tcpdump and going through the same test from the WLC with radiusd -X still running:
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:28:43.411368 IP (tos 0x0, ttl 64, id 39566, offset 0, flags [none], proto UDP (17), length 281)
$Cisco_WLC_IP.46462 > Wireless-Svr.local.radius: [udp sum ok] RADIUS, length: 253
Access Request (1), id: 0x09, Authenticator: 14bed22da4bdc6c0475f59b8ff007627
Username Attribute (1), length: 10, Value: $username
0x0000: 7065 6961 646d 696e
Called Station Attribute (30), length: 29, Value: 00-00-00-00-00-00:SGR_Guest
0x0000: 3030 2d30 302d 3030 2d30 302d 3030 2d30
0x0010: 303a 5347 525f 4775 6573 74
Calling Station Attribute (31), length: 19, Value: 00-11-22-33-44-55
0x0000: 3030 2d31 312d 3232 2d33 332d 3434 2d35
0x0010: 35
NAS Port Attribute (5), length: 6, Value: 5
0x0000: 0000 0005
NAS IP Address Attribute (4), length: 6, Value: $Cisco_WLC_IP
0x0000: 0ac8 0119
NAS ID Attribute (32), length: 16, Value: $WLC_Hostname
0x0000: 5363 6865 696e 6572 2d57 4c43 3031
Vendor Specific Attribute (26), length: 12, Value: Vendor: Unknown (14179)
Vendor Attribute: 1, Length: 4, Value: ….
0x0000: 0000 3763 0106 0000 0003
Password Attribute (2), length: 18, Value:
0x0000: db47 c907 0ce1 a532 3c49 0cfa 0b6c 096f
Service Type Attribute (6), length: 6, Value: Authenticate Only
0x0000: 0000 0008
Framed MTU Attribute (12), length: 6, Value: 1300
0x0000: 0000 0514
NAS Port Type Attribute (61), length: 6, Value: Wireless – IEEE 802.11
0x0000: 0000 0013
Tunnel Type Attribute (64), length: 6, Value: Tag[Unused]#13
0x0000: 0000 000d
Tunnel Medium Attribute (65), length: 6, Value: Tag[Unused]802
0x0000: 0000 0006
Tunnel Private Group Attribute (81), length: 6, Value: 3299
0x0000: 3332 3939
Vendor Specific Attribute (26), length: 49, Value: Vendor: Cisco (9)
Vendor Attribute: 1, Length: 41, Value: audit-session-id=0ac80119000003a55c3deb00
0x0000: 0000 0009 012b 6175 6469 742d 7365 7373
0x0010: 696f 6e2d 6964 3d30 6163 3830 3131 3930
0x0020: 3030 3030 3361 3535 6333 6465 6230 30
Accounting Session ID Attribute (44), length: 32, Value: 5c3deb00/00:11:22:33:44:55/961
0x0000: 3563 3364 6562 3030 2f30 303a 3131 3a32
0x0010: 323a 3333 3a34 343a 3535 2f39 3631
13:28:43.411794 IP (tos 0x0, ttl 64, id 41678, offset 0, flags [none], proto UDP (17), length 48)
Wireless-Svr.local.radius > $Cisco_WLC_IP.46462: [bad udp cksum 0x17eb -> 0x2d6f!] RADIUS, length: 20
Access Accept (2), id: 0x09, Authenticator: d46aef4399099a7bfd5410bfb14a4547
Configuration:
- First enable the mysql module for freeradius
- Now, assuming mysql is started, login via root and create the radius database
root@Wireless-Svr:~# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3033
Server version: 5.5.50-0ubuntu0.14.04.1 (Ubuntu)Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> create database radius;
Query OK, 1 row affected (0.00 sec)
mysql> quit
Bye
- Now apply the mysql schema to the database
Enter password:
root@Wireless-Svr:~#
- Now edit /etc/freeradius/sites-enabled/default and remove the ‘-‘ from sql or uncomment as necessary in the following sections just like so:
…
sql
…
}
accounting {
…
sql
…
}
session {
…
sql
…
}
post-auth {
…
sql
…
}
Post-Auth-Type REJECT {
sql
}
- Now login to mysql and create a user for the radius database
mysql> GRANT ALL PRIVILEGES ON radius.* TO ‘radius’@’localhost’ IDENTIFIED by ‘$password’;
Query OK, 0 rows affected (0.00 sec)mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
- Test the user
root@Wireless-Svr:~# mysql -u radius -p radius
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -AWelcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3037
Server version: 5.5.50-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> show tables;
+——————+
| Tables_in_radius |
+——————+
| nas |
| radacct |
| radcheck |
| radgroupcheck |
| radgroupreply |
| radpostauth |
| radreply |
| radusergroup |
+——————+
8 rows in set (0.00 sec)
- Now edit /apps/freeradius-3.0.17/etc/raddb/mods-available/sql /apps/freeradius-3.0.17/etc/raddb/mods-enabled/sql, change or edit options to look like the following
dialect = “mysql”
server = “localhost”
port = 3306
login = “radius”
password = “$password”
read_clients = yes
- Now run the radiusd -X and look for the following to ensure that everything is connecting properly
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql_mysql: Connected to database ‘radius’ on Localhost via UNIX socket, server version 5.5.50-0ubuntu0.14.04.1, protocol version 10
rlm_sql (sql): Opening additional connection (1), 1 of 31 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.5.50-0ubuntu0.14.04.1, protocol version 10
rlm_sql (sql): Opening additional connection (2), 1 of 30 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.5.50-0ubuntu0.14.04.1, protocol version 10
rlm_sql (sql): Opening additional connection (3), 1 of 29 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.5.50-0ubuntu0.14.04.1, protocol version 10
rlm_sql (sql): Opening additional connection (4), 1 of 28 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.5.50-0ubuntu0.14.04.1, protocol version 10
- Now, add the same entry to the ‘nas’ table in mysql that we added to the clients.conf
Query OK, 1 row affected (0.01 sec)
mysql>
- Edit /etc/freeradius/clients.conf and comment out your nas entry like so
# ipaddr = $Cisco_WLC_IP
# secret = $password
# shortname = $WLC_Hostname
#}
- Now run radiusd -X and test authentication from the WLC.
- Assuming that went well, go ahead and create a user in the mysql database
mysql> INSERT INTO radcheck (username, attribute, op, value) VALUES (‘$username’, ‘Cleartext-Password’, ‘:=’, ‘$password’);
Query OK, 1 row affected (0.00 sec)
mysql>
- Comment out the entry you created in /etc/freeradius/users
- Startup radiusd -X and re-test authentication.
- Assuming that all worked, time to verify accounting is working properly. Go ahead and login to the AP you setup for authentication with the credentials just created and then check the radacct mysql table for an entry
*************************** 1. row ***************************
radacctid: 1
acctsessionid: 5c3e0bad/e0:9d:31:e9:ea:94/974
acctuniqueid: dbad7aaaa3f7800ca714047fb43c51b4
username: $username
realm:
nasipaddress: $Cisco_WLC_IP
nasportid: 5
nasporttype: Wireless-802.11
acctstarttime: 2019-01-15 11:36:14
acctupdatetime: 2019-01-15 11:36:14
acctstoptime: NULL
acctinterval: NULL
acctsessiontime: 0
acctauthentic: RADIUS
connectinfo_start:
connectinfo_stop:
acctinputoctets: 0
acctoutputoctets: 0
calledstationid: cc-70-ed-14-e3-b0
callingstationid: e0-9d-31-e9-ea-94
acctterminatecause:
servicetype:
framedprotocol:
framedipaddress: $Authenticated_ClientIP
1 row in set (0.00 sec)
- Cool, now check the postauth table for entries (failed and good)
+-—+——————————-—+——-—+—————+———————+
| id | username | pass | reply | authdate |
+-—+——————————-—+——-—+—————+———————+
| 1 | $username | $password | Access-Accept | 2019-01-15 15:15:39 |
| 2 | $username | $password | Access-Accept | 2019-01-15 15:27:06 |
| 3 | $username | $password | Access-Accept | 2019-01-15 15:36:16 |
| 4 | $username | $password | Access-Accept | 2019-01-15 15:43:15 |
| 5 | $username | $password | Access-Accept | 2019-01-15 15:43:39 |
| 6 | host/mfuller-lt7490.corp.pei.com | | Access-Reject | 2019-01-15 15:48:49 |
| 7 | host/mfuller-lt7490.corp.pei.com | | Access-Reject | 2019-01-15 15:48:49 |
| 8 | $username | | Access-Accept | 2019-01-15 15:49:29 |
| 9 | $username | | Access-Accept | 2019-01-15 15:49:29 |
+-—+——————————-—+——-—+—————+———————+
9 rows in set (0.00 sec)mysql>
- Now wait about 10 minutes for an accounting update to go through and verify that inOctets and outOctets is updated
*************************** 1. row ***************************
radacctid: 1
acctsessionid: 5c3e0bad/e0:9d:31:e9:ea:94/974
acctuniqueid: dbad7aaaa3f7800ca714047fb43c51b4
username: $username
realm:
nasipaddress: $Cisco_WLC_IP
nasportid: 5
nasporttype: Wireless-802.11
acctstarttime: 2019-01-15 11:36:14
acctupdatetime: 2019-01-15 11:36:14
acctstoptime: 2019-01-15 11:45:31
acctinterval: NULL
acctsessiontime: 556
acctauthentic: RADIUS
connectinfo_start:
connectinfo_stop:
acctinputoctets: 48819
acctoutputoctets: 22468
calledstationid: cc-70-ed-14-e3-b0
callingstationid: e0-9d-31-e9-ea-94
acctterminatecause: Idle-Timeout
servicetype:
framedprotocol:
framedipaddress: $Authenticated_ClientIP
1 row in set (0.00 sec)
- YAY, all worky. Can even see the IP the client grabbed from our switch’s DHCP server.
mfuller, PEI