Hi,

> From my perspective, Chargeable-User-Identity is something that should
be logged with the 'custom' SQL logging rules being used.  Slipping it
into a separate table, somehow feels weird; I guess that's what makes me
a packet-pusher and someone else a database guru :)

The question is: where to put it. The CUI information comes with the Access-Accept, and needs to be stored before the first accounting packet (if any) arrives at the server. So it can't be an extra column in any accounting query. SQL logging in post-auth would be an option. But that usually doesn't store the necessary bits to retrofit the incoming accounting queries with the CUI value (Calling-Station-Id being one thing that needs to be logged alongside, to correlate the auth and acct). So that requires a new structure for radpostauth - which is certainly a possibility. I just wonder how much people fancy if radpostauth structure changes between releases - it hasn't changed in a long while now.


  * I thought Client-IP-Address was deprecated and we all should be using
        '%{%{Packet-Src-IPv6-Address}:-%{Packet-Src-IP-Address}}'

Humm. That deserves updating the code :-)

  * section 2.1 of RFC 4372 lets you be awkward about mis-matching CUI's
        and offers you the option to Reject :)

That's the paragraph for re-authentications, right? i.e

"Upon receiving a non-nul CUI value in an Access-Request, the home

   RADIUS server MAY verify that the value of CUI matches the CUI from
   the previous Access-Accept.  If the verification fails, then the
   RADIUS server SHOULD respond with an Access-Reject message."

I don't think that is essential or even clever to implement. A home server is 
allowed to change its CUIs after a (long) while. Now what happens if a user 
authenticated with one value for his CUI, the home server meanwhile rolled over 
to a new CUI, and then the client reauthenticates? Rejecting the re-auth is 
rather drastic, and out of control of the user in question.


  * not too sure about the outer.request bits.  It seems cleaner to get
        the inner layer to return just the User-Name to the outer layer,
        the outer layer can then add the CUI bits (as if it was a
        non-EAP request) and trim the User-Name in the reply packet
        before it sends out the Access-Accept

The code in that section is the result of a rather long and fruitful trial-and-error: there are EAP methods which don't have an inner method. Some other EAP types generate the CUI value not in the last inner-tunnel packet, but the penultimate one. I'm not the one who implemented it, but I know that much pain has gone into testing and refining these statements. But this doesn't preclude from advancing the implementation even more, of course. But I'd be happy to have *some* implementation in mainline release eventually, and then take it from there.

  * I never thought to add Operator-Name as part of the hash key for CUI,
        noted for myself, ta
  * not sure about even having cui_require_operator_name as the
        user's realm would tell you who you need to pester surely?

No, the user's realm gives the Service Provider an idea who the responsible Identity Provider is. Operator-Name gives the Identity Provider an idea which Service Provider to pester.

The "require" part of this is due to privacy considerations: if Operator-Name is not in the packet, CUI for a user will be the same *at all Service Provider locations* - enabling tracking mobility profiles. As an Identity Provider you could say: "I'll only release CUI if I can do it per Service Provider to prevent tracking" - and the "require" option allows you to make just that happen.

Greetings,

Stefan Winter

My approach is a bit more softly-softly (although I will admit it has
not had any field testing), most of the brains is here in policy.conf:
----
cui {
         if (Realm == "%{config:local.MY.realm}") {
                 update control {
                         # md5(cui_hash_key + u...@realm)
                         Chargeable-User-Identity := 
"%{md5:%{config:local.MY.cui_hash_key}%{tolower:%{%{reply:User-Name}:-%{request:User-Name}}}}"
                 }

                 if ((request:Chargeable-User-Identity)) {
                         update reply {
                                 Chargeable-User-Identity := 
"%{control:Chargeable-User-Identity}"
                         }

                         if (request:Chargeable-User-Identity != "\\000") {
                                 if (request:Chargeable-User-Identity != 
reply:Chargeable-User-Identity) {
                                         update reply {
                                                 Reply-Message := "CUI Mismatch"
                                         }
                                         reject
                                 }
                         }
                 }
                 else {
                         update request {
                                 Chargeable-User-Identity := 
"%{control:Chargeable-User-Identity}"
                         }
                 }

                 ok
         }

         noop
}
----

The for internal clients I have something like[1]:
----
post-auth {
         update reply {
                 Operator-Name := "1%{config:local.MY.realm}"
         }

         cui

         [snipped policy]

         [snipped logging]
}

accounting {
         [snipped logging]

         cui

         [snipped logging]
}

pre-proxy {
         if (Packet-Type != "Accounting-Request") {
                 update proxy-request {
                         Service-Type := Authenticate-Only
                         Chargeable-User-Identity := "\\000"
                 }
         }

         update proxy-request {
                 Operator-Name := "1%{config:local.MY.realm}"

                 NAS-IP-Address := "%{config:local.MY.addr.lanwarden.v4}"
                 NAS-IPv6-Address := "%{config:local.MY.addr.lanwarden.v6}"
         }

         [snipped logging]
}
----

For the roamers:
----
post-auth {
         cui

         [snipped policy]

         [snipped logging]
}
----

For the SQL logging, it is just an extra column on my table:
----
CREATE TABLE dot1x_auth
(
   id bigserial NOT NULL,
   realm character varying(253),
   nas_ip_address inet,
   nas_port_type character varying(32),
   nas_port_id character varying(64),
   calling_station_id character varying(64) NOT NULL,
   called_station_id character varying(64),
   packet_src_address inet NOT NULL,
   nas_identifier character varying(253),
   reply_message character varying(253),
   module_message character varying(253),
   eap_type character varying(16),
   auth_type character varying(16),
   "timestamp" timestamp with time zone NOT NULL,
   packet_type character varying(32) NOT NULL,
   tunnel_private_group_id character varying(32),
   user_name character varying(253) NOT NULL,
   inet_client_addr inet NOT NULL DEFAULT inet_client_addr(),
   nas_port integer,
   nas_ipv6_address inet,
   chargeable_user_identity character varying(253),<------
   operator_name character varying(253),<------
   CONSTRAINT dot1x_auth_id PRIMARY KEY (id)
)
----

Cheers

[1] snipped irrelevant bits of course, if anyone wants our full
        FreeRADIUS config dump to see this in real life then do ask
        offlist



--
Stefan WINTER
Ingenieur de Recherche
Fondation RESTENA - Réseau Téléinformatique de l'Education Nationale et de la 
Recherche
6, rue Richard Coudenhove-Kalergi
L-1359 Luxembourg

Tel: +352 424409 1
Fax: +352 422473

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html

Reply via email to