Mikrotik and FreeRadius for Wireless Authentication

FreeRadius is a Radius server responsible for what they call “Triple A” Authentication / Authorization / Accounting, it easily allows system administrators to manage services on a user by user basis.

Imagine the scenario where we have a customer, that hosts a wireless access point or hotspot. Rather than authenticating directly to the access point via WPA2/PSK encryption we can authenticate the user to the radius server to allow access to services such as wifi.

Using a Radius server also allows us greater secure our network using protocols such as.

EAP-TLS – Extensible Authentication Protocol – Transport Layer Security#

PEAP – Protected Extensible Authentication Protocol

This also means that in instance of where an employee leaves a company we can disable the account on the radius server, rather than changing the WPA2/PSK password, that will disconnect every client on the network. More information and use cases can be found at https://freeradius.org

In this example i am connecting a mikrotik routerboard to FreeRadius running on my Raspberry Pi.

First of all we need to create the relevant rules on the firewall.

Basic Installation and Configuration

Lets install FreeRadius

sudo apt install freeradius

Next up we create a user so we can test our FreeRadius server.

sudo nano etc/freeradius/3.0/users

At the beginning of the line insert the information for your test user, in the following syntax.

# Remove the "#" before the next line
freeradius Cleartext-Password := "123456789"

Next we need to restart the FreeRadius server to reload the changes we have just made.

sudo freeraduis restart
Or on first time start up i run with the below commands to view the log in information. 

sudo freeradius stop
sudo freeradius -X 

FreeRadius is running and ready to take Authentication Requests.

Open up a second terminal, so we can view the authentication request in the logs.

Next lets Authenticate our test user “freeradius” to do this we can use the radtest command as below.

radtest freeradius 123456789 127.0.0.1 10 123456789

If all is good we should see our test user “freeradius” log into our FreeRadius server.


Sent Access-Request Id 57 from 0.0.0.0:58551 to 127.0.0.1:1812 length 80
        User-Name = "freeradius"
        User-Password = "123456789"
        NAS-IP-Address = 127.0.1.1
        NAS-Port = 10
        Message-Authenticator = 0x00
        Cleartext-Password = "123456789"
Received Access-Accept Id 57 from 127.0.0.1:1812 to 127.0.0.1:58551 length 20

In our first terminal we should see the RADIUS request


(14) Login OK: [freeradius/123456789] (from client localhost port 10)
(14) Sent Access-Accept Id 167 from 127.0.0.1:1812 to 127.0.0.1:41233 length 0
(14) Finished request

FreeRadius is now ready to take authentication requests.

We can see that the Wifi connection we made earlier is visible as below.

Lets try and authenticate to the WiFI hotspot created hotspot.

As we have configured the access point wlan3 according to our firewall rules, clients are only allowed to connect via a RADIUS server, with the credentials that we earlier defined in etc/freeradius/3.0/users

Mikrotik Hotspot Login Page For FreeRadius Server Authentication.

Login is successful 802.1XEAP

A successful auth request will look like this.

 Login OK: [freeradius/<via Auth-Type = eap>] (from client mikrotik-router port 0 cli 98-09-CF-01-09-19)
