RADIUS Server, RADIUS Client and TACACS+ Client APIs

Home

Search

Prices & Ordering

Support

RADIUS Server

RADIUS Client

TACACS+ Client

Other Java Software

Company

Contact

Privacy

Disclaimer


RADIUS Server Frequently Asked Questions

The RADIUS Client has it's own FAQ.

Why do I get the exception 'java.lang.NoClassDefFoundError?

How many transations per second can the server handle?

What is a TLV attribute?

How do I create attributes?

Why don't the accent characters in the User-Name look correct?

How do I create Vendor-Specific attributes (VSA)?

What about Cisco Vendor-Specific attributes?

How do I prevent or limit multiple logins?

What is a realm?

What is a Proxy or Forwarding server?

How do I match forwarded requests and responses?

How can I tell how long a round trip to another server takes?

How are realms handled by the server?

How do I use the ProxyImpl to handle local domains?

There is no realm in the User-Name. How do I forward a packet to another server?

How do I directly respond to the client and not forward some packets?

How do I forward a packet to a server with a realm different than the one in the User-Name?

Why does the server say the password is bad, when it's obviously correct?

How do I decode the client password and compare it to the plain text password?

How do I handle User-Names in the form REALM / NAME?

How can an authentication succeed (Access-Accept is returned) even though there was a secret mismatch between the server and client?

When the RADIUS Server receives a packet with an incorrect secret it MUST be silently discarded. Why isn't the packet discarded?

What kind of packet should be sent back if the back end accounting system fails?

How does the Prepaid Application work with a RADIUS server?

What causes Proxy Failed errors?

What causes to server to say the packet is malformed?


I get the exception 'java.lang.NoClassDefFoundError:' when I start the examples - what's wrong?

Your CLASSPATH is incorrect. The example classes are meant to run in the directory where they're found. The batch and shell files are set up to find the correct jar file (please look at the batch files to see how they're trying to access the jar file). If you have extracted everything correctly and set the CLASSPATH to include the extracted files it will all work. There are many Web resources to help you set up your CLASSPATH.

How many transactions per second can the AXL RADIUS Server handle?

It is very difficult to determine the number of simultaneous requests the AXL RADIUS Server can handle in a particular situation.

  1. Rhe server may be starved for database connections (very common) which will limit performance. Any backend service may cause problems.
  2. With a large number of concurrent sessions and high CPU loads the server will be impacted by the JVM's garbage collection.
  3. Since the server uses code that your company writes it's impossible to predict how that will affect performance.
  4. There are underlying operating system UDP socket performance issues that remain mysterious.
  5. Many client load simulations merely determine how fast the client simulator can run instead of determining server performance.

As an example of #5 a short test was run recently of the client load test distributed with the AXL Server. This is by no means a much different test than that other so-called RADIUS client load testers we've tried.

This test was made with two office machines to illustrate the failure of client tests.

The tests ran a total of 200,000 PAP authentications. In the first test the timeout was one second and in the second test the timeout was 10 seconds. You can see that the throughput was apparently better with the shorter timeout with more lost packets than the test with the more typical timeout. This shows that the second test with the longer time outs was losing throughput because it was blocking for server responses and therefore not really measuring server throughput.

test A - 1 second timeout:
Successful Packets sent: 198,916 Packets per second 306
Total Packets sent: 200,000
Packets lost: 1084 Percent: 0

Test B - 10 second timeout:
Successful Packets sent: 199,967 Packets per second 163
Total Packets sent: 200,000
Packets lost: 33 Percent: 0

The best way to test performance is to use multiple client computers with load testing software and to program the demonstration server with software similar to what you will be using in the field.

What is a TLV attribute?

TLV stands for Tag / Length / Value. A RADIUS attribute consists of a tag field (one octet), a length field (one octet) and the value field. The length field include the tag and length field as well as the length of the data field. All attributes are TLV attributes.

How do I create attributes?

Use the class AttributeList. It has many ways to create attributes, merge attributes, and delete attributes.

Why don't the accent characters in the User-Name look correct?

This is usually because the User-Name is not being correctly encoded using the Util.toUTF8() method. the default encoding for the platform may not be UTF8 (when doing IO or using String().getBytes()). Similarly the data creating the name uses a Windows encoding that wasn't using Unicode or UFT8 encoding. You may have to decode the data differently before encoding it for the RADIUS client in UTF8.

