RADIUS Challenge/Response Troubleshooting

Instead of continuing to hijack another thread, I’m starting a new one here. I recently integrated an SMS provider and am testing SMS tokens with PI 3.4. Basic functionality is currently working:

  1. User enters username and token PIN
  2. Authentication fails, triggering an SMS token
  3. User reauthenticates using PIN+SMS token
  4. Authentication success

What doesn’t appear to be working for me is FreeRADIUS sending back an Access-Challenge packet.

Currently, when a user authentications, they have to enter their PIN+OTP for the password field. I guess before going any further, is it possible to support both this current behavior and challenge response where a user enters their userstore password and then challenged for an SMS/Email token from the same authenticating application? For example:

Scenario A
User enters username and PIN+OTP (TOTP/HOTP)
User is authenticated

Scenario B
User enters username and user store password
SMS/Email token generated
RADIUS/application request challenge response
User enters SMS/Email token to challenge response
User is authenticated

As indicated in another thread, PrivacyIDEA/FreeRADIUS is capable of sending an Access-Challenge packet back to the authenticating application prompting the user for the challenge token. Another user has indicated successfully configuring PrivacyIDEA and associated applications of supporting this behavior. However, only the perl-based plugin works for challenge-response and attribute mapping.

I initially suspected that because I am using FreeRADIUS 3.0, I was using the rest-based plugin. However, I am successfully using attribute mapping for user VPN connections. Furthermore, digging into my configurations, it appears I really AM using the perl-based plugin, though with slight syntactical modifications to get it to work with FreeRADIUS 3.0.

/freeradius/3.0/mods-enabled/perl

perl {
        filename = /usr/share/privacyidea/freeradius/privacyidea_radius.pm
}

/freeradius/3.0/sites-enabled/privacyidea
There’s a greater deviation on the site configuration under authentication. When adding the digest and unix modules, FreeRADIUS does not start. Though at the moment, I haven’t been able to troubleshoot why.

server {
    authorize {
        #files
        perl-privacyidea
        if (ok || updated) {
            update control {
                Auth-Type := Perl
            }
        }
    }
    listen {
        type = auth
        ipaddr = *
        port = 0
    }
    authenticate {
        Auth-Type Perl {
            perl-privacyidea
        }
    }
}

/freeradius/3.0/users

DEFAULT Auth-type := perl

I’ve then got a configuration file under /etc/privacyidea/rlm_perl.ini where I specify basic configuration settings and attribute mapppings.

So it seems I’m using the proper plugin and have SMS token configuration setup properly, but the additional challenege response box for our vpn connection doesn’t appear as anticipated.

I’m assuming radclient would allow me to see the Access-Challenge response, but instead, all I get is an Access-Reject

image

I have two policies setup
image
image

With the authentication policy enabled, my first authentication with user store credentials works and an SMS token is sent, but I still only get an Access-Reject. Attempting to authenticate using PIN+SMS OTP fails and generates another OTP.

So…I know I’m doing something wrong, but I’m not sure where. Any ideas?

Hitting PrivacyIDEA directly, it appears that it is making the request for the SMS token, so there’s just something not right with freeRADIUS.

image

Running freeradius in debug mode, an error is thrown while trying to build the RAD_REPLY variable. Could this be the cause of the issue?

