Sample config of FreeRadius as a Mobile authentication

This article shows you a sample configuration of FreeRadius as a mobile authentication to assign static IP address to the clients. In previous post, we have installed and configured FreeRadius on various operating systems such as Linux (CentOS, Ubuntu), FreeBSD, and OpenBSD. The Radius is ready to process requests.

This sample setup is based-on my project on a company which is serving hundred of customers around the country (Indonesia) using Telkomsel as the mobile operator. The customers are using a USB modem with a SIM card to connect to intranet.

By default the clients are assigned with dynamic IP pool by mobile operators. Since we need the clients to be assigned with a static IP address, we need to build a RADIUS server which will reply to radius request from mobile operator to assign the static IP address. This article shows you a sample configuration of FreeRadius as a mobile authentication to assign static IP address to the clients.

For this sample configuration we will use the following setup / configuration:
a. MSISDN (Mobile Station International Subscriber Directory Number) or mobile phone number is +628111234567 (Telkomsel, Indonesia). Change this value with your MSISDNs.
b. APN_NAME as the APN intranet name. Change it with your APN assigned by the mobile operator.
c. Username will use MSISDN@APN_NAME format so in this example is using 628111234567@APN_NAME as the username.
d. The password will use ‘password’. This is the default password as far as we know. Ask your mobile operator to make sure for this password.
e. Clients will be assigned with a static IP address. So clients can be easily monitor using ping tool.

I assume that you have configured FreeRadius correctly and it is ready to process request. If not then follow my previous post to install and configure FreeRadius with MySQL / MariaDB database.

We will not store NAS servers of mobile operator on database, instead we will write it appended on clients.conf. To allow NAS servers to request to our FreeRadius server, add the following lines in the bottom of $freeradius_config/clients.conf file.

client	10.123.45.176/28 {
	secret = mysecret
	shortname = nas-servers # NAS servers of mobile operator
}

Populating database

Using PhpMyAdmin or sql command, insert a new field in radcheck and radreply table like below! Follow the FreeRadius wiki on populating database http://wiki.freeradius.org/guide/SQL-HOWTO

mysql> select * from radcheck;
+----+--------------------------+--------------------+----+----------+
| id | username                 | attribute          | op | value    |
+----+--------------------------+--------------------+----+----------+
|  1 | 628111234567@APN_NAME    | Cleartext-Password | := | password |
+----+--------------------------+--------------------+----+----------+
1 rows in set (0.00 sec)

mysql> select * from radreply;
+----+--------------------------+-------------------+----+------------+
| id | username                 | attribute         | op | value      |
+----+--------------------------+-------------------+----+------------+
|  1 | 628111234567@APN_NAME    | Framed-IP-Address | := | 10.128.0.10|
+----+--------------------------+-------------------+----+------------+
1 rows in set (0.00 sec)

Run freeradius in debug mode using ‘freeradius -X‘ command, and monitor the debugging. On the client side, using ‘APN_NAME’ try to connect using dialer modem. I got the following log on debugging mode:

rad_recv: Access-Request packet from host 10.123.45.178 port 61053, id=152, length=252
	User-Name = "628111234567@APN_NAME"
	User-Password = "password"
	NAS-IP-Address = 10.123.45.178
	NAS-Identifier = "GGTBS1"
	Called-Station-Id = "APN_NAME"
	Framed-Protocol = GPRS-PDP-Context
	Service-Type = Framed-User
	NAS-Port-Type = Virtual
	Calling-Station-Id = "628111234567"
	Acct-Session-Id = "XXXXXXXXXXXXXXX"
	3GPP-IMSI = "XXXXXXXXXXXXXXX"
	3GPP-PDP-Type = 0
	3GPP-SGSN-Address = 12.34.56.78
	3GPP-GGSN-Address = 87.65.43.21
	3GPP-NSAPI = "5"
	3GPP-Selection-Mode = "0"
	3GPP-Charging-Characteristics = "0000"
	3GPP-SGSN-MCC-MNC = "51010"
	3GPP-Attr-27 = 0x00