Sometimes this can be seen in the length of the displayed User-Name attribute. The Attribute.toString() or AttributeList.toString() methods will display the User-Name. Accent characters should take up two octets, while Windows page code will only produce one character accent octets, usually in high ASCII values.

How do I create Vendor-Specific attributes (VSA)?

The VendorSpecific class builds VSA's. Vendor-Specific attributes allow a company to create extensions to the RADIUS attributes. Each vendor has a specific vendor number assigned to them.

First a little background: VSA's are attributes that contain sub-attributes. That is to say each VSA will contain one or more RADIUS style Tag/Length/Value (TLV) attributes. This allows the AttributeList class the create the sub-attributes. While it's possible to place a number of VSA sub-attributes in one Vendor-Specific attribute many RADIUS servers only examine the first sub-attribute. It's safer to use one VSA per attribute value.

Here's an example of creating an Ascend VSA:

// Create and populate the request attribute list.
AttributeList requestList = new AttributeList();
...
// Create the Ascend VSA.
VendorSpecific vs = new VendorSpecific(Ascend.VENDORID);
vs.addAttribute(Ascend.Ascend_Disconnect_Cause, 1);
Attribute vsAttr = vs.getAttribute();
// Merge the completed VSA with the request attributes.
requestList.addAttribute(vsAttr);

There are more examples of creating and extracting VSA's in the API documentation for the VendorSpecific class.

What about Cisco Vendor-Specific attributes?

Cisco's VSA's are a legacy from their proprietary TACACS protocol that offers services similar to RADIUS. Cisco VSA's use what are called Attribute Value Pairs (AVPairs). These are strings that represent the attribute name and it's value. An example might help illustrate this.

VendorSpecific vs = new VendorSpecific(Cisco.VENDORID);
vs.addAttribute(Cisco.323_credit_amount, "323_credit_amount=1");

Or this:

VendorSpecific vs = new VendorSpecific(Cisco.VENDORID);
vs.addAttribute(Cisco.avpair, "323_credit_amount=1");

Good descriptions of AVPairs are available at Cisco.

How do I prevent or limit multiple logins?

This is a back end function and not related to the AXL RADIUS Server's responsibilities. The method most commonly used is to watch Accounting-Request packets for Acct-Status-Type Stop and Start values. Matching them up can determine if multiple logins have occurred.

What is a realm?

A realm is the name of the final authenticating or accounting server. Usually this is explicitly given as part of the User-Name attribute's contents. The name is separated from the realm name by a '@' as in michael@company.com. The realm name is not necessarily a valid domain name. Internally servers use a mapping of names to IP address. This is related to forwarding packets or proxy servers.

Realms may also be implicitly determined from attributes like Called-Station-Id or Calling-Station-Id and other methods.

What is a Proxy or Forwarding server?

RADIUS packet submitted by a client may go directly to the authenticating or accounting server. In many cases the RADIUS packets are sent to an aggregating server that distributes the packets to other servers. This facilitates customer roaming whereby someone may travel and yet use the same final authenticating server while using local aggregating RADIUS servers provided by other ISP's.

The proxy server uses the realm information to direct the packet to another server. This server may be another in a chain of proxy servers or the final authenticator or accounting server. The proxy server must re-encode some attributes using the shared secret of the source of the packet and the shared secret of the destination server.

How do I match forwarded requests and responses?

Sometimes it's necessary to restore or otherwise change attributes that were passed to a proxy server. The ProxyInfo methods setProxyStateObject() and getProxyStateObject(); can be used to save and restore state information.

Suppose a proxy server must alter some response attributes for a particular realm. For example the authenticating server may sent an Access-Reject's Reply-Message attribute in french. The ProxyImpl.changeRequest() would set the would create as harsh replacement string in english and sets the Proxy-State information to contain the string: ProxyInfo.setProxyStateObject("Access Denied - Go away"), Other realms do not get have a Proxy-State object associated with them.

The ProxyImpl.changeResponse() method would check for the Access-Reject packet, and if found could substitute the Reply-Message with the contents it receives from the ProxyInfo.getProxyStateObject() if it exists.

Obviously more complex behavior is possible.

How can I tell how long a round trip to another server takes?

Sometimes the performance of the AXL RADIUS server is questioned particularly when forwarding packets. Clients can be used for ordinary performance measurements. It's another matter to determine where a bottleneck occurs when forwarding packets.

