simllll / node-radius-server

Radius Server in node js optimized for google auth
https://www.npmjs.com/package/radius-server
Other
64 stars 31 forks source link

Google LDAP - Multiple Base DN #285

Open nilldot opened 2 years ago

nilldot commented 2 years ago

Hi Guys,

Our Google workspace instance has 10+ domains which makes user search tricky, as requires multiple Base DN entries to find the users. I couldn't find a way to add more than one Base DN so far. Any advice would be appreciated.

Thanks!

nilldot commented 2 years ago

Anyone ? :)

simllll commented 2 years ago

Hi @nilldot , check out the Google LDAP Implementation here: https://github.com/simllll/node-radius-server/blob/master/src/auth/GoogleLDAPAuth.ts You can easily create your own auth Provider, just use this one as a base and extend it to your needs!

All the best Simon

nilldot commented 2 years ago

Unfortunately, getting the build error as per below. Seems to be typescript tsc related image

./node_modules/.bin/tsc -v

Version 4.6.4

Any advice would be appreciated Thank you

simllll commented 2 years ago

Seems related to ts 4.6.4... try to run it with 4.6.3 in the meantime. not quite sure where this is coming from.. looks like an upstream bug to me.

simllll commented 2 years ago

With typescript@next (nightly) the error is gone already, couldn't find the related ticket, but as long as the error is gone already with the nightly, I assume they found the upstream bug for this already :)

https://github.com/microsoft/TypeScript/issues/48914

nilldot commented 2 years ago

Right. It does work now. Good catch!

In regards to creating your own provider. I have to admin I'm a little bit puzzled.

  1. I tried to follow the example defined here: https://github.com/simllll/node-radius-server/blob/master/src/auth/README.md. I'm not sure how to reference C in that case

  2. I also tried to copy/create new files/classes to refferance in config.js dist/auth/GoogleLDAPAuth.d.ts > dist/auth/GoogleLDAPAuth_domainA.d.ts dist/auth/GoogleLDAPAuth.js.map > dist/auth/GoogleLDAPAuth_domainA.js.map dist/auth/GoogleLDAPAuth.js > dist/auth/GoogleLDAPAuth_domainA.js

config.js

add authentication: 'GoogleLDAPAuth_domainA', base: 'dc=domain1,dc=com' ...

But unfortunately, it didn't work.

Would it be possible for your to share/define the example for a new domain if possible? You have one for dc=hokify,dc=com', so dc=hokify2,dc=com' would do really.

Thank you!

simllll commented 2 years ago

Mhm by looking at it quickly, I actually guess it's not even necessary to change the code. The google ldap auth works like the following: 1.) Query all LDAP entries and generate a mappign between <username> -> DNand <email> -> DN 2.) at a login attempt, it checks if we find the username or the email in the table, and tries to authorize it with the DN + password.

so what you need is that the lookup adds other entries of the ldap directory. right now it looks it up by generating a searchBase and collects the result of it. the query for the search is the searchBase . which can be freely configured, or if it is not set, it is ou=users,${this.base} and this.base is for exampe "dc=hokify,dc=com"

so just try to overwrite "searchBase" with a query that returns all users of all your domains. not tested it but something like "ou=users" could do it? That means set in the config instead of "base" the value for "searchBase".

nilldot commented 2 years ago

Unfortunately, Google LDAP doesn't support the global catalog (similar to AD for instance) feature. Neither supports search across multiple domains. Really a joke for "enterprise" service IMHO. I have already checked this with Google (we use a Google Enterprise subscription) at some point too.

That said, some clients (Softerra LDAP Browser for example), can handle enumeration and then use sub-search, but it's the client-side implementation I'm afraid.

Also, i tried leaving the base DB empty '' as a test, but got [GoogleLDAPAuth] error: {"lde_message":"No Such Object","lde_dn":null} in the end. Bummer.

simllll commented 2 years ago

Can you try this branch: https://github.com/simllll/node-radius-server/tree/feat/multiple-dns

now you an add more base paths as an array in the config, e.g. base: ["dc=hokify,dc=com", "dc=hokify2,dc=com", "dc=hokify3,dc=com"]

nilldot commented 2 years ago

Odd, I get

image

I have even tried using your base DN as an example. Brach is correct though

simllll commented 2 years ago

Sounds like an error in the config? Can you post the whole file

nilldot commented 2 years ago

Right, apparently, I missed the comma after the base DN definition, hence the issue ... It does look to work using NTradPing utility, also it is worth mentioning that NTradPing shows more logs so to speak.

The running [UDPServer] radius-server process, listening 0.0.0.0:1812 only shows SUCCESS (or FAILURE) for the first connection, and doesn't show sequential logins. Not sure whether this is by design, but NTradPing for instance shows the response: Access-Accept.

Looks very promising though. I will try this in the pre-production early this week and will report back. Thank you!

simllll commented 2 years ago

Good luck, for more verbose output you can set a loglevel e.g. in the config.

E.g. set loglevel: 'verbose'

All levels are: export enum LogLevel { Verbose = 'verbose', Debug = 'debug', Log = 'log', Warn = 'warn', Error = 'error', }

nilldot commented 2 years ago

Sorry for the delay on this one. Unfortunately, got "Error: no eap message found", after which app crashes :( image

Any advice? Thank you

Just to clarify, PEAP-MSCHAPv2 is expected here

nilldot commented 2 years ago

Also, It is odd default config/connection tries to use EAP-TTLS (I have no cert either way) and not eap-mschapv2

image

nilldot commented 2 years ago

Well, apparently no eap_mschapv2 module in the code, hence the issue :( image

nilldot commented 2 years ago

So guys, what is the real-world scenario usage for this app ? PAP is unencrypted (in fact, with debug set on server-side, one can read user password!) and hardly used these days. Any workaround? Thanks

simllll commented 2 years ago

TTLS is the way to go, the communication is encrypted!

nilldot commented 2 years ago

I'm confused now tbh.

TTLS is in essence tunnelled TLS. The issue here is that "PEAP-EAP-TLS aka EAP-TLS" needs a user/machine certificate, and has nothing to do with Google LDAP so to speak. We need EAP-PEAP here.

As per the error (see above), the app crashes after I try to connect from Windows 10 client. What I'm doing wrong ? Thank you

simllll commented 2 years ago

I guess you haven't authenticated with TTLS / PAP or the client is not supporting it. The error comes up if there is a type 21 (TTLS) EAP package that has no EAP message in it - sounds like a buggy client to me.

nilldot commented 2 years ago

It is a Windows 10 Pro client, so expected to work out of the box to be honest. Does it work for anyone actually? Thanks

simllll commented 2 years ago

There must be some issue on your side, we have several windows 10 pro clients. It should work out of the box, for example it does on our end with all kind of clients: Android,apple devices, windows 10/11, Linux, tv screens,....

Maybe this checklist helps:

nilldot commented 2 years ago

The problem is that TTLS is not selected by default Windows client, even as a fallback. Anyhow make this work using the MS-CHAP v2? Thanks

simllll commented 2 years ago

The radius server actually tells the client what mechanism can be used and they usually should find an agreement automatically. Are you sure you have no other config on your side that interferes? I can 100% assure that win 10 pro clients can automatically connect on our side.

Regarding MS-CHAP v2: I'm not sure if this can work in this case as you need to tunnel the (plaintext) password to the LDAP Server for authentication. But it's a while since when I was looking into it.