server 10.123.45.178 {
No such virtual server "10.123.45.178"
Invalid user: [628111234567@APN_NAME/password] (from client nas-servers port 0 cli 628111234567)
} # server 10.123.45.178
Using Post-Auth-Type Reject
No such virtual server "10.123.45.178"
Delaying reject of request 0 for 1 seconds
Going to the next request
Waking up in 0.9 seconds.
Sending delayed reject for request 0
Sending Access-Reject of id 152 to 10.123.45.178 port 61053
Waking up in 4.9 seconds.
Cleaning up request 0 ID 152 with timestamp +229
Ready to process requests.

As you can see above, there is a message said that ‘No such virtual server “10.123.45.178”‘ and client is failed to login.

Lets create a virtual server in the clients.conf file. Add ‘virtual_server’ name in the client directive.

client	10.123.45.176/28 {
	secret = mysecret
	shortname = nas-servers	
	virtual_server = a_virtual_name
}

Then add and configure the virtual server under $freeradius_config/site-available/ directory or you can also configure it directly inside clients.conf file as below:

server a_virtual_name {
	authorize {
		preprocess
		auth_log
		chap
		mschap
		digest
		suffix
		eap {
				ok = return
		}
		files
		sql
		expiration
		logintime
		pap
	}

	authenticate {
		Auth-Type PAP {
				pap
		}
		Auth-Type CHAP {
				chap
		}
		Auth-Type MS-CHAP {
				mschap
		}
		digest
		unix
		eap
	}

	session {
		radutmp
		sql
	}

	post-auth {
		sql
		exec
	}

}

Re-run the radius in debug mode and try to re-connect the dialer modem. You should see something like below with successful Login: OK.

rad_recv: Access-Request packet from host 10.123.45.182 port 62147, id=65, length=252
       User-Name = "628111234567@APN_NAME"
       User-Password = "password"
       NAS-IP-Address = 10.123.45.182
       NAS-Identifier = "GGTBS1"
       Called-Station-Id = "APN_NAME"
       Framed-Protocol = GPRS-PDP-Context
       Service-Type = Framed-User
       NAS-Port-Type = Virtual
       Calling-Station-Id = "628111234567"
       Acct-Session-Id = "XXXXXXXXXXXXXXX"
       3GPP-IMSI = "XXXXXXXXXXXXXXX"
       3GPP-PDP-Type = 0
       3GPP-SGSN-Address = 12.34.56.78
       3GPP-GGSN-Address = 87.65.43.21
       3GPP-NSAPI = "5"
       3GPP-Selection-Mode = "0"
       3GPP-Charging-Characteristics = "0000"
       3GPP-SGSN-MCC-MNC = "51010"
       3GPP-Attr-27 = 0x00
