logo_kerberos.gif

Difference between revisions of "Projects/OTPOverRADIUS"

From K5Wiki
Jump to: navigation, search
Line 1: Line 1:
 
{{project-early}}
 
{{project-early}}
   
== Description ==
+
= Description =
 
In 1.11 KRB5 gained client side support for OTP Preauth (RFC 6560), but up until now there is no server side support in tree. Red Hat has created an out-of-tree solution ([https://fedorahosted.org/AuthHub AuthHub]), based upon a plugin model. But our experimenting with this approach has demonstrated:
 
In 1.11 KRB5 gained client side support for OTP Preauth (RFC 6560), but up until now there is no server side support in tree. Red Hat has created an out-of-tree solution ([https://fedorahosted.org/AuthHub AuthHub]), based upon a plugin model. But our experimenting with this approach has demonstrated:
 
# Access to vendor SDKs is non-trivial
 
# Access to vendor SDKs is non-trivial
 
# All vendors provide a RADIUS server for OTP validation
 
# All vendors provide a RADIUS server for OTP validation
   
== Proposal ==
+
= Proposal =
   
The KDC-side support for OTP should read configuration from a user string and forward token validation to an appropriate RADIUS server. This plugin will be called otp_radius.
+
The KDC-side support for OTP should read configuration and forward token validation to an appropriate RADIUS server. This plugin will be called otp.
   
=== User String ===
+
=== Configuration ===
The user string '''otp_radius''' would contain a JSON formatted object which roughly reflects PA-OTP-CHALLENGE and is a near-duplicate of KRB5_RESPONDER_QUESTION_OTP, but containing support for RADIUS configuration:
+
  +
Configuration should go into kdc.conf as it may contain secrets that shouldn't be world readable. The configuration is defined as follows:
 
<code>
 
<code>
{
 
  +
[otp]
"service": <string>,
 
  +
<name> = {
"tokenInfo": [{
 
  +
vendor = <string>
"vendor": <string>,
 
  +
length = <integer>
"length": <integer>,
 
  +
format = <enum: decimal|hexadecimal|alphanumeric|binary|base64>
"format": <integer>,
 
  +
algID = <string>
"tokenID": <base64string>,
 
  +
server = {
"algID": <string>,
+
remote = <string>
"servers": [{
+
secret = <string>
"host": <string>,
+
striprealm = <boolean>
"port": <integer>,
+
attributes = {
"secret": <string>,
+
<name> = <string>
"attributes": {
+
}
"custom": [[<number_or_string>, <base64string>], ...]
+
}
}
+
}
}, ...]
 
}, ...]
 
}
 
 
</code>
 
</code>
   
In the object above, all fields are optional. If tokenInfo or servers is not specified, '[{}]' is assumed. If a server object is missing any fields, the following defaults are assumed:
 
  +
The follow values are informational only and will be sent to the client only if set in the config.
* host: localhost
 
  +
* vendor
* port: getservbyname("radius", "udp")
 
  +
* length
* secret: send password in cleartext
 
  +
* format
* attributes: {}
 
  +
* algID
  +
  +
Server configuration is a little more complicated. If no token types are defined in the configuration and a user is configured for OTP access (see below), the otp plugin will fall back to a non-standard RADIUS-over-UNIX-Socket (RoUS; inconceivable!): $KDCDIR/otp.socket. If at least one token type is defined, any token type that does not implement the server section will fall back to RoUS, but with the name of the tokenType: $KDCDIR/<name>.socket.
  +
  +
If a server section is defined, it MUST contain the secret field or the token type will be ignored. This is to prevent insecure message passing in non-RoUS mode. All of the other values are optional, with the following defaults:
  +
* remote: localhost:getservbyname("radius", "udp")
  +
* striprealm: false
  +
* attributes: none
  +
  +
The remote field can contain the following formats:
  +
* host
  +
* host:port
  +
* /path/to/unix/socket
  +
  +
=== User Strings ===
  +
  +
Some portion of the otp plugin configuration is user specific. This value will be stored as the user string ``otp`` with the following (JSON) format:
  +
<code>
  +
[{
  +
"type": <string>,
  +
"id": <string>,
  +
"username": <string>
  +
}, ...]
  +
</code>
   
RADIUS attributes may be specified by a string ONLY in the case of the attributes defined in RFC 2865. Otherwise, a number must be used. Support for custom dictionaries is NOT provided.
 
  +
All values above are optional. If ``type`` is not specified, the following will occur:
  +
* If no token types are defined in the config, we fall back to RoUS mode with the default socket.
  +
* If one or more token type is specified, the first one with valid configuration will be chosen.
   
 
=== Workflow ===
 
=== Workflow ===
In the first pass (no PA-OTP-REQUEST present), a PA-OTP-CHALLENGE will be generated from the user string (using all fields present except servers).
+
In the first pass (no PA-OTP-REQUEST present), a PA-OTP-CHALLENGE will be generated from the configuration and user strings.
   
Upon receipt of a PA-OTP-REQUEST, the KDC will attempt to match the PA-OTP-REQUEST with a tokenInfo from the user string. All matching tokenInfo objects will then be used as configuration for RADIUS validation, in the order they were specified, stopping after the first AccessAccept response is received. A round-robin approach will be used on the servers specified for load balancing.
+
Upon receipt of a PA-OTP-REQUEST, the KDC will attempt to match the PA-OTP-REQUEST with a tokenInfo from the user string. All matching tokenInfo objects will then be used as configuration for RADIUS validation, in the order they were specified, stopping after the first AccessAccept response is received.
   
 
=== RADIUS Packet ===
 
=== RADIUS Packet ===
 
The packet sent to the configured RADIUS server will contain:
 
The packet sent to the configured RADIUS server will contain:
* User-Name (default: user principal)
+
* User-Name (default: user principal; realm stripped per config)
 
* User-Password (otp-value from PA-OTP-REQUEST)
 
* User-Password (otp-value from PA-OTP-REQUEST)
 
* NAS-Identifier (default: gethostname())
 
* NAS-Identifier (default: gethostname())
* NAS-IP-Address (default: getsockname())
 
 
* Service-Type (default: Authenticate-Only)
 
* Service-Type (default: Authenticate-Only)
 
* Any custom attributes defined
 
* Any custom attributes defined
   
Any of the attributes specified above may be overridden by custom attribute except User-Password.
+
Any of the attributes specified above may be overridden by custom attribute except User-Name and User-Password.
   
 
=== Remaining Issues ===
 
=== Remaining Issues ===
* Should we use a RADIUS library or hand-craft packets? We should use a RADIUS library which provides support for EAP methods.
+
* Should we use a RADIUS library or hand-craft packets? We should use a RADIUS library which provides support for EAP methods. Unfortunately no such libraries exist.
* Should the default value of User-Name contain the realm or not?
+
* This architecture is not FIPS compliant due to RADIUS' use of MD5

Revision as of 18:07, 4 December 2012

This is an early stage project for MIT Kerberos. It is being fleshed out by its proponents. Feel free to help flesh out the details of this project. After the project is ready, it will be presented for review and approval.


Description

In 1.11 KRB5 gained client side support for OTP Preauth (RFC 6560), but up until now there is no server side support in tree. Red Hat has created an out-of-tree solution (AuthHub), based upon a plugin model. But our experimenting with this approach has demonstrated:

  1. Access to vendor SDKs is non-trivial
  2. All vendors provide a RADIUS server for OTP validation

Proposal

The KDC-side support for OTP should read configuration and forward token validation to an appropriate RADIUS server. This plugin will be called otp.

Configuration

Configuration should go into kdc.conf as it may contain secrets that shouldn't be world readable. The configuration is defined as follows:

[otp]
 <name> = {
  vendor = <string>
  length = <integer>
  format = <enum: decimal|hexadecimal|alphanumeric|binary|base64>
  algID  = <string>
  server = {
   remote = <string>
   secret = <string>
   striprealm = <boolean>
   attributes = {
    <name> = <string>
   }
  }
 }

The follow values are informational only and will be sent to the client only if set in the config.

  • vendor
  • length
  • format
  • algID

Server configuration is a little more complicated. If no token types are defined in the configuration and a user is configured for OTP access (see below), the otp plugin will fall back to a non-standard RADIUS-over-UNIX-Socket (RoUS; inconceivable!): $KDCDIR/otp.socket. If at least one token type is defined, any token type that does not implement the server section will fall back to RoUS, but with the name of the tokenType: $KDCDIR/<name>.socket.

If a server section is defined, it MUST contain the secret field or the token type will be ignored. This is to prevent insecure message passing in non-RoUS mode. All of the other values are optional, with the following defaults:

  • remote: localhost:getservbyname("radius", "udp")
  • striprealm: false
  • attributes: none

The remote field can contain the following formats:

  • host
  • host:port
  • /path/to/unix/socket

User Strings

Some portion of the otp plugin configuration is user specific. This value will be stored as the user string ``otp`` with the following (JSON) format:

[{
   "type": <string>,
   "id": <string>,
   "username": <string>
 }, ...]

All values above are optional. If ``type`` is not specified, the following will occur:

  • If no token types are defined in the config, we fall back to RoUS mode with the default socket.
  • If one or more token type is specified, the first one with valid configuration will be chosen.

Workflow

In the first pass (no PA-OTP-REQUEST present), a PA-OTP-CHALLENGE will be generated from the configuration and user strings.

Upon receipt of a PA-OTP-REQUEST, the KDC will attempt to match the PA-OTP-REQUEST with a tokenInfo from the user string. All matching tokenInfo objects will then be used as configuration for RADIUS validation, in the order they were specified, stopping after the first AccessAccept response is received.

RADIUS Packet

The packet sent to the configured RADIUS server will contain:

  • User-Name (default: user principal; realm stripped per config)
  • User-Password (otp-value from PA-OTP-REQUEST)
  • NAS-Identifier (default: gethostname())
  • Service-Type (default: Authenticate-Only)
  • Any custom attributes defined

Any of the attributes specified above may be overridden by custom attribute except User-Name and User-Password.

Remaining Issues

  • Should we use a RADIUS library or hand-craft packets? We should use a RADIUS library which provides support for EAP methods. Unfortunately no such libraries exist.
  • This architecture is not FIPS compliant due to RADIUS' use of MD5