back-slash in username that making escape character issue

Eric Lin pirate585 at gmail.com
Tue Jan 2 08:26:19 UTC 2024


Hello,

The story:
I got an issue for escaping character issue when back-slash is in
username. Recently, my company has introduced Azure MFA. On Microsoft
RD Gateway, it sends radius auth to Microsoft NPS server in order to
integrate to the Azure MFA authentication workflow. Everything works
fine; however, NPS did not support account bypassing. Meaning, all
radius auth requests sent to the NPS server will be enforced to use
MFA. So we need to put a radius proxy in-between RD gateway and NPS to
filter/redirect the radius auth requests for these special accounts.
We plan to use freeradius as radius proxy for this purpose. The flow
is RD client --> RD gateway --radius auth request --> freeradius
--proxy to--> NPS.

On the freeradius, normal accounts will be proxied to the NPS
server and special accounts will be proxied to another radius server.
The whole workflow looks good and only issue is the escaping
characters (\n, \r, and \t). The username sent by RD Gateway server is
DomainA\\username format

The issue:
for account without escape characters, it works fine as follows.
-----------------------------------
Ready to process requests
(0) Received Access-Request Id 3 from 10.88.18.245:56346 to
10.88.18.212:1812 length 153
(0)   Service-Type = Sip-session
(0)   User-Name = "domainA\\eric"
(0)   Called-Station-Id = "UserAuthType:PW"
(0)   MS-Network-Access-Server-Type = Terminal-Server-Gateway
(0)   NAS-Port-Type = Virtual
(0)   Proxy-State = 0xfe800000000000003558d7bb169c1a1f0000001e
(0)   Message-Authenticator = 0xf2ac68355d495175cda15b87b7157ed5
(0) # Executing section authorize from file
/etc/freeradius/3.0/sites-enabled/default
(0)   authorize {
(0)     policy filter_username {
(0)       if (&User-Name) {
(0)       if (&User-Name)  -> TRUE
(0)       if (&User-Name)  {
(0)         if (&User-Name =~ / /) {
(0)         if (&User-Name =~ / /)  -> FALSE
(0)         if (&User-Name =~ /@[^@]*@/ ) {
(0)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(0)         if (&User-Name =~ /\.\./ ) {
(0)         if (&User-Name =~ /\.\./ )  -> FALSE
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))
  -> FALSE
(0)         if (&User-Name =~ /\.$/)  {
(0)         if (&User-Name =~ /\.$/)   -> FALSE
(0)         if (&User-Name =~ /@\./)  {
(0)         if (&User-Name =~ /@\./)   -> FALSE
(0)       } # if (&User-Name)  = notfound
(0)     } # policy filter_username = notfound
(0)     [preprocess] = ok
(0)     [chap] = noop
(0)     [mschap] = noop
(0)     [digest] = noop
(0) ntdomain: Checking for prefix before "\"
(0) ntdomain: Looking up realm "domainA" for User-Name = "domainA\eric"
(0) ntdomain: Found realm "domainA"
(0) ntdomain: Adding Realm = "domainA"
(0) ntdomain: Proxying request from user domainA\eric to realm domainA
(0) ntdomain: Preparing to proxy authentication request to realm "domainA"
-----------------------------------

but accounts starting with r, t and n will encounter escape character issue
-----------------------------------
Ready to process requests
(0) Received Access-Request Id 3 from 10.88.18.245:56346 to
10.88.18.212:1812 length 153
(0)   Service-Type = Sip-session
(0)   User-Name = "domainA\tee"
(0)   Called-Station-Id = "UserAuthType:PW"
(0)   MS-Network-Access-Server-Type = Terminal-Server-Gateway
(0)   NAS-Port-Type = Virtual
(0)   Proxy-State = 0xfe800000000000003558d7bb169c1a1f0000001e
(0)   Message-Authenticator = 0xf2ac68355d495175cda15b87b7157ed5
(0) # Executing section authorize from file
/etc/freeradius/3.0/sites-enabled/default
(0)   authorize {
(0)     policy filter_username {
(0)       if (&User-Name) {
(0)       if (&User-Name)  -> TRUE
(0)       if (&User-Name)  {
(0)         if (&User-Name =~ / /) {
(0)         if (&User-Name =~ / /)  -> FALSE
(0)         if (&User-Name =~ /@[^@]*@/ ) {
(0)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(0)         if (&User-Name =~ /\.\./ ) {
(0)         if (&User-Name =~ /\.\./ )  -> FALSE
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(0)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))
  -> FALSE
(0)         if (&User-Name =~ /\.$/)  {
(0)         if (&User-Name =~ /\.$/)   -> FALSE
(0)         if (&User-Name =~ /@\./)  {
(0)         if (&User-Name =~ /@\./)   -> FALSE
(0)       } # if (&User-Name)  = notfound
(0)     } # policy filter_username = notfound
(0)     [preprocess] = ok
(0)     [chap] = noop
(0)     [mschap] = noop
(0)     [digest] = noop
(0) ntdomain: Checking for prefix before "\"
(0) ntdomain: No '\' in User-Name = "domainA    ee", looking up realm NULL
(0) ntdomain: Found realm "NULL"
(0) ntdomain: Adding Realm = "NULL"
(0) ntdomain: Proxying request from user domainA        ee to realm NULL
(0) ntdomain: Preparing to proxy authentication request to realm "NULL"
(0)     [ntdomain] = updated
-----------------------------------

my freeradius version
radiusd: FreeRADIUS Version 3.0.26, for host x86_64-pc-linux-gnu,
built on Jan  4 2023 at 03:23:09

I had done my google search and found only one similar case
https://lists.freeradius.org/pipermail/freeradius-users/2017-February/086635.html
I also tried different config/tests on freeradius, but no luck.

Is there a way to not escaping characters in user-name on freeradius?

in my tests, there are two solutions on Windows side
1. ask all users to use UPN name instead of Domain\username to login.
This will have a major impact to users as it will change user
behavior globally. Not a good option,
2. on RD Gateway server, add filters to radius auth requests for t, n
and r accounts, for example,
search (.*)\\(t.*)
replace $1\$2
this solution will need to be applied to 30+ RD Gateway servers
managed by different teams/admins across global.

I am seeking if there is a more simple solution on freeradius. Can someone help?

Regards,
Eric


More information about the Freeradius-Users mailing list