server a_virtual_name {
# Executing section authorize from file /etc/freeradius/clients.conf
+- entering group authorize {...}
++[preprocess] returns ok
[auth_log]      expand: /var/log/freeradius/radacct/%{Client-IP-Address}/auth-detail-%Y%m%d -> /var/log/freeradius/radacct/10.123.45.182/auth-detail-20150409
[auth_log] /var/log/freeradius/radacct/%{Client-IP-Address}/auth-detail-%Y%m%d expands to /var/log/freeradius/radacct/10.123.45.182/auth-detail-20150409
[auth_log]      expand: %t -> Thu Apr  9 09:09:37 2015
++[auth_log] returns ok
++[chap] returns noop
++[mschap] returns noop
++[digest] returns noop
[suffix] Looking up realm "APN_NAME" for User-Name = "628111234567@APN_NAME"
[suffix] No such realm "APN_NAME"
++[suffix] returns noop
[eap] No EAP-Message, not doing EAP
++[eap] returns noop
++[files] returns noop
[sql]   expand: %{User-Name} -> 628111234567@APN_NAME
[sql] sql_set_user escaped user --> '628111234567@APN_NAME'
rlm_sql (sql): Reserving sql socket id: 4
[sql]   expand: SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = '%{SQL-User-Name}'    ORDER BY id -> SELECT id, username, attribute, value, op           FROM radcheck           WHERE username = '628111234567@APN_NAME'           ORDER BY id
[sql] User found in radcheck table
[sql]   expand: SELECT id, username, attribute, value, op           FROM radreply           WHERE username = '%{SQL-User-Name}'      ORDER BY id -> SELECT id, username, attribute, value, op           FROM radreply           WHERE username = '628111234567@APN_NAME'           ORDER BY id
[sql]   expand: SELECT groupname           FROM radusergroup           WHERE username = '%{SQL-User-Name}'           ORDER BY priority -> SELECT groupname           FROM radusergroup           WHERE username = '628111234567@APN_NAME'           ORDER BY priority
rlm_sql (sql): Released sql socket id: 4
++[sql] returns ok
++[expiration] returns noop
++[logintime] returns noop
++[pap] returns updated
Found Auth-Type = PAP
# Executing group from file /etc/freeradius/clients.conf
+- entering group PAP {...}
[pap] login attempt with password "password"
[pap] Using clear text password "password"
[pap] User authenticated successfully
++[pap] returns ok
Login OK: [628111234567@APN_NAME/password] (from client nas-servers port 0 cli 628111234567)
# Executing section post-auth from file /etc/freeradius/clients.conf
+- entering group post-auth {...}
[reply_log]     expand: /var/log/freeradius/radacct/%{Client-IP-Address}/reply-detail-%Y%m%d -> /var/log/freeradius/radacct/10.123.45.182/reply-detail-20150409
[reply_log] /var/log/freeradius/radacct/%{Client-IP-Address}/reply-detail-%Y%m%d expands to /var/log/freeradius/radacct/10.123.45.182/reply-detail-20150409
[reply_log]     expand: %t -> Thu Apr  9 09:09:37 2015
++[reply_log] returns ok
[sql]   expand: %{User-Name} -> 628111234567@APN_NAME
[sql] sql_set_user escaped user --> '628111234567@APN_NAME'
[sql]   expand: %{User-Password} -> password
[sql]   expand: INSERT INTO radpostauth                           (username, pass, reply, authdate)                           VALUES (                      '%{User-Name}',                           '%{%{User-Password}:-%{Chap-Password}}',                           '%{reply:Packet-Type}', '%S') -> INSERT INTO radpostauth                          (username, pass, reply, authdate)                           VALUES (                           '628111234567@APN_NAME',                          'password',                           'Access-Accept', '2015-04-09 09:09:37')
rlm_sql (sql) in sql_postauth: query is INSERT INTO radpostauth                          (username, pass, reply, authdate)                          VALUES (                           '628111234567@APN_NAME',                          'password',                           'Access-Accept', '2015-04-09 09:09:37')
rlm_sql (sql): Reserving sql socket id: 3
rlm_sql (sql): Released sql socket id: 3
++[sql] returns ok
++[exec] returns noop
} # server perpusnas
Sending Access-Accept of id 65 to 10.123.45.182 port 62147
       Framed-IP-Address := 10.128.0.10 ---> Assigned IP statically using FreeRadius
Finished request 0.

The clients should be able to connect and get static IP address as assigned in Radius configuration above. Verify it using ‘ipconfig’ command in Windows prompt.

Troubleshoting

If you select PAP as the authentication method, you do not need to enter username and password in the modem dialer. You can simple leave them blank.
On the other hand, if you select CHAP, leave the username blank but you have to manually enter the ‘password’ in the password field of the modem dialer. Otherwise users will fail to authenticate using CHAP as shown on the log below:

[chap] login attempt by "628111234567@APN_NAME" with CHAP password
[chap] Using clear text password "password" for user 628111234567@APN_NAME authentication.
[chap] Password check failed
++[chap] returns reject
Failed to authenticate the user.
Login incorrect (rlm_chap: Wrong user password): [628111234567@APN_NAME/] (from client nas-servers port 0 cli 628111234567)

Hopefully this sample configuration of FreeRadius is helpful for everyone who uses it as a mobile authentication server.