Private APN with FreeRadius

posted on 2013-01-15

I've had the change to play around with setting up a private APN (like the APN on your mobile phone) with FreeRadius at my new job at ForeyeT. It took some time to get working, so here is the overview of what works.

What is a private APN

With a private APN you configure your phone or mobile device to request an Access Point Name specifically for a special bussiness. Although the Radius server at the mobile provider still gets the request, they forward the decision on to your Radius server. So in the end, you get to decide which mobile device connects to your mobile network. Having your own Radius server allows you to have more stupid mobile devices then hoping the mobile device will be able to set up a VPN connection correctly. Appart from that, I think the approaches can be considered much the same: taking control over who enteres your network and at what point you can monitor them.

Architecture overview

Configuring FreeRadius

FreeRadius is a free, open-source Radius server. What I gathered from Radius, it's a pretty simple protocol: clients can request, the server can accept or reject. Inside the requests and responses can be an arbitrary number of fields, each identified by a unique id which is registered in a dictionary.

FreeRadius is a fully featured Radius server, where you can pretty much send any kind of response you want and there are a lot of modules to allow different sources to get the message information (e.g. SQL, LDAP, etc.).

We start at the beginning, from a clean config we need to make sure the conenction between our radius server and the Radius server of the provider is working. Passwords are encrypted using a pre shared secret, so we need to configure that first.

In /etc/freeradius/clients.conf we add a section which matches the Radius server IP of the mobile provider to set the shared secret:

client {
    secret = AVbL17edZdpsDf
    nastype = other

If you now run freeradius -X you should be able to see plain text passwords float by with every request. A request should look like this:

rad_recv: Access-Request packet from host port 10010, id=107, length=116
    User-Name = "31635307788"
    User-Password = "password"
    NAS-Port-Type = Virtual
    Calling-Station-Id = "31635307788"
    Called-Station-Id = ""
    Event-Timestamp = "Jan 15 2013 23:01:33 CET"
    Service-Type = Framed-User
    Framed-Protocol = GPRS-PDP-Context
    NAS-IP-Address =
    Acct-Multi-Session-Id = "097ce631"

Using the simple PAP module, you can register users in a flat text file. Open /etc/freeradius/users and add a section like so:

31635307788	Cleartext-Password := "password"
    Framed-IP-Address =,
    Framed-IP-Netmask =,
    MS-Primary-DNS-Server =,
    MS-Secondary-DNS-Server =

The first part entry is the User-Name we get in the request. Because of this section, our freeradius will start answering with an Accept response:

Sending Access-Accept of id 107 to port 10010
    Framed-IP-Address =
    Framed-IP-Netmask =
    MS-Primary-DNS-Server =
    MS-Secondary-DNS-Server =

This means the mobile device will configure itself as and the provider should then make sure the device is routed onto your VPN connection. Remember, you are talking to the mobile providers Radius server, not the mobile device directly.

Hope this clears everything up. It took me a while to find out what reponse to send for the GPRS-PDP-Context with the best hint coming from this tuxlanding post.

Happy hacking setting up your own private APN with FreeRadius!