How to properly deal with HTTP 200 response with body with rlm_rest?

Martin Gignac martin.gignac at gmail.com
Fri Apr 19 14:24:38 CEST 2019


Hi,

I have FreeRADIUS 3.0.17 set up to use rlm_rest to contact a custom
REST server that does LDAP queries in the back and optionally does
TOTP validation as well. The REST server then returns HTTP 204 when
the request is accepted and HTTP 401 when it is rejected. So far this
has been working great for pfSense OpenVPN authentication and
WPA2-Enterprise, but now I want to use the same REST server to also
handle FreeRADIUS requests for a Raritan Dominion KVM. The KVM says
that I can optionally return a Filter-Id attribute containing a user
group in the Access-Accept to authorize the authenticating user to
access specific ports. Therefore, I've modified the REST server to
return an HTTP 200 OK along with a JSON payload that contains the
Filter-Id content I want to send back. When rlm_rest receives 204 it
reurns the 'ok' code, but when receiving any other 2xx response it
processes the body and returns the 'updated' code.

Where I'm having an issue is, even after reading the Technical Guide,
I'm having trouble wrapping my head around how I should properly deal
with the 'updated' return code so that ultimately it is not the
'Post-Auth-Type REJECT' that gets called, but instead some other
action where:

1) The request is seen as 'ok'/authorized, and
2) I can take the content of the Filter-Id and return it only with the
Access-Accept message.

Any guidance would be appreciated.

Thanks,
-Martin

P.S. Find below the debug output of:

a) a request with no returned body (and a resulting Access-Accept)
b) a request with a returned Filter-Id body (and a resulting Access-Reject)