The ProxyInfo class provides a pair of methods that can determine the round trip time. Use the method ProxyInfo.setRoundTripTiming(boolean enable) in the ProxyImpl.changeRequest() with a value of 'true' to enable timing of ALL forwarded packets. It can be dynamically disabled by calling the method with the 'false' value.

The ProxyImpl.changeResponse() can get the timing of packets by using the ProxyInfo.getRoundTripTiming() to get the round trip time in milliseconds. The ProxyInfo.getRoundTripTimingString() gets a human readable time for logging. This information can be quite informative and aids in finger-pointing.

How are realms handled by the server?

There are two ways realms are handled.

Normally the server will handle realms without any programming intervention. The ProxyTarget class is used to configure the next RADIUS server where the packet will be forwarded. Synonyms may also be defined for each ProxyTarget such that all realms that match the synonyms will also be forwarded to that RADIUS server. A special 'empty' synonym can designate that User-Names without realms may be sent to that ProxyTarget. If this 'empty' realm is not defined in a ProxyTarget it will be handled locally.

Much of the configuration of the local server is also defined by a ProxyTarget so the local server may handle a number of realms. By default if no other ProxyTarget's have the 'empty' realm defined the local server handles all packets without realm information.

The second way to handle the routing of realms is to use the ProxyImpl class to define rules for handle forwarding based on realms or other attributes.

How do I use the ProxyImpl to handle local domains?

Extend the ProxyImpl class and use the ProxyInfo method:

ProxyImpl(ProxyInfo pi)
...
pi.setTransparentProxy(pi.getServerName());

Or edit the UserName realm:

AttributeList requestList = pi.getRequestAttributeList();
// Extract the name without the realm
String nameNoRealm = pi.getName();
// And substitute the value for the User-Name attribute.
requestList.setAttribute(Attribute.User_Name, Util.toUTF8(nameNoRealm));

There is no realm in the User-Name. How do I forward a packet to another server?

Please see the question on forwarding packets to other realms.

How do I directly respond to the client and not forward some packets?

See forwarding packets.

How do I forward a packet to a server with a realm different than the one in the User-Name?

The AXL RADIUS Server provides a ProxyImpl class which is extended to examine the request attributes and make decisions on where to route the packet.

The packet may be rerouted by altering the realm typically modifying the User-Name realm information.

Another way is to transparently route the packet using the ProxyInfo.setTransparentProxy() method. Transparent routing doesn't require and modification of the attributes. It can also be used to route packets and strip the realm from the User-Name attribute. Transparent routing may allow local handling of packet destined for many realms. In other words michael@company.com and michael@axlradius.com could both be handles locally or routed to a server at company.com.

For truly unusual situations please look at the ProxyClient class.This can be used to create new packets that may be cloned and sent to other servers. An example of this could be round-robin distribution of packets and fail-over situations.

The ProxyImpl class can also reroute reply packets in the same way, permitting replies to be handled locally for example. This would leave a client timing out but it could handle truly unusual situations.

Why does the server say the password is bad, when it's obviously correct?

It is possible for the password to encoded properly (in any method but PAP) yet the shared secret is wrong. The server will deduce that the password is correct but the client will discover that the response packet's authenticator is incorrect (ms-signed). The client MUST treat the packet as an Access-Reject.

How do I decode the client password and compare it to the plain text password?

Except for PAP authentication it is impossible to decode the client password for a direct comparison to a local plain text or otherwise encoded password. PAP passwords are decoded using Authinfo.decode(byte[] password) or AuthInfo.getDecodedUserPassword().

The method employed is to perform the same encoding on the plain text password as the client used. The two encoded passwords are compared. If the encoding match the passwords match. There is a very slight chance that a different password will match but that is out of the scope of this document.

All other passwords are sent as one-way hashes (encodings) that cannot be decoded.

For MSCHAP & MSCHAP V1 the AuthInfo method cmpMSCHAP(byte[] password) encoded and compares the password to the MSCHAP Vendor-Specific attributes in the request packet.

CHAP uses the cmpCHAP(byte[] plaintextPassword) method.

How do I handle User-Names in the form REALM / NAME?

There is an example of a ProxyImpl class called ProxySlashRealm.java in the server's example directory that handles this (com.theorem.radserver3.examples.server.ProxySlashRealm). It divides the User-Name attribute and determines if there is a realm present. It routes the packet to it's destination, either a remote machine or to the local machine (if the realm is missing). A similar conversion must be made in your AuthImpl and AccoutingImpl classes.

