Wednesday, December 2, 2015

Using OpenAM 13's Radius Server

It has been a long and busy few months as we work to migrate from Oracle's OAM product to OpenAM. With OpenAM v13 just around the corner I've been asked to kick the tires of the new Radius Server that is included therein. So I've taken time to summarize my results here. If you are one of those readers that peeks at the last chapter before reading a book I'll save you that step: it works, and works nicely.

Getting It Installed

After downloading, I opened the nightly build zip and copied OpenAM-13.0.0-SNAPSHOT.war to my tomcat 8's webapps directory with name sso13.war. Then in a bash shell I created ~/sso13 and fired up tomcat running on Java 7. I used default configuration and it found and filled my ~/sso13 directory. Once configuration was complete I followed its provided link to the sign in page and signed in as amadmin.

Wow. The forgerock crew has been busy. What was previously the Access Control tab is now the Realms tab or rather the Realms page and that portion of the admin console is now moved to XUI. Looks great.

Turning It On

I select the Configuration link and get dumped back into the legacy JATO UI. Maybe by v14 it will be removed altogether. Here's hoping.

I select Global and then Radius Server. I enable the server on port 1813 since I have another instance of OpenAM running with the server on 1812. I then poke around in the ~/sso13/sso13 directory structure looking for log files indicating that Radius configuration was changed but didn't find anything.

So I went to the admin console's debug page at /sso13/Debug.jsp. Sure enough, in the Category drop down box at the top there is now a Radius option. I select it, set the level to Message, and press Submit. It asked me to confirm the change which I did.

Still didn't see any radius related log file. Decided to try generating some traffic.

Using Console Client

Back in May I outlined a tool for testing communication with any radius server. There was discussion of rolling console client into the ssoadmin tool. But time did not permit prior to v13's release. Is console client still available via an executable jar? When forgerock engineer Jamie Bowen rolled the Radius Server code into baseline, he split the code base into three distinct maven modules as manifest by the following jars in the WEB-INF/lib directory:

openam-auth-radius-13.0.0-SNAPSHOT.jar
openam-radius-common-13.0.0-SNAPSHOT.jar
openam-radius-server-13.0.0-SNAPSHOT.jar

The first holds the legacy radius authentication module. The second holds the radius protocol classes. And the third holds the radius server functionality. On a whim I attempted to execute the server jar and low and behold, console client revealed it was indeed still available. Nice! (Note: For anyone reading this using an version beyond v13.0.0 check the documentation to see if it has been moved to ssoadmin in your version.)

$ java -jar openam-radius-server-13.0.0-SNAPSHOT.jar
Missing required config file 'radius.properties' in current directory /Users/boydmr/tomcat8/apache-tomcat-8.0.9/webapps/sso13/WEB-INF/lib/.
Must Contain:
 secret=<shared-secret-with-server>
 host=<hostname-or-ip-address>
 port=<port-on-target-host>

So I created radius.properties with the following values. Don't tell anyone my password. :-)

secret=letmein
host=127.0.0.1
port=1813
show-traffic=true

Now I ran console client again with the following output and it hung as expected since I did not define a client in the Radius Server:

$ java -jar openam-radius-server-13.0.0-SNAPSHOT.jar
? Username: amadmin
? Password: password1

Packet To 127.0.0.1:1813
DebugConfiguration:12/02/2015 08:10:02:028 AM MST: Thread[main,5,main]
'/debugconfig.properties' isn't valid, the default configuration will be used instead: Can't find the configuration file '/debugconfig.properties'.
  ACCESS_REQUEST [1]
    - USER_NAME : amadmin
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : localhost/127.0.0.1
    - NAS_PORT : 0

Accessing Radius Logs

At this point I ran bash's find while sitting in ~/sso13/sso13 and found the file that I was looking for:

./debug/Radius

When I cat that file I found what I was looking for. You can see the dropped packet warning indicating a client with that IP address was not defined.

$ cat ./debug/Radius
amRadiusServer:12/02/2015 08:10:02:054 AM MST: Thread[RADIUS-1813-Listener,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-154]
RadiusServerEventRegistrar.packetReceived() called by EventBus
amRadiusServer:12/02/2015 08:10:02:056 AM MST: Thread[RADIUS-1813-Listener,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-154]
RadiusServerEventRegistrar.packetReceived() - total now 1
amRadiusServer:12/02/2015 08:10:02:056 AM MST: Thread[RADIUS-1813-Listener,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-154]
WARNING: No Defined RADIUS Client matches IP address /127.0.0.1. Dropping request.

Defining a Client

Back in the admin console in Configuration/Global/Radius Server I now press the New button in the Secondary Instances table. (Wish we could give that table a name rather than that generic term. But I digress.) The form auto-populates a number of fields including the realm and chain properties for the default handler and a default IP address for testing from the same machine as is running OpenAM. Sweet. I name the client test, enable packet content logging, set the shared secret to the one used in my radius.properties file, and press the Add button. 