-- Access-Accept
(2) Received Access-Request Id 89 from 192.168.18.23:33311 to
192.168.40.34:1812 length 80
(2)   NAS-Port-Type = Virtual
(2)   NAS-IP-Address = 192.168.18.23
(2)   User-Name = "toto"
(2)   Acct-Session-Id = "koko1234"
(2)   User-Password = "fsdfsd"
(2) # Executing section authorize from file
/usr/local/etc/raddb/sites-enabled/default
(2)   authorize {
(2)     policy filter_username {
(2)       if (&User-Name) {
(2)       if (&User-Name)  -> TRUE
(2)       if (&User-Name)  {
(2)         if (&User-Name =~ / /) {
(2)         if (&User-Name =~ / /)  -> FALSE
(2)         if (&User-Name =~ /@[^@]*@/ ) {
(2)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(2)         if (&User-Name =~ /\.\./ ) {
(2)         if (&User-Name =~ /\.\./ )  -> FALSE
(2)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(2)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))
  -> FALSE
(2)         if (&User-Name =~ /\.$/)  {
(2)         if (&User-Name =~ /\.$/)   -> FALSE
(2)         if (&User-Name =~ /@\./)  {
(2)         if (&User-Name =~ /@\./)   -> FALSE
(2)       } # if (&User-Name)  = notfound
(2)     } # policy filter_username = notfound
(2)     [preprocess] = ok
(2)     [chap] = noop
(2)     [mschap] = noop
(2)     [digest] = noop
(2) suffix: Checking for suffix after "@"
(2) suffix: No '@' in User-Name = "sdfsdf", looking up realm NULL
(2) suffix: No such realm "NULL"
(2)     [suffix] = noop
(2) eap: No EAP-Message, not doing EAP
(2)     [eap] = noop
(2)     [files] = noop
(2)     [expiration] = noop
(2)     [logintime] = noop
(2)     if (User-Password) {
(2)     if (User-Password)  -> TRUE
(2)     if (User-Password)  {
(2)       update control {
(2)         Auth-Type := rest
(2)       } # update control = noop
(2)     } # if (User-Password)  = noop
(2) pap: WARNING: No "known good" password found for the user.  Not
setting Auth-Type
(2) pap: WARNING: Authentication will fail unless a "known good"
password is available
(2)     [pap] = noop
(2)   } # authorize = ok
(2) Found Auth-Type = rest
(2) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
(2)   authenticate {
(2) rest: Expanding URI components
(2) rest: EXPAND http://127.0.0.1:9080
(2) rest:    --> http://127.0.0.1:9080
(2) rest: EXPAND /user/%{User-Name}/mac/%{Called-Station-ID}?action=authenticate
(2) rest:    --> /user/sdfsdf/mac/?action=authenticate
(2) rest: Sending HTTP POST to
"http://127.0.0.1:9080/user/sdfsdf/mac/?action=authenticate"
(2) rest: Encoding attribute "NAS-Port-Type"
(2) rest: Encoding attribute "NAS-IP-Address"
(2) rest: Encoding attribute "User-Name"
(2) rest: Encoding attribute "Acct-Session-Id"
(2) rest: Encoding attribute "User-Password"
(2) rest: Encoding attribute "Event-Timestamp"
(2) rest: Processing response header
(2) rest:   Status : 204 (No Content)
(2)     [rest] = ok
(2)   } # authenticate = ok
(2) # Executing section post-auth from file
/usr/local/etc/raddb/sites-enabled/default
(2)   post-auth {
(2)     update {
(2)       No attributes updated
(2)     } # update = noop
(2)     [exec] = noop
(2)     policy remove_reply_message_if_eap {
(2)       if (&reply:EAP-Message && &reply:Reply-Message) {
(2)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(2)       else {
(2)         [noop] = noop
(2)       } # else = noop
(2)     } # policy remove_reply_message_if_eap = noop
(2)   } # post-auth = noop
(2) Sent Access-Accept Id 89 from 192.168.40.34:1812 to
192.168.18.23:33311 length 0
(2) Finished request

-- Access-Reject
(4) Received Access-Request Id 212 from 192.168.18.23:56985 to
192.168.40.34:1812 length 81
(4)   NAS-Port-Type = Virtual
(4)   NAS-IP-Address = 192.168.18.23
(4)   User-Name = "toto"
(4)   Acct-Session-Id = "01dc5cb9b7469d20072c"
(4)   User-Password = "koko1234"
(4) # Executing section authorize from file
/usr/local/etc/raddb/sites-enabled/default
(4)   authorize {
(4)     policy filter_username {
(4)       if (&User-Name) {
(4)       if (&User-Name)  -> TRUE
(4)       if (&User-Name)  {
(4)         if (&User-Name =~ / /) {
(4)         if (&User-Name =~ / /)  -> FALSE
(4)         if (&User-Name =~ /@[^@]*@/ ) {
(4)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(4)         if (&User-Name =~ /\.\./ ) {
(4)         if (&User-Name =~ /\.\./ )  -> FALSE
(4)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(4)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))
  -> FALSE
(4)         if (&User-Name =~ /\.$/)  {
(4)         if (&User-Name =~ /\.$/)   -> FALSE
(4)         if (&User-Name =~ /@\./)  {
(4)         if (&User-Name =~ /@\./)   -> FALSE
(4)       } # if (&User-Name)  = notfound
(4)     } # policy filter_username = notfound
(4)     [preprocess] = ok
(4)     [chap] = noop
(4)     [mschap] = noop
(4)     [digest] = noop
(4) suffix: Checking for suffix after "@"
(4) suffix: No '@' in User-Name = "asdfasd", looking up realm NULL
(4) suffix: No such realm "NULL"
(4)     [suffix] = noop
(4) eap: No EAP-Message, not doing EAP
(4)     [eap] = noop
(4)     [files] = noop
(4)     [expiration] = noop
(4)     [logintime] = noop
(4)     if (User-Password) {
(4)     if (User-Password)  -> TRUE
(4)     if (User-Password)  {
(4)       update control {
(4)         Auth-Type := rest
(4)       } # update control = noop
(4)     } # if (User-Password)  = noop
(4) pap: WARNING: No "known good" password found for the user.  Not
setting Auth-Type
(4) pap: WARNING: Authentication will fail unless a "known good"
password is available
(4)     [pap] = noop
(4)   } # authorize = ok
(4) Found Auth-Type = rest
(4) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
(4)   authenticate {
(4) rest: Expanding URI components
(4) rest: EXPAND http://127.0.0.1:9080
(4) rest:    --> http://127.0.0.1:9080
(4) rest: EXPAND /user/%{User-Name}/mac/%{Called-Station-ID}?action=authenticate
(4) rest:    --> /user/asdfasd/mac/?action=authenticate
(4) rest: Sending HTTP POST to
"http://127.0.0.1:9080/user/asdfasd/mac/?action=authenticate"
(4) rest: Encoding attribute "NAS-Port-Type"
(4) rest: Encoding attribute "NAS-IP-Address"
(4) rest: Encoding attribute "User-Name"
(4) rest: Encoding attribute "Acct-Session-Id"
(4) rest: Encoding attribute "User-Password"
(4) rest: Encoding attribute "Event-Timestamp"
(4) rest: Processing response header
(4) rest:   Status : 200 (OK)
(4) rest:   Type   : json (application/json)
(4) rest: Parsing attribute "Filter-Id"
(4) rest: EXPAND Raritan:Gusergroup
(4) rest:    --> Raritan:Gusergroup
(4) rest: Filter-Id := "Raritan:Gusergroup"
(4)     [rest] = updated
(4)   } # authenticate = updated
(4) Failed to authenticate the user
(4) Using Post-Auth-Type Reject
(4) # Executing group from file /usr/local/etc/raddb/sites-enabled/default
(4)   Post-Auth-Type REJECT {
(4) attr_filter.access_reject: EXPAND %{User-Name}
(4) attr_filter.access_reject:    --> asdfasd
(4) attr_filter.access_reject: Matched entry DEFAULT at line 11
(4)     [attr_filter.access_reject] = updated
(4)     [eap] = noop
(4)     policy remove_reply_message_if_eap {
(4)       if (&reply:EAP-Message && &reply:Reply-Message) {
(4)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(4)       else {
(4)         [noop] = noop
(4)       } # else = noop
(4)     } # policy remove_reply_message_if_eap = noop
(4)   } # Post-Auth-Type REJECT = updated
(4) Delaying response for 1.000000 seconds
(4) (4) Discarding duplicate request from client wifi port 56985 - ID:
212 due to delayed response
(4) Sending delayed response
(4) Sent Access-Reject Id 212 from 192.168.40.34:1812 to
192.168.18.23:56985 length 20
(4) Cleaning up request packet ID 212 with timestamp +1997


More information about the Freeradius-Users mailing list