This page describes how CoovaChilli can be used as a proxy for WPA authentication with the following twist:
There are many ways to implement what is described here. For this example, however, we are using CoovaAP combined with FreeRADIUS and JRadius. You will also find this feature in the CoovaAAA services.
To 'enable' this feature within chilli itself, an option was defined. By setting the configuration flag wpaguests (in combination with the proxylisten, proxyport, and proxysecret settings) chilli will do a couple things:
If the reply is an Access-Reject, then, of course, that is sent on by proxy and WPA is not granted.
Actual authentication of the WPA RADIUS is handled by FreeRADIUS. It must be configured for EAP, TLS, and PEAP. Additionally, this example uses the JRadius module to easily code our "GuestWPA" RADIUS logic.
For basics on FreeRADIUS and EAP authentication, see:
For information on installing and using JRadius with FreeRADIUS, see:
For this example, the following JRadius handler is defined (abbreviated for readability):
public class WPACaptivePortal extends PacketHandlerBase
{
public boolean handle(JRadiusRequest request)
{
try
{
/*
* Gather some information about the JRadius request
*/
AttributeList ci = request.getConfigItems();
RadiusPacket req = request.getRequestPacket();
RadiusPacket rep = request.getReplyPacket();
/*
* Find the username in the request packet
*/
String username = (String)req.getAttributeValue(Attr_UserName.TYPE);
if (rep instanceof AccessAccept)
{
RadiusLog.info("Allowing WPA access for username: " + username);
}
else
{ // Is an Access-Reject
if ("allow-wpa-guests".
equals((String)req.getAttributeValue(Attr_ChilliSpotConfig.TYPE)))
{ // Allowing WPA "guest" access
if (req.findAttribute(Attr_EAPMessage.TYPE) != null)
{ // Is EAP (802.1x)
if (req.findAttribute(Attr_FreeRADIUSProxiedTo.TYPE) != null)
{ // Is the inner request, TLS termianted
rep = new AccessAccept();
rep.addAttribute(new Attr_ChilliSpotConfig("require-uam-auth"));
request.setReplyPacket(rep);
ci.add(new Attr_AuthType("Accept"));
request.setReturnValue(JRadiusServer.RLM_MODULE_UPDATED);
RadiusLog.error("Allowing Guest WPA access for username: " + username);
return true;
}
}
}
RadiusLog.info("Authentication failed for username: " + username);
}
}
catch (RadiusException e) { e.printStackTrace(); }
request.setReturnValue(JRadiusServer.RLM_MODULE_UPDATED);
return false;
}
}
This handler is to be ran in the post-auth section of FreeRADIUS, as defined in this JRadius config.xml snippit:
<chain name="post_auth">
<init-session name="post_auth-init-session"
description="Initialize The Radius Session"/>
<command className="org.coova.jradius.example.WPACaptivePortal" />
<class-post-auth name="post_auth-class"
description="Post-Auth Class Attribute Handler"/>
</chain>
And requires that FreeRADIUS is configured such that Access-Rejects are processed in the post-auth section too (by default, they are not):
# in radiusd.conf
post-auth {
jradius
Post-Auth-Type REJECT {
jradius
}
}
Putting it all together, with a (FreeRADIUS/JRadius) RADIUS server up and running, the setup is tested using a Linksys running the CoovaAP firmware (version beta.4 or better).
On the HotSpot / RADIUS configuration page in the firmware, you can select to allow/enable "WPA Guests".
It is important that chilli is started after everything else because it will actually rewrite some configurations (so that the nas program uses chillispot for RADIUS) and restarts other programs.
Some simple tests using Mac OS X as the client (PEAP).
Just using a FreeRADIUS raddb/users entry to define the user:
david User-Password == "testing"
WISPr-Redirection-URL = "http://coova.org/"
The user experience, at least on Mac OS X, is summarized by:
FreeRADIUS/JRadius log (highlights only):
Access-Request packet from host 192.168.100.200:2084, id=2, length=170
User-Name = "david"
EAP-Message = 0x020200061900
ChilliSpot-Config = "allow-wpa-guests"
Calling-Station-Id = "00-11-24-90-XX-XX"
Called-Station-Id = "00-06-25-C5-XX-XX"
NAS-Port-Type = Wireless-802.11
NAS-Port = 1
NAS-IP-Address = 192.168.100.200
NAS-Identifier = "00:06:25:c6:xx:xx"
.. EAP Access Challenge/Request and TLS Termination ..
Sending Access-Accept of id 8 to 192.168.100.200 port 2084
User-Name = "david"
MS-MPPE-Recv-Key = 0x239ae8a15596cc224f6990e0713e3524dcac4cc22de68226d2de01fee7b4e77f
MS-MPPE-Send-Key = 0x938b61d3487a87a6e1a2442767cd6c10036384f6b368d23e553ab53caf13e742
EAP-Message = 0x03080004
This time, I did the following:
FreeRADIUS/JRadius log (highlights only):
Access-Request packet from host 192.168.100.200:2084, id=14, length=171
User-Name = "nobody"
EAP-Message = 0x020200061900
ChilliSpot-Config = "allow-wpa-guests"
Calling-Station-Id = "00-11-24-90-XX-XX"
Called-Station-Id = "00-06-25-C5-XX-XX"
NAS-Port-Type = Wireless-802.11
NAS-Port = 1
NAS-IP-Address = 192.168.100.200
NAS-Identifier = "00:06:25:c6:xx:xx"
.. EAP Access Challenge/Request and TLS Termination ..
Sending Access-Accept of id 19 to 192.168.100.200 port 2084
ChilliSpot-Config := "require-uam-auth"
MS-MPPE-Recv-Key = 0x317f2c50e739bd69d14be1d09ec111abe3f562886879b70eee16395637dc5eb5
MS-MPPE-Send-Key = 0xcbc74e30dce41c343b4afe0ea90b7a6413b659bba3a330bcd265da9df4e85ae7
EAP-Message = 0x03070004
User-Name = "nobody"