(11) Sent Access-Accept Id 9 from 192.168.1.130:1812 to 192.168.1.1:55735 length 0
(11)   MS-MPPE-Recv-Key = 0x2baa774964da591e155a291f59b1cec01f969a9ae54d464505a1bcb852a00efb
(11)   MS-MPPE-Send-Key = 0x497e182c23848604df6175968b98872f8ea687f947224f80a3b4663f089cc8dd
(11)   EAP-Message = 0x03090004
(11)   Message-Authenticator = 0x00000000000000000000000000000000
(11)   User-Name = "freeradius"
(11) Finished request
Waking up in 4.7 seconds.
(12) Received Accounting-Request Id 10 from 192.168.1.1:35596 to 192.168.1.130:1813 length 48
(12)   Acct-Status-Type = Accounting-On
(12)   NAS-Identifier = "MikroTik"
(12)   Acct-Delay-Time = 0
(12)   NAS-IP-Address = 192.168.1.1
(12) # Executing section preacct from file /etc/freeradius/3.0/sites-enabled/default
(12)   preacct {
(12)     [preprocess] = ok
(12)     policy acct_unique {
(12)       update request {
(12)         &Tmp-String-9 := "ai:"
(12)       } # update request = noop
(12)       if (("%{hex:&Class}" =~ /^%{hex:&Tmp-String-9}/) &&      ("%{string:&Class}" =~ /^ai:([0-9a-f]{32})/i)) {
(12)       EXPAND %{hex:&Class}
(12)          -->
(12)       EXPAND ^%{hex:&Tmp-String-9}
(12)          --> ^61693a
(12)       if (("%{hex:&Class}" =~ /^%{hex:&Tmp-String-9}/) &&      ("%{string:&Class}" =~ /^ai:([0-9a-f]{32})/i))  -> FALSE
(12)       else {
(12)         update request {
(12)           EXPAND %{md5:%{User-Name},%{Acct-Session-ID},%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}},%{NAS-Identifier},%{NAS-Port-ID},%{NAS-Port}}
(12)              --> 90392519317af13544308c4c572a1d25
(12)           &Acct-Unique-Session-Id := 90392519317af13544308c4c572a1d25
(12)         } # update request = noop
(12)       } # else = noop
(12)     } # policy acct_unique = noop
(12)     [suffix] = noop
(12)     [files] = noop
(12)   } # preacct = ok
(12) # Executing section accounting from file /etc/freeradius/3.0/sites-enabled/default
(12)   accounting {
(12) detail: EXPAND /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d
(12) detail:    --> /var/log/freeradius/radacct/192.168.1.1/detail-20191125
(12) detail: /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d expands to /var/log/freeradius/radacct/192.168.1.1/detail-20191125
(12) detail: EXPAND %t
(12) detail:    --> Mon Nov 25 18:11:25 2019
(12)     [detail] = ok
(12)     [unix] = noop
(12)     [exec] = noop
(12) attr_filter.accounting_response: EXPAND %{User-Name}
(12) attr_filter.accounting_response:    -->
(12)     [attr_filter.accounting_response] = noop
(12)   } # accounting = ok
(12) Sent Accounting-Response Id 10 from 192.168.1.130:1813 to 192.168.1.1:35596 length 0
(12) Finished request
(12) Cleaning up request packet ID 10 with timestamp +106
Waking up in 4.7 seconds.
(13) Received Accounting-Request Id 11 from 192.168.1.1:47296 to 192.168.1.130:1813 length 210
(13)   Service-Type = Framed-User
(13)   NAS-Port-Id = "wlan3"
(13)   NAS-Port-Type = Wireless-802.11
(13)   User-Name = "freeradius"
(13)   Acct-Session-Id = "8200000f"
(13)   Acct-Multi-Session-Id = "BA-69-F4-15-3C-B2-98-09-CF-01-09-19-82-00-00-00-00-00-00-0F"
(13)   Calling-Station-Id = "98-09-CF-01-09-19"
(13)   Called-Station-Id = "BA-69-F4-15-3C-B2:Wild_freeradius"
(13)   Acct-Authentic = RADIUS
(13)   Acct-Status-Type = Start
(13)   NAS-Identifier = "MikroTik"
(13)   Acct-Delay-Time = 0
(13)   NAS-IP-Address = 192.168.1.1
(13) # Executing section preacct from file /etc/freeradius/3.0/sites-enabled/default
(13)   preacct {
(13)     [preprocess] = ok
(13)     policy acct_unique {
(13)       update request {
(13)         &Tmp-String-9 := "ai:"
(13)       } # update request = noop
(13)       if (("%{hex:&Class}" =~ /^%{hex:&Tmp-String-9}/) &&      ("%{string:&Class}" =~ /^ai:([0-9a-f]{32})/i)) {
(13)       EXPAND %{hex:&Class}
(13)          -->
(13)       EXPAND ^%{hex:&Tmp-String-9}
(13)          --> ^61693a
(13)       if (("%{hex:&Class}" =~ /^%{hex:&Tmp-String-9}/) &&      ("%{string:&Class}" =~ /^ai:([0-9a-f]{32})/i))  -> FALSE
(13)       else {
(13)         update request {
(13)           EXPAND %{md5:%{User-Name},%{Acct-Session-ID},%{%{NAS-IPv6-Address}:-%{NAS-IP-Address}},%{NAS-Identifier},%{NAS-Port-ID},%{NAS-Port}}
(13)              --> a574c8094e4a9eafa0c6fbb2b631619a
(13)           &Acct-Unique-Session-Id := a574c8094e4a9eafa0c6fbb2b631619a
(13)         } # update request = noop
(13)       } # else = noop
(13)     } # policy acct_unique = noop
(13) suffix: Checking for suffix after "@"
(13) suffix: No '@' in User-Name = "freeradius", looking up realm NULL
(13) suffix: No such realm "NULL"
(13)     [suffix] = noop
(13)     [files] = noop
(13)   } # preacct = ok
(13) # Executing section accounting from file /etc/freeradius/3.0/sites-enabled/default
(13)   accounting {
(13) detail: EXPAND /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d
(13) detail:    --> /var/log/freeradius/radacct/192.168.1.1/detail-20191125
(13) detail: /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d expands to /var/log/freeradius/radacct/192.168.1.1/detail-20191125
(13) detail: EXPAND %t
(13) detail:    --> Mon Nov 25 18:11:25 2019
(13)     [detail] = ok
(13)     [unix] = ok
(13)     [exec] = noop
(13) attr_filter.accounting_response: EXPAND %{User-Name}
(13) attr_filter.accounting_response:    --> freeradius
(13) attr_filter.accounting_response: Matched entry DEFAULT at line 12
(13)     [attr_filter.accounting_response] = updated
(13)   } # accounting = updated
(13) Sent Accounting-Response Id 11 from 192.168.1.130:1813 to 192.168.1.1:47296 length 0
(13) Finished request
(13) Cleaning up request packet ID 11 with timestamp +106

MORE INFO WILL BE ADDED SOON

About the Author

Leave a Reply

Your email address will not be published. Required fields are marked *