How can an authentication succeed (Access-Accept is returned) even though there was a secret mismatch between the server and client?

Only PAP authentications are sensitive to mismatched secrets.

Other forms of authentication like CHAP and MSCHAP don't use the shared secret to perform the authentication. The server will certainly find the encoded password acceptable. Although the server may send back an Access-Accept the client is responsible for checking the signed authenticator and rejecting the message if the signature isn't correct.

For example, a CHAP client uses an MD5 hash of a random challenge and the plain text password to produce a hash of the password. The server checks the MD5 of the password and the challenge and compares the two results. If they're the same the password is correct.

The server resigns the packet using the original authenticator, the secret, and the entire packet's contents. This is checked by the client and if there's a mismatch the client MUST reject the packet even if it's an Access-Accept.

The presence of a Message-Authenticator (MA) attribute in the client fixes the problem. The MA signs the authentication packet. The server checks the signature which includes the shared secret. The response packet also is provided with an MA and the client must check the response MA for correctness. The AXL RADIUS Client can include an MA by creating an Attribute.Message_Authenticator with any contents (even empty). The contents are discarded by the client and replaced with the signature.

When the RADIUS Server receives a packet with an incorrect secret it MUST be silently discarded. Why isn't the packet discarded?

This comes from a misreading of the RADIUS server authentication RFC. The relevant text states:

Once the RADIUS server receives the request, it validates the sending client. A request from a client for which the RADIUS server does not have a shared secret MUST be silently discarded.

Notice that the statement says 'does not have a shared secret' and not 'does not have a correct shared secret'. There is no possible way that the server can detect an incorrect secret in a normal packet as there is generally no information that is generated using the shared secret. It is the responsibility of the client to determine if the response packet is properly signed by the server.

The use of the Message-Authenticator attribute will force the detection of an incorrect secret by the server. This is generally used in conjunction with an EAP-Message but may be used alone.

Other side effects of an incorrect secret: PAP passwords will be incorrect as the PAP password is encoded using the shared secret. MSCHAP, CHAP, and other authentication methods will appear to succeed but the client should reject the response as the response packet's response authenticator (signature) will be incorrect as the server's secret is used in the signing process.

What kind of packet should be sent back if the back end accounting system fails?

The correct procedure if accounting is not completed is to issue NO response. You must throw an AccessDropException.

The RADIUS Accounting RFC 2866 is very clear on this:

"Upon receipt of an Accounting-Request, the server MUST transmit an
Accounting-Response reply if it successfully records the
accounting packet, and MUST NOT transmit any reply if it fails to
record the accounting packet."

An Access-Reject is never an acceptable response to an Accounting-Request. This type of response is made available only if some future and undefined packet type that arrives on the accounting port supports some form of packet-reject.

How does the Prepaid Application work with a RADIUS server?

Typically a phone gateway controlling the phone or other device contacts the RADIUS server and requests authorization to make the call. The RADIUS server will either make the calculation itself or communicate with another application to determine the maximum length of the call based on the money in the account. If the RADIUS server is performing all accounting functions it will use a database - otherwise it may use a TCP connection to the billing application to request information.

The RADIUS server will send a reply to the gateway with the maximum credited time allowed for the call. The gateway is then responsible for disconnections if either time or bandwidth are exceeded. The RADIUS server does not typically control the phone directly. So no monitoring of the log is necessary and the RADIUS server need not notify the gateway of a disconnect.

The gateway will send actual accounting information to the RADIUS server at the start and end of the call for actual billing.

I'm seeing the error PROXY FAILED - OUR PROXY-STATE ERROR Proxy-State: Can't find associated Proxy Target NAS 192.168.1.1 - PACKET DROPPED. What's causing this?

This error is usually transient and is caused when the ProxyTarget list is modified by perhaps removing existing ProxyTarget's and replacing them with updated versions. During this modification some packets may be dropped since they're proxy information has temporarily vanished. Proper clients will retry the request which will should succeed once your changes have completed.

What causes to server to say the packet is malformed?

If the RADIUS server is compliant with the basic packet construction the AXL RADIUS Client will construct correct packets. However it's possible to create attributes with a tag value of 0 or with an empty data value. Both of these conditions are forbidden by servers. There is no such attribute tag as 0 (valid values are 1 to 255). Attributes must always have data with a length greater than 1 byte. Attribute values with no value must not be sent.

 

TOP