(0) # Executing group from file /etc/freeradius/3.0/sites-enabled/privacyidea
(0)   Auth-Type perl {
(0) perl-privacyidea:   $RAD_REQUEST{'User-Name'} = &request:User-Name -> 'abc123'
(0) perl-privacyidea:   $RAD_REQUEST{'User-Password'} = &request:User-Password -> '1234'
(0) perl-privacyidea:   $RAD_REQUEST{'NAS-IP-Address'} = &request:NAS-IP-Address -> '192.168.1.1'
(0) perl-privacyidea:   $RAD_REQUEST{'Called-Station-Id'} = &request:Called-Station-Id -> '192.168.1.1'
(0) perl-privacyidea:   $RAD_REQUEST{'NAS-Identifier'} = &request:NAS-Identifier -> 'HA-Cluster'
(0) perl-privacyidea:   $RAD_REQUEST{'NAS-Port-Type'} = &request:NAS-Port-Type -> 'Virtual'
(0) perl-privacyidea:   $RAD_REQUEST{'Acct-Session-Id'} = &request:Acct-Session-Id -> '1fd'
(0) perl-privacyidea:   $RAD_REQUEST{'Connect-Info'} = &request:Connect-Info -> 'test'
(0) perl-privacyidea:   $RAD_REQUEST{'Fortinet-Vdom-Name'} = &request:Fortinet-Vdom-Name -> 'root'
(0) perl-privacyidea:   $RAD_REQUEST{'Packet-Src-IP-Address'} = &request:Packet-Src-IP-Address -> '192.168.1.1'
(0) perl-privacyidea:   $RAD_CHECK{'Auth-Type'} = &control:Auth-Type -> 'perl'
(0) perl-privacyidea:   $RAD_CONFIG{'Auth-Type'} = &control:Auth-Type -> 'perl'
rlm_perl: Config File /etc/privacyidea/rlm_perl.ini found!
rlm_perl: Debugging config: true
rlm_perl: Default URL https://server.fqdn.com/validate/check
rlm_perl: Looking for config for auth-type perl
rlm_perl: RAD_REQUEST: NAS-IP-Address = 192.168.1.1
rlm_perl: RAD_REQUEST: NAS-Port-Type = Virtual
rlm_perl: RAD_REQUEST: User-Name = abc123
rlm_perl: RAD_REQUEST: Fortinet-Vdom-Name = root
rlm_perl: RAD_REQUEST: User-Password = 1234
rlm_perl: RAD_REQUEST: Packet-Src-IP-Address = 192.168.1.1
rlm_perl: RAD_REQUEST: Connect-Info = test
rlm_perl: RAD_REQUEST: NAS-Identifier = HA-Cluster
rlm_perl: RAD_REQUEST: Acct-Session-Id = 1fd
rlm_perl: RAD_REQUEST: Called-Station-Id = 192.168.1.1
rlm_perl: Auth-Type: perl
rlm_perl: url: https://server.fqdn.com/validate/check
rlm_perl: user sent to privacyidea: abc123
rlm_perl: realm sent to privacyidea: userrealm
rlm_perl: resolver sent to privacyidea: userResolver
rlm_perl: client sent to privacyidea: 192.168.1.1
rlm_perl: state sent to privacyidea:
rlm_perl: urlparam realm = userrealm
rlm_perl: urlparam user = abc123
rlm_perl: urlparam resConf = userResolver
rlm_perl: urlparam client = 192.168.1.1
rlm_perl: urlparam pass = 1234
rlm_perl: Request timeout: 10
rlm_perl: elapsed time for privacyidea call: 2.649907
rlm_perl: Content {"id": 1, "jsonrpc": "2.0", "result": {"status": true, "value": false}, "time": 1624658921.3977695, "version": "privacyIDEA 3.4.1", "versionnumber": "3.4.1", "signature": "rsa_sha256_pss:17547b0
rlm_perl: privacyIDEA Result status is true!
rlm_perl: privacyIDEA access denied
rlm_perl: return RLM_MODULE_REJECT
(0) perl-privacyidea: &request:NAS-IP-Address = $RAD_REQUEST{'NAS-IP-Address'} -> '192.168.1.1'
(0) perl-privacyidea: &request:NAS-Port-Type = $RAD_REQUEST{'NAS-Port-Type'} -> 'Virtual'
(0) perl-privacyidea: &request:User-Name = $RAD_REQUEST{'User-Name'} -> 'abc123'
(0) perl-privacyidea: &request:Fortinet-Vdom-Name = $RAD_REQUEST{'Fortinet-Vdom-Name'} -> 'root'
(0) perl-privacyidea: &request:User-Password = $RAD_REQUEST{'User-Password'} -> '1234'
(0) perl-privacyidea: &request:Packet-Src-IP-Address = $RAD_REQUEST{'Packet-Src-IP-Address'} -> '192.168.1.1'
(0) perl-privacyidea: &request:Connect-Info = $RAD_REQUEST{'Connect-Info'} -> 'test'
(0) perl-privacyidea: &request:NAS-Identifier = $RAD_REQUEST{'NAS-Identifier'} -> 'HA-Cluster'
(0) perl-privacyidea: &request:Acct-Session-Id = $RAD_REQUEST{'Acct-Session-Id'} -> '1fd'
(0) perl-privacyidea: &request:Called-Station-Id = $RAD_REQUEST{'Called-Station-Id'} -> '192.168.1.1'
(0) perl-privacyidea: ERROR: Internal failure creating pair &reply:Reply-Message = $RAD_REPLY{'Reply-Message'} -> 'undef'
(0) perl-privacyidea: &control:Auth-Type = $RAD_CHECK{'Auth-Type'} -> 'perl'
(0)     [perl-privacyidea] = reject
(0)   } # Auth-Type perl = reject
(0) Failed to authenticate the user
(0) Using Post-Auth-Type Reject
(0) Post-Auth-Type sub-section not found.  Ignoring.
(0) Login incorrect (perl-privacyidea: Internal failure creating pair &reply:Reply-Message = $RAD_REPLY{'Reply-Message'} -> 'undef'): [abc123]

Could it be, that you have the policies no_detail_on_success or no_detail_on_fail set in your privacyIDEA policies?
https://privacyidea.readthedocs.io/en/latest/policies/authorization.html#no-detail-on-success

You must no deactivate the detail if you are doing challenge/response.

1 Like

Oh jeez…that was the problem…I spent WAAAYYY too much time on this for me not to see that.

Hi there,
i do not really understand the solution.
I’m testing privacyidea 3.8 with ubuntu setup, to evaluate the system.
Our aim is it to replace our old sms passcode system with privacyidea with the “smart migration” with a passthru policy.

Now we are at the nearly same point, we’ve got no access-challenge to privacyidea.

If I authenticate my testuser over the Web /validate/check then i get the following message:
https://192.168.xx.xx/validate/check?user=test-user&pass=password

{"detail": {"message": "The user has no tokens assigned", "threadid": 140119862851328}, "id": 2, "jsonrpc": "2.0", 
"result": {"authentication": "REJECT", "status": true, "value": false}, 
"time": 1675172052.3182726, "version": "privacyIDEA 3.8", "versionnumber": "3.8", 
"signature": "rsa_sha256_pss:d...3a"}

But directly after, i get the sms i expected. btw. i see the packet flow over tcpdump and the radius server sends back a access-challenge.

21:55:05.748252 IP 192.168.xx.xx.38548 > 192.168.xx.yy.1812: RADIUS, Access-Request (1), id: 0x74 length: 80
E..l<.@.@.....2F..21.....X.1.t.P...1.x].\......m..test-user .privacyIDEA."L.A8...q.o...&.I.v<r.S]Q.....5."
21:55:05.792493 IP 192.168.xx.yy.1812 > 192.168.xx.xx.38548: RADIUS, Access-Challenge (11), id: 0x74 length: 67
E.._......L...21..2F.....K{..t.C_.F7.@a....@O+....test-user:192.168.xx.xx:PAP..Enter PASSCODE

If i use now the passcode from the sms to authenticate at the webapi /validate/check
https://192.168.xx.xx/validate/check?user=test-user&pass=vyjudu

{"detail": {"message": "against RADIUS server passcode due to 'authentication-passcode'", 
"threadid": 139631070000896}, 
"id": 2, 
"jsonrpc": "2.0", 
"result": {"authentication": "ACCEPT", "status": true, "value": true}, "time": 1675249509.7527173, 
"version": "privacyIDEA 3.8", "versionnumber": "3.8", 
"signature": "rsa_sha256_pss:98..0b"}

so, this works so far, but no access-challenge on the web /validate/check and even not when i try this over the freeradius plugin.

root@vm:/etc/privacyidea# radtest -t pap test-user password 127.0.0.1 0 sharedsecret
Sent Access-Request Id 10 from 0.0.0.0:60617 to 127.0.0.1:1812 length 97
        User-Name = "test-user"
        User-Password = "password"
        NAS-IP-Address = 127.0.1.1
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "password"
Received Access-Reject Id 10 from 127.0.0.1:1812 to 127.0.0.1:60617 length 53
        Reply-Message = "The user has no tokens assigned"
(0) -: Expected Access-Accept got Access-Reject

same like the web endpoint

root@vm:/etc/privacyidea$ radtest -t pap test-user tukryt 127.0.0.1 0 sharesecret
Sent Access-Request Id 130 from 0.0.0.0:34313 to 127.0.0.1:1812 length 81
        User-Name = "test-user"
        User-Password = "tukryt"
        NAS-IP-Address = 127.0.1.1
        NAS-Port = 0
        Message-Authenticator = 0x00
        Cleartext-Password = "tukryt"
Received Access-Accept Id 130 from 127.0.0.1:1812 to 127.0.0.1:34313 length 48
        Reply-Message = "privacyIDEA access granted"

btw: another reply message, not the same as in the web endpoint
tcpdump of the web auth:

Web Endpoint auth / tcpdump

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), capture size 262144 bytes
11:23:00.270716 IP vm.36421 > PassCode.radius: RADIUS, Access-Request (1), id: 0x93 length: 80
11:23:00.324734 IP PassCode.radius > vm.36421: RADIUS, Access-Challenge (11), id: 0x93 length: 67
11:23:21.289896 IP vm.58762 > PassCode.radius: RADIUS, Access-Request (1), id: 0x94 length: 64
11:23:21.319381 IP PassCode.radius > vm.58762: RADIUS, Access-Accept (2), id: 0x94 length: 66

We only use one authentication rule with passthru, without some specials like no_details…

Did somebody have an hint for me?

To my knowledge passthru does not support challenge/response.

The SMS Passcode system receives the correct password, this is why it sends the SMS.
But privacyIDEA does not receive an ACCEPT, this is why it sends an authentication failure.

Hello @cornelinux,

thanks, that explains why I can’t get it to work, of course.
this could be a good feature as I need to be minimally invasive on the existing systems.

Is there perhabs another way to achieve this with privacyidea + freeradius?

Actually these are SMS.

So you have the phone numbers of the users.
You could easily create all SMS-tokens with the phone numbers in privacyIDEA at once and then migrate to any other tokentype you wish to.