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.
- Rhe server may be starved for database connections (very common) which
will limit performance. Any backend service may cause problems.
- With a large number of concurrent sessions and high CPU loads
the server will be impacted by the JVM's garbage collection.
- Since the
server uses code that your company writes it's impossible
to predict how that will affect performance.
- There are underlying
operating system UDP socket performance issues that remain mysterious.
- 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@theorem.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@theorem.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.