Contemplating Logs

The tailed Radius log file shows configuration changing... three times. Don't know why. The following lines appear to include three repeats of configuration changing as if there were three listeners registered for configuration changes. That might need attention if it caused problems. But as you'll see, it appears to be benign since thinks work just fine.

amRadiusServer:12/02/2015 08:24:26:980 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-7]
Entering globalConfigChange()
amRadiusServer:12/02/2015 08:24:26:981 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-7]
Leaving globalConfigChange()
amRadiusServer:12/02/2015 08:24:26:983 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Exiting ConfigChangeListener.waitForConfigChange, returning RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:26:994 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-10]
Entering globalConfigChange()
amRadiusServer:12/02/2015 08:24:26:995 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-10]
Leaving globalConfigChange()
amRadiusServer:12/02/2015 08:24:26:999 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-12]
Entering globalConfigChange()
amRadiusServer:12/02/2015 08:24:26:999 AM MST: Thread[smIdmThreadPool,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-12]
Leaving globalConfigChange()
amRadiusServer:12/02/2015 08:24:27:987 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:28:029 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
New RADIUS configuration loaded.[RadiusServiceConfig YES 1813 P( 1, 10, 10, 20), C( /127.0.0.1=test, letmein, true, org.forgerock.openam.radius.server.spi.handlers.OpenAMAuthHandler, {realm=/, chain=ldapService})]

amRadiusServer:12/02/2015 08:24:28:030 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Updating client configs.
amRadiusServer:12/02/2015 08:24:28:030 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Entering ConfigChangeListener.waitForConfigChange()
amRadiusServer:12/02/2015 08:24:28:030 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Exiting ConfigChangeListener.waitForConfigChange, returning RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:29:034 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:29:034 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
New RADIUS configuration loaded.[RadiusServiceConfig YES 1813 P( 1, 10, 10, 20), C( /127.0.0.1=test, letmein, true, org.forgerock.openam.radius.server.spi.handlers.OpenAMAuthHandler, {realm=/, chain=ldapService})]

amRadiusServer:12/02/2015 08:24:29:034 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Updating client configs.
amRadiusServer:12/02/2015 08:24:29:034 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Entering ConfigChangeListener.waitForConfigChange()
amRadiusServer:12/02/2015 08:24:29:035 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Exiting ConfigChangeListener.waitForConfigChange, returning RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:30:039 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
RADIUS Config Changed. Loading...
amRadiusServer:12/02/2015 08:24:30:040 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
New RADIUS configuration loaded.[RadiusServiceConfig YES 1813 P( 1, 10, 10, 20), C( /127.0.0.1=test, letmein, true, org.forgerock.openam.radius.server.spi.handlers.OpenAMAuthHandler, {realm=/, chain=ldapService})]

amRadiusServer:12/02/2015 08:24:30:040 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Updating client configs.
amRadiusServer:12/02/2015 08:24:30:040 AM MST: Thread[RADIUS-RadiusServerManager,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-263]
Entering ConfigChangeListener.waitForConfigChange()

Trying Again

Now we run the console client again and this time with a successful result:

$ java -jar openam-radius-server-13.0.0-SNAPSHOT.jar
? Username: amadmin
? Password: password1

Packet To 127.0.0.1:1813
DebugConfiguration:12/02/2015 08:28:59:279 AM MST: Thread[main,5,main]
'/debugconfig.properties' isn't valid, the default configuration will be used instead: Can't find the configuration file '/debugconfig.properties'.
  ACCESS_REQUEST [1]
    - USER_NAME : amadmin
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : localhost/127.0.0.1
    - NAS_PORT : 0

Packet From 127.0.0.1:1813
  ACCESS_ACCEPT [1]

---> SUCCESS! You've Authenticated!

In the tailed Radius log file a ton of lines scroll by. But embedded within them are the important ones that we are looking for:

...
amRadiusServer:12/02/2015 08:28:59:357 AM MST: Thread[pool-24-thread-1,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-154]
WARNING:
Packet from test:
  ACCESS_REQUEST [1]
    - USER_NAME : amadmin
    - USER_PASSWORD : *******
    - NAS_IP_ADDRESS : /127.0.0.1
    - NAS_PORT : 0
...
amRadiusServer:12/02/2015 08:28:59:404 AM MST: Thread[pool-24-thread-1,5,main]: TransactionId[73182e78-f842-4c29-ac57-9809fef53cfe-154]
WARNING:
Packet to test:
  ACCESS_ACCEPT [1]

Conclusions

The Radius Server functionality debuting in OpenAM 13 is working as expected. Open source and the collaborative process rocks. Doesn't it? Yes there are some new features that many of us would like to add in and will certainly start work on once the V13 code base is finalized and ready to roll. But what a great start for a Radius platform that can leverage many of the existing authentication features of OpenAM. Kudos to Jamie and the other engineers at forgerock for their work adding the Radius Server into baseline.

